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::setUpdateNeeded()
00232 {
00233   mPendingChanges = true;
00234 }
00235 
00236 void KODayMatrix::updateView( const QDate &actdate )
00237 {
00238  kdDebug(5850) << "KODayMatrix::updateView() " << actdate << ", day start="<<mStartDate<< endl;
00239  if ( !actdate.isValid() ) return;
00240   //flag to indicate if the starting day of the matrix has changed by this call
00241   bool daychanged = false;
00242 
00243   // if a new startdate is to be set then apply Cornelius's calculation
00244   // of the first day to be shown
00245   if ( actdate != mStartDate ) {
00246     // reset index of selection according to shift of starting date from startdate to actdate
00247     if ( mSelStart != NOSELECTION ) {
00248       int tmp = actdate.daysTo( mStartDate );
00249       //kdDebug(5850) << "Shift of Selection1: " << mSelStart << " - " << mSelEnd << " -> " << tmp << "(" << offset << ")" << endl;
00250       // shift selection if new one would be visible at least partly !
00251 
00252       if ( mSelStart + tmp < NUMDAYS && mSelEnd + tmp >= 0 ) {
00253         // nested if is required for next X display pushed from a different month - correction required
00254         // otherwise, for month forward and backward, it must be avoided
00255         if( mSelStart > NUMDAYS || mSelStart < 0 )
00256           mSelStart = mSelStart + tmp;
00257         if( mSelEnd > NUMDAYS || mSelEnd < 0 )
00258           mSelEnd = mSelEnd + tmp;
00259       }
00260     }
00261 
00262     mStartDate = actdate;
00263     daychanged = true;
00264   }
00265 
00266   if ( daychanged ) {
00267     recalculateToday();
00268   }
00269 
00270   // the calendar hasn't changed in the meantime and the selected range is still the same
00271   // so we can safe the expensive updateEvents() call
00272   if ( !daychanged && !mPendingChanges )
00273     return;
00274 
00275   // TODO_Recurrence: If we just change the selection, but not the data, there's
00276   // no need to update the whole list of events... This is just a waste of
00277   // computational power (and it takes forever!)
00278   updateEvents();
00279   for( int i = 0; i < NUMDAYS; i++ ) {
00280     //if it is a holy day then draw it red. Sundays are consider holidays, too
00281     QStringList holidays = KOGlobals::self()->holiday( mDays[ i ] );
00282     QString holiStr = QString::null;
00283 
00284     if ( ( KOGlobals::self()->calendarSystem()->dayOfWeek( mDays[ i ] ) ==
00285            KOGlobals::self()->calendarSystem()->weekDayOfPray() ) ||
00286          !holidays.isEmpty() ) {
00287       if ( !holidays.isEmpty() ) holiStr = holidays.join( i18n("delimiter for joining holiday names", ", " ) );
00288       if ( holiStr.isNull() ) holiStr = "";
00289     }
00290     mHolidays[ i ] = holiStr;
00291   }
00292 }
00293 
00294 void KODayMatrix::updateEvents()
00295 {
00296   kdDebug( 5850 ) << k_funcinfo << endl;
00297   if ( !mCalendar ) return;
00298 
00299   for( int i = 0; i < NUMDAYS; i++ ) {
00300     // if events are set for the day then remember to draw it bold
00301     Event::List eventlist = mCalendar->events( mDays[ i ] );
00302     int numEvents = eventlist.count();
00303     Event::List::ConstIterator it;
00304     for( it = eventlist.begin(); it != eventlist.end(); ++it ) {
00305       Event *event = *it;
00306       ushort recurType = event->recurrenceType();
00307       if ( ( recurType == Recurrence::rDaily &&
00308              !KOPrefs::instance()->mDailyRecur ) ||
00309            ( recurType == Recurrence::rWeekly &&
00310              !KOPrefs::instance()->mWeeklyRecur ) ) {
00311         numEvents--;
00312       }
00313     }
00314     mEvents[ i ] = numEvents;
00315   }
00316 
00317   mPendingChanges = false;
00318 }
00319 
00320 const QDate& KODayMatrix::getDate( int offset )
00321 {
00322   if ( offset < 0 || offset > NUMDAYS - 1 ) {
00323     kdDebug(5850) << "Wrong offset (" << offset << ") in KODayMatrix::getDate(int)" << endl;
00324     return mDays[ 0 ];
00325   }
00326   return mDays[ offset ];
00327 }
00328 
00329 QString KODayMatrix::getHolidayLabel( int offset )
00330 {
00331   if ( offset < 0 || offset > NUMDAYS - 1 ) {
00332     kdDebug(5850) << "Wrong offset (" << offset << ") in KODayMatrix::getHolidayLabel(int)" << endl;
00333     return 0;
00334   }
00335   return mHolidays[ offset ];
00336 }
00337 
00338 int KODayMatrix::getDayIndexFrom( int x, int y )
00339 {
00340   return 7 * ( y / mDaySize.height() ) +
00341          ( KOGlobals::self()->reverseLayout() ?
00342            6 - x / mDaySize.width() : x / mDaySize.width() );
00343 }
00344 
00345 void KODayMatrix::calendarIncidenceAdded(Incidence * incidence)
00346 {
00347   mPendingChanges = true;
00348 }
00349 
00350 void KODayMatrix::calendarIncidenceChanged(Incidence * incidence)
00351 {
00352   mPendingChanges = true;
00353 }
00354 
00355 void KODayMatrix::calendarIncidenceDeleted(Incidence * incidence)
00356 {
00357   mPendingChanges = true;
00358 }
00359 
00360 void KODayMatrix::resourcesChanged()
00361 {
00362   mPendingChanges = true;
00363 }
00364 
00365 
00366 // ----------------------------------------------------------------------------
00367 //  M O U S E   E V E N T   H A N D L I N G
00368 // ----------------------------------------------------------------------------
00369 
00370 void KODayMatrix::mousePressEvent( QMouseEvent *e )
00371 {
00372   mSelStart = getDayIndexFrom(e->x(), e->y());
00373   if (mSelStart > NUMDAYS-1) mSelStart=NUMDAYS-1;
00374   mSelInit = mSelStart;
00375 }
00376 
00377 void KODayMatrix::mouseReleaseEvent( QMouseEvent *e )
00378 {
00379   int tmp = getDayIndexFrom(e->x(), e->y());
00380   if (tmp > NUMDAYS-1) tmp=NUMDAYS-1;
00381 
00382   if (mSelInit > tmp) {
00383     mSelEnd = mSelInit;
00384     if (tmp != mSelStart) {
00385       mSelStart = tmp;
00386       repaint();
00387     }
00388   } else {
00389     mSelStart = mSelInit;
00390 
00391     //repaint only if selection has changed
00392     if (tmp != mSelEnd) {
00393       mSelEnd = tmp;
00394       repaint();
00395     }
00396   }
00397 
00398   DateList daylist;
00399   if ( mSelStart < 0 ) mSelStart = 0;
00400   for ( int i = mSelStart; i <= mSelEnd; ++i ) {
00401     daylist.append( mDays[i] );
00402   }
00403   emit selected((const DateList)daylist);
00404 }
00405 
00406 void KODayMatrix::mouseMoveEvent( QMouseEvent *e )
00407 {
00408   int tmp = getDayIndexFrom(e->x(), e->y());
00409   if (tmp > NUMDAYS-1) tmp=NUMDAYS-1;
00410 
00411   if (mSelInit > tmp) {
00412     mSelEnd = mSelInit;
00413     if (tmp != mSelStart) {
00414       mSelStart = tmp;
00415       repaint();
00416     }
00417   } else {
00418     mSelStart = mSelInit;
00419 
00420     //repaint only if selection has changed
00421     if (tmp != mSelEnd) {
00422       mSelEnd = tmp;
00423       repaint();
00424     }
00425   }
00426 }
00427 
00428 // ----------------------------------------------------------------------------
00429 //  D R A G ' N   D R O P   H A N D L I N G
00430 // ----------------------------------------------------------------------------
00431 
00432 //-----------------------------------------------------------------------------
00433 // Drag and Drop handling -- based on the Troll Tech dirview example
00434 
00435 enum {
00436   DRAG_COPY = 0,
00437   DRAG_MOVE = 1,
00438   DRAG_CANCEL = 2
00439 };
00440 
00441 void KODayMatrix::dragEnterEvent( QDragEnterEvent *e )
00442 {
00443 #ifndef KORG_NODND
00444   if ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) ) {
00445     e->ignore();
00446     return;
00447   }
00448 
00449   // some visual feedback
00450 //  oldPalette = palette();
00451 //  setPalette(my_HilitePalette);
00452 //  update();
00453 #endif
00454 }
00455 
00456 void KODayMatrix::dragMoveEvent( QDragMoveEvent *e )
00457 {
00458 #ifndef KORG_NODND
00459   if ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) ) {
00460     e->ignore();
00461     return;
00462   }
00463 
00464   e->accept();
00465 #endif
00466 }
00467 
00468 void KODayMatrix::dragLeaveEvent( QDragLeaveEvent * /*dl*/ )
00469 {
00470 #ifndef KORG_NODND
00471 //  setPalette(oldPalette);
00472 //  update();
00473 #endif
00474 }
00475 
00476 void KODayMatrix::dropEvent( QDropEvent *e )
00477 {
00478 #ifndef KORG_NODND
00479   kdDebug(5850) << "KODayMatrix::dropEvent(e) begin" << endl;
00480 
00481   if ( !mCalendar ||
00482        ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) ) ) {
00483     e->ignore();
00484     return;
00485   }
00486 
00487   DndFactory factory( mCalendar );
00488   Event *event = factory.createDrop( e );
00489   Todo *todo = factory.createDropTodo( e );
00490   if ( !event && !todo ) {
00491     e->ignore();
00492     return;
00493   }
00494 
00495   Todo *existingTodo = 0;
00496   Event *existingEvent = 0;
00497 
00498   // Find the incidence in the calendar, then we don't need the drag object any more
00499   if ( event ) existingEvent = mCalendar->event( event->uid() );
00500   if ( todo ) existingTodo = mCalendar->todo( todo->uid() );
00501 
00502   int action = DRAG_CANCEL;
00503 
00504   int root_x, root_y, win_x, win_y;
00505   uint keybstate;
00506   Window rootw, childw;
00507   XQueryPointer( qt_xdisplay(), qt_xrootwin(), &rootw, &childw,
00508                  &root_x, &root_y, &win_x, &win_y, &keybstate );
00509 
00510   if ( keybstate & ControlMask ) {
00511     action = DRAG_COPY;
00512   } else if ( keybstate & ShiftMask ) {
00513     action = DRAG_MOVE;
00514   } else {
00515     KPopupMenu *menu = new KPopupMenu( this );
00516     if ( existingEvent || existingTodo ) {
00517       menu->insertItem( i18n("Move"), DRAG_MOVE, 0 );
00518       if (existingEvent)
00519         menu->insertItem( KOGlobals::self()->smallIcon("editcopy"), i18n("Copy"), DRAG_COPY, 1 );
00520     } else {
00521       menu->insertItem( i18n("Add"), DRAG_MOVE, 0 );
00522     }
00523     menu->insertSeparator();
00524     menu->insertItem( KOGlobals::self()->smallIcon("cancel"), i18n("Cancel"), DRAG_CANCEL, 3 );
00525     action = menu->exec( QCursor::pos(), 0 );
00526   }
00527 
00528   if ( action == DRAG_COPY  || action == DRAG_MOVE ) {
00529     e->accept();
00530     int idx = getDayIndexFrom( e->pos().x(), e->pos().y() );
00531 
00532     if ( action == DRAG_COPY ) {
00533       if ( event ) emit incidenceDropped( event, mDays[idx] );
00534       if ( todo )  emit incidenceDropped( todo, mDays[idx] );
00535     } else if ( action == DRAG_MOVE ) {
00536       if ( event ) emit incidenceDroppedMove( event, mDays[idx] );
00537       if ( todo )  emit incidenceDroppedMove( todo, mDays[idx] );
00538     }
00539   }
00540   delete event;
00541   delete todo;
00542 #endif
00543 }
00544 
00545 // ----------------------------------------------------------------------------
00546 //  P A I N T   E V E N T   H A N D L I N G
00547 // ----------------------------------------------------------------------------
00548 
00549 void KODayMatrix::paintEvent( QPaintEvent * )
00550 {
00551 // kdDebug(5850) << "KODayMatrix::paintEvent() BEGIN" << endl;
00552 
00553   QPainter p;
00554   QRect sz = frameRect();
00555   QPixmap pm( sz.size() );
00556   int dheight = mDaySize.height();
00557   int dwidth = mDaySize.width();
00558   int row,col;
00559   int selw, selh;
00560   bool isRTL = KOGlobals::self()->reverseLayout();
00561 
00562   QColorGroup cg = palette().active();
00563 
00564   p.begin(  &pm, this );
00565   pm.fill( cg.base() );
00566 
00567   // draw topleft frame
00568   p.setPen( cg.mid() );
00569   p.drawRect(0, 0, sz.width()-1, sz.height()-1);
00570   // don't paint over borders
00571   p.translate(1,1);
00572 
00573   // draw selected days with highlighted background color
00574   if (mSelStart != NOSELECTION) {
00575 
00576     row = mSelStart/7;
00577     // fix larger selections starting in the previous month
00578     if ( row < 0 && mSelEnd > 0 ) row = 0;
00579     col = mSelStart -row*7;
00580     QColor selcol = KOPrefs::instance()->mHighlightColor;
00581 
00582     if ( row < 6 && row >= 0 ) {
00583       if (row == mSelEnd/7) {
00584         // Single row selection
00585         p.fillRect(isRTL ? (7 - (mSelEnd-mSelStart+1) - col)*dwidth : col*dwidth,
00586                     row*dheight, (mSelEnd-mSelStart+1)*dwidth, dheight, selcol);
00587       } else {
00588         // draw first row to the right
00589         p.fillRect(isRTL ? 0 : col*dwidth, row*dheight, (7-col)*dwidth,
00590                    dheight, selcol);
00591         // draw full block till last line
00592         selh = mSelEnd/7-row;
00593         if ( selh + row >= 6 ) selh = 6-row;
00594         if ( selh > 1 ) {
00595           p.fillRect(0, (row+1)*dheight, 7*dwidth, (selh-1)*dheight,selcol);
00596         }
00597         // draw last block from left to mSelEnd
00598         if ( mSelEnd/7 < 6 ) {
00599           selw = mSelEnd-7*(mSelEnd/7)+1;
00600           p.fillRect(isRTL ? (7-selw)*dwidth : 0, (row+selh)*dheight,
00601                      selw*dwidth, dheight, selcol);
00602         }
00603       }
00604     }
00605   }
00606 
00607   // iterate over all days in the matrix and draw the day label in appropriate colors
00608   QColor textColor = cg.text();
00609   QColor textColorShaded = getShadedColor( textColor );
00610   QColor actcol = textColorShaded;
00611   p.setPen(actcol);
00612   QPen tmppen;
00613   for ( int i = 0; i < NUMDAYS; ++i ) {
00614     row = i/7;
00615     col = isRTL ? 6-(i-row*7) : i-row*7;
00616 
00617     // if it is the first day of a month switch color from normal to shaded and vice versa
00618     if ( KOGlobals::self()->calendarSystem()->day( mDays[i] ) == 1) {
00619       if (actcol == textColorShaded) {
00620         actcol = textColor;
00621       } else {
00622         actcol = textColorShaded;
00623       }
00624       p.setPen(actcol);
00625     }
00626 
00627     //Reset pen color after selected days block
00628     if (i == mSelEnd+1) {
00629       p.setPen(actcol);
00630     }
00631 
00632     bool holiday = ! KOGlobals::self()->isWorkDay( mDays[ i ] );
00633 
00634     QColor holidayColorShaded = getShadedColor( KOPrefs::instance()->mHolidayColor );
00635     // if today then draw rectangle around day
00636     if (mToday == i) {
00637       tmppen = p.pen();
00638       QPen mTodayPen(p.pen());
00639 
00640       mTodayPen.setWidth(mTodayMarginWidth);
00641       //draw red rectangle for holidays
00642       if (holiday) {
00643         if (actcol == textColor) {
00644           mTodayPen.setColor(KOPrefs::instance()->mHolidayColor);
00645         } else {
00646           mTodayPen.setColor(holidayColorShaded);
00647         }
00648       }
00649       //draw gray rectangle for today if in selection
00650       if (i >= mSelStart && i <= mSelEnd) {
00651         QColor grey("grey");
00652         mTodayPen.setColor(grey);
00653       }
00654       p.setPen(mTodayPen);
00655       p.drawRect(col*dwidth, row*dheight, dwidth, dheight);
00656       p.setPen(tmppen);
00657     }
00658 
00659     // if any events are on that day then draw it using a bold font
00660     if (mEvents[i] > 0) {
00661       QFont myFont = font();
00662       myFont.setBold(true);
00663       p.setFont(myFont);
00664     }
00665 
00666     // if it is a holiday then use the default holiday color
00667     if (holiday) {
00668       if (actcol == textColor) {
00669         p.setPen(KOPrefs::instance()->mHolidayColor);
00670       } else {
00671         p.setPen(holidayColorShaded);
00672       }
00673     }
00674 
00675     // draw selected days with special color
00676     // DO NOT specially highlight holidays in selection !
00677     if (i >= mSelStart && i <= mSelEnd) {
00678       p.setPen( QColor( "white" ) );
00679     }
00680 
00681     p.drawText(col*dwidth, row*dheight, dwidth, dheight,
00682               Qt::AlignHCenter | Qt::AlignVCenter,  mDayLabels[i]);
00683 
00684     // reset color to actual color
00685     if (holiday) {
00686       p.setPen(actcol);
00687     }
00688     // reset bold font to plain font
00689     if (mEvents[i] > 0) {
00690       QFont myFont = font();
00691       myFont.setBold(false);
00692       p.setFont(myFont);
00693     }
00694   }
00695   p.end();
00696   bitBlt(  this, 0, 0, &pm );
00697 }
00698 
00699 // ----------------------------------------------------------------------------
00700 //  R E SI Z E   E V E N T   H A N D L I N G
00701 // ----------------------------------------------------------------------------
00702 
00703 void KODayMatrix::resizeEvent( QResizeEvent * )
00704 {
00705   QRect sz = frameRect();
00706   mDaySize.setHeight( sz.height() * 7 / NUMDAYS );
00707   mDaySize.setWidth( sz.width() / 7 );
00708 }
KDE Home | KDE Accessibility Home | Description of Access Keys