00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <qpainter.h>
00027 #include <qlayout.h>
00028 #include <qframe.h>
00029 #include <qlabel.h>
00030 #include <qptrlist.h>
00031 #include <qintdict.h>
00032
00033 #include <kglobal.h>
00034 #include <klocale.h>
00035 #include <kdebug.h>
00036 #include <kconfig.h>
00037 #include <kcalendarsystem.h>
00038 #include <kprinter.h>
00039 #include <kwordwrap.h>
00040
00041 #include <libkcal/calendar.h>
00042 #include <libkcal/todo.h>
00043 #include <libkcal/event.h>
00044
00045 #include "korganizer/corehelper.h"
00046 #include "cellitem.h"
00047
00048 #include "calprinthelper.h"
00049
00050 #ifndef KORG_NOPRINTER
00051
00052
00053
00054 class CalPrintHelper::TodoParentStart
00055 {
00056 public:
00057 TodoParentStart( QRect pt = QRect(), bool page = true )
00058 : mRect( pt ), mSamePage( page ) {}
00059
00060 QRect mRect;
00061 bool mSamePage;
00062 };
00063
00064 class PrintCellItem : public KOrg::CellItem
00065 {
00066 public:
00067 PrintCellItem( Event *event, const QDateTime &start, const QDateTime &end )
00068 : mEvent( event ), mStart( start), mEnd( end )
00069 {
00070 }
00071
00072 Event *event() const { return mEvent; }
00073
00074 QString label() const { return mEvent->summary(); }
00075
00076 QDateTime start() const { return mStart; }
00077 QDateTime end() const { return mEnd; }
00078
00081 bool overlaps( KOrg::CellItem *o ) const
00082 {
00083 PrintCellItem *other = static_cast<PrintCellItem *>( o );
00084
00085 #if 0
00086 kdDebug(5850) << "PrintCellItem::overlaps() " << event()->summary()
00087 << " <-> " << other->event()->summary() << endl;
00088 kdDebug(5850) << " start : " << start.toString() << endl;
00089 kdDebug(5850) << " end : " << end.toString() << endl;
00090 kdDebug(5850) << " otherStart: " << otherStart.toString() << endl;
00091 kdDebug(5850) << " otherEnd : " << otherEnd.toString() << endl;
00092 #endif
00093
00094 return !( other->start() >= end() || other->end() <= start() );
00095 }
00096
00097 private:
00098 Event *mEvent;
00099 QDateTime mStart, mEnd;
00100 };
00101
00102 CalPrintHelper::CalPrintHelper( KPrinter *pr, Calendar *cal, KConfig *cfg,
00103 KOrg::CoreHelper *corehelper )
00104 : mPrinter( pr ), mCalendar( cal ), mConfig( cfg ),
00105 mCoreHelper( corehelper ),
00106 mHeaderHeight( 72 ), mSubHeaderHeight( 20 ), mMargin( 36 )
00107 {
00108 if ( corehelper )
00109 setCalendarSystem( mCoreHelper->calendarSystem() );
00110 }
00111
00112 CalPrintHelper::~CalPrintHelper()
00113 {
00114 }
00115
00116
00117
00118 void CalPrintHelper::setCategoryColors( QPainter &p, Incidence *incidence )
00119 {
00120 if ( mCoreHelper ) {
00121 QColor bgColor = mCoreHelper->categoryColor( incidence->categories() );
00122 QColor textColor = mCoreHelper->textColor( bgColor );
00123 p.setPen( textColor );
00124 p.setBrush( bgColor );
00125 }
00126 }
00127
00128
00129
00131
00132 void CalPrintHelper::drawHeader( QPainter &p, QString title,
00133 const QDate &month1, const QDate &month2,
00134 int x, int y, int width, int height )
00135 {
00136 p.drawRect( x, y, width, height );
00137 p.fillRect( x + 1, y + 1, width - 2, height - 2,
00138 QBrush( Qt::Dense7Pattern ) );
00139
00140 int right=x+width;
00141
00142
00143 int smallMonthWidth=width/4-10;
00144 if (smallMonthWidth>100) smallMonthWidth=100;
00145 if (month2.isValid()) {
00146 right -= (10+smallMonthWidth);
00147 drawSmallMonth(p, QDate(month2.year(), month2.month(), 1),
00148 right, y+2, smallMonthWidth, height-4);
00149 right-=10;
00150 }
00151 if (month1.isValid()) {
00152 right -= (10+smallMonthWidth);
00153 drawSmallMonth(p, QDate(month1.year(), month1.month(), 1),
00154 right, y+2, smallMonthWidth, height-4);
00155 right-=10;
00156 }
00157
00158
00159 QFont oldFont(p.font());
00160 p.setFont( QFont("helvetica", 18, QFont::Bold) );
00161 QRect textRect( x+5, y+5, right-10-x, height-10 );
00162 p.drawText( textRect, Qt::AlignLeft | Qt::AlignTop | Qt::WordBreak, title );
00163 p.setFont(oldFont);
00164 }
00165
00166
00167 void CalPrintHelper::drawSmallMonth(QPainter &p, const QDate &qd,
00168 int x, int y, int width, int height)
00169 {
00170 bool firstCol = true;
00171 QDate monthDate(QDate(qd.year(), qd.month(), 1));
00172 QDate monthDate2;
00173 int month = monthDate.month();
00174
00175
00176 QFont oldFont( p.font() );
00177 p.setFont(QFont("helvetica", 8, QFont::Bold));
00178
00179 if ( mCalSys )
00180 p.drawText(x, y, width, height/4, Qt::AlignCenter,
00181 mCalSys->monthName( qd ) );
00182
00183 int cellWidth = width/7;
00184 int cellHeight = height/8;
00185 QString tmpStr;
00186
00187
00188 int weekdayCol = weekdayColumn( qd.dayOfWeek() );
00189 monthDate2 = monthDate.addDays( -weekdayCol );
00190
00191
00192 if ( mCalSys ) {
00193 for (int col = 0; col < 7; ++col) {
00194
00195 tmpStr=mCalSys->weekDayName( monthDate2 )[0].upper();
00196 p.drawText( x + col*cellWidth, y + height/4, cellWidth, cellHeight,
00197 Qt::AlignCenter, tmpStr );
00198 monthDate2 = monthDate2.addDays( 1 );
00199 }
00200 }
00201
00202
00203 p.drawLine( x, y + height/4 + cellHeight, x + width,
00204 y + height/4 + cellHeight );
00205
00206 for ( int row = 0; row < 5; row++ ) {
00207 for ( int col = 0; col < 7; col++ ) {
00208 if ( monthDate.month() != month )
00209 break;
00210 if (firstCol) {
00211 firstCol = true;
00212 col = weekdayColumn( monthDate.dayOfWeek() );
00213 }
00214 p.drawText( x+col*cellWidth,
00215 y+height/4+cellHeight+(row*cellHeight),
00216 cellWidth, cellHeight, Qt::AlignCenter,
00217 tmpStr.setNum( monthDate.day() ) );
00218 monthDate = monthDate.addDays(1);
00219 }
00220 }
00221 p.setFont( oldFont );
00222 }
00223
00224
00226
00227
00228
00229
00230
00231 void CalPrintHelper::drawDaysOfWeek(QPainter &p,
00232 const QDate &fromDate, const QDate &toDate,
00233 int x, int y, int width, int height)
00234 {
00235 int cellWidth = width/(fromDate.daysTo( toDate )+1);
00236 int currx=x;
00237 QDate cellDate(fromDate);
00238
00239 while (cellDate<=toDate) {
00240 drawDaysOfWeekBox(p, cellDate, currx, y, cellWidth, height);
00241 currx+=cellWidth;
00242 cellDate = cellDate.addDays(1);
00243 }
00244 }
00245
00246
00247 void CalPrintHelper::drawDaysOfWeekBox(QPainter &p, const QDate &qd,
00248 int x, int y, int width, int height)
00249 {
00250 QFont oldFont( p.font() );
00251 p.setFont( QFont( "helvetica", 10, QFont::Bold ) );
00252 p.drawRect( x, y, width, height );
00253 p.fillRect( x+1, y+1,
00254 width-2, height-2,
00255 QBrush( Qt::Dense7Pattern ) );
00256 if ( mCalSys )
00257 p.drawText( x+5, y, width-10, height, Qt::AlignCenter | Qt::AlignVCenter,
00258 mCalSys->weekDayName( qd ) );
00259 p.setFont( oldFont );
00260 }
00261
00262
00263 void CalPrintHelper::drawTimeLine(QPainter &p,
00264 const QTime &fromTime, const QTime &toTime,
00265 int x, int y, int width, int height)
00266 {
00267 p.drawRect(x, y, width, height);
00268
00269 int totalsecs=fromTime.secsTo(toTime);
00270 float minlen=(float)height*60./(float)totalsecs;
00271 float cellHeight=(60.*(float)minlen);
00272 float currY=y;
00273
00274 QTime curTime( fromTime );
00275 QTime endTime( toTime );
00276 if ( fromTime.minute() > 30 )
00277 curTime = QTime( fromTime.hour()+1, 0, 0 );
00278 else if ( fromTime.minute() > 0 ) {
00279 curTime = QTime( fromTime.hour(), 30, 0 );
00280 float yy = currY + minlen*(float)fromTime.secsTo( curTime )/60.;
00281 p.drawLine( x+width/2, (int)yy, x+width, (int)yy );
00282 curTime = QTime( fromTime.hour()+1, 0, 0 );
00283 }
00284 currY += ( fromTime.secsTo(curTime)*minlen/60 );
00285
00286 while ( curTime < endTime ) {
00287 p.drawLine( x, (int)currY, x+width, (int)currY );
00288 int newY=(int)(currY+cellHeight/2.);
00289 QString numStr;
00290 if (newY < y+height) {
00291 QFont oldFont( p.font() );
00292 p.drawLine(x+width/2, (int)newY, x+width, (int)newY);
00293
00294 if ( !KGlobal::locale()->use12Clock() ) {
00295 numStr.setNum(curTime.hour());
00296 if (cellHeight > 30) {
00297 p.setFont(QFont("helvetica", 16, QFont::Bold));
00298 } else {
00299 p.setFont(QFont("helvetica", 12, QFont::Bold));
00300 }
00301 p.drawText(x+2, (int)currY+2, width/2-2, (int)cellHeight,
00302 Qt::AlignTop | Qt::AlignRight, numStr);
00303 p.setFont(QFont("helvetica", 10, QFont::Normal));
00304 p.drawText(x+width/2, (int)currY+2, width/2+2, (int)(cellHeight/2)-3,
00305 Qt::AlignTop | Qt::AlignLeft, "00");
00306 } else {
00307 QTime time( curTime.hour(), 0 );
00308 numStr = KGlobal::locale()->formatTime( time );
00309 p.setFont(QFont("helvetica", 14, QFont::Bold));
00310 p.drawText(x+2, (int)currY+2, width-4, (int)cellHeight/2-3,
00311 Qt::AlignTop|Qt::AlignLeft, numStr);
00312 }
00313 currY+=cellHeight;
00314 p.setFont( oldFont );
00315 }
00316 if (curTime.secsTo(endTime)>3600)
00317 curTime=curTime.addSecs(3600);
00318 else curTime=endTime;
00319 }
00320 }
00321
00322 Event *CalPrintHelper::holiday( const QDate &dt )
00323 {
00324 #ifndef KORG_NOPLUGINS
00325 if ( !mCoreHelper ) return 0;
00326 QString hstring( mCoreHelper->holidayString( dt ) );
00327 if ( !hstring.isEmpty() ) {
00328 Event*holiday=new Event();
00329 holiday->setDtStart( dt );
00330 holiday->setDtEnd( dt );
00331 holiday->setFloats( true );
00332 holiday->setCategories( i18n("Holiday") );
00333 return holiday;
00334 }
00335 return 0;
00336 #endif
00337
00338 }
00339
00341
00347 void CalPrintHelper::drawAllDayBox(QPainter &p, Event::List &eventList,
00348 const QDate &qd, bool expandable,
00349 int x, int y, int width, int &height)
00350 {
00351 Event::List::Iterator it, itold;
00352
00353 int offset=y;
00354
00355 QPen oldPen( p.pen() );
00356 QColor oldBgColor( p.backgroundColor() );
00357 QBrush oldBrush( p.brush() );
00358 QString multiDayStr;
00359
00360 Event*hd = holiday( qd );
00361 if ( hd ) eventList.prepend( hd );
00362
00363 it = eventList.begin();
00364 Event *currEvent = 0;
00365
00366 while( it!=eventList.end() ) {
00367 currEvent=*it;
00368 itold=it;
00369 ++it;
00370 if ( currEvent->doesFloat() ) {
00371
00372 if ( expandable ) {
00373 if ( mUseColors )
00374 setCategoryColors( p, currEvent );
00375
00376 p.drawRect( x, offset, width, height );
00377 p.drawText( x + 5, offset + 5, width - 10, height - 10,
00378 Qt::AlignCenter | Qt::AlignVCenter | Qt::AlignJustify |
00379 Qt::WordBreak,
00380 currEvent->summary() );
00381
00382 p.setBrush( oldBrush );
00383 p.setPen( oldPen );
00384 p.setBackgroundColor( oldBgColor );
00385
00386 offset += height;
00387 } else {
00388 if ( !multiDayStr.isEmpty() ) multiDayStr += ", ";
00389 multiDayStr += currEvent->summary() + "\n";
00390 }
00391 eventList.remove( itold );
00392 }
00393 }
00394
00395 if (!expandable) {
00396 p.drawRect(x, offset, width, height);
00397 if (!multiDayStr.isEmpty()) {
00398 p.fillRect( x + 1, offset + 1, width - 2, height - 2,
00399 QBrush( Qt::Dense5Pattern ) );
00400 p.drawText( x + 5, offset + 5, width - 10, height - 10,
00401 Qt::AlignCenter | Qt::AlignVCenter | Qt::AlignJustify |
00402 Qt::WordBreak,
00403 multiDayStr);
00404 }
00405 } else {
00406 height=offset-y;
00407 }
00408 p.setBrush( oldBrush );
00409 }
00410
00411
00412 void CalPrintHelper::drawAgendaDayBox( QPainter &p, Event::List &events,
00413 const QDate &qd, bool expandable,
00414 QTime &fromTime, QTime &toTime,
00415 int x, int y, int width, int height )
00416 {
00417 p.drawRect( x, y, width, height );
00418
00419 Event *event;
00420
00421 if ( expandable ) {
00422
00423 Event::List::ConstIterator it;
00424 for ( it = events.begin(); it != events.end(); ++it ) {
00425 event = *it;
00426 if ( event->dtStart().time() < fromTime )
00427 fromTime = event->dtStart().time();
00428 if ( event->dtEnd().time() > toTime )
00429 toTime = event->dtEnd().time();
00430 }
00431 }
00432
00433
00434 if ( fromTime.secsTo( toTime ) < 3600 ) {
00435 fromTime = QTime( fromTime.hour(), 0, 0 );
00436 toTime = fromTime.addSecs( 3600 );
00437 }
00438
00439
00440 int totalsecs = fromTime.secsTo( toTime );
00441 float minlen = height * 60. / totalsecs;
00442 float cellHeight = 60. * minlen;
00443 float currY = y;
00444
00445
00446 QTime curTime( QTime( fromTime.hour(), 0, 0 ) );
00447 currY += fromTime.secsTo( curTime ) * minlen / 60;
00448
00449 while ( curTime < toTime && curTime.isValid() ) {
00450 if ( currY > y ) p.drawLine( x, int( currY ), x + width, int( currY ) );
00451 currY += cellHeight / 2;
00452 if ( ( currY > y ) && ( currY < y + height ) ) {
00453 QPen oldPen( p.pen() );
00454 p.setPen( QColor( 192, 192, 192 ) );
00455 p.drawLine( x, int( currY ), x + width, int( currY ) );
00456 p.setPen( oldPen );
00457 }
00458 if ( curTime.secsTo( toTime ) > 3600 )
00459 curTime = curTime.addSecs( 3600 );
00460 else curTime = toTime;
00461 currY += cellHeight / 2;
00462 }
00463
00464 QDateTime startPrintDate = QDateTime( qd, fromTime );
00465 QDateTime endPrintDate = QDateTime( qd, toTime );
00466
00467
00468
00469
00470 QPtrList<KOrg::CellItem> cells;
00471 cells.setAutoDelete( true );
00472
00473 Event::List::ConstIterator itEvents;
00474 for( itEvents = events.begin(); itEvents != events.end(); ++itEvents ) {
00475 QValueList<QDateTime> times = (*itEvents)->startDateTimesForDate( qd );
00476 for ( QValueList<QDateTime>::ConstIterator it = times.begin();
00477 it != times.end(); ++it ) {
00478 cells.append( new PrintCellItem( *itEvents, (*it), (*itEvents)->endDateForStart( *it ) ) );
00479 }
00480 }
00481
00482 QPtrListIterator<KOrg::CellItem> it1( cells );
00483 for( it1.toFirst(); it1.current(); ++it1 ) {
00484 KOrg::CellItem *placeItem = it1.current();
00485
00486 KOrg::CellItem::placeItem( cells, placeItem );
00487 }
00488
00489 QPen oldPen( p.pen() );
00490 QColor oldBgColor( p.backgroundColor() );
00491 QBrush oldBrush( p.brush() );
00492 QFont oldFont( p.font() );
00493
00494 p.setFont( QFont( "helvetica", 10 ) );
00495 p.setBrush( QBrush( Qt::Dense7Pattern ) );
00496
00497 for( it1.toFirst(); it1.current(); ++it1 ) {
00498 PrintCellItem *placeItem = static_cast<PrintCellItem *>( it1.current() );
00499
00500 drawAgendaItem( placeItem, p, qd, startPrintDate, endPrintDate, minlen, x,
00501 y, width );
00502
00503 p.setBrush( oldBrush );
00504 p.setPen( oldPen );
00505 p.setBackgroundColor( oldBgColor );
00506 }
00507 p.setFont( oldFont );
00508
00509 }
00510
00511
00512 void CalPrintHelper::drawAgendaItem( PrintCellItem *item, QPainter &p,
00513 const QDate &qd,
00514 const QDateTime &startPrintDate,
00515 const QDateTime &endPrintDate,
00516 float minlen, int x, int y, int width )
00517 {
00518 Event *event = item->event();
00519
00520
00521 if ( mUseColors ) setCategoryColors( p, event );
00522
00523
00524 QDateTime startTime = item->start();
00525 QDateTime endTime = item->end();
00526 if ( ( startTime < endPrintDate && endTime > startPrintDate ) ||
00527 ( endTime > startPrintDate && startTime < endPrintDate ) ) {
00528 if ( startTime < startPrintDate ) startTime = startPrintDate;
00529 if ( endTime > endPrintDate ) endTime = endPrintDate;
00530 int currentHeight = int( startTime.secsTo( endTime ) / 60. * minlen );
00531 int currentYPos = int( y + startPrintDate.secsTo( startTime ) *
00532 minlen / 60. );
00533 int currentWidth = width / item->subCells();
00534 int currentX = x + item->subCell() * currentWidth;
00535
00536 p.drawRect( currentX, currentYPos, currentWidth, currentHeight );
00537 int offset = 4;
00538
00539
00540 int flags = Qt::AlignLeft | Qt::WordBreak;
00541 QRect bound = p.boundingRect ( currentX + offset, currentYPos,
00542 currentWidth - 2 * offset, currentHeight,
00543 flags, event->summary() );
00544 flags |= Qt::AlignTop;
00545 p.drawText( currentX+offset, currentYPos+offset, currentWidth-2*offset,
00546 currentHeight-2*offset, flags, event->summary() );
00547 }
00548 }
00549
00550 void CalPrintHelper::drawDayBox( QPainter &p, const QDate &qd,
00551 int x, int y, int width, int height,
00552 bool fullDate, bool printRecurDaily, bool printRecurWeekly )
00553 {
00554 QString dayNumStr;
00555 QString ampm;
00556 const KLocale*local = KGlobal::locale();
00557
00558
00559
00560 if ( fullDate && mCalSys ) {
00561
00562 dayNumStr = i18n("weekday month date", "%1 %2 %3")
00563 .arg( mCalSys->weekDayName( qd ) )
00564 .arg( mCalSys->monthName( qd ) )
00565 .arg( qd.day() );
00566
00567 } else {
00568 dayNumStr = QString::number( qd.day() );
00569 }
00570
00571 p.eraseRect( x, y, width, height );
00572 QRect dayBox( x, y, width, height );
00573 p.drawRect( dayBox );
00574 p.drawRect( x, y, width, mSubHeaderHeight );
00575 p.fillRect( x + 1, y + 1, width - 2, mSubHeaderHeight - 2,
00576 QBrush( Qt::Dense7Pattern ) );
00577 QString hstring;
00578 #ifndef KORG_NOPLUGINS
00579 if ( mCoreHelper ) hstring = mCoreHelper->holidayString(qd);
00580 #endif
00581 QFont oldFont( p.font() );
00582
00583 if (!hstring.isEmpty()) {
00584 p.setFont( QFont( "helvetica", 8, QFont::Bold, true ) );
00585
00586 p.drawText( x+5, y, width-25, mSubHeaderHeight,
00587 Qt::AlignLeft | Qt::AlignVCenter, hstring );
00588 }
00589 p.setFont(QFont("helvetica", 10, QFont::Bold));
00590 p.drawText( x + 5, y, width - 10, mSubHeaderHeight,
00591 Qt::AlignRight | Qt::AlignVCenter, dayNumStr);
00592
00593 Event::List eventList = mCalendar->events( qd,
00594 EventSortStartDate,
00595 SortDirectionAscending );
00596 QString text;
00597 p.setFont( QFont( "helvetica", 8 ) );
00598
00599 int textY=mSubHeaderHeight+3;
00600 Event::List::ConstIterator it;
00601
00602 for( it = eventList.begin(); it != eventList.end() && textY<height; ++it ) {
00603 Event *currEvent = *it;
00604 if ( ( !printRecurDaily && currEvent->recurrenceType() == Recurrence::rDaily ) ||
00605 ( !printRecurWeekly && currEvent->recurrenceType() == Recurrence::rWeekly ) ) {
00606 continue; }
00607 if ( currEvent->doesFloat() || currEvent->isMultiDay() )
00608 text = "";
00609 else
00610 text = local->formatTime( currEvent->dtStart().time() );
00611
00612 drawIncidence( p, dayBox, text, currEvent->summary(), textY );
00613 }
00614
00615 if ( textY<height ) {
00616 Todo::List todos = mCalendar->todos( qd );
00617 Todo::List::ConstIterator it2;
00618 for( it2 = todos.begin(); it2 != todos.end() && textY<height; ++it2 ) {
00619 Todo *todo = *it2;
00620 if ( ( !printRecurDaily && todo->recurrenceType() == Recurrence::rDaily ) ||
00621 ( !printRecurWeekly && todo->recurrenceType() == Recurrence::rWeekly ) )
00622 continue;
00623 if ( todo->hasDueDate() && !todo->doesFloat() )
00624 text += KGlobal::locale()->formatTime(todo->dtDue().time()) + " ";
00625 else
00626 text = "";
00627 drawIncidence( p, dayBox, text, i18n("To-do: %1").arg(todo->summary()), textY );
00628 }
00629 }
00630
00631 p.setFont( oldFont );
00632 }
00633
00634 void CalPrintHelper::drawIncidence( QPainter &p, QRect &dayBox, const QString &time, const QString &summary, int &textY )
00635 {
00636 kdDebug(5850) << "summary = " << summary << endl;
00637
00638 int flags = Qt::AlignLeft;
00639 QFontMetrics fm = p.fontMetrics();
00640 QRect timeBound = p.boundingRect( dayBox.x() + 5, dayBox.y() + textY,
00641 dayBox.width() - 10, fm.lineSpacing(),
00642 flags, time );
00643 p.drawText( timeBound, flags, time );
00644
00645 int summaryWidth = time.isEmpty() ? 0 : timeBound.width() + 4;
00646 QRect summaryBound = QRect( dayBox.x() + 5 + summaryWidth, dayBox.y() + textY,
00647 dayBox.width() - summaryWidth -5, dayBox.height() );
00648
00649 KWordWrap *ww = KWordWrap::formatText( fm, summaryBound, flags, summary );
00650 ww->drawText( &p, dayBox.x() + 5 + summaryWidth, dayBox.y() + textY, flags );
00651
00652 textY += ww->boundingRect().height();
00653
00654 delete ww;
00655 }
00656
00657
00659
00660 void CalPrintHelper::drawWeek(QPainter &p, const QDate &qd,
00661 int x, int y, int width, int height)
00662 {
00663 QDate weekDate = qd;
00664 bool portrait = ( height > width );
00665 int cellWidth, cellHeight;
00666 int vcells;
00667 if (portrait) {
00668 cellWidth = width/2;
00669 vcells=3;
00670 } else {
00671 cellWidth = width/6;
00672 vcells=1;
00673 }
00674 cellHeight = height/vcells;
00675
00676
00677 int weekdayCol = weekdayColumn( qd.dayOfWeek() );
00678 weekDate = qd.addDays( -weekdayCol );
00679
00680 for (int i = 0; i < 7; i++, weekDate = weekDate.addDays(1)) {
00681 if (i<5) {
00682 drawDayBox(p, weekDate, x+cellWidth*(int)(i/vcells), y+cellHeight*(i%vcells),
00683 cellWidth, cellHeight, true);
00684 } else if (i==5) {
00685 drawDayBox(p, weekDate, x+cellWidth*(int)(i/vcells), y+cellHeight*(i%vcells),
00686 cellWidth, cellHeight/2, true);
00687 } else if (i==6) {
00688 drawDayBox(p, weekDate, x+cellWidth*(int)((i-1)/vcells),
00689 y+cellHeight*((i-1)%vcells)+cellHeight/2, cellWidth, cellHeight/2, true);
00690 }
00691 }
00692 }
00693
00694
00695 void CalPrintHelper::drawTimeTable(QPainter &p,
00696 const QDate &fromDate, const QDate &toDate,
00697 QTime &fromTime, QTime &toTime,
00698 int x, int y, int width, int height)
00699 {
00700
00701 int alldayHeight = (int)( 3600.*height/(fromTime.secsTo(toTime)+3600.) );
00702 int timelineWidth = 50;
00703 int cellWidth = (int)( (width-timelineWidth)/(fromDate.daysTo(toDate)+1) );
00704 int currY=y;
00705 int currX=x;
00706
00707 drawDaysOfWeek( p, fromDate, toDate, x+timelineWidth, currY, width-timelineWidth, mSubHeaderHeight);
00708 currY+=mSubHeaderHeight;
00709 drawTimeLine( p, fromTime, toTime, x, currY+alldayHeight,
00710 timelineWidth, height-mSubHeaderHeight-alldayHeight );
00711
00712 currX=x+timelineWidth;
00713
00714 QDate curDate(fromDate);
00715 while (curDate<=toDate) {
00716 Event::List eventList = mCalendar->events(curDate,
00717 EventSortStartDate,
00718 SortDirectionAscending);
00719 drawAllDayBox( p, eventList, curDate, false, currX, currY, cellWidth, alldayHeight);
00720 drawAgendaDayBox( p, eventList, curDate, false, fromTime, toTime, currX,
00721 currY+alldayHeight, cellWidth, height-mSubHeaderHeight-alldayHeight );
00722 currX+=cellWidth;
00723 curDate=curDate.addDays(1);
00724 }
00725
00726 }
00727
00728
00730
00731 void CalPrintHelper::drawMonth(QPainter &p, const QDate &qd, bool weeknumbers,
00732 bool recurDaily, bool recurWeekly, int x, int y,
00733 int width, int height)
00734 {
00735 int yoffset = mSubHeaderHeight;
00736 int xoffset = 0;
00737 QDate monthDate(QDate(qd.year(), qd.month(), 1));
00738 QDate monthFirst(monthDate);
00739 QDate monthLast(monthDate.addMonths(1).addDays(-1));
00740
00741
00742 int weekdayCol = weekdayColumn( monthDate.dayOfWeek() );
00743 monthDate = monthDate.addDays(-weekdayCol);
00744
00745 int rows=(weekdayCol + qd.daysInMonth() - 1)/7 +1;
00746 int cellHeight = (height-yoffset) / rows;
00747
00748 if (weeknumbers) {
00749 QFont oldFont(p.font());
00750 QFont newFont(p.font());
00751 newFont.setPointSize(6);
00752 p.setFont(newFont);
00753 xoffset += 14;
00754 QDate weekDate(monthDate);
00755 for (int row = 0; row<rows; ++row ) {
00756 int calWeek = weekDate.weekNumber();
00757 QRect rc( x, y + yoffset + cellHeight*row, xoffset - 1, cellHeight );
00758 p.drawText( rc, Qt::AlignRight | Qt::AlignVCenter,
00759 QString::number( calWeek ) );
00760 weekDate = weekDate.addDays( 7 );
00761 }
00762 p.setFont( oldFont );
00763 }
00764
00765 drawDaysOfWeek( p, monthDate, monthDate.addDays( 6 ), x + xoffset,
00766 y, width - xoffset, mSubHeaderHeight );
00767 int cellWidth = ( width - xoffset ) / 7;
00768
00769 QColor back = p.backgroundColor();
00770 bool darkbg = false;
00771 for ( int row = 0; row < rows; ++row ) {
00772 for ( int col = 0; col < 7; ++col ) {
00773
00774 if ( (monthDate < monthFirst) || (monthDate > monthLast) ) {
00775 p.setBackgroundColor( back.dark( 120 ) );
00776 darkbg = true;
00777 }
00778 drawDayBox(p, monthDate, x+xoffset+col*cellWidth, y+yoffset+row*cellHeight,
00779 cellWidth, cellHeight, false, recurDaily, recurWeekly );
00780 if ( darkbg ) {
00781 p.setBackgroundColor( back );
00782 darkbg = false;
00783 }
00784 monthDate = monthDate.addDays(1);
00785 }
00786 }
00787 }
00788
00789
00791
00792 void CalPrintHelper::drawTodo( int &count, Todo *todo, QPainter &p,
00793 TodoSortField sortField, SortDirection sortDir,
00794 bool connectSubTodos, bool strikeoutCompleted,
00795 bool desc, int posPriority, int posSummary,
00796 int posDueDt, int posPercentComplete,
00797 int level, int x, int &y, int width,
00798 int pageHeight, const Todo::List &todoList,
00799 TodoParentStart *r )
00800 {
00801 QString outStr;
00802 const KLocale *local = KGlobal::locale();
00803 QRect rect;
00804 TodoParentStart startpt;
00805
00806
00807
00808 static QPtrList<TodoParentStart> startPoints;
00809 if ( level < 1 ) {
00810 startPoints.clear();
00811 }
00812
00813
00814 int rhs = posPercentComplete;
00815 if ( rhs < 0 ) rhs = posDueDt;
00816 if ( rhs < 0 ) rhs = x+width;
00817
00818
00819 outStr=todo->summary();
00820 int left = posSummary + ( level*10 );
00821 rect = p.boundingRect( left, y, ( rhs-left-5 ), -1, Qt::WordBreak, outStr );
00822 if ( !todo->description().isEmpty() && desc ) {
00823 outStr = todo->description();
00824 rect = p.boundingRect( left+20, rect.bottom()+5, width-(left+10-x), -1,
00825 Qt::WordBreak, outStr );
00826 }
00827
00828 if ( rect.bottom() > pageHeight ) {
00829
00830 if ( level > 0 && connectSubTodos ) {
00831 TodoParentStart *rct;
00832 for ( rct = startPoints.first(); rct; rct = startPoints.next() ) {
00833 int start;
00834 int center = rct->mRect.left() + (rct->mRect.width()/2);
00835 int to = p.viewport().bottom();
00836
00837
00838 if ( rct->mSamePage )
00839 start = rct->mRect.bottom() + 1;
00840 else
00841 start = p.viewport().top();
00842 p.moveTo( center, start );
00843 p.lineTo( center, to );
00844 rct->mSamePage = false;
00845 }
00846 }
00847 y=0;
00848 mPrinter->newPage();
00849 }
00850
00851
00852
00853 bool showPriority = posPriority>=0;
00854 int lhs = posPriority;
00855 if ( r ) {
00856 lhs = r->mRect.right() + 1;
00857 }
00858
00859 outStr.setNum( todo->priority() );
00860 rect = p.boundingRect( lhs, y + 10, 5, -1, Qt::AlignCenter, outStr );
00861
00862 rect.setWidth(18);
00863 rect.setHeight(18);
00864
00865
00866 p.setBrush( QBrush( Qt::NoBrush ) );
00867 p.drawRect( rect );
00868 if ( todo->isCompleted() ) {
00869
00870 p.drawLine( rect.topLeft(), rect.bottomRight() );
00871 p.drawLine( rect.topRight(), rect.bottomLeft() );
00872 }
00873 lhs = rect.right() + 3;
00874
00875
00876 if ( todo->priority() > 0 && showPriority ) {
00877 p.drawText( rect, Qt::AlignCenter, outStr );
00878 }
00879 startpt.mRect = rect;
00880
00881
00882 if ( level > 0 && connectSubTodos ) {
00883 int bottom;
00884 int center( r->mRect.left() + (r->mRect.width()/2) );
00885 if ( r->mSamePage )
00886 bottom = r->mRect.bottom() + 1;
00887 else
00888 bottom = 0;
00889 int to( rect.top() + (rect.height()/2) );
00890 int endx( rect.left() );
00891 p.moveTo( center, bottom );
00892 p.lineTo( center, to );
00893 p.lineTo( endx, to );
00894 }
00895
00896
00897 outStr=todo->summary();
00898 rect = p.boundingRect( lhs, rect.top(), (rhs-(left + rect.width() + 5)),
00899 -1, Qt::WordBreak, outStr );
00900
00901 QRect newrect;
00902
00903 #if 0
00904 QFont f( p.font() );
00905 if ( todo->isCompleted() && strikeoutCompleted ) {
00906 f.setStrikeOut( true );
00907 p.setFont( f );
00908 }
00909 p.drawText( rect, Qt::WordBreak, outStr, -1, &newrect );
00910 f.setStrikeOut( false );
00911 p.setFont( f );
00912 #endif
00913
00914 p.drawText( rect, Qt::WordBreak, outStr, -1, &newrect );
00915 if ( todo->isCompleted() && strikeoutCompleted ) {
00916
00917
00918
00919 int delta = p.fontMetrics().lineSpacing();
00920 int lines = ( rect.height() / delta ) + 1;
00921 for ( int i=0; i<lines; i++ ) {
00922 p.moveTo( rect.left(), rect.top() + ( delta/2 ) + ( i*delta ) );
00923 p.lineTo( rect.right(), rect.top() + ( delta/2 ) + ( i*delta ) );
00924 }
00925 }
00926
00927
00928 if ( todo->hasDueDate() && posDueDt>=0 ) {
00929 outStr = local->formatDate( todo->dtDue().date(), true );
00930 rect = p.boundingRect( posDueDt, y, x + width, -1,
00931 Qt::AlignTop | Qt::AlignLeft, outStr );
00932 p.drawText( rect, Qt::AlignTop | Qt::AlignLeft, outStr );
00933 }
00934
00935
00936 bool showPercentComplete = posPercentComplete>=0;
00937 if ( showPercentComplete ) {
00938 int lwidth = 24;
00939 int lheight = 12;
00940
00941 int progress = (int)(( lwidth*todo->percentComplete())/100.0 + 0.5);
00942
00943 p.setBrush( QBrush( Qt::NoBrush ) );
00944 p.drawRect( posPercentComplete, y+3, lwidth, lheight );
00945 if ( progress > 0 ) {
00946 p.setBrush( QBrush( Qt::Dense5Pattern ) );
00947 p.drawRect( posPercentComplete, y+3, progress, lheight );
00948 }
00949
00950
00951 outStr = i18n( "%1%" ).arg( todo->percentComplete() );
00952 rect = p.boundingRect( posPercentComplete+lwidth+3, y, x + width, -1,
00953 Qt::AlignTop | Qt::AlignLeft, outStr );
00954 p.drawText( rect, Qt::AlignTop | Qt::AlignLeft, outStr );
00955 }
00956
00957
00958 if ( !todo->description().isEmpty() && desc ) {
00959 y = newrect.bottom() + 5;
00960 outStr = todo->description();
00961 rect = p.boundingRect( left+20, y, x+width-(left+10), -1,
00962 Qt::WordBreak, outStr );
00963 p.drawText( rect, Qt::WordBreak, outStr, -1, &newrect );
00964 }
00965
00966
00967 y = newrect.bottom() + 10;
00968
00969
00970 #if 0
00971 Incidence::List l = todo->relations();
00972 Incidence::List::ConstIterator it;
00973 startPoints.append( &startpt );
00974 for( it = l.begin(); it != l.end(); ++it ) {
00975 count++;
00976
00977
00978
00979
00980 Todo* subtodo = dynamic_cast<Todo *>( *it );
00981 if (subtodo && todoList.contains( subtodo ) ) {
00982 drawTodo( count, subtodo, p, connectSubTodos, strikeoutCompleted,
00983 desc, posPriority, posSummary, posDueDt, posPercentComplete,
00984 level+1, x, y, width, pageHeight, todoList, &startpt );
00985 }
00986 }
00987 #endif
00988
00989 Todo::List t;
00990 Incidence::List l = todo->relations();
00991 Incidence::List::ConstIterator it;
00992 for( it=l.begin(); it!=l.end(); ++it ) {
00993
00994
00995
00996
00997 Todo* subtodo = dynamic_cast<Todo *>( *it );
00998 if ( subtodo && todoList.contains( subtodo ) ) {
00999 t.append( subtodo );
01000 }
01001 }
01002
01003
01004 Todo::List sl = mCalendar->sortTodos( &t, sortField, sortDir );
01005 Todo::List::ConstIterator isl;
01006 startPoints.append( &startpt );
01007 for( isl = sl.begin(); isl != sl.end(); ++isl ) {
01008 count++;
01009 drawTodo( count, ( *isl ), p, sortField, sortDir,
01010 connectSubTodos, strikeoutCompleted,
01011 desc, posPriority, posSummary, posDueDt, posPercentComplete,
01012 level+1, x, y, width, pageHeight, todoList, &startpt );
01013 }
01014 startPoints.remove( &startpt );
01015 }
01016
01017 int CalPrintHelper::weekdayColumn( int weekday )
01018 {
01019 return ( weekday + 7 - KGlobal::locale()->weekStartDay() ) % 7;
01020 }
01021
01022 void CalPrintHelper::drawJournalField( QPainter &p, QString field, QString text,
01023 int x, int &y, int width, int pageHeight )
01024 {
01025 if ( text.isEmpty() ) return;
01026
01027 QString entry( field.arg( text ) );
01028
01029 QRect rect( p.boundingRect( x, y, width, -1, Qt::WordBreak, entry) );
01030 if ( rect.bottom() > pageHeight) {
01031
01032
01033
01034 y=0;
01035 mPrinter->newPage();
01036 rect = p.boundingRect( x, y, width, -1, Qt::WordBreak, entry);
01037 }
01038 QRect newrect;
01039 p.drawText( rect, Qt::WordBreak, entry, -1, &newrect );
01040 y = newrect.bottom() + 7;
01041 }
01042
01043 void CalPrintHelper::drawJournal( Journal * journal, QPainter &p, int x, int &y,
01044 int width, int pageHeight )
01045 {
01046 QFont oldFont( p.font() );
01047 p.setFont( QFont( "helvetica", 15 ) );
01048 QString headerText;
01049 QString dateText( KGlobal::locale()->
01050 formatDate( journal->dtStart().date(), false ) );
01051
01052 if ( journal->summary().isEmpty() ) {
01053 headerText = dateText;
01054 } else {
01055 headerText = i18n("Description - date", "%1 - %2")
01056 .arg( journal->summary() )
01057 .arg( dateText );
01058 }
01059
01060 QRect rect( p.boundingRect( x, y, width, -1, Qt::WordBreak, headerText) );
01061 if ( rect.bottom() > pageHeight) {
01062
01063 y=0;
01064 mPrinter->newPage();
01065 rect = p.boundingRect( x, y, width, -1, Qt::WordBreak, headerText );
01066 }
01067 QRect newrect;
01068 p.drawText( rect, Qt::WordBreak, headerText, -1, &newrect );
01069 p.setFont( oldFont );
01070
01071 y = newrect.bottom() + 4;
01072
01073 p.drawLine( x + 3, y, x + width - 6, y );
01074 y += 5;
01075
01076 drawJournalField( p, i18n("Person: %1"), journal->organizer().fullName(), x, y, width, pageHeight );
01077 drawJournalField( p, i18n("%1"), journal->description(), x, y, width, pageHeight );
01078 y += 10;
01079 }
01080
01081
01082 void CalPrintHelper::drawSplitHeaderRight( QPainter &p, const QDate &fd,
01083 const QDate &td,
01084 const QDate &,
01085 int width, int )
01086 {
01087 QFont oldFont( p.font() );
01088
01089 QPen oldPen( p.pen() );
01090 QPen pen( Qt::black, 4 );
01091
01092 QString title;
01093 if ( mCalSys ) {
01094 if ( fd.month() == td.month() ) {
01095 title = i18n("Date range: Month dayStart - dayEnd", "%1 %2 - %3")
01096 .arg( mCalSys->monthName( fd.month(), false ) )
01097 .arg( mCalSys->dayString( fd, false ) )
01098 .arg( mCalSys->dayString( td, false ) );
01099 } else {
01100 title = i18n("Date range: monthStart dayStart - monthEnd dayEnd", "%1 %2 - %3 %4")
01101 .arg( mCalSys->monthName( fd.month(), false ) )
01102 .arg( mCalSys->dayString( fd, false ) )
01103 .arg( mCalSys->monthName( td.month(), false ) )
01104 .arg( mCalSys->dayString( td, false ) );
01105 }
01106 }
01107
01108 QFont serifFont("Times", 30);
01109 p.setFont(serifFont);
01110
01111 int lineSpacing = p.fontMetrics().lineSpacing();
01112 p.drawText( 0, lineSpacing * 0, width, lineSpacing,
01113 Qt::AlignRight | Qt::AlignTop, title );
01114
01115 title.truncate(0);
01116
01117 p.setPen( pen );
01118 p.drawLine(300, lineSpacing * 1, width, lineSpacing * 1);
01119 p.setPen( oldPen );
01120
01121 p.setFont(QFont("Times", 20, QFont::Bold, TRUE));
01122 int newlineSpacing = p.fontMetrics().lineSpacing();
01123 title += QString::number(fd.year());
01124 p.drawText( 0, lineSpacing * 1 + 4, width, newlineSpacing,
01125 Qt::AlignRight | Qt::AlignTop, title );
01126
01127 p.setFont( oldFont );
01128 }
01129
01130 #endif