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
00031 #include <kdebug.h>
00032 #include <kconfig.h>
00033 #include <kcalendarsystem.h>
00034 #include <kwordwrap.h>
00035
00036 #include "calprintpluginbase.h"
00037 #include "cellitem.h"
00038
00039 #ifndef KORG_NOPRINTER
00040
00041 inline int round(const double x)
00042 {
00043 return int(x > 0.0 ? x + 0.5 : x - 0.5);
00044 }
00045
00046
00047
00048 class CalPrintPluginBase::TodoParentStart
00049 {
00050 public:
00051 TodoParentStart( QRect pt = QRect(), bool page = true )
00052 : mRect( pt ), mSamePage( page ) {}
00053
00054 QRect mRect;
00055 bool mSamePage;
00056 };
00057
00058
00059
00060
00061
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
00103
00104
00105
00106
00107
00108
00109
00110 CalPrintPluginBase::CalPrintPluginBase() : PrintPlugin(), mUseColors( true ),
00111 mHeaderHeight( -1 ), mSubHeaderHeight( SUBHEADER_HEIGHT ), mFooterHeight( -1 ),
00112 mMargin( MARGIN_SIZE ), mPadding( PADDING_SIZE), mCalSys( 0 )
00113 {
00114 }
00115 CalPrintPluginBase::~CalPrintPluginBase()
00116 {
00117 }
00118
00119
00120
00121 QWidget *CalPrintPluginBase::createConfigWidget( QWidget *w )
00122 {
00123 QFrame *wdg = new QFrame( w );
00124 QVBoxLayout *layout = new QVBoxLayout( wdg );
00125
00126 QLabel *title = new QLabel( description(), wdg );
00127 QFont titleFont( title->font() );
00128 titleFont.setPointSize( 20 );
00129 titleFont.setBold( true );
00130 title->setFont( titleFont );
00131
00132 layout->addWidget( title );
00133 layout->addWidget( new QLabel( info(), wdg ) );
00134 layout->addSpacing( 20 );
00135 layout->addWidget( new QLabel( i18n("This printing style does not "
00136 "have any configuration options."),
00137 wdg ) );
00138 layout->addStretch();
00139 return wdg;
00140 }
00141
00142 void CalPrintPluginBase::doPrint( KPrinter *printer )
00143 {
00144 if ( !printer ) return;
00145 mPrinter = printer;
00146 QPainter p;
00147
00148 mPrinter->setColorMode( mUseColors?(KPrinter::Color):(KPrinter::GrayScale) );
00149
00150 p.begin( mPrinter );
00151
00152
00153
00154 int margins = margin();
00155 p.setViewport( margins, margins,
00156 p.viewport().width() - 2*margins,
00157 p.viewport().height() - 2*margins );
00158
00159
00160
00161
00162 int pageWidth = p.window().width();
00163 int pageHeight = p.window().height();
00164
00165
00166
00167 print( p, pageWidth, pageHeight );
00168
00169 p.end();
00170 mPrinter = 0;
00171 }
00172
00173 void CalPrintPluginBase::doLoadConfig()
00174 {
00175 if ( mConfig ) {
00176 KConfigGroupSaver saver( mConfig, description() );
00177 mConfig->sync();
00178 QDateTime currDate( QDate::currentDate() );
00179 mFromDate = mConfig->readDateTimeEntry( "FromDate", &currDate ).date();
00180 mToDate = mConfig->readDateTimeEntry( "ToDate" ).date();
00181 mUseColors = mConfig->readBoolEntry( "UseColors", true );
00182 setUseColors( mUseColors );
00183 loadConfig();
00184 } else {
00185 kdDebug(5850) << "No config available in loadConfig!!!!" << endl;
00186 }
00187 }
00188
00189 void CalPrintPluginBase::doSaveConfig()
00190 {
00191 if ( mConfig ) {
00192 KConfigGroupSaver saver( mConfig, description() );
00193 saveConfig();
00194 mConfig->writeEntry( "FromDate", QDateTime( mFromDate ) );
00195 mConfig->writeEntry( "ToDate", QDateTime( mToDate ) );
00196 mConfig->writeEntry( "UseColors", mUseColors );
00197 mConfig->sync();
00198 } else {
00199 kdDebug(5850) << "No config available in saveConfig!!!!" << endl;
00200 }
00201 }
00202
00203
00204
00205
00206 void CalPrintPluginBase::setKOrgCoreHelper( KOrg::CoreHelper*helper )
00207 {
00208 PrintPlugin::setKOrgCoreHelper( helper );
00209 if ( helper )
00210 setCalendarSystem( helper->calendarSystem() );
00211 }
00212
00213 bool CalPrintPluginBase::useColors() const
00214 {
00215 return mUseColors;
00216 }
00217 void CalPrintPluginBase::setUseColors( bool useColors )
00218 {
00219 mUseColors = useColors;
00220 }
00221
00222 KPrinter::Orientation CalPrintPluginBase::orientation() const
00223 {
00224 return (mPrinter)?(mPrinter->orientation()):(KPrinter::Portrait);
00225 }
00226
00227
00228
00229 QTime CalPrintPluginBase::dayStart()
00230 {
00231 QTime start( 8,0,0 );
00232 if ( mCoreHelper ) start = mCoreHelper->dayStart();
00233 return start;
00234 }
00235
00236 void CalPrintPluginBase::setCategoryColors( QPainter &p, Incidence *incidence )
00237 {
00238 QColor bgColor = categoryBgColor( incidence );
00239 if ( bgColor.isValid() )
00240 p.setBrush( bgColor );
00241 QColor tColor( textColor( bgColor ) );
00242 if ( tColor.isValid() )
00243 p.setPen( tColor );
00244 }
00245
00246 QColor CalPrintPluginBase::categoryBgColor( Incidence *incidence )
00247 {
00248 if (mCoreHelper && incidence)
00249 return mCoreHelper->categoryColor( incidence->categories() );
00250 else
00251 return QColor();
00252 }
00253
00254 QColor CalPrintPluginBase::textColor( const QColor &color )
00255 {
00256 return (mCoreHelper)?(mCoreHelper->textColor( color )):QColor();
00257 }
00258
00259 bool CalPrintPluginBase::isWorkingDay( const QDate &dt )
00260 {
00261 return (mCoreHelper)?( mCoreHelper->isWorkingDay( dt ) ):true;
00262 }
00263
00264 QString CalPrintPluginBase::holidayString( const QDate &dt )
00265 {
00266 return (mCoreHelper)?(mCoreHelper->holidayString(dt)):(QString::null);
00267 }
00268
00269
00270 Event *CalPrintPluginBase::holiday( const QDate &dt )
00271 {
00272 QString hstring( holidayString( dt ) );
00273 if ( !hstring.isEmpty() ) {
00274 Event*holiday=new Event();
00275 holiday->setSummary( hstring );
00276 holiday->setDtStart( dt );
00277 holiday->setDtEnd( dt );
00278 holiday->setFloats( true );
00279 holiday->setCategories( i18n("Holiday") );
00280 return holiday;
00281 }
00282 return 0;
00283 }
00284
00285 const KCalendarSystem *CalPrintPluginBase::calendarSystem() const
00286 {
00287 return mCalSys;
00288 }
00289 void CalPrintPluginBase::setCalendarSystem( const KCalendarSystem *calsys )
00290 {
00291 mCalSys = calsys;
00292 }
00293
00294 int CalPrintPluginBase::headerHeight() const
00295 {
00296 if ( mHeaderHeight >= 0 )
00297 return mHeaderHeight;
00298 else if ( orientation() == KPrinter::Portrait )
00299 return PORTRAIT_HEADER_HEIGHT;
00300 else
00301 return LANDSCAPE_HEADER_HEIGHT;
00302 }
00303 void CalPrintPluginBase::setHeaderHeight( const int height )
00304 {
00305 mHeaderHeight = height;
00306 }
00307
00308 int CalPrintPluginBase::subHeaderHeight() const
00309 {
00310 return mSubHeaderHeight;
00311 }
00312 void CalPrintPluginBase::setSubHeaderHeight( const int height )
00313 {
00314 mSubHeaderHeight = height;
00315 }
00316
00317 int CalPrintPluginBase::footerHeight() const
00318 {
00319 if ( mFooterHeight >= 0 )
00320 return mFooterHeight;
00321 else if ( orientation() == KPrinter::Portrait )
00322 return PORTRAIT_FOOTER_HEIGHT;
00323 else
00324 return LANDSCAPE_FOOTER_HEIGHT;
00325 }
00326 void CalPrintPluginBase::setFooterHeight( const int height )
00327 {
00328 mFooterHeight = height;
00329 }
00330
00331 int CalPrintPluginBase::margin() const
00332 {
00333 return mMargin;
00334 }
00335 void CalPrintPluginBase::setMargin( const int margin )
00336 {
00337 mMargin = margin;
00338 }
00339
00340 int CalPrintPluginBase::padding() const
00341 {
00342 return mPadding;
00343 }
00344 void CalPrintPluginBase::setPadding( const int padding )
00345 {
00346 mPadding = padding;
00347 }
00348
00349 int CalPrintPluginBase::borderWidth() const
00350 {
00351 return mBorder;
00352 }
00353 void CalPrintPluginBase::setBorderWidth( const int borderwidth )
00354 {
00355 mBorder = borderwidth;
00356 }
00357
00358
00359
00360
00361 void CalPrintPluginBase::drawBox( QPainter &p, int linewidth, const QRect &rect )
00362 {
00363 QPen pen( p.pen() );
00364 QPen oldpen( pen );
00365 pen.setWidth( linewidth );
00366 p.setPen( pen );
00367 p.drawRect( rect );
00368 p.setPen( oldpen );
00369 }
00370
00371 void CalPrintPluginBase::drawShadedBox( QPainter &p, int linewidth, const QBrush &brush, const QRect &rect )
00372 {
00373 QBrush oldbrush( p.brush() );
00374 p.setBrush( brush );
00375 drawBox( p, linewidth, rect );
00376 p.setBrush( oldbrush );
00377 }
00378
00379 void CalPrintPluginBase::printEventString( QPainter &p, const QRect &box, const QString &str, int flags )
00380 {
00381 QRect newbox( box );
00382 newbox.addCoords( 3, 1, -1, -1 );
00383 p.drawText( newbox, (flags==-1)?(Qt::AlignTop | Qt::AlignJustify | Qt::BreakAnywhere):flags, str );
00384 }
00385
00386
00387 void CalPrintPluginBase::showEventBox( QPainter &p, const QRect &box, Incidence *incidence, const QString &str, int flags )
00388 {
00389 QPen oldpen( p.pen() );
00390 QBrush oldbrush( p.brush() );
00391 QColor bgColor( categoryBgColor( incidence ) );
00392 if ( mUseColors & bgColor.isValid() ) {
00393 p.setBrush( bgColor );
00394 } else {
00395 p.setBrush( QColor( 232, 232, 232 ) );
00396 }
00397 drawBox( p, EVENT_BORDER_WIDTH, box );
00398
00399 if ( mUseColors && bgColor.isValid() ) {
00400 p.setPen( textColor( bgColor ) );
00401 }
00402 printEventString( p, box, str, flags );
00403 p.setPen( oldpen );
00404 p.setBrush( oldbrush );
00405 }
00406
00407
00408 void CalPrintPluginBase::drawSubHeaderBox(QPainter &p, const QString &str,
00409 const QRect &box )
00410 {
00411 drawShadedBox( p, BOX_BORDER_WIDTH, QColor( 232, 232, 232 ), box );
00412 QFont oldfont( p.font() );
00413 p.setFont( QFont( "sans-serif", 10, QFont::Bold ) );
00414 p.drawText( box, Qt::AlignCenter | Qt::AlignVCenter, str );
00415 p.setFont( oldfont );
00416 }
00417
00418 void CalPrintPluginBase::drawVerticalBox( QPainter &p, const QRect &box, const QString &str )
00419 {
00420 p.save();
00421 p.rotate( -90 );
00422 QRect rotatedBox( -box.top()-box.height(), box.left(), box.height(), box.width() );
00423 showEventBox( p, rotatedBox, 0, str, Qt::AlignLeft | Qt::AlignVCenter | Qt::SingleLine );
00424
00425 p.restore();
00426 }
00427
00428
00429
00431
00432
00433
00434 int CalPrintPluginBase::drawBoxWithCaption( QPainter &p, const QRect &allbox,
00435 const QString &caption, const QString &contents, bool sameLine, bool expand, const QFont &captionFont, const QFont &textFont )
00436 {
00437 QFont oldFont( p.font() );
00438
00439
00440
00441
00442
00443
00444 QRect box( allbox );
00445
00446
00447 QRect captionBox( box.left() + padding(), box.top() + padding(), 0, 0 );
00448 p.setFont( captionFont );
00449 captionBox = p.boundingRect( captionBox, Qt::AlignLeft | Qt::AlignTop | Qt::SingleLine, caption );
00450 p.setFont( oldFont );
00451 if ( captionBox.right() > box.right() )
00452 captionBox.setRight( box.right() );
00453 if ( expand && captionBox.bottom() + padding() > box.bottom() )
00454 box.setBottom( captionBox.bottom() + padding() );
00455
00456
00457 QRect textBox( captionBox );
00458 if ( !contents.isEmpty() ) {
00459 if ( sameLine ) {
00460 textBox.setLeft( captionBox.right() + padding() );
00461 } else {
00462 textBox.setTop( captionBox.bottom() + padding() );
00463 }
00464 textBox.setRight( box.right() );
00465 textBox.setHeight( 0 );
00466 p.setFont( textFont );
00467 textBox = p.boundingRect( textBox, Qt::WordBreak | Qt::AlignTop | Qt::AlignLeft, contents );
00468 p.setFont( oldFont );
00469 if ( textBox.bottom() + padding() > box.bottom() ) {
00470 if ( expand ) {
00471 box.setBottom( textBox.bottom() + padding() );
00472 } else {
00473 textBox.setBottom( box.bottom() );
00474 }
00475 }
00476 }
00477
00478 drawBox( p, BOX_BORDER_WIDTH, box );
00479 p.setFont( captionFont );
00480 p.drawText( captionBox, Qt::AlignLeft | Qt::AlignTop | Qt::SingleLine, caption );
00481 if ( !contents.isEmpty() ) {
00482 p.setFont( textFont );
00483 p.drawText( textBox, Qt::WordBreak | Qt::AlignTop | Qt::AlignLeft, contents );
00484 }
00485 p.setFont( oldFont );
00486
00487 if ( expand ) {
00488 return box.bottom();
00489 } else {
00490 return textBox.bottom();
00491 }
00492 }
00493
00494
00496
00497 int CalPrintPluginBase::drawHeader( QPainter &p, QString title,
00498 const QDate &month1, const QDate &month2, const QRect &allbox, bool expand )
00499 {
00500
00501 int smallMonthWidth = (allbox.width()/4) - 10;
00502 if (smallMonthWidth>100) smallMonthWidth=100;
00503
00504 int right = allbox.right();
00505 if ( month1.isValid() ) right -= (20+smallMonthWidth);
00506 if ( month2.isValid() ) right -= (20+smallMonthWidth);
00507 QRect box( allbox );
00508 QRect textRect( allbox );
00509 textRect.addCoords( 5, 0, 0, 0 );
00510 textRect.setRight( right );
00511
00512
00513 QFont oldFont( p.font() );
00514 QFont newFont("sans-serif", (textRect.height()<60)?16:18, QFont::Bold);
00515 if ( expand ) {
00516 p.setFont( newFont );
00517 QRect boundingR = p.boundingRect( textRect, Qt::AlignLeft | Qt::AlignVCenter | Qt::WordBreak, title );
00518 p.setFont( oldFont );
00519 int h = boundingR.height();
00520 if ( h > allbox.height() ) {
00521 box.setHeight( h );
00522 textRect.setHeight( h );
00523 }
00524 }
00525
00526 drawShadedBox( p, BOX_BORDER_WIDTH, QColor( 232, 232, 232 ), box );
00527
00528 QRect monthbox( box.right()-10-smallMonthWidth, box.top(), smallMonthWidth, box.height() );
00529 if (month2.isValid()) {
00530 drawSmallMonth( p, QDate(month2.year(), month2.month(), 1), monthbox );
00531 monthbox.moveBy( -20 - smallMonthWidth, 0 );
00532 }
00533 if (month1.isValid()) {
00534 drawSmallMonth( p, QDate(month1.year(), month1.month(), 1), monthbox );
00535 monthbox.moveBy( -20 - smallMonthWidth, 0 );
00536 }
00537
00538
00539 p.setFont( newFont );
00540 p.drawText( textRect, Qt::AlignLeft | Qt::AlignVCenter | Qt::WordBreak, title );
00541 p.setFont( oldFont );
00542
00543 return textRect.bottom();
00544 }
00545
00546
00547 int CalPrintPluginBase::drawFooter( QPainter &p, QRect &footbox )
00548 {
00549 QFont oldfont( p.font() );
00550 p.setFont( QFont( "sans-serif", 6 ) );
00551 QFontMetrics fm( p.font() );
00552 QString dateStr = KGlobal::locale()->formatDateTime( QDateTime::currentDateTime() );
00553 p.drawText( footbox, Qt::AlignCenter | Qt::AlignVCenter | Qt::SingleLine,
00554 i18n( "print date: formatted-datetime", "printed: %1" ).arg( dateStr ) );
00555 p.setFont( oldfont );
00556
00557 return footbox.bottom();
00558 }
00559
00560 void CalPrintPluginBase::drawSmallMonth(QPainter &p, const QDate &qd,
00561 const QRect &box )
00562 {
00563
00564 int weekdayCol = weekdayColumn( qd.dayOfWeek() );
00565 int month = qd.month();
00566 QDate monthDate(QDate(qd.year(), qd.month(), 1));
00567
00568 QDate monthDate2( monthDate.addDays( -weekdayCol ) );
00569
00570 double cellWidth = double(box.width())/double(7);
00571 int rownr = 3 + ( qd.daysInMonth() + weekdayCol - 1 ) / 7;
00572
00573 double cellHeight = (box.height() - 5) / rownr;
00574 QFont oldFont( p.font() );
00575 p.setFont(QFont("sans-serif", int(cellHeight-1), QFont::Normal));
00576
00577
00578 if ( mCalSys ) {
00579 QRect titleBox( box );
00580 titleBox.setHeight( int(cellHeight+1) );
00581 p.drawText( titleBox, Qt::AlignTop | Qt::AlignHCenter, mCalSys->monthName( qd ) );
00582 }
00583
00584
00585 QRect wdayBox( box );
00586 wdayBox.setTop( int( box.top() + 3 + cellHeight ) );
00587 wdayBox.setHeight( int(2*cellHeight)-int(cellHeight) );
00588
00589 if ( mCalSys ) {
00590 for (int col = 0; col < 7; ++col) {
00591 QString tmpStr = mCalSys->weekDayName( monthDate2 )[0].upper();
00592 wdayBox.setLeft( int(box.left() + col*cellWidth) );
00593 wdayBox.setRight( int(box.left() + (col+1)*cellWidth) );
00594 p.drawText( wdayBox, Qt::AlignCenter, tmpStr );
00595 monthDate2 = monthDate2.addDays( 1 );
00596 }
00597 }
00598
00599
00600 int calStartY = wdayBox.bottom() + 2;
00601 p.drawLine( box.left(), calStartY, box.right(), calStartY );
00602 monthDate = monthDate.addDays( -weekdayCol );
00603
00604 for ( int row = 0; row < (rownr-2); row++ ) {
00605 for ( int col = 0; col < 7; col++ ) {
00606 if ( monthDate.month() == month ) {
00607 QRect dayRect( int( box.left() + col*cellWidth ), int( calStartY + row*cellHeight ), 0, 0 );
00608 dayRect.setRight( int( box.left() + (col+1)*cellWidth ) );
00609 dayRect.setBottom( int( calStartY + (row+1)*cellHeight ) );
00610 p.drawText( dayRect, Qt::AlignCenter, QString::number( monthDate.day() ) );
00611 }
00612 monthDate = monthDate.addDays(1);
00613 }
00614 }
00615 p.setFont( oldFont );
00616 }
00617
00618
00619
00620
00621
00623
00624
00625
00626
00627
00628 void CalPrintPluginBase::drawDaysOfWeek(QPainter &p,
00629 const QDate &fromDate, const QDate &toDate, const QRect &box )
00630 {
00631 double cellWidth = double(box.width()) / double(fromDate.daysTo( toDate )+1);
00632 QDate cellDate( fromDate );
00633 QRect dateBox( box );
00634 int i = 0;
00635
00636 while ( cellDate <= toDate ) {
00637 dateBox.setLeft( box.left() + int(i*cellWidth) );
00638 dateBox.setRight( box.left() + int((i+1)*cellWidth) );
00639 drawDaysOfWeekBox(p, cellDate, dateBox );
00640 cellDate = cellDate.addDays(1);
00641 i++;
00642 }
00643 }
00644
00645
00646 void CalPrintPluginBase::drawDaysOfWeekBox(QPainter &p, const QDate &qd,
00647 const QRect &box )
00648 {
00649 drawSubHeaderBox( p, (mCalSys)?(mCalSys->weekDayName( qd )):(QString::null), box );
00650 }
00651
00652
00653 void CalPrintPluginBase::drawTimeLine( QPainter &p, const QTime &fromTime,
00654 const QTime &toTime, const QRect &box )
00655 {
00656 drawBox( p, BOX_BORDER_WIDTH, box );
00657
00658 int totalsecs = fromTime.secsTo( toTime );
00659 float minlen = (float)box.height() * 60. / (float)totalsecs;
00660 float cellHeight = ( 60. * (float)minlen );
00661 float currY = box.top();
00662
00663 int xcenter = box.left() + box.width() / 2;
00664
00665 QTime curTime( fromTime );
00666 QTime endTime( toTime );
00667 if ( fromTime.minute() > 30 ) {
00668 curTime = QTime( fromTime.hour()+1, 0, 0 );
00669 } else if ( fromTime.minute() > 0 ) {
00670 curTime = QTime( fromTime.hour(), 30, 0 );
00671 float yy = currY + minlen * (float)fromTime.secsTo( curTime ) / 60.;
00672 p.drawLine( xcenter, (int)yy, box.right(), (int)yy );
00673 curTime = QTime( fromTime.hour() + 1, 0, 0 );
00674 }
00675 currY += ( float( fromTime.secsTo( curTime ) * minlen ) / 60. );
00676
00677 while ( curTime < endTime ) {
00678 p.drawLine( box.left(), (int)currY, box.right(), (int)currY );
00679 int newY = (int)( currY + cellHeight / 2. );
00680 QString numStr;
00681 if ( newY < box.bottom() ) {
00682 QFont oldFont( p.font() );
00683
00684 if ( !KGlobal::locale()->use12Clock() ) {
00685 p.drawLine( xcenter, (int)newY, box.right(), (int)newY );
00686 numStr.setNum( curTime.hour() );
00687 if ( cellHeight > 30 ) {
00688 p.setFont( QFont( "sans-serif", 14, QFont::Bold ) );
00689 } else {
00690 p.setFont( QFont( "sans-serif", 12, QFont::Bold ) );
00691 }
00692 p.drawText( box.left() + 4, (int)currY + 2, box.width() / 2 - 2, (int)cellHeight,
00693 Qt::AlignTop | Qt::AlignRight, numStr );
00694 p.setFont( QFont ( "helvetica", 10, QFont::Normal ) );
00695 p.drawText( xcenter + 4, (int)currY + 2, box.width() / 2 + 2, (int)(cellHeight / 2 ) - 3,
00696 Qt::AlignTop | Qt::AlignLeft, "00" );
00697 } else {
00698 p.drawLine( box.left(), (int)newY, box.right(), (int)newY );
00699 QTime time( curTime.hour(), 0 );
00700 numStr = KGlobal::locale()->formatTime( time );
00701 if ( box.width() < 60 ) {
00702 p.setFont( QFont( "sans-serif", 7, QFont::Bold ) );
00703 } else {
00704 p.setFont( QFont( "sans-serif", 12, QFont::Bold ) );
00705 }
00706 p.drawText( box.left() + 2, (int)currY + 2, box.width() - 4, (int)cellHeight / 2 - 3,
00707 Qt::AlignTop|Qt::AlignLeft, numStr );
00708 }
00709 currY += cellHeight;
00710 p.setFont( oldFont );
00711 }
00712 if ( curTime.secsTo( endTime ) > 3600 ) {
00713 curTime = curTime.addSecs( 3600 );
00714 } else {
00715 curTime = endTime;
00716 }
00717 }
00718 }
00719
00726 int CalPrintPluginBase::drawAllDayBox(QPainter &p, Event::List &eventList,
00727 const QDate &qd, bool expandable, const QRect &box )
00728 {
00729 Event::List::Iterator it, itold;
00730
00731 int offset=box.top();
00732
00733 QString multiDayStr;
00734
00735 Event*hd = holiday( qd );
00736 if ( hd ) eventList.prepend( hd );
00737
00738 it = eventList.begin();
00739 Event *currEvent = 0;
00740
00741 while( it!=eventList.end() ) {
00742 currEvent=*it;
00743 itold=it;
00744 ++it;
00745 if ( currEvent && currEvent->doesFloat() ) {
00746
00747 if ( expandable ) {
00748 QRect eventBox( box );
00749 eventBox.setTop( offset );
00750 showEventBox( p, eventBox, currEvent, currEvent->summary() );
00751 offset += box.height();
00752 } else {
00753 if ( !multiDayStr.isEmpty() ) multiDayStr += ", ";
00754 multiDayStr += currEvent->summary();
00755 }
00756 eventList.remove( itold );
00757 }
00758 }
00759 if ( hd ) delete hd;
00760
00761 int ret = box.height();
00762 QRect eventBox( box );
00763 if (!expandable) {
00764 if (!multiDayStr.isEmpty()) {
00765 drawShadedBox( p, BOX_BORDER_WIDTH, QColor( 128, 128, 128 ), eventBox );
00766 printEventString( p, eventBox, multiDayStr );
00767 } else {
00768 drawBox( p, BOX_BORDER_WIDTH, eventBox );
00769 }
00770 } else {
00771 ret = offset - box.top();
00772 eventBox.setBottom( ret );
00773 drawBox( p, BOX_BORDER_WIDTH, eventBox );
00774 }
00775 return ret;
00776 }
00777
00778
00779 void CalPrintPluginBase::drawAgendaDayBox( QPainter &p, Event::List &events,
00780 const QDate &qd, bool expandable,
00781 QTime &fromTime, QTime &toTime,
00782 const QRect &oldbox )
00783 {
00784 if ( !isWorkingDay( qd ) ) {
00785 drawShadedBox( p, BOX_BORDER_WIDTH, QColor( 232, 232, 232 ), oldbox );
00786 } else {
00787 drawBox( p, BOX_BORDER_WIDTH, oldbox );
00788 }
00789 QRect box( oldbox );
00790
00791
00792
00793 Event *event;
00794
00795 if ( expandable ) {
00796
00797 Event::List::ConstIterator it;
00798 for ( it = events.begin(); it != events.end(); ++it ) {
00799 event = *it;
00800 if ( event->dtStart().time() < fromTime )
00801 fromTime = event->dtStart().time();
00802 if ( event->dtEnd().time() > toTime )
00803 toTime = event->dtEnd().time();
00804 }
00805 }
00806
00807
00808
00809
00810
00811
00812
00813
00814 int totalsecs = fromTime.secsTo( toTime );
00815 float minlen = box.height() * 60. / totalsecs;
00816 float cellHeight = 60. * minlen;
00817 float currY = box.top();
00818
00819
00820 QTime curTime( QTime( fromTime.hour(), 0, 0 ) );
00821 currY += fromTime.secsTo( curTime ) * minlen / 60;
00822
00823 while ( curTime < toTime && curTime.isValid() ) {
00824 if ( currY > box.top() )
00825 p.drawLine( box.left(), int( currY ), box.right(), int( currY ) );
00826 currY += cellHeight / 2;
00827 if ( ( currY > box.top() ) && ( currY < box.bottom() ) ) {
00828
00829 QPen oldPen( p.pen() );
00830 p.setPen( QColor( 192, 192, 192 ) );
00831 p.drawLine( box.left(), int( currY ), box.right(), int( currY ) );
00832 p.setPen( oldPen );
00833 }
00834 if ( curTime.secsTo( toTime ) > 3600 )
00835 curTime = curTime.addSecs( 3600 );
00836 else curTime = toTime;
00837 currY += cellHeight / 2;
00838 }
00839
00840 QDateTime startPrintDate = QDateTime( qd, fromTime );
00841 QDateTime endPrintDate = QDateTime( qd, toTime );
00842
00843
00844
00845
00846 QPtrList<KOrg::CellItem> cells;
00847 cells.setAutoDelete( true );
00848
00849 Event::List::ConstIterator itEvents;
00850 for( itEvents = events.begin(); itEvents != events.end(); ++itEvents ) {
00851 QValueList<QDateTime> times = (*itEvents)->startDateTimesForDate( qd );
00852 for ( QValueList<QDateTime>::ConstIterator it = times.begin();
00853 it != times.end(); ++it ) {
00854 cells.append( new PrintCellItem( *itEvents, (*it), (*itEvents)->endDateForStart( *it ) ) );
00855 }
00856 }
00857
00858 QPtrListIterator<KOrg::CellItem> it1( cells );
00859 for( it1.toFirst(); it1.current(); ++it1 ) {
00860 KOrg::CellItem *placeItem = it1.current();
00861 KOrg::CellItem::placeItem( cells, placeItem );
00862 }
00863
00864
00865
00866 for( it1.toFirst(); it1.current(); ++it1 ) {
00867 PrintCellItem *placeItem = static_cast<PrintCellItem *>( it1.current() );
00868 drawAgendaItem( placeItem, p, startPrintDate, endPrintDate, minlen, box );
00869 }
00870
00871 }
00872
00873
00874
00875 void CalPrintPluginBase::drawAgendaItem( PrintCellItem *item, QPainter &p,
00876 const QDateTime &startPrintDate,
00877 const QDateTime &endPrintDate,
00878 float minlen, const QRect &box )
00879 {
00880 Event *event = item->event();
00881
00882
00883 QDateTime startTime = item->start();
00884 QDateTime endTime = item->end();
00885 if ( ( startTime < endPrintDate && endTime > startPrintDate ) ||
00886 ( endTime > startPrintDate && startTime < endPrintDate ) ) {
00887 if ( startTime < startPrintDate ) startTime = startPrintDate;
00888 if ( endTime > endPrintDate ) endTime = endPrintDate;
00889 int currentWidth = box.width() / item->subCells();
00890 int currentX = box.left() + item->subCell() * currentWidth;
00891 int currentYPos = int( box.top() + startPrintDate.secsTo( startTime ) *
00892 minlen / 60. );
00893 int currentHeight = int( box.top() + startPrintDate.secsTo( endTime ) * minlen / 60. ) - currentYPos;
00894
00895 QRect eventBox( currentX, currentYPos, currentWidth, currentHeight );
00896 QString str;
00897 if ( event->location().isEmpty() ) {
00898 str = i18n( "starttime - endtime summary",
00899 "%1-%2 %3" ).
00900 arg( KGlobal::locale()->formatTime( startTime.time() ) ).
00901 arg( KGlobal::locale()->formatTime( endTime.time() ) ).
00902 arg( event->summary() );
00903 } else {
00904 str = i18n( "starttime - endtime summary, location",
00905 "%1-%2 %3, %4" ).
00906 arg( KGlobal::locale()->formatTime( startTime.time() ) ).
00907 arg( KGlobal::locale()->formatTime( endTime.time() ) ).
00908 arg( event->summary() ).
00909 arg( event->location() );
00910 }
00911 showEventBox( p, eventBox, event, str );
00912 }
00913 }
00914
00915
00916 void CalPrintPluginBase::drawDayBox( QPainter &p, const QDate &qd,
00917 const QRect &box,
00918 bool fullDate, bool printRecurDaily, bool printRecurWeekly )
00919 {
00920 QString dayNumStr;
00921 QString ampm;
00922 const KLocale*local = KGlobal::locale();
00923
00924
00925
00926 if ( fullDate && mCalSys ) {
00927
00928 dayNumStr = i18n("weekday month date", "%1 %2 %3")
00929 .arg( mCalSys->weekDayName( qd ) )
00930 .arg( mCalSys->monthName( qd ) )
00931 .arg( qd.day() );
00932
00933 } else {
00934 dayNumStr = QString::number( qd.day() );
00935 }
00936
00937 QRect subHeaderBox( box );
00938 subHeaderBox.setHeight( mSubHeaderHeight );
00939 drawShadedBox( p, BOX_BORDER_WIDTH, p.backgroundColor(), box );
00940 drawShadedBox( p, 0, QColor( 232, 232, 232 ), subHeaderBox );
00941 drawBox( p, BOX_BORDER_WIDTH, box );
00942 QString hstring( holidayString( qd ) );
00943 QFont oldFont( p.font() );
00944
00945 QRect headerTextBox( subHeaderBox );
00946 headerTextBox.setLeft( subHeaderBox.left()+5 );
00947 headerTextBox.setRight( subHeaderBox.right()-5 );
00948 if (!hstring.isEmpty()) {
00949 p.setFont( QFont( "sans-serif", 8, QFont::Bold, true ) );
00950
00951 p.drawText( headerTextBox, Qt::AlignLeft | Qt::AlignVCenter, hstring );
00952 }
00953 p.setFont(QFont("sans-serif", 10, QFont::Bold));
00954 p.drawText( headerTextBox, Qt::AlignRight | Qt::AlignVCenter, dayNumStr);
00955
00956 Event::List eventList = mCalendar->events( qd,
00957 EventSortStartDate,
00958 SortDirectionAscending );
00959 QString timeText;
00960 p.setFont( QFont( "sans-serif", 8 ) );
00961
00962 int textY=mSubHeaderHeight+3;
00963 Event::List::ConstIterator it;
00964
00965 for( it = eventList.begin(); it != eventList.end() && textY<box.height(); ++it ) {
00966 Event *currEvent = *it;
00967 if ( ( !printRecurDaily && currEvent->recurrenceType() == Recurrence::rDaily ) ||
00968 ( !printRecurWeekly && currEvent->recurrenceType() == Recurrence::rWeekly ) ) {
00969 continue;
00970 }
00971 if ( currEvent->doesFloat() || currEvent->isMultiDay() ) {
00972 timeText = "";
00973 } else {
00974 timeText = local->formatTime( currEvent->dtStart().time() );
00975 }
00976
00977 QString str;
00978 if ( !currEvent->location().isEmpty() ) {
00979 str = i18n( "summary, location", "%1, %2" ).
00980 arg( currEvent->summary() ).arg( currEvent->location() );
00981 } else {
00982 str = currEvent->summary();
00983 }
00984 drawIncidence( p, box, timeText, str, textY );
00985 }
00986
00987 if ( textY < box.height() ) {
00988 Todo::List todos = mCalendar->todos( qd );
00989 Todo::List::ConstIterator it2;
00990 for ( it2 = todos.begin(); it2 != todos.end() && textY <box.height(); ++it2 ) {
00991 Todo *todo = *it2;
00992 if ( ( !printRecurDaily && todo->recurrenceType() == Recurrence::rDaily ) ||
00993 ( !printRecurWeekly && todo->recurrenceType() == Recurrence::rWeekly ) ) {
00994 continue;
00995 }
00996 if ( todo->hasStartDate() && !todo->doesFloat() ) {
00997 timeText = KGlobal::locale()->formatTime( todo->dtStart().time() ) + " ";
00998 } else {
00999 timeText = "";
01000 }
01001 QString summaryStr;
01002 if ( !todo->location().isEmpty() ) {
01003 summaryStr = i18n( "summary, location", "%1, %2" ).
01004 arg( todo->summary() ).arg( todo->location() );
01005 } else {
01006 summaryStr = todo->summary();
01007 }
01008 QString str;
01009 if ( todo->hasDueDate() ) {
01010 if ( !todo->doesFloat() ) {
01011 str = i18n( "%1 (Due: %2)" ).
01012 arg( summaryStr ).
01013 arg( KGlobal::locale()->formatDateTime( todo->dtDue() ) );
01014 } else {
01015 str = i18n( "%1 (Due: %2)" ).
01016 arg( summaryStr ).
01017 arg( KGlobal::locale()->formatDate( todo->dtDue().date(), true ) );
01018 }
01019 } else {
01020 str = summaryStr;
01021 }
01022 drawIncidence( p, box, timeText, i18n("To-do: %1").arg( str ), textY );
01023 }
01024 }
01025
01026 p.setFont( oldFont );
01027 }
01028
01029
01030 void CalPrintPluginBase::drawIncidence( QPainter &p, const QRect &dayBox, const QString &time, const QString &summary, int &textY )
01031 {
01032 kdDebug(5850) << "summary = " << summary << endl;
01033
01034 int flags = Qt::AlignLeft;
01035 QFontMetrics fm = p.fontMetrics();
01036 QRect timeBound = p.boundingRect( dayBox.x() + 5, dayBox.y() + textY,
01037 dayBox.width() - 10, fm.lineSpacing(),
01038 flags, time );
01039 p.drawText( timeBound, flags, time );
01040
01041 int summaryWidth = time.isEmpty() ? 0 : timeBound.width() + 4;
01042 QRect summaryBound = QRect( dayBox.x() + 5 + summaryWidth, dayBox.y() + textY,
01043 dayBox.width() - summaryWidth -5, dayBox.height() );
01044
01045 KWordWrap *ww = KWordWrap::formatText( fm, summaryBound, flags, summary );
01046 ww->drawText( &p, dayBox.x() + 5 + summaryWidth, dayBox.y() + textY, flags );
01047
01048 textY += ww->boundingRect().height();
01049
01050 delete ww;
01051 }
01052
01053
01055
01056 void CalPrintPluginBase::drawWeek(QPainter &p, const QDate &qd, const QRect &box )
01057 {
01058 QDate weekDate = qd;
01059 bool portrait = ( box.height() > box.width() );
01060 int cellWidth, cellHeight;
01061 int vcells;
01062 if (portrait) {
01063 cellWidth = box.width()/2;
01064 vcells=3;
01065 } else {
01066 cellWidth = box.width()/6;
01067 vcells=1;
01068 }
01069 cellHeight = box.height()/vcells;
01070
01071
01072 int weekdayCol = weekdayColumn( qd.dayOfWeek() );
01073 weekDate = qd.addDays( -weekdayCol );
01074
01075 for (int i = 0; i < 7; i++, weekDate = weekDate.addDays(1)) {
01076
01077 int hpos = ((i<6)?i:(i-1)) / vcells;
01078 int vpos = ((i<6)?i:(i-1)) % vcells;
01079 QRect dayBox( box.left()+cellWidth*hpos, box.top()+cellHeight*vpos + ((i==6)?(cellHeight/2):0),
01080 cellWidth, (i<5)?(cellHeight):(cellHeight/2) );
01081 drawDayBox(p, weekDate, dayBox, true);
01082 }
01083 }
01084
01085
01086 void CalPrintPluginBase::drawTimeTable(QPainter &p,
01087 const QDate &fromDate, const QDate &toDate,
01088 QTime &fromTime, QTime &toTime,
01089 const QRect &box)
01090 {
01091
01092 int alldayHeight = (int)( 3600.*box.height()/(fromTime.secsTo(toTime)+3600.) );
01093 int timelineWidth = TIMELINE_WIDTH;
01094
01095 QRect dowBox( box );
01096 dowBox.setLeft( box.left() + timelineWidth );
01097 dowBox.setHeight( mSubHeaderHeight );
01098 drawDaysOfWeek( p, fromDate, toDate, dowBox );
01099
01100 QRect tlBox( box );
01101 tlBox.setWidth( timelineWidth );
01102 tlBox.setTop( dowBox.bottom() + BOX_BORDER_WIDTH + alldayHeight );
01103 drawTimeLine( p, fromTime, toTime, tlBox );
01104
01105
01106 QDate curDate(fromDate);
01107 int i=0;
01108 double cellWidth = double(dowBox.width()) / double(fromDate.daysTo(toDate)+1);
01109 while (curDate<=toDate) {
01110 QRect allDayBox( dowBox.left()+int(i*cellWidth), dowBox.bottom() + BOX_BORDER_WIDTH,
01111 int((i+1)*cellWidth)-int(i*cellWidth), alldayHeight );
01112 QRect dayBox( allDayBox );
01113 dayBox.setTop( tlBox.top() );
01114 dayBox.setBottom( box.bottom() );
01115 Event::List eventList = mCalendar->events(curDate,
01116 EventSortStartDate,
01117 SortDirectionAscending);
01118 alldayHeight = drawAllDayBox( p, eventList, curDate, false, allDayBox );
01119 drawAgendaDayBox( p, eventList, curDate, false, fromTime, toTime, dayBox );
01120 i++;
01121 curDate=curDate.addDays(1);
01122 }
01123
01124 }
01125
01126
01128
01129 class MonthEventStruct
01130 {
01131 public:
01132 MonthEventStruct() : event(0) {}
01133 MonthEventStruct( const QDateTime &s, const QDateTime &e, Event *ev)
01134 {
01135 event = ev;
01136 start = s;
01137 end = e;
01138 if ( event->doesFloat() ) {
01139 start = QDateTime( start.date(), QTime(0,0,0) );
01140 end = QDateTime( end.date().addDays(1), QTime(0,0,0) ).addSecs(-1);
01141 }
01142 }
01143 bool operator<(const MonthEventStruct &mes) { return start < mes.start; }
01144 QDateTime start;
01145 QDateTime end;
01146 Event *event;
01147 };
01148
01149 void CalPrintPluginBase::drawMonth( QPainter &p, const QDate &dt, const QRect &box, int maxdays, int subDailyFlags, int holidaysFlags )
01150 {
01151 const KCalendarSystem *calsys = calendarSystem();
01152 QRect subheaderBox( box );
01153 subheaderBox.setHeight( subHeaderHeight() );
01154 QRect borderBox( box );
01155 borderBox.setTop( subheaderBox.bottom()+1 );
01156 drawSubHeaderBox( p, calsys->monthName(dt), subheaderBox );
01157
01158 int correction = (BOX_BORDER_WIDTH)/2;
01159 QRect daysBox( borderBox );
01160 daysBox.addCoords( correction, correction, -correction, -correction );
01161
01162 int daysinmonth = calsys->daysInMonth( dt );
01163 if ( maxdays <= 0 ) maxdays = daysinmonth;
01164
01165 int d;
01166 float dayheight = float(daysBox.height()) / float( maxdays );
01167
01168 QColor holidayColor( 240, 240, 240 );
01169 QColor workdayColor( 255, 255, 255 );
01170 int dayNrWidth = p.fontMetrics().width( "99" );
01171
01172
01173 if ( daysinmonth<maxdays ) {
01174 QRect dayBox( box.left(), daysBox.top() + round(dayheight*daysinmonth), box.width(), 0 );
01175 dayBox.setBottom( daysBox.bottom() );
01176 p.fillRect( dayBox, Qt::DiagCrossPattern );
01177 }
01178
01179 QBrush oldbrush( p.brush() );
01180 for ( d = 0; d < daysinmonth; ++d ) {
01181 QDate day;
01182 calsys->setYMD( day, dt.year(), dt.month(), d+1 );
01183 QRect dayBox( daysBox.left(), daysBox.top() + round(dayheight*d), daysBox.width(), 0 );
01184
01185 dayBox.setBottom( daysBox.top()+round(dayheight*(d+1)) - 1 );
01186
01187 p.setBrush( isWorkingDay( day )?workdayColor:holidayColor );
01188 p.drawRect( dayBox );
01189 QRect dateBox( dayBox );
01190 dateBox.setWidth( dayNrWidth+3 );
01191 p.drawText( dateBox, Qt::AlignRight | Qt::AlignVCenter | Qt::SingleLine,
01192 QString::number(d+1) );
01193 }
01194 p.setBrush( oldbrush );
01195 int xstartcont = box.left() + dayNrWidth + 5;
01196
01197 QDate start, end;
01198 calsys->setYMD( start, dt.year(), dt.month(), 1 );
01199 end = calsys->addMonths( start, 1 );
01200 end = calsys->addDays( end, -1 );
01201
01202 Event::List events = mCalendar->events( start, end );
01203 QMap<int, QStringList> textEvents;
01204 QPtrList<KOrg::CellItem> timeboxItems;
01205 timeboxItems.setAutoDelete( true );
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215 Event::List holidays;
01216 holidays.setAutoDelete( true );
01217 for ( QDate d(start); d <= end; d = d.addDays(1) ) {
01218 Event *e = holiday( d );
01219 if ( e ) {
01220 holidays.append( e );
01221 if ( holidaysFlags & TimeBoxes ) {
01222 timeboxItems.append( new PrintCellItem( e, QDateTime(d, QTime(0,0,0) ),
01223 QDateTime( d.addDays(1), QTime(0,0,0) ) ) );
01224 }
01225 if ( holidaysFlags & Text ) {
01226 textEvents[ d.day() ] << e->summary();
01227 }
01228 }
01229 }
01230
01231 QValueList<MonthEventStruct> monthentries;
01232
01233 for ( Event::List::ConstIterator evit = events.begin();
01234 evit != events.end(); ++evit ) {
01235 Event *e = (*evit);
01236 if (!e) continue;
01237 if ( e->doesRecur() ) {
01238 if ( e->recursOn( start ) ) {
01239
01240
01241 QValueList<QDateTime> starttimes = e->startDateTimesForDate( start );
01242 QValueList<QDateTime>::ConstIterator it = starttimes.begin();
01243 for ( ; it != starttimes.end(); ++it ) {
01244 monthentries.append( MonthEventStruct( *it, e->endDateForStart( *it ), e ) );
01245 }
01246 }
01247
01248
01249
01250
01251 Recurrence *recur = e->recurrence();
01252 QDate d1( start.addDays(1) );
01253 while ( d1 <= end ) {
01254 if ( recur->recursOn(d1) ) {
01255 TimeList times( recur->recurTimesOn( d1 ) );
01256 for ( TimeList::ConstIterator it = times.begin();
01257 it != times.end(); ++it ) {
01258 QDateTime d1start( d1, *it );
01259 monthentries.append( MonthEventStruct( d1start, e->endDateForStart( d1start ), e ) );
01260 }
01261 }
01262 d1 = d1.addDays(1);
01263 }
01264 } else {
01265 monthentries.append( MonthEventStruct( e->dtStart(), e->dtEnd(), e ) );
01266 }
01267 }
01268 qHeapSort( monthentries );
01269
01270 QValueList<MonthEventStruct>::ConstIterator mit = monthentries.begin();
01271 QDateTime endofmonth( end, QTime(0,0,0) );
01272 endofmonth = endofmonth.addDays(1);
01273 for ( ; mit != monthentries.end(); ++mit ) {
01274 if ( (*mit).start.date() == (*mit).end.date() ) {
01275
01276 if ( subDailyFlags & TimeBoxes ) {
01277 timeboxItems.append( new PrintCellItem( (*mit).event, (*mit).start, (*mit).end ) );
01278 }
01279
01280 if ( subDailyFlags & Text ) {
01281 textEvents[ (*mit).start.date().day() ] << (*mit).event->summary();
01282 }
01283 } else {
01284
01285 QDateTime thisstart( (*mit).start );
01286 QDateTime thisend( (*mit).end );
01287 if ( thisstart.date()<start ) thisstart = start;
01288 if ( thisend>endofmonth ) thisend = endofmonth;
01289 timeboxItems.append( new PrintCellItem( (*mit).event, thisstart, thisend ) );
01290 }
01291 }
01292
01293
01294 QPtrListIterator<KOrg::CellItem> it1( timeboxItems );
01295 for( it1.toFirst(); it1.current(); ++it1 ) {
01296 KOrg::CellItem *placeItem = it1.current();
01297 KOrg::CellItem::placeItem( timeboxItems, placeItem );
01298 }
01299 QDateTime starttime( start, QTime( 0, 0, 0 ) );
01300 int newxstartcont = xstartcont;
01301
01302 QFont oldfont( p.font() );
01303 p.setFont( QFont( "sans-serif", 7 ) );
01304 for( it1.toFirst(); it1.current(); ++it1 ) {
01305 PrintCellItem *placeItem = static_cast<PrintCellItem *>( it1.current() );
01306 int minsToStart = starttime.secsTo( placeItem->start() )/60;
01307 int minsToEnd = starttime.secsTo( placeItem->end() )/60;
01308
01309 QRect eventBox( xstartcont + placeItem->subCell()*17,
01310 daysBox.top() + round( double( minsToStart*daysBox.height()) / double(maxdays*24*60) ),
01311 14, 0 );
01312 eventBox.setBottom( daysBox.top() + round( double( minsToEnd*daysBox.height()) / double(maxdays*24*60) ) );
01313 drawVerticalBox( p, eventBox, placeItem->event()->summary() );
01314 newxstartcont = QMAX( newxstartcont, eventBox.right() );
01315 }
01316 xstartcont = newxstartcont;
01317
01318
01319
01320 for ( int d=0; d<daysinmonth; ++d ) {
01321 QStringList dayEvents( textEvents[d+1] );
01322 QString txt = dayEvents.join(", ");
01323 QRect dayBox( xstartcont, daysBox.top()+round(dayheight*d), 0, 0 );
01324 dayBox.setRight( box.right() );
01325 dayBox.setBottom( daysBox.top()+round(dayheight*(d+1)) );
01326 printEventString(p, dayBox, txt, Qt::AlignTop | Qt::AlignLeft | Qt::BreakAnywhere );
01327 }
01328 p.setFont( oldfont );
01329
01330 drawBox( p, BOX_BORDER_WIDTH, borderBox );
01331 p.restore();
01332 }
01333
01335
01336 void CalPrintPluginBase::drawMonthTable(QPainter &p, const QDate &qd, bool weeknumbers,
01337 bool recurDaily, bool recurWeekly,
01338 const QRect &box)
01339 {
01340 int yoffset = mSubHeaderHeight;
01341 int xoffset = 0;
01342 QDate monthDate(QDate(qd.year(), qd.month(), 1));
01343 QDate monthFirst(monthDate);
01344 QDate monthLast(monthDate.addMonths(1).addDays(-1));
01345
01346
01347 int weekdayCol = weekdayColumn( monthDate.dayOfWeek() );
01348 monthDate = monthDate.addDays(-weekdayCol);
01349
01350 if (weeknumbers) {
01351 xoffset += 14;
01352 }
01353
01354 int rows=(weekdayCol + qd.daysInMonth() - 1)/7 +1;
01355 double cellHeight = ( box.height() - yoffset ) / (1.*rows);
01356 double cellWidth = ( box.width() - xoffset ) / 7.;
01357
01358
01359
01360 int coledges[8], rowedges[8];
01361 for ( int i = 0; i <= 7; i++ ) {
01362 rowedges[i] = int( box.top() + yoffset + i*cellHeight );
01363 coledges[i] = int( box.left() + xoffset + i*cellWidth );
01364 }
01365
01366 if (weeknumbers) {
01367 QFont oldFont(p.font());
01368 QFont newFont(p.font());
01369 newFont.setPointSize(6);
01370 p.setFont(newFont);
01371 QDate weekDate(monthDate);
01372 for (int row = 0; row<rows; ++row ) {
01373 int calWeek = weekDate.weekNumber();
01374 QRect rc( box.left(), rowedges[row], coledges[0] - 3 - box.left(), rowedges[row+1]-rowedges[row] );
01375 p.drawText( rc, Qt::AlignRight | Qt::AlignVCenter, QString::number( calWeek ) );
01376 weekDate = weekDate.addDays( 7 );
01377 }
01378 p.setFont( oldFont );
01379 }
01380
01381 QRect daysOfWeekBox( box );
01382 daysOfWeekBox.setHeight( mSubHeaderHeight );
01383 daysOfWeekBox.setLeft( box.left()+xoffset );
01384 drawDaysOfWeek( p, monthDate, monthDate.addDays( 6 ), daysOfWeekBox );
01385
01386 QColor back = p.backgroundColor();
01387 bool darkbg = false;
01388 for ( int row = 0; row < rows; ++row ) {
01389 for ( int col = 0; col < 7; ++col ) {
01390
01391 if ( (monthDate < monthFirst) || (monthDate > monthLast) ) {
01392 p.setBackgroundColor( back.dark( 120 ) );
01393 darkbg = true;
01394 }
01395 QRect dayBox( coledges[col], rowedges[row], coledges[col+1]-coledges[col], rowedges[row+1]-rowedges[row] );
01396 drawDayBox(p, monthDate, dayBox, false, recurDaily, recurWeekly );
01397 if ( darkbg ) {
01398 p.setBackgroundColor( back );
01399 darkbg = false;
01400 }
01401 monthDate = monthDate.addDays(1);
01402 }
01403 }
01404 }
01405
01406
01408
01409 void CalPrintPluginBase::drawTodo( int &count, Todo *todo, QPainter &p,
01410 TodoSortField sortField, SortDirection sortDir,
01411 bool connectSubTodos, bool strikeoutCompleted,
01412 bool desc, int posPriority, int posSummary,
01413 int posDueDt, int posPercentComplete,
01414 int level, int x, int &y, int width,
01415 int pageHeight, const Todo::List &todoList,
01416 TodoParentStart *r )
01417 {
01418 QString outStr;
01419 const KLocale *local = KGlobal::locale();
01420 QRect rect;
01421 TodoParentStart startpt;
01422
01423
01424
01425 static QPtrList<TodoParentStart> startPoints;
01426 if ( level < 1 ) {
01427 startPoints.clear();
01428 }
01429
01430
01431 int rhs = posPercentComplete;
01432 if ( rhs < 0 ) rhs = posDueDt;
01433 if ( rhs < 0 ) rhs = x+width;
01434
01435
01436 outStr=todo->summary();
01437 int left = posSummary + ( level*10 );
01438 rect = p.boundingRect( left, y, ( rhs-left-5 ), -1, Qt::WordBreak, outStr );
01439 if ( !todo->description().isEmpty() && desc ) {
01440 outStr = todo->description();
01441 rect = p.boundingRect( left+20, rect.bottom()+5, width-(left+10-x), -1,
01442 Qt::WordBreak, outStr );
01443 }
01444
01445 if ( rect.bottom() > pageHeight ) {
01446
01447 if ( level > 0 && connectSubTodos ) {
01448 TodoParentStart *rct;
01449 for ( rct = startPoints.first(); rct; rct = startPoints.next() ) {
01450 int start;
01451 int center = rct->mRect.left() + (rct->mRect.width()/2);
01452 int to = p.viewport().bottom();
01453
01454
01455 if ( rct->mSamePage )
01456 start = rct->mRect.bottom() + 1;
01457 else
01458 start = p.viewport().top();
01459 p.moveTo( center, start );
01460 p.lineTo( center, to );
01461 rct->mSamePage = false;
01462 }
01463 }
01464 y=0;
01465 mPrinter->newPage();
01466 }
01467
01468
01469
01470 bool showPriority = posPriority>=0;
01471 int lhs = posPriority;
01472 if ( r ) {
01473 lhs = r->mRect.right() + 1;
01474 }
01475
01476 outStr.setNum( todo->priority() );
01477 rect = p.boundingRect( lhs, y + 10, 5, -1, Qt::AlignCenter, outStr );
01478
01479 rect.setWidth(18);
01480 rect.setHeight(18);
01481
01482
01483 p.setBrush( QBrush( Qt::NoBrush ) );
01484 p.drawRect( rect );
01485 if ( todo->isCompleted() ) {
01486
01487 p.drawLine( rect.topLeft(), rect.bottomRight() );
01488 p.drawLine( rect.topRight(), rect.bottomLeft() );
01489 }
01490 lhs = rect.right() + 3;
01491
01492
01493 if ( todo->priority() > 0 && showPriority ) {
01494 p.drawText( rect, Qt::AlignCenter, outStr );
01495 }
01496 startpt.mRect = rect;
01497
01498
01499 if ( level > 0 && connectSubTodos ) {
01500 int bottom;
01501 int center( r->mRect.left() + (r->mRect.width()/2) );
01502 if ( r->mSamePage )
01503 bottom = r->mRect.bottom() + 1;
01504 else
01505 bottom = 0;
01506 int to( rect.top() + (rect.height()/2) );
01507 int endx( rect.left() );
01508 p.moveTo( center, bottom );
01509 p.lineTo( center, to );
01510 p.lineTo( endx, to );
01511 }
01512
01513
01514 outStr=todo->summary();
01515 rect = p.boundingRect( lhs, rect.top(), (rhs-(left + rect.width() + 5)),
01516 -1, Qt::WordBreak, outStr );
01517
01518 QRect newrect;
01519
01520 #if 0
01521 QFont f( p.font() );
01522 if ( todo->isCompleted() && strikeoutCompleted ) {
01523 f.setStrikeOut( true );
01524 p.setFont( f );
01525 }
01526 p.drawText( rect, Qt::WordBreak, outStr, -1, &newrect );
01527 f.setStrikeOut( false );
01528 p.setFont( f );
01529 #endif
01530
01531 p.drawText( rect, Qt::WordBreak, outStr, -1, &newrect );
01532 if ( todo->isCompleted() && strikeoutCompleted ) {
01533
01534
01535
01536 int delta = p.fontMetrics().lineSpacing();
01537 int lines = ( rect.height() / delta ) + 1;
01538 for ( int i=0; i<lines; i++ ) {
01539 p.moveTo( rect.left(), rect.top() + ( delta/2 ) + ( i*delta ) );
01540 p.lineTo( rect.right(), rect.top() + ( delta/2 ) + ( i*delta ) );
01541 }
01542 }
01543
01544
01545 if ( todo->hasDueDate() && posDueDt>=0 ) {
01546 outStr = local->formatDate( todo->dtDue().date(), true );
01547 rect = p.boundingRect( posDueDt, y, x + width, -1,
01548 Qt::AlignTop | Qt::AlignLeft, outStr );
01549 p.drawText( rect, Qt::AlignTop | Qt::AlignLeft, outStr );
01550 }
01551
01552
01553 bool showPercentComplete = posPercentComplete>=0;
01554 if ( showPercentComplete ) {
01555 int lwidth = 24;
01556 int lheight = 12;
01557
01558 int progress = (int)(( lwidth*todo->percentComplete())/100.0 + 0.5);
01559
01560 p.setBrush( QBrush( Qt::NoBrush ) );
01561 p.drawRect( posPercentComplete, y+3, lwidth, lheight );
01562 if ( progress > 0 ) {
01563 p.setBrush( QColor( 128, 128, 128 ) );
01564 p.drawRect( posPercentComplete, y+3, progress, lheight );
01565 }
01566
01567
01568 outStr = i18n( "%1%" ).arg( todo->percentComplete() );
01569 rect = p.boundingRect( posPercentComplete+lwidth+3, y, x + width, -1,
01570 Qt::AlignTop | Qt::AlignLeft, outStr );
01571 p.drawText( rect, Qt::AlignTop | Qt::AlignLeft, outStr );
01572 }
01573
01574
01575 if ( !todo->description().isEmpty() && desc ) {
01576 y = newrect.bottom() + 5;
01577 outStr = todo->description();
01578 rect = p.boundingRect( left+20, y, x+width-(left+10), -1,
01579 Qt::WordBreak, outStr );
01580 p.drawText( rect, Qt::WordBreak, outStr, -1, &newrect );
01581 }
01582
01583
01584 y = newrect.bottom() + 10;
01585
01586
01587 #if 0
01588 Incidence::List l = todo->relations();
01589 Incidence::List::ConstIterator it;
01590 startPoints.append( &startpt );
01591 for( it = l.begin(); it != l.end(); ++it ) {
01592 count++;
01593
01594
01595
01596
01597 Todo* subtodo = dynamic_cast<Todo *>( *it );
01598 if (subtodo && todoList.contains( subtodo ) ) {
01599 drawTodo( count, subtodo, p, connectSubTodos, strikeoutCompleted,
01600 desc, posPriority, posSummary, posDueDt, posPercentComplete,
01601 level+1, x, y, width, pageHeight, todoList, &startpt );
01602 }
01603 }
01604 #endif
01605
01606 Todo::List t;
01607 Incidence::List l = todo->relations();
01608 Incidence::List::ConstIterator it;
01609 for( it=l.begin(); it!=l.end(); ++it ) {
01610
01611
01612
01613
01614 Todo* subtodo = dynamic_cast<Todo *>( *it );
01615 if ( subtodo && todoList.contains( subtodo ) ) {
01616 t.append( subtodo );
01617 }
01618 }
01619
01620
01621 Todo::List sl = mCalendar->sortTodos( &t, sortField, sortDir );
01622 Todo::List::ConstIterator isl;
01623 startPoints.append( &startpt );
01624 for( isl = sl.begin(); isl != sl.end(); ++isl ) {
01625 count++;
01626 drawTodo( count, ( *isl ), p, sortField, sortDir,
01627 connectSubTodos, strikeoutCompleted,
01628 desc, posPriority, posSummary, posDueDt, posPercentComplete,
01629 level+1, x, y, width, pageHeight, todoList, &startpt );
01630 }
01631 startPoints.remove( &startpt );
01632 }
01633
01634 int CalPrintPluginBase::weekdayColumn( int weekday )
01635 {
01636 return ( weekday + 7 - KGlobal::locale()->weekStartDay() ) % 7;
01637 }
01638
01639 void CalPrintPluginBase::drawJournalField( QPainter &p, QString field, QString text,
01640 int x, int &y, int width, int pageHeight )
01641 {
01642 if ( text.isEmpty() ) return;
01643
01644 QString entry( field.arg( text ) );
01645
01646 QRect rect( p.boundingRect( x, y, width, -1, Qt::WordBreak, entry) );
01647 if ( rect.bottom() > pageHeight) {
01648
01649
01650
01651 y=0;
01652 mPrinter->newPage();
01653 rect = p.boundingRect( x, y, width, -1, Qt::WordBreak, entry);
01654 }
01655 QRect newrect;
01656 p.drawText( rect, Qt::WordBreak, entry, -1, &newrect );
01657 y = newrect.bottom() + 7;
01658 }
01659
01660 void CalPrintPluginBase::drawJournal( Journal * journal, QPainter &p, int x, int &y,
01661 int width, int pageHeight )
01662 {
01663 QFont oldFont( p.font() );
01664 p.setFont( QFont( "sans-serif", 15 ) );
01665 QString headerText;
01666 QString dateText( KGlobal::locale()->
01667 formatDate( journal->dtStart().date(), false ) );
01668
01669 if ( journal->summary().isEmpty() ) {
01670 headerText = dateText;
01671 } else {
01672 headerText = i18n("Description - date", "%1 - %2")
01673 .arg( journal->summary() )
01674 .arg( dateText );
01675 }
01676
01677 QRect rect( p.boundingRect( x, y, width, -1, Qt::WordBreak, headerText) );
01678 if ( rect.bottom() > pageHeight) {
01679
01680 y=0;
01681 mPrinter->newPage();
01682 rect = p.boundingRect( x, y, width, -1, Qt::WordBreak, headerText );
01683 }
01684 QRect newrect;
01685 p.drawText( rect, Qt::WordBreak, headerText, -1, &newrect );
01686 p.setFont( oldFont );
01687
01688 y = newrect.bottom() + 4;
01689
01690 p.drawLine( x + 3, y, x + width - 6, y );
01691 y += 5;
01692
01693 drawJournalField( p, i18n("Person: %1"), journal->organizer().fullName(), x, y, width, pageHeight );
01694 drawJournalField( p, i18n("%1"), journal->description(), x, y, width, pageHeight );
01695 y += 10;
01696 }
01697
01698
01699 void CalPrintPluginBase::drawSplitHeaderRight( QPainter &p, const QDate &fd,
01700 const QDate &td,
01701 const QDate &,
01702 int width, int )
01703 {
01704 QFont oldFont( p.font() );
01705
01706 QPen oldPen( p.pen() );
01707 QPen pen( Qt::black, 4 );
01708
01709 QString title;
01710 if ( mCalSys ) {
01711 if ( fd.month() == td.month() ) {
01712 title = i18n("Date range: Month dayStart - dayEnd", "%1 %2 - %3")
01713 .arg( mCalSys->monthName( fd.month(), false ) )
01714 .arg( mCalSys->dayString( fd, false ) )
01715 .arg( mCalSys->dayString( td, false ) );
01716 } else {
01717 title = i18n("Date range: monthStart dayStart - monthEnd dayEnd", "%1 %2 - %3 %4")
01718 .arg( mCalSys->monthName( fd.month(), false ) )
01719 .arg( mCalSys->dayString( fd, false ) )
01720 .arg( mCalSys->monthName( td.month(), false ) )
01721 .arg( mCalSys->dayString( td, false ) );
01722 }
01723 }
01724
01725 QFont serifFont("Times", 30);
01726 p.setFont(serifFont);
01727
01728 int lineSpacing = p.fontMetrics().lineSpacing();
01729 p.drawText( 0, lineSpacing * 0, width, lineSpacing,
01730 Qt::AlignRight | Qt::AlignTop, title );
01731
01732 title.truncate(0);
01733
01734 p.setPen( pen );
01735 p.drawLine(300, lineSpacing * 1, width, lineSpacing * 1);
01736 p.setPen( oldPen );
01737
01738 p.setFont(QFont("Times", 20, QFont::Bold, TRUE));
01739 int newlineSpacing = p.fontMetrics().lineSpacing();
01740 title += QString::number(fd.year());
01741 p.drawText( 0, lineSpacing * 1 + 4, width, newlineSpacing,
01742 Qt::AlignRight | Qt::AlignTop, title );
01743
01744 p.setFont( oldFont );
01745 }
01746
01747 #endif