korganizer

kodaymatrix.cpp

00001 /*
00002     This file is part of KOrganizer.
00003 
00004     Copyright (c) 2001 Eitzenberger Thomas <thomas.eitzenberger@siemens.at>
00005     Parts of the source code have been copied from kdpdatebutton.cpp
00006 
00007     Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
00008     Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
00009 
00010     This program is free software; you can redistribute it and/or modify
00011     it under the terms of the GNU General Public License as published by
00012     the Free Software Foundation; either version 2 of the License, or
00013     (at your option) any later version.
00014 
00015     This program is distributed in the hope that it will be useful,
00016     but WITHOUT ANY WARRANTY; without even the implied warranty of
00017     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00018     GNU General Public License for more details.
00019 
00020     You should have received a copy of the GNU General Public License
00021     along with this program; if not, write to the Free Software
00022     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00023 
00024     As a special exception, permission is given to link this program
00025     with any edition of Qt, and distribute the resulting executable,
00026     without including the source code for Qt in the source distribution.
00027 */
00028 
00029 #include <qevent.h>
00030 #include <qpainter.h>
00031 #include <qptrlist.h>
00032 
00033 #include <kglobal.h>
00034 #include <kdebug.h>
00035 #include <klocale.h>
00036 #include <kiconloader.h>
00037 
00038 #include <libkcal/vcaldrag.h>
00039 #include <libkcal/icaldrag.h>
00040 #include <libkcal/dndfactory.h>
00041 #include <libkcal/calendarresources.h>
00042 #include <libkcal/resourcecalendar.h>
00043 
00044 #include <kcalendarsystem.h>
00045 
00046 #include "koprefs.h"
00047 #include "koglobals.h"
00048 #include "kodialogmanager.h"
00049 
00050 #include "kodaymatrix.h"
00051 #include "kodaymatrix.moc"
00052 
00053 #ifndef NODND
00054 #include <qcursor.h>
00055 #include <kpopupmenu.h>
00056 #include <X11/Xlib.h>
00057 #undef FocusIn
00058 #undef KeyPress
00059 #undef None
00060 #undef Status
00061 #endif
00062 
00063 // ============================================================================
00064 //  D Y N A M I C   T I P
00065 // ============================================================================
00066 
00067 DynamicTip::DynamicTip( QWidget * parent )
00068     : QToolTip( parent )
00069 {
00070   mMatrix = static_cast<KODayMatrix *>( parent );
00071 }
00072 
00073 
00074 void DynamicTip::maybeTip( const QPoint &pos )
00075 {
00076   //calculate which cell of the matrix the mouse is in
00077   QRect sz = mMatrix->frameRect();
00078   int dheight = sz.height() * 7 / 42;
00079   int dwidth = sz.width() / 7;
00080   int row = pos.y() / dheight;
00081   int col = pos.x() / dwidth;
00082 
00083   QRect rct( col * dwidth, row * dheight, dwidth, dheight );
00084 
00085 //  kdDebug(5850) << "DynamicTip::maybeTip matrix cell index [" <<
00086 //                col << "][" << row << "] => " <<(col+row*7) << endl;
00087 
00088   //show holiday names only
00089   QString str = mMatrix->getHolidayLabel( col + row * 7 );
00090   if ( str.isEmpty() ) return;
00091   tip( rct, str );
00092 }
00093 
00094 
00095 // ============================================================================
00096 //  K O D A Y M A T R I X
00097 // ============================================================================
00098 
00099 const int KODayMatrix::NOSELECTION = -1000;
00100 const int KODayMatrix::NUMDAYS = 42;
00101 
00102 KODayMatrix::KODayMatrix( QWidget *parent, const char *name )
00103   : QFrame( parent, name ), mCalendar( 0 ), mStartDate(), mPendingChanges( false )
00104 {
00105   // initialize dynamic arrays
00106   mDays = new QDate[ NUMDAYS ];
00107   mDayLabels = new QString[ NUMDAYS ];
00108   mEvents = new int[ NUMDAYS ];
00109   mToolTip = new DynamicTip( this );
00110 
00111   mTodayMarginWidth = 2;
00112   mSelEnd = mSelStart = NOSELECTION;
00113   setBackgroundMode( NoBackground );
00114   recalculateToday();
00115 }
00116 
00117 void KODayMatrix::setCalendar( Calendar *cal )
00118 {
00119   if ( mCalendar ) {
00120     mCalendar->unregisterObserver( this );
00121     mCalendar->disconnect( this );
00122   }
00123 
00124   mCalendar = cal;
00125   mCalendar->registerObserver( this );
00126   CalendarResources *calres = dynamic_cast<CalendarResources*>( cal );
00127   if ( calres ) {
00128     connect( calres, SIGNAL(signalResourceAdded(ResourceCalendar *)), SLOT(resourcesChanged()) );
00129     connect( calres, SIGNAL(signalResourceModified( ResourceCalendar *)), SLOT(resourcesChanged()) );
00130     connect( calres, SIGNAL(signalResourceDeleted(ResourceCalendar *)), SLOT(resourcesChanged()) );
00131   }
00132 
00133   setAcceptDrops( mCalendar );
00134 
00135   updateEvents();
00136 }
00137 
00138 QColor KODayMatrix::getShadedColor( const QColor &color )
00139 {
00140   QColor shaded;
00141   int h = 0;
00142   int s = 0;
00143   int v = 0;
00144   color.hsv( &h, &s, &v );
00145   s = s / 4;
00146   v = 192 + v / 4;
00147   shaded.setHsv( h, s, v );
00148 
00149   return shaded;
00150 }
00151 
00152 KODayMatrix::~KODayMatrix()
00153 {
00154   if ( mCalendar )
00155     mCalendar->unregisterObserver( this );
00156   delete [] mDays;
00157   delete [] mDayLabels;
00158   delete [] mEvents;
00159   delete mToolTip;
00160 }
00161 
00162 void KODayMatrix::addSelectedDaysTo( DateList &selDays )
00163 {
00164   kdDebug(5850) << "KODayMatrix::addSelectedDaysTo() - " << "mSelStart:" << mSelStart << endl;
00165 
00166   if ( mSelStart == NOSELECTION ) {
00167     return;
00168   }
00169 
00170   // cope with selection being out of matrix limits at top (< 0)
00171   int i0 = mSelStart;
00172   if ( i0 < 0 ) {
00173     for ( int i = i0; i < 0; i++ ) {
00174       selDays.append( mDays[ 0 ].addDays( i ) );
00175     }
00176     i0 = 0;
00177   }
00178 
00179   // cope with selection being out of matrix limits at bottom (> NUMDAYS-1)
00180   if ( mSelEnd > NUMDAYS-1 ) {
00181     for ( int i = i0; i <= NUMDAYS - 1; i++ ) {
00182       selDays.append( mDays[ i ] );
00183     }
00184     for ( int i = NUMDAYS; i < mSelEnd; i++ ) {
00185       selDays.append( mDays[ 0 ].addDays( i ) );
00186     }
00187   } else {
00188     // apply normal routine to selection being entirely within matrix limits
00189     for ( int i = i0; i <= mSelEnd; i++ ) {
00190       selDays.append( mDays[ i ] );
00191     }
00192   }
00193 }
00194 
00195 void KODayMatrix::setSelectedDaysFrom( const QDate &start, const QDate &end )
00196 {
00197   if ( mStartDate.isValid() ) {
00198     mSelStart = mStartDate.daysTo( start );
00199     mSelEnd = mStartDate.daysTo( end );
00200   }
00201 }
00202 
00203 void KODayMatrix::clearSelection()
00204 {
00205   mSelEnd = mSelStart = NOSELECTION;
00206 }
00207 
00208 void KODayMatrix::recalculateToday()
00209 {
00210   if ( !mStartDate.isValid() ) return;
00211   mToday = -1;
00212   for ( int i = 0; i < NUMDAYS; i++ ) {
00213     mDays[ i ] = mStartDate.addDays( i );
00214     mDayLabels[ i ] = QString::number( KOGlobals::self()->calendarSystem()->day( mDays[i] ));
00215 
00216     // if today is in the currently displayed month, hilight today
00217     if ( mDays[ i ].year() == QDate::currentDate().year() &&
00218          mDays[ i ].month() == QDate::currentDate().month() &&
00219          mDays[ i ].day() == QDate::currentDate().day() ) {
00220       mToday = i;
00221     }
00222   }
00223   // kdDegug(5850) << "Today is visible at "<< today << "." << endl;
00224 }
00225 
00226 /* slot */ void KODayMatrix::updateView()
00227 {
00228   updateView( mStartDate );
00229 }
00230 
00231 void KODayMatrix::updateView( const QDate &actdate )
00232 {
00233  kdDebug(5850) << "KODayMatrix::updateView() " << actdate << ", day start="<<mStartDate<< endl;
00234  if ( !actdate.isValid() ) return;
00235 
00236   //flag to indicate if the starting day of the matrix has changed by this call
00237   bool daychanged = false;
00238 
00239   // if a new startdate is to be set then apply Cornelius's calculation
00240   // of the first day to be shown
00241   if ( actdate != mStartDate ) {
00242     // reset index of selection according to shift of starting date from startdate to actdate
00243     if ( mSelStart != NOSELECTION ) {
00244       int tmp = actdate.daysTo( mStartDate );
00245       //kdDebug(5850) << "Shift of Selection1: " << mSelStart << " - " << mSelEnd << " -> " << tmp << "(" << offset << ")" << endl;
00246       // shift selection if new one would be visible at least partly !
00247 
00248       if ( mSelStart + tmp < NUMDAYS && mSelEnd + tmp >= 0 ) {
00249         // nested if is required for next X display pushed from a different month - correction required
00250         // otherwise, for month forward and backward, it must be avoided
00251         if( mSelStart > NUMDAYS || mSelStart < 0 )
00252           mSelStart = mSelStart + tmp;
00253         if( mSelEnd > NUMDAYS || mSelEnd < 0 )
00254           mSelEnd = mSelEnd + tmp;
00255       }
00256     }
00257 
00258     mStartDate = actdate;
00259     daychanged = true;
00260   }
00261 
00262   if ( daychanged ) {
00263     recalculateToday();
00264   }
00265 
00266   // the calendar hasn't changed in the meantime and the selected range is still the same
00267   // so we can safe the expensive updateEvents() call
00268   if ( !daychanged && !mPendingChanges )
00269     return;
00270 
00271   // TODO_Recurrence: If we just change the selection, but not the data, there's
00272   // no need to update the whole list of events... This is just a waste of
00273   // computational power (and it takes forever!)
00274   updateEvents();
00275   for( int i = 0; i < NUMDAYS; i++ ) {
00276     //if it is a holy day then draw it red. Sundays are consider holidays, too
00277     QStringList holidays = KOGlobals::self()->holiday( mDays[ i ] );
00278     QString holiStr = QString::null;
00279 
00280     if ( ( KOGlobals::self()->calendarSystem()->dayOfWeek( mDays[ i ] ) ==
00281            KOGlobals::self()->calendarSystem()->weekDayOfPray() ) ||
00282          !holidays.isEmpty() ) {
00283       if ( !holidays.isEmpty() ) holiStr = holidays.join( i18n("delimiter for joining holiday names", ", " ) );
00284       if ( holiStr.isNull() ) holiStr = "";
00285     }
00286     mHolidays[ i ] = holiStr;
00287   }
00288 }
00289 
00290 void KODayMatrix::updateEvents()
00291 {
00292   kdDebug( 5850 ) << k_funcinfo << endl;
00293   if ( !mCalendar ) return;
00294 
00295   for( int i = 0; i < NUMDAYS; i++ ) {
00296     // if events are set for the day then remember to draw it bold
00297     Event::List eventlist = mCalendar->events( mDays[ i ] );
00298     int numEvents = eventlist.count();
00299     Event::List::ConstIterator it;
00300     for( it = eventlist.begin(); it != eventlist.end(); ++it ) {
00301       Event *event = *it;
00302       ushort recurType = event->recurrenceType();
00303       if ( ( recurType == Recurrence::rDaily &&
00304              !KOPrefs::instance()->mDailyRecur ) ||
00305            ( recurType == Recurrence::rWeekly &&
00306              !KOPrefs::instance()->mWeeklyRecur ) ) {
00307         numEvents--;
00308       }
00309     }
00310     mEvents[ i ] = numEvents;
00311   }
00312 
00313   mPendingChanges = false;
00314 }
00315 
00316 const QDate& KODayMatrix::getDate( int offset )
00317 {
00318   if ( offset < 0 || offset > NUMDAYS - 1 ) {
00319     kdDebug(5850) << "Wrong offset (" << offset << ") in KODayMatrix::getDate(int)" << endl;
00320     return mDays[ 0 ];
00321   }
00322   return mDays[ offset ];
00323 }
00324 
00325 QString KODayMatrix::getHolidayLabel( int offset )
00326 {
00327   if ( offset < 0 || offset > NUMDAYS - 1 ) {
00328     kdDebug(5850) << "Wrong offset (" << offset << ") in KODayMatrix::getHolidayLabel(int)" << endl;
00329     return 0;
00330   }
00331   return mHolidays[ offset ];
00332 }
00333 
00334 int KODayMatrix::getDayIndexFrom( int x, int y )
00335 {
00336   return 7 * ( y / mDaySize.height() ) +
00337          ( KOGlobals::self()->reverseLayout() ?
00338            6 - x / mDaySize.width() : x / mDaySize.width() );
00339 }
00340 
00341 void KODayMatrix::calendarIncidenceAdded(Incidence * incidence)
00342 {
00343   mPendingChanges = true;
00344 }
00345 
00346 void KODayMatrix::calendarIncidenceChanged(Incidence * incidence)
00347 {
00348   mPendingChanges = true;
00349 }
00350 
00351 void KODayMatrix::calendarIncidenceRemoved(Incidence * incidence)
00352 {
00353   mPendingChanges = true;
00354 }
00355 
00356 void KODayMatrix::resourcesChanged()
00357 {
00358   mPendingChanges = true;
00359 }
00360 
00361 
00362 // ----------------------------------------------------------------------------
00363 //  M O U S E   E V E N T   H A N D L I N G
00364 // ----------------------------------------------------------------------------
00365 
00366 void KODayMatrix::mousePressEvent( QMouseEvent *e )
00367 {
00368   mSelStart = getDayIndexFrom(e->x(), e->y());
00369   if (mSelStart > NUMDAYS-1) mSelStart=NUMDAYS-1;
00370   mSelInit = mSelStart;
00371 }
00372 
00373 void KODayMatrix::mouseReleaseEvent( QMouseEvent *e )
00374 {
00375   int tmp = getDayIndexFrom(e->x(), e->y());
00376   if (tmp > NUMDAYS-1) tmp=NUMDAYS-1;
00377 
00378   if (mSelInit > tmp) {
00379     mSelEnd = mSelInit;
00380     if (tmp != mSelStart) {
00381       mSelStart = tmp;
00382       repaint();
00383     }
00384   } else {
00385     mSelStart = mSelInit;
00386 
00387     //repaint only if selection has changed
00388     if (tmp != mSelEnd) {
00389       mSelEnd = tmp;
00390       repaint();
00391     }
00392   }
00393 
00394   DateList daylist;
00395   if ( mSelStart < 0 ) mSelStart = 0;
00396   for ( int i = mSelStart; i <= mSelEnd; ++i ) {
00397     daylist.append( mDays[i] );
00398   }
00399   emit selected((const DateList)daylist);
00400 }
00401 
00402 void KODayMatrix::mouseMoveEvent( QMouseEvent *e )
00403 {
00404   int tmp = getDayIndexFrom(e->x(), e->y());
00405   if (tmp > NUMDAYS-1) tmp=NUMDAYS-1;
00406 
00407   if (mSelInit > tmp) {
00408     mSelEnd = mSelInit;
00409     if (tmp != mSelStart) {
00410       mSelStart = tmp;
00411       repaint();
00412     }
00413   } else {
00414     mSelStart = mSelInit;
00415 
00416     //repaint only if selection has changed
00417     if (tmp != mSelEnd) {
00418       mSelEnd = tmp;
00419       repaint();
00420     }
00421   }
00422 }
00423 
00424 // ----------------------------------------------------------------------------
00425 //  D R A G ' N   D R O P   H A N D L I N G
00426 // ----------------------------------------------------------------------------
00427 
00428 //-----------------------------------------------------------------------------
00429 // Drag and Drop handling -- based on the Troll Tech dirview example
00430 
00431 enum {
00432   DRAG_COPY = 0,
00433   DRAG_MOVE = 1,
00434   DRAG_CANCEL = 2
00435 };
00436 
00437 void KODayMatrix::dragEnterEvent( QDragEnterEvent *e )
00438 {
00439 #ifndef KORG_NODND
00440   if ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) ) {
00441     e->ignore();
00442     return;
00443   }
00444 
00445   // some visual feedback
00446 //  oldPalette = palette();
00447 //  setPalette(my_HilitePalette);
00448 //  update();
00449 #endif
00450 }
00451 
00452 void KODayMatrix::dragMoveEvent( QDragMoveEvent *e )
00453 {
00454 #ifndef KORG_NODND
00455   if ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) ) {
00456     e->ignore();
00457     return;
00458   }
00459 
00460   e->accept();
00461 #endif
00462 }
00463 
00464 void KODayMatrix::dragLeaveEvent( QDragLeaveEvent * /*dl*/ )
00465 {
00466 #ifndef KORG_NODND
00467 //  setPalette(oldPalette);
00468 //  update();
00469 #endif
00470 }
00471 
00472 void KODayMatrix::dropEvent( QDropEvent *e )
00473 {
00474 #ifndef KORG_NODND
00475   kdDebug(5850) << "KODayMatrix::dropEvent(e) begin" << endl;
00476 
00477   if ( !mCalendar ||
00478        ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) ) ) {
00479     e->ignore();
00480     return;
00481   }
00482 
00483   DndFactory factory( mCalendar );
00484   Event *event = factory.createDrop( e );
00485   Todo *todo = factory.createDropTodo( e );
00486   if ( !event && !todo ) {
00487     e->ignore();
00488     return;
00489   }
00490 
00491   Todo *existingTodo = 0;
00492   Event *existingEvent = 0;
00493 
00494   // Find the incidence in the calendar, then we don't need the drag object any more
00495   if ( event ) existingEvent = mCalendar->event( event->uid() );
00496   if ( todo ) existingTodo = mCalendar->todo( todo->uid() );
00497 
00498   int action = DRAG_CANCEL;
00499 
00500   int root_x, root_y, win_x, win_y;
00501   uint keybstate;
00502   Window rootw, childw;
00503   XQueryPointer( qt_xdisplay(), qt_xrootwin(), &rootw, &childw,
00504                  &root_x, &root_y, &win_x, &win_y, &keybstate );
00505 
00506   if ( keybstate & ControlMask ) {
00507     action = DRAG_COPY;
00508   } else if ( keybstate & ShiftMask ) {
00509     action = DRAG_MOVE;
00510   } else {
00511     KPopupMenu *menu = new KPopupMenu( this );
00512     if ( existingEvent || existingTodo ) {
00513       menu->insertItem( i18n("Move"), DRAG_MOVE, 0 );
00514       if (existingEvent)
00515         menu->insertItem( KOGlobals::self()->smallIcon("editcopy"), i18n("Copy"), DRAG_COPY, 1 );
00516     } else {
00517       menu->insertItem( i18n("Add"), DRAG_MOVE, 0 );
00518     }
00519     menu->insertSeparator();
00520     menu->insertItem( KOGlobals::self()->smallIcon("cancel"), i18n("Cancel"), DRAG_CANCEL, 3 );
00521     action = menu->exec( QCursor::pos(), 0 );
00522   }
00523 
00524   if ( action == DRAG_COPY  || action == DRAG_MOVE ) {
00525     e->accept();
00526     int idx = getDayIndexFrom( e->pos().x(), e->pos().y() );
00527 
00528     if ( action == DRAG_COPY ) {
00529       if ( event ) emit incidenceDropped( event, mDays[idx] );
00530       if ( todo )  emit incidenceDropped( todo, mDays[idx] );
00531     } else if ( action == DRAG_MOVE ) {
00532       if ( event ) emit incidenceDroppedMove( event, mDays[idx] );
00533       if ( todo )  emit incidenceDroppedMove( todo, mDays[idx] );
00534     }
00535   }
00536   delete event;
00537   delete todo;
00538 #endif
00539 }
00540 
00541 // ----------------------------------------------------------------------------
00542 //  P A I N T   E V E N T   H A N D L I N G
00543 // ----------------------------------------------------------------------------
00544 
00545 void KODayMatrix::paintEvent( QPaintEvent * )
00546 {
00547 // kdDebug(5850) << "KODayMatrix::paintEvent() BEGIN" << endl;
00548 
00549   QPainter p;
00550   QRect sz = frameRect();
00551   QPixmap pm( sz.size() );
00552   int dheight = mDaySize.height();
00553   int dwidth = mDaySize.width();
00554   int row,col;
00555   int selw, selh;
00556   bool isRTL = KOGlobals::self()->reverseLayout();
00557 
00558   QColorGroup cg = palette().active();
00559 
00560   p.begin(  &pm, this );
00561   pm.fill( cg.base() );
00562 
00563   // draw topleft frame
00564   p.setPen( cg.mid() );
00565   p.drawRect(0, 0, sz.width()-1, sz.height()-1);
00566   // don't paint over borders
00567   p.translate(1,1);
00568 
00569   // draw selected days with highlighted background color
00570   if (mSelStart != NOSELECTION) {
00571 
00572     row = mSelStart/7;
00573     // fix larger selections starting in the previous month
00574     if ( row < 0 && mSelEnd > 0 ) row = 0;
00575     col = mSelStart -row*7;
00576     QColor selcol = KOPrefs::instance()->mHighlightColor;
00577 
00578     if ( row < 6 && row >= 0 ) {
00579       if (row == mSelEnd/7) {
00580         // Single row selection
00581         p.fillRect(isRTL ? (7 - (mSelEnd-mSelStart+1) - col)*dwidth : col*dwidth,
00582                     row*dheight, (mSelEnd-mSelStart+1)*dwidth, dheight, selcol);
00583       } else {
00584         // draw first row to the right
00585         p.fillRect(isRTL ? 0 : col*dwidth, row*dheight, (7-col)*dwidth,
00586                    dheight, selcol);
00587         // draw full block till last line
00588         selh = mSelEnd/7-row;
00589         if ( selh + row >= 6 ) selh = 6-row;
00590         if ( selh > 1 ) {
00591           p.fillRect(0, (row+1)*dheight, 7*dwidth, (selh-1)*dheight,selcol);
00592         }
00593         // draw last block from left to mSelEnd
00594         if ( mSelEnd/7 < 6 ) {
00595           selw = mSelEnd-7*(mSelEnd/7)+1;
00596           p.fillRect(isRTL ? (7-selw)*dwidth : 0, (row+selh)*dheight,
00597                      selw*dwidth, dheight, selcol);
00598         }
00599       }
00600     }
00601   }
00602 
00603   // iterate over all days in the matrix and draw the day label in appropriate colors
00604   QColor textColor = cg.text();
00605   QColor textColorShaded = getShadedColor( textColor );
00606   QColor actcol = textColorShaded;
00607   p.setPen(actcol);
00608   QPen tmppen;
00609   for ( int i = 0; i < NUMDAYS; ++i ) {
00610     row = i/7;
00611     col = isRTL ? 6-(i-row*7) : i-row*7;
00612 
00613     // if it is the first day of a month switch color from normal to shaded and vice versa
00614     if ( KOGlobals::self()->calendarSystem()->day( mDays[i] ) == 1) {
00615       if (actcol == textColorShaded) {
00616         actcol = textColor;
00617       } else {
00618         actcol = textColorShaded;
00619       }
00620       p.setPen(actcol);
00621     }
00622 
00623     //Reset pen color after selected days block
00624     if (i == mSelEnd+1) {
00625       p.setPen(actcol);
00626     }
00627 
00628     bool holiday = ! KOGlobals::self()->isWorkDay( mDays[ i ] );
00629 
00630     QColor holidayColorShaded = getShadedColor( KOPrefs::instance()->mHolidayColor );
00631     // if today then draw rectangle around day
00632     if (mToday == i) {
00633       tmppen = p.pen();
00634       QPen mTodayPen(p.pen());
00635 
00636       mTodayPen.setWidth(mTodayMarginWidth);
00637       //draw red rectangle for holidays
00638       if (holiday) {
00639         if (actcol == textColor) {
00640           mTodayPen.setColor(KOPrefs::instance()->mHolidayColor);
00641         } else {
00642           mTodayPen.setColor(holidayColorShaded);
00643         }
00644       }
00645       //draw gray rectangle for today if in selection
00646       if (i >= mSelStart && i <= mSelEnd) {
00647         QColor grey("grey");
00648         mTodayPen.setColor(grey);
00649       }
00650       p.setPen(mTodayPen);
00651       p.drawRect(col*dwidth, row*dheight, dwidth, dheight);
00652       p.setPen(tmppen);
00653     }
00654 
00655     // if any events are on that day then draw it using a bold font
00656     if (mEvents[i] > 0) {
00657       QFont myFont = font();
00658       myFont.setBold(true);
00659       p.setFont(myFont);
00660     }
00661 
00662     // if it is a holiday then use the default holiday color
00663     if (holiday) {
00664       if (actcol == textColor) {
00665         p.setPen(KOPrefs::instance()->mHolidayColor);
00666       } else {
00667         p.setPen(holidayColorShaded);
00668       }
00669     }
00670 
00671     // draw selected days with special color
00672     // DO NOT specially highlight holidays in selection !
00673     if (i >= mSelStart && i <= mSelEnd) {
00674       p.setPen( QColor( "white" ) );
00675     }
00676 
00677     p.drawText(col*dwidth, row*dheight, dwidth, dheight,
00678               Qt::AlignHCenter | Qt::AlignVCenter,  mDayLabels[i]);
00679 
00680     // reset color to actual color
00681     if (holiday) {
00682       p.setPen(actcol);
00683     }
00684     // reset bold font to plain font
00685     if (mEvents[i] > 0) {
00686       QFont myFont = font();
00687       myFont.setBold(false);
00688       p.setFont(myFont);
00689     }
00690   }
00691   p.end();
00692   bitBlt(  this, 0, 0, &pm );
00693 }
00694 
00695 // ----------------------------------------------------------------------------
00696 //  R E SI Z E   E V E N T   H A N D L I N G
00697 // ----------------------------------------------------------------------------
00698 
00699 void KODayMatrix::resizeEvent( QResizeEvent * )
00700 {
00701   QRect sz = frameRect();
00702   mDaySize.setHeight( sz.height() * 7 / NUMDAYS );
00703   mDaySize.setWidth( sz.width() / 7 );
00704 }
KDE Home | KDE Accessibility Home | Description of Access Keys