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