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 TQt, and distribute the resulting executable, 00026 without including the source code for TQt in the source distribution. 00027 */ 00028 00029 #include <tqevent.h> 00030 #include <tqpainter.h> 00031 #include <tqptrlist.h> 00032 00033 #include <tdeglobal.h> 00034 #include <kdebug.h> 00035 #include <tdelocale.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 <tqcursor.h> 00055 #include <tdepopupmenu.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( TQWidget * parent ) 00068 : TQToolTip( parent ) 00069 { 00070 mMatrix = static_cast<KODayMatrix *>( parent ); 00071 } 00072 00073 00074 void DynamicTip::maybeTip( const TQPoint &pos ) 00075 { 00076 //calculate which cell of the matrix the mouse is in 00077 TQRect 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 TQRect 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 TQString 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( TQWidget *parent, const char *name ) 00103 : TQFrame( parent, name ), mCalendar( 0 ), mStartDate(), mPendingChanges( false ) 00104 { 00105 // initialize dynamic arrays 00106 mDays = new TQDate[ NUMDAYS ]; 00107 mDayLabels = new TQString[ 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, TQT_SIGNAL(signalResourceAdded(ResourceCalendar *)), TQT_SLOT(resourcesChanged()) ); 00129 connect( calres, TQT_SIGNAL(signalResourceModified( ResourceCalendar *)), TQT_SLOT(resourcesChanged()) ); 00130 connect( calres, TQT_SIGNAL(signalResourceDeleted(ResourceCalendar *)), TQT_SLOT(resourcesChanged()) ); 00131 } 00132 00133 setAcceptDrops( mCalendar ); 00134 00135 updateEvents(); 00136 } 00137 00138 TQColor KODayMatrix::getShadedColor( const TQColor &color ) 00139 { 00140 TQColor 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 TQDate &start, const TQDate &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 ] = TQString::number( KOGlobals::self()->calendarSystem()->day( mDays[i] )); 00215 00216 // if today is in the currently displayed month, hilight today 00217 if ( mDays[ i ].year() == TQDate::currentDate().year() && 00218 mDays[ i ].month() == TQDate::currentDate().month() && 00219 mDays[ i ].day() == TQDate::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 TQDate &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 TQStringList holidays = KOGlobals::self()->holiday( mDays[ i ] ); 00282 TQString holiStr = TQString(); 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 TQDate& 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 TQString 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 Q_UNUSED( incidence ); 00348 mPendingChanges = true; 00349 } 00350 00351 void KODayMatrix::calendarIncidenceChanged(Incidence * incidence) 00352 { 00353 Q_UNUSED( incidence ); 00354 mPendingChanges = true; 00355 } 00356 00357 void KODayMatrix::calendarIncidenceDeleted(Incidence * incidence) 00358 { 00359 Q_UNUSED( incidence ); 00360 mPendingChanges = true; 00361 } 00362 00363 void KODayMatrix::resourcesChanged() 00364 { 00365 mPendingChanges = true; 00366 } 00367 00368 00369 // ---------------------------------------------------------------------------- 00370 // M O U S E E V E N T H A N D L I N G 00371 // ---------------------------------------------------------------------------- 00372 00373 void KODayMatrix::mousePressEvent( TQMouseEvent *e ) 00374 { 00375 mSelStart = getDayIndexFrom(e->x(), e->y()); 00376 if (mSelStart > NUMDAYS-1) mSelStart=NUMDAYS-1; 00377 mSelInit = mSelStart; 00378 } 00379 00380 void KODayMatrix::mouseReleaseEvent( TQMouseEvent *e ) 00381 { 00382 int tmp = getDayIndexFrom(e->x(), e->y()); 00383 if (tmp > NUMDAYS-1) tmp=NUMDAYS-1; 00384 00385 if (mSelInit > tmp) { 00386 mSelEnd = mSelInit; 00387 if (tmp != mSelStart) { 00388 mSelStart = tmp; 00389 repaint(); 00390 } 00391 } else { 00392 mSelStart = mSelInit; 00393 00394 //repaint only if selection has changed 00395 if (tmp != mSelEnd) { 00396 mSelEnd = tmp; 00397 repaint(); 00398 } 00399 } 00400 00401 DateList daylist; 00402 if ( mSelStart < 0 ) mSelStart = 0; 00403 for ( int i = mSelStart; i <= mSelEnd; ++i ) { 00404 daylist.append( mDays[i] ); 00405 } 00406 emit selected((const DateList)daylist); 00407 } 00408 00409 void KODayMatrix::mouseMoveEvent( TQMouseEvent *e ) 00410 { 00411 int tmp = getDayIndexFrom(e->x(), e->y()); 00412 if (tmp > NUMDAYS-1) tmp=NUMDAYS-1; 00413 00414 if (mSelInit > tmp) { 00415 mSelEnd = mSelInit; 00416 if ( tmp != mSelStart ) { 00417 mSelStart = tmp; 00418 repaint(); 00419 } 00420 } else { 00421 mSelStart = mSelInit; 00422 00423 //repaint only if selection has changed 00424 if ( tmp != mSelEnd ) { 00425 mSelEnd = tmp; 00426 repaint(); 00427 } 00428 } 00429 } 00430 00431 // ---------------------------------------------------------------------------- 00432 // D R A G ' N D R O P H A N D L I N G 00433 // ---------------------------------------------------------------------------- 00434 00435 //----------------------------------------------------------------------------- 00436 // Drag and Drop handling -- based on the Troll Tech dirview example 00437 00438 enum { 00439 DRAG_COPY = 0, 00440 DRAG_MOVE = 1, 00441 DRAG_CANCEL = 2 00442 }; 00443 00444 void KODayMatrix::dragEnterEvent( TQDragEnterEvent *e ) 00445 { 00446 #ifndef KORG_NODND 00447 if ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) ) { 00448 e->ignore(); 00449 return; 00450 } 00451 00452 // some visual feedback 00453 // oldPalette = palette(); 00454 // setPalette(my_HilitePalette); 00455 // update(); 00456 #endif 00457 } 00458 00459 void KODayMatrix::dragMoveEvent( TQDragMoveEvent *e ) 00460 { 00461 #ifndef KORG_NODND 00462 if ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) ) { 00463 e->ignore(); 00464 return; 00465 } 00466 00467 e->accept(); 00468 #endif 00469 } 00470 00471 void KODayMatrix::dragLeaveEvent( TQDragLeaveEvent * /*dl*/ ) 00472 { 00473 #ifndef KORG_NODND 00474 // setPalette(oldPalette); 00475 // update(); 00476 #endif 00477 } 00478 00479 void KODayMatrix::dropEvent( TQDropEvent *e ) 00480 { 00481 #ifndef KORG_NODND 00482 kdDebug(5850) << "KODayMatrix::dropEvent(e) begin" << endl; 00483 00484 if ( !mCalendar || 00485 ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) ) ) { 00486 e->ignore(); 00487 return; 00488 } 00489 00490 DndFactory factory( mCalendar ); 00491 Event *event = factory.createDrop( e ); 00492 Todo *todo = factory.createDropTodo( e ); 00493 if ( !event && !todo ) { 00494 e->ignore(); 00495 return; 00496 } 00497 00498 Todo *existingTodo = 0; 00499 Event *existingEvent = 0; 00500 00501 // Find the incidence in the calendar, then we don't need the drag object any more 00502 if ( event ) existingEvent = mCalendar->event( event->uid() ); 00503 if ( todo ) existingTodo = mCalendar->todo( todo->uid() ); 00504 00505 int action = DRAG_CANCEL; 00506 00507 int root_x, root_y, win_x, win_y; 00508 uint keybstate; 00509 Window rootw, childw; 00510 XQueryPointer( tqt_xdisplay(), tqt_xrootwin(), &rootw, &childw, 00511 &root_x, &root_y, &win_x, &win_y, &keybstate ); 00512 00513 if ( keybstate & ControlMask ) { 00514 action = DRAG_COPY; 00515 } else if ( keybstate & ShiftMask ) { 00516 action = DRAG_MOVE; 00517 } else { 00518 TDEPopupMenu *menu = new TDEPopupMenu( this ); 00519 if ( existingEvent || existingTodo ) { 00520 menu->insertItem( i18n("Move"), DRAG_MOVE, 0 ); 00521 if (existingEvent) 00522 menu->insertItem( KOGlobals::self()->smallIcon("edit-copy"), i18n("Copy"), DRAG_COPY, 1 ); 00523 } else { 00524 menu->insertItem( i18n("Add"), DRAG_MOVE, 0 ); 00525 } 00526 menu->insertSeparator(); 00527 menu->insertItem( KOGlobals::self()->smallIcon("cancel"), i18n("Cancel"), DRAG_CANCEL, 3 ); 00528 action = menu->exec( TQCursor::pos(), 0 ); 00529 } 00530 00531 if ( action == DRAG_COPY || action == DRAG_MOVE ) { 00532 e->accept(); 00533 int idx = getDayIndexFrom( e->pos().x(), e->pos().y() ); 00534 00535 if ( action == DRAG_COPY ) { 00536 if ( event ) emit incidenceDropped( event, mDays[idx] ); 00537 if ( todo ) emit incidenceDropped( todo, mDays[idx] ); 00538 } else if ( action == DRAG_MOVE ) { 00539 if ( event ) emit incidenceDroppedMove( event, mDays[idx] ); 00540 if ( todo ) emit incidenceDroppedMove( todo, mDays[idx] ); 00541 } 00542 } 00543 delete event; 00544 delete todo; 00545 #endif 00546 } 00547 00548 // ---------------------------------------------------------------------------- 00549 // P A I N T E V E N T H A N D L I N G 00550 // ---------------------------------------------------------------------------- 00551 00552 void KODayMatrix::paintEvent( TQPaintEvent * ) 00553 { 00554 // kdDebug(5850) << "KODayMatrix::paintEvent() BEGIN" << endl; 00555 00556 TQPainter p; 00557 TQRect sz = frameRect(); 00558 TQPixmap pm( sz.size() ); 00559 int dheight = mDaySize.height(); 00560 int dwidth = mDaySize.width(); 00561 int row,col; 00562 int selw, selh; 00563 bool isRTL = KOGlobals::self()->reverseLayout(); 00564 00565 TQColorGroup cg = palette().active(); 00566 00567 p.begin( &pm, this ); 00568 pm.fill( cg.base() ); 00569 00570 // draw topleft frame 00571 p.setPen( cg.mid() ); 00572 p.drawRect(0, 0, sz.width()-1, sz.height()-1); 00573 // don't paint over borders 00574 p.translate(1,1); 00575 00576 // draw selected days with highlighted background color 00577 if (mSelStart != NOSELECTION) { 00578 00579 row = mSelStart/7; 00580 // fix larger selections starting in the previous month 00581 if ( row < 0 && mSelEnd > 0 ) row = 0; 00582 col = mSelStart -row*7; 00583 TQColor selcol = KOPrefs::instance()->mHighlightColor; 00584 00585 if ( row < 6 && row >= 0 ) { 00586 if (row == mSelEnd/7) { 00587 // Single row selection 00588 p.fillRect(isRTL ? (7 - (mSelEnd-mSelStart+1) - col)*dwidth : col*dwidth, 00589 row*dheight, (mSelEnd-mSelStart+1)*dwidth, dheight, selcol); 00590 } else { 00591 // draw first row to the right 00592 p.fillRect(isRTL ? 0 : col*dwidth, row*dheight, (7-col)*dwidth, 00593 dheight, selcol); 00594 // draw full block till last line 00595 selh = mSelEnd/7-row; 00596 if ( selh + row >= 6 ) selh = 6-row; 00597 if ( selh > 1 ) { 00598 p.fillRect(0, (row+1)*dheight, 7*dwidth, (selh-1)*dheight,selcol); 00599 } 00600 // draw last block from left to mSelEnd 00601 if ( mSelEnd/7 < 6 ) { 00602 selw = mSelEnd-7*(mSelEnd/7)+1; 00603 p.fillRect(isRTL ? (7-selw)*dwidth : 0, (row+selh)*dheight, 00604 selw*dwidth, dheight, selcol); 00605 } 00606 } 00607 } 00608 } 00609 00610 // iterate over all days in the matrix and draw the day label in appropriate colors 00611 TQColor textColor = cg.text(); 00612 TQColor textColorShaded = getShadedColor( textColor ); 00613 TQColor actcol = textColorShaded; 00614 p.setPen(actcol); 00615 TQPen tmppen; 00616 for ( int i = 0; i < NUMDAYS; ++i ) { 00617 row = i/7; 00618 col = isRTL ? 6-(i-row*7) : i-row*7; 00619 00620 // if it is the first day of a month switch color from normal to shaded and vice versa 00621 if ( KOGlobals::self()->calendarSystem()->day( mDays[i] ) == 1) { 00622 if (actcol == textColorShaded) { 00623 actcol = textColor; 00624 } else { 00625 actcol = textColorShaded; 00626 } 00627 p.setPen(actcol); 00628 } 00629 00630 //Reset pen color after selected days block 00631 if (i == mSelEnd+1) { 00632 p.setPen(actcol); 00633 } 00634 00635 bool holiday = ! KOGlobals::self()->isWorkDay( mDays[ i ] ); 00636 00637 TQColor holidayColorShaded = getShadedColor( KOPrefs::instance()->mHolidayColor ); 00638 // if today then draw rectangle around day 00639 if (mToday == i) { 00640 tmppen = p.pen(); 00641 TQPen mTodayPen(p.pen()); 00642 00643 mTodayPen.setWidth(mTodayMarginWidth); 00644 //draw red rectangle for holidays 00645 if (holiday) { 00646 if (actcol == textColor) { 00647 mTodayPen.setColor(KOPrefs::instance()->mHolidayColor); 00648 } else { 00649 mTodayPen.setColor(holidayColorShaded); 00650 } 00651 } 00652 //draw gray rectangle for today if in selection 00653 if (i >= mSelStart && i <= mSelEnd) { 00654 TQColor grey("grey"); 00655 mTodayPen.setColor(grey); 00656 } 00657 p.setPen(mTodayPen); 00658 p.drawRect(col*dwidth, row*dheight, dwidth, dheight); 00659 p.setPen(tmppen); 00660 } 00661 00662 // if any events are on that day then draw it using a bold font 00663 if (mEvents[i] > 0) { 00664 TQFont myFont = font(); 00665 myFont.setBold(true); 00666 p.setFont(myFont); 00667 } 00668 00669 // if it is a holiday then use the default holiday color 00670 if (holiday) { 00671 if (actcol == textColor) { 00672 p.setPen(KOPrefs::instance()->mHolidayColor); 00673 } else { 00674 p.setPen(holidayColorShaded); 00675 } 00676 } 00677 00678 // draw selected days with special color 00679 if ( i >= mSelStart && i <= mSelEnd && !holiday ) { 00680 p.setPen( TQColor( "white" ) ); 00681 } 00682 00683 p.drawText(col*dwidth, row*dheight, dwidth, dheight, 00684 TQt::AlignHCenter | TQt::AlignVCenter, mDayLabels[i]); 00685 00686 // reset color to actual color 00687 if ( holiday ) { 00688 p.setPen(actcol); 00689 } 00690 // reset bold font to plain font 00691 if (mEvents[i] > 0) { 00692 TQFont myFont = font(); 00693 myFont.setBold(false); 00694 p.setFont(myFont); 00695 } 00696 } 00697 p.end(); 00698 bitBlt( this, 0, 0, &pm ); 00699 } 00700 00701 // ---------------------------------------------------------------------------- 00702 // R E SI Z E E V E N T H A N D L I N G 00703 // ---------------------------------------------------------------------------- 00704 00705 void KODayMatrix::resizeEvent( TQResizeEvent * ) 00706 { 00707 TQRect sz = frameRect(); 00708 mDaySize.setHeight( sz.height() * 7 / NUMDAYS ); 00709 mDaySize.setWidth( sz.width() / 7 ); 00710 } 00711 00712 /* static */ 00713 TQPair<TQDate,TQDate> KODayMatrix::matrixLimits( const TQDate &month ) 00714 { 00715 const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem(); 00716 TQDate d = month; 00717 calSys->setYMD( d, calSys->year( month ), calSys->month( month ), 1 ); 00718 00719 const int dayOfWeek = calSys->dayOfWeek( d ); 00720 const int weekstart = TDEGlobal::locale()->weekStartDay(); 00721 00722 d = d.addDays( weekstart - dayOfWeek ); 00723 00724 if ( dayOfWeek == weekstart ) { 00725 d = d.addDays( -7 ); // Start on the second line 00726 } 00727 00728 return tqMakePair( d, d.addDays( NUMDAYS-1 ) ); 00729 }