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