calprintpluginbase.cpp
00001 /* 00002 This file is part of KOrganizer. 00003 00004 Copyright (c) 1998 Preston Brown <pbrown@kde.org> 00005 Copyright (c) 2003 Reinhold Kainhofer <reinhold@kainhofer.com> 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 2 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program; if not, write to the Free Software 00019 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00020 00021 As a special exception, permission is given to link this program 00022 with any edition of TQt, and distribute the resulting executable, 00023 without including the source code for TQt in the source distribution. 00024 */ 00025 00026 #include <tqpainter.h> 00027 #include <tqlayout.h> 00028 #include <tqframe.h> 00029 #include <tqlabel.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 TQString cleanStr( const TQString &instr ) 00047 { 00048 TQString ret = instr; 00049 return ret.replace( '\n', ' ' ); 00050 } 00051 00052 /****************************************************************** 00053 ** The Todo positioning structure ** 00054 ******************************************************************/ 00055 class CalPrintPluginBase::TodoParentStart 00056 { 00057 public: 00058 TodoParentStart( TQRect pt = TQRect(), bool page = true ) 00059 : mRect( pt ), mSamePage( page ) {} 00060 00061 TQRect mRect; 00062 bool mSamePage; 00063 }; 00064 00065 00066 /****************************************************************** 00067 ** The Print item ** 00068 ******************************************************************/ 00069 00070 00071 class PrintCellItem : public KOrg::CellItem 00072 { 00073 public: 00074 PrintCellItem( Event *event, const TQDateTime &start, const TQDateTime &end ) 00075 : mEvent( event ), mStart( start), mEnd( end ) 00076 { 00077 } 00078 00079 Event *event() const { return mEvent; } 00080 00081 TQString label() const { return mEvent->summary(); } 00082 00083 TQDateTime start() const { return mStart; } 00084 TQDateTime 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 TQDateTime mStart, mEnd; 00107 }; 00108 00109 00110 00111 00112 /****************************************************************** 00113 ** The Print plugin ** 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 TQWidget *CalPrintPluginBase::createConfigWidget( TQWidget *w ) 00129 { 00130 TQFrame *wdg = new TQFrame( w ); 00131 TQVBoxLayout *layout = new TQVBoxLayout( wdg ); 00132 00133 TQLabel *title = new TQLabel( description(), wdg ); 00134 TQFont titleFont( title->font() ); 00135 titleFont.setPointSize( 20 ); 00136 titleFont.setBold( true ); 00137 title->setFont( titleFont ); 00138 00139 layout->addWidget( title ); 00140 layout->addWidget( new TQLabel( info(), wdg ) ); 00141 layout->addSpacing( 20 ); 00142 layout->addWidget( new TQLabel( 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 TQPainter p; 00154 00155 mPrinter->setColorMode( mUseColors?(KPrinter::Color):(KPrinter::GrayScale) ); 00156 00157 p.begin( mPrinter ); 00158 // TODO: Fix the margins!!! 00159 // the painter initially begins at 72 dpi per the TQt docs. 00160 // we want half-inch margins. 00161 int margins = margin(); 00162 p.setViewport( margins, margins, 00163 p.viewport().width() - 2*margins, 00164 p.viewport().height() - 2*margins ); 00165 // TQRect vp( p.viewport() ); 00166 // vp.setRight( vp.right()*2 ); 00167 // vp.setBottom( vp.bottom()*2 ); 00168 // p.setWindow( vp ); 00169 int pageWidth = p.window().width(); 00170 int pageHeight = p.window().height(); 00171 // int pageWidth = p.viewport().width(); 00172 // int pageHeight = p.viewport().height(); 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 TQDateTime currDate( TQDate::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", TQDateTime( mFromDate ) ); 00202 mConfig->writeEntry( "ToDate", TQDateTime( 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 TQTime CalPrintPluginBase::dayStart() 00237 { 00238 TQTime start( 8,0,0 ); 00239 if ( mCoreHelper ) start = mCoreHelper->dayStart(); 00240 return start; 00241 } 00242 00243 void CalPrintPluginBase::setCategoryColors( TQPainter &p, Incidence *incidence ) 00244 { 00245 TQColor bgColor = categoryBgColor( incidence ); 00246 if ( bgColor.isValid() ) 00247 p.setBrush( bgColor ); 00248 TQColor tColor( textColor( bgColor ) ); 00249 if ( tColor.isValid() ) 00250 p.setPen( tColor ); 00251 } 00252 00253 TQColor CalPrintPluginBase::categoryBgColor( Incidence *incidence ) 00254 { 00255 if (mCoreHelper && incidence) 00256 return mCoreHelper->categoryColor( incidence->categories() ); 00257 else 00258 return TQColor(); 00259 } 00260 00261 TQColor CalPrintPluginBase::textColor( const TQColor &color ) 00262 { 00263 return (mCoreHelper)?(mCoreHelper->textColor( color )):TQColor(); 00264 } 00265 00266 bool CalPrintPluginBase::isWorkingDay( const TQDate &dt ) 00267 { 00268 return (mCoreHelper)?( mCoreHelper->isWorkingDay( dt ) ):true; 00269 } 00270 00271 TQString CalPrintPluginBase::holidayString( const TQDate &dt ) 00272 { 00273 return (mCoreHelper)?(mCoreHelper->holidayString(dt)):(TQString()); 00274 } 00275 00276 00277 Event *CalPrintPluginBase::holiday( const TQDate &dt ) 00278 { 00279 TQString 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( TQPainter &p, int linewidth, const TQRect &rect ) 00369 { 00370 TQPen pen( p.pen() ); 00371 TQPen oldpen( pen ); 00372 pen.setWidth( linewidth ); 00373 p.setPen( pen ); 00374 p.drawRect( rect ); 00375 p.setPen( oldpen ); 00376 } 00377 00378 void CalPrintPluginBase::drawShadedBox( TQPainter &p, int linewidth, const TQBrush &brush, const TQRect &rect ) 00379 { 00380 TQBrush oldbrush( p.brush() ); 00381 p.setBrush( brush ); 00382 drawBox( p, linewidth, rect ); 00383 p.setBrush( oldbrush ); 00384 } 00385 00386 void CalPrintPluginBase::printEventString( TQPainter &p, const TQRect &box, const TQString &str, int flags ) 00387 { 00388 TQRect newbox( box ); 00389 newbox.addCoords( 3, 1, -1, -1 ); 00390 p.drawText( newbox, (flags==-1)?(TQt::AlignTop | TQt::AlignJustify | TQt::BreakAnywhere):flags, str ); 00391 } 00392 00393 00394 void CalPrintPluginBase::showEventBox( TQPainter &p, int linewidth, const TQRect &box, 00395 Incidence *incidence, const TQString &str, int flags ) 00396 { 00397 TQPen oldpen( p.pen() ); 00398 TQBrush oldbrush( p.brush() ); 00399 TQColor bgColor( categoryBgColor( incidence ) ); 00400 if ( mUseColors & bgColor.isValid() ) { 00401 p.setBrush( bgColor ); 00402 } else { 00403 p.setBrush( TQColor( 232, 232, 232 ) ); 00404 } 00405 drawBox( p, ( linewidth > 0 ) ? linewidth : EVENT_BORDER_WIDTH, box ); 00406 00407 if ( mUseColors && bgColor.isValid() ) { 00408 p.setPen( textColor( bgColor ) ); 00409 } 00410 printEventString( p, box, str, flags ); 00411 p.setPen( oldpen ); 00412 p.setBrush( oldbrush ); 00413 } 00414 00415 00416 void CalPrintPluginBase::drawSubHeaderBox(TQPainter &p, const TQString &str, const TQRect &box ) 00417 { 00418 drawShadedBox( p, BOX_BORDER_WIDTH, TQColor( 232, 232, 232 ), box ); 00419 TQFont oldfont( p.font() ); 00420 p.setFont( TQFont( "sans-serif", 10, TQFont::Bold ) ); 00421 p.drawText( box, TQt::AlignCenter | TQt::AlignVCenter, str ); 00422 p.setFont( oldfont ); 00423 } 00424 00425 void CalPrintPluginBase::drawVerticalBox( TQPainter &p, int linewidth, const TQRect &box, 00426 const TQString &str, int flags ) 00427 { 00428 p.save(); 00429 p.rotate( -90 ); 00430 TQRect rotatedBox( -box.top()-box.height(), box.left(), box.height(), box.width() ); 00431 showEventBox( p, linewidth, rotatedBox, 0, str, 00432 ( flags == -1 ) ? TQt::AlignLeft | TQt::AlignVCenter | TQt::SingleLine : flags ); 00433 00434 p.restore(); 00435 } 00436 00437 00438 00440 // Return value: If expand, bottom of the printed box, otherwise vertical end 00441 // of the printed contents inside the box. 00442 00443 int CalPrintPluginBase::drawBoxWithCaption( TQPainter &p, const TQRect &allbox, 00444 const TQString &caption, const TQString &contents, bool sameLine, bool expand, const TQFont &captionFont, const TQFont &textFont ) 00445 { 00446 TQFont oldFont( p.font() ); 00447 // TQFont captionFont( "sans-serif", 11, TQFont::Bold ); 00448 // TQFont textFont( "sans-serif", 11, TQFont::Normal ); 00449 // TQFont captionFont( "Tahoma", 11, TQFont::Bold ); 00450 // TQFont textFont( "Tahoma", 11, TQFont::Normal ); 00451 00452 00453 TQRect box( allbox ); 00454 00455 // Bounding rectangle for caption, single-line, clip on the right 00456 TQRect captionBox( box.left() + padding(), box.top() + padding(), 0, 0 ); 00457 p.setFont( captionFont ); 00458 captionBox = p.boundingRect( captionBox, TQt::AlignLeft | TQt::AlignTop | TQt::SingleLine, caption ); 00459 p.setFont( oldFont ); 00460 if ( captionBox.right() > box.right() ) 00461 captionBox.setRight( box.right() ); 00462 if ( expand && captionBox.bottom() + padding() > box.bottom() ) 00463 box.setBottom( captionBox.bottom() + padding() ); 00464 00465 // Bounding rectangle for the contents (if any), word break, clip on the bottom 00466 TQRect textBox( captionBox ); 00467 if ( !contents.isEmpty() ) { 00468 if ( sameLine ) { 00469 textBox.setLeft( captionBox.right() + padding() ); 00470 } else { 00471 textBox.setTop( captionBox.bottom() + padding() ); 00472 } 00473 textBox.setRight( box.right() ); 00474 textBox.setHeight( 0 ); 00475 p.setFont( textFont ); 00476 textBox = p.boundingRect( textBox, TQt::WordBreak | TQt::AlignTop | TQt::AlignLeft, contents ); 00477 p.setFont( oldFont ); 00478 if ( textBox.bottom() + padding() > box.bottom() ) { 00479 if ( expand ) { 00480 box.setBottom( textBox.bottom() + padding() ); 00481 } else { 00482 textBox.setBottom( box.bottom() ); 00483 } 00484 } 00485 } 00486 00487 drawBox( p, BOX_BORDER_WIDTH, box ); 00488 p.setFont( captionFont ); 00489 p.drawText( captionBox, TQt::AlignLeft | TQt::AlignTop | TQt::SingleLine, caption ); 00490 if ( !contents.isEmpty() ) { 00491 p.setFont( textFont ); 00492 p.drawText( textBox, TQt::WordBreak | TQt::AlignTop | TQt::AlignLeft, contents ); 00493 } 00494 p.setFont( oldFont ); 00495 00496 if ( expand ) { 00497 return box.bottom(); 00498 } else { 00499 return textBox.bottom(); 00500 } 00501 } 00502 00503 00505 00506 int CalPrintPluginBase::drawHeader( TQPainter &p, TQString title, 00507 const TQDate &month1, const TQDate &month2, const TQRect &allbox, bool expand ) 00508 { 00509 // print previous month for month view, print current for to-do, day and week 00510 int smallMonthWidth = (allbox.width()/4) - 10; 00511 if (smallMonthWidth>100) smallMonthWidth=100; 00512 00513 int right = allbox.right(); 00514 if ( month1.isValid() ) right -= (20+smallMonthWidth); 00515 if ( month2.isValid() ) right -= (20+smallMonthWidth); 00516 TQRect box( allbox ); 00517 TQRect textRect( allbox ); 00518 textRect.addCoords( 5, 0, 0, 0 ); 00519 textRect.setRight( right ); 00520 00521 00522 TQFont oldFont( p.font() ); 00523 TQFont newFont("sans-serif", (textRect.height()<60)?16:18, TQFont::Bold); 00524 if ( expand ) { 00525 p.setFont( newFont ); 00526 TQRect boundingR = p.boundingRect( textRect, TQt::AlignLeft | TQt::AlignVCenter | TQt::WordBreak, title ); 00527 p.setFont( oldFont ); 00528 int h = boundingR.height(); 00529 if ( h > allbox.height() ) { 00530 box.setHeight( h ); 00531 textRect.setHeight( h ); 00532 } 00533 } 00534 00535 drawShadedBox( p, BOX_BORDER_WIDTH, TQColor( 232, 232, 232 ), box ); 00536 00537 TQRect monthbox( box.right()-10-smallMonthWidth, box.top(), smallMonthWidth, box.height() ); 00538 if (month2.isValid()) { 00539 drawSmallMonth( p, TQDate(month2.year(), month2.month(), 1), monthbox ); 00540 monthbox.moveBy( -20 - smallMonthWidth, 0 ); 00541 } 00542 if (month1.isValid()) { 00543 drawSmallMonth( p, TQDate(month1.year(), month1.month(), 1), monthbox ); 00544 monthbox.moveBy( -20 - smallMonthWidth, 0 ); 00545 } 00546 00547 // Set the margins 00548 p.setFont( newFont ); 00549 p.drawText( textRect, TQt::AlignLeft | TQt::AlignVCenter | TQt::WordBreak, title ); 00550 p.setFont( oldFont ); 00551 00552 return textRect.bottom(); 00553 } 00554 00555 00556 int CalPrintPluginBase::drawFooter( TQPainter &p, TQRect &footbox ) 00557 { 00558 TQFont oldfont( p.font() ); 00559 p.setFont( TQFont( "sans-serif", 6 ) ); 00560 TQFontMetrics fm( p.font() ); 00561 TQString dateStr = KGlobal::locale()->formatDateTime( TQDateTime::currentDateTime(), false ); 00562 p.drawText( footbox, TQt::AlignCenter | TQt::AlignVCenter | TQt::SingleLine, 00563 i18n( "print date: formatted-datetime", "printed: %1" ).arg( dateStr ) ); 00564 p.setFont( oldfont ); 00565 00566 return footbox.bottom(); 00567 } 00568 00569 void CalPrintPluginBase::drawSmallMonth(TQPainter &p, const TQDate &qd, 00570 const TQRect &box ) 00571 { 00572 00573 int weekdayCol = weekdayColumn( qd.dayOfWeek() ); 00574 int month = qd.month(); 00575 TQDate monthDate(TQDate(qd.year(), qd.month(), 1)); 00576 // correct begin of week 00577 TQDate monthDate2( monthDate.addDays( -weekdayCol ) ); 00578 00579 double cellWidth = double(box.width())/double(7); 00580 int rownr = 3 + ( qd.daysInMonth() + weekdayCol - 1 ) / 7; 00581 // 3 Pixel after month name, 2 after day names, 1 after the calendar 00582 double cellHeight = (box.height() - 5) / rownr; 00583 TQFont oldFont( p.font() ); 00584 p.setFont(TQFont("sans-serif", int(cellHeight-1), TQFont::Normal)); 00585 00586 // draw the title 00587 if ( mCalSys ) { 00588 TQRect titleBox( box ); 00589 titleBox.setHeight( int(cellHeight+1) ); 00590 p.drawText( titleBox, TQt::AlignTop | TQt::AlignHCenter, mCalSys->monthName( qd ) ); 00591 } 00592 00593 // draw days of week 00594 TQRect wdayBox( box ); 00595 wdayBox.setTop( int( box.top() + 3 + cellHeight ) ); 00596 wdayBox.setHeight( int(2*cellHeight)-int(cellHeight) ); 00597 00598 if ( mCalSys ) { 00599 for (int col = 0; col < 7; ++col) { 00600 TQString tmpStr = mCalSys->weekDayName( monthDate2 )[0].upper(); 00601 wdayBox.setLeft( int(box.left() + col*cellWidth) ); 00602 wdayBox.setRight( int(box.left() + (col+1)*cellWidth) ); 00603 p.drawText( wdayBox, TQt::AlignCenter, tmpStr ); 00604 monthDate2 = monthDate2.addDays( 1 ); 00605 } 00606 } 00607 00608 // draw separator line 00609 int calStartY = wdayBox.bottom() + 2; 00610 p.drawLine( box.left(), calStartY, box.right(), calStartY ); 00611 monthDate = monthDate.addDays( -weekdayCol ); 00612 00613 for ( int row = 0; row < (rownr-2); row++ ) { 00614 for ( int col = 0; col < 7; col++ ) { 00615 if ( monthDate.month() == month ) { 00616 TQRect dayRect( int( box.left() + col*cellWidth ), int( calStartY + row*cellHeight ), 0, 0 ); 00617 dayRect.setRight( int( box.left() + (col+1)*cellWidth ) ); 00618 dayRect.setBottom( int( calStartY + (row+1)*cellHeight ) ); 00619 p.drawText( dayRect, TQt::AlignCenter, TQString::number( monthDate.day() ) ); 00620 } 00621 monthDate = monthDate.addDays(1); 00622 } 00623 } 00624 p.setFont( oldFont ); 00625 } 00626 00627 00628 00629 00630 00632 00633 /* 00634 * This routine draws a header box over the main part of the calendar 00635 * containing the days of the week. 00636 */ 00637 void CalPrintPluginBase::drawDaysOfWeek(TQPainter &p, 00638 const TQDate &fromDate, const TQDate &toDate, const TQRect &box ) 00639 { 00640 double cellWidth = double(box.width()) / double(fromDate.daysTo( toDate )+1); 00641 TQDate cellDate( fromDate ); 00642 TQRect dateBox( box ); 00643 int i = 0; 00644 00645 while ( cellDate <= toDate ) { 00646 dateBox.setLeft( box.left() + int(i*cellWidth) ); 00647 dateBox.setRight( box.left() + int((i+1)*cellWidth) ); 00648 drawDaysOfWeekBox(p, cellDate, dateBox ); 00649 cellDate = cellDate.addDays(1); 00650 i++; 00651 } 00652 } 00653 00654 00655 void CalPrintPluginBase::drawDaysOfWeekBox(TQPainter &p, const TQDate &qd, 00656 const TQRect &box ) 00657 { 00658 drawSubHeaderBox( p, (mCalSys)?(mCalSys->weekDayName( qd )):(TQString()), box ); 00659 } 00660 00661 00662 void CalPrintPluginBase::drawTimeLine( TQPainter &p, const TQTime &fromTime, 00663 const TQTime &toTime, const TQRect &box ) 00664 { 00665 drawBox( p, BOX_BORDER_WIDTH, box ); 00666 00667 int totalsecs = fromTime.secsTo( toTime ); 00668 float minlen = (float)box.height() * 60. / (float)totalsecs; 00669 float cellHeight = ( 60. * (float)minlen ); 00670 float currY = box.top(); 00671 // TODO: Don't use half of the width, but less, for the minutes! 00672 int xcenter = box.left() + box.width() / 2; 00673 00674 TQTime curTime( fromTime ); 00675 TQTime endTime( toTime ); 00676 if ( fromTime.minute() > 30 ) { 00677 curTime = TQTime( fromTime.hour()+1, 0, 0 ); 00678 } else if ( fromTime.minute() > 0 ) { 00679 curTime = TQTime( fromTime.hour(), 30, 0 ); 00680 float yy = currY + minlen * (float)fromTime.secsTo( curTime ) / 60.; 00681 p.drawLine( xcenter, (int)yy, box.right(), (int)yy ); 00682 curTime = TQTime( fromTime.hour() + 1, 0, 0 ); 00683 } 00684 currY += ( float( fromTime.secsTo( curTime ) * minlen ) / 60. ); 00685 00686 while ( curTime < endTime ) { 00687 p.drawLine( box.left(), (int)currY, box.right(), (int)currY ); 00688 int newY = (int)( currY + cellHeight / 2. ); 00689 TQString numStr; 00690 if ( newY < box.bottom() ) { 00691 TQFont oldFont( p.font() ); 00692 // draw the time: 00693 if ( !KGlobal::locale()->use12Clock() ) { 00694 p.drawLine( xcenter, (int)newY, box.right(), (int)newY ); 00695 numStr.setNum( curTime.hour() ); 00696 if ( cellHeight > 30 ) { 00697 p.setFont( TQFont( "sans-serif", 14, TQFont::Bold ) ); 00698 } else { 00699 p.setFont( TQFont( "sans-serif", 12, TQFont::Bold ) ); 00700 } 00701 p.drawText( box.left() + 4, (int)currY + 2, box.width() / 2 - 2, (int)cellHeight, 00702 TQt::AlignTop | TQt::AlignRight, numStr ); 00703 p.setFont( TQFont ( "helvetica", 10, TQFont::Normal ) ); 00704 p.drawText( xcenter + 4, (int)currY + 2, box.width() / 2 + 2, (int)(cellHeight / 2 ) - 3, 00705 TQt::AlignTop | TQt::AlignLeft, "00" ); 00706 } else { 00707 p.drawLine( box.left(), (int)newY, box.right(), (int)newY ); 00708 TQTime time( curTime.hour(), 0 ); 00709 numStr = KGlobal::locale()->formatTime( time ); 00710 if ( box.width() < 60 ) { 00711 p.setFont( TQFont( "sans-serif", 7, TQFont::Bold ) ); // for weekprint 00712 } else { 00713 p.setFont( TQFont( "sans-serif", 12, TQFont::Bold ) ); // for dayprint 00714 } 00715 p.drawText( box.left() + 2, (int)currY + 2, box.width() - 4, (int)cellHeight / 2 - 3, 00716 TQt::AlignTop|TQt::AlignLeft, numStr ); 00717 } 00718 currY += cellHeight; 00719 p.setFont( oldFont ); 00720 } // enough space for half-hour line and time 00721 if ( curTime.secsTo( endTime ) > 3600 ) { 00722 curTime = curTime.addSecs( 3600 ); 00723 } else { 00724 curTime = endTime; 00725 } 00726 } // currTime<endTime 00727 } 00728 00735 int CalPrintPluginBase::drawAllDayBox(TQPainter &p, Event::List &eventList, 00736 const TQDate &qd, bool expandable, const TQRect &box ) 00737 { 00738 Event::List::Iterator it, itold; 00739 00740 int offset=box.top(); 00741 00742 TQString multiDayStr; 00743 00744 Event*hd = holiday( qd ); 00745 if ( hd ) eventList.prepend( hd ); 00746 00747 it = eventList.begin(); 00748 Event *currEvent = 0; 00749 // First, print all floating events 00750 while( it!=eventList.end() ) { 00751 currEvent=*it; 00752 itold=it; 00753 ++it; 00754 if ( currEvent && currEvent->doesFloat() ) { 00755 // set the colors according to the categories 00756 if ( expandable ) { 00757 TQRect eventBox( box ); 00758 eventBox.setTop( offset ); 00759 showEventBox( p, EVENT_BORDER_WIDTH, eventBox, currEvent, currEvent->summary() ); 00760 offset += box.height(); 00761 } else { 00762 if ( !multiDayStr.isEmpty() ) multiDayStr += ", "; 00763 multiDayStr += currEvent->summary(); 00764 } 00765 eventList.remove( itold ); 00766 } 00767 } 00768 if ( hd ) delete hd; 00769 00770 int ret = box.height(); 00771 TQRect eventBox( box ); 00772 if (!expandable) { 00773 if (!multiDayStr.isEmpty()) { 00774 drawShadedBox( p, BOX_BORDER_WIDTH, TQColor( 128, 128, 128 ), eventBox ); 00775 printEventString( p, eventBox, multiDayStr ); 00776 } else { 00777 drawBox( p, BOX_BORDER_WIDTH, eventBox ); 00778 } 00779 } else { 00780 ret = offset - box.top(); 00781 eventBox.setBottom( ret ); 00782 drawBox( p, BOX_BORDER_WIDTH, eventBox ); 00783 } 00784 return ret; 00785 } 00786 00787 00788 void CalPrintPluginBase::drawAgendaDayBox( TQPainter &p, Event::List &events, 00789 const TQDate &qd, bool expandable, 00790 TQTime &fromTime, TQTime &toTime, 00791 const TQRect &oldbox ) 00792 { 00793 if ( !isWorkingDay( qd ) ) { 00794 drawShadedBox( p, BOX_BORDER_WIDTH, TQColor( 232, 232, 232 ), oldbox ); 00795 } else { 00796 drawBox( p, BOX_BORDER_WIDTH, oldbox ); 00797 } 00798 TQRect box( oldbox ); 00799 // Account for the border with and cut away that margin from the interior 00800 // box.setRight( box.right()-BOX_BORDER_WIDTH ); 00801 00802 Event *event; 00803 00804 if ( expandable ) { 00805 // Adapt start/end times to include complete events 00806 Event::List::ConstIterator it; 00807 for ( it = events.begin(); it != events.end(); ++it ) { 00808 event = *it; 00809 if ( event->dtStart().time() < fromTime ) 00810 fromTime = event->dtStart().time(); 00811 if ( event->dtEnd().time() > toTime ) 00812 toTime = event->dtEnd().time(); 00813 } 00814 } 00815 00816 // Show at least one hour 00817 // if ( fromTime.secsTo( toTime ) < 3600 ) { 00818 // fromTime = TQTime( fromTime.hour(), 0, 0 ); 00819 // toTime = fromTime.addSecs( 3600 ); 00820 // } 00821 00822 // calculate the height of a cell and of a minute 00823 int totalsecs = fromTime.secsTo( toTime ); 00824 float minlen = box.height() * 60. / totalsecs; 00825 float cellHeight = 60. * minlen; 00826 float currY = box.top(); 00827 00828 // print grid: 00829 TQTime curTime( TQTime( fromTime.hour(), 0, 0 ) ); 00830 currY += fromTime.secsTo( curTime ) * minlen / 60; 00831 00832 while ( curTime < toTime && curTime.isValid() ) { 00833 if ( currY > box.top() ) 00834 p.drawLine( box.left(), int( currY ), box.right(), int( currY ) ); 00835 currY += cellHeight / 2; 00836 if ( ( currY > box.top() ) && ( currY < box.bottom() ) ) { 00837 // enough space for half-hour line 00838 TQPen oldPen( p.pen() ); 00839 p.setPen( TQColor( 192, 192, 192 ) ); 00840 p.drawLine( box.left(), int( currY ), box.right(), int( currY ) ); 00841 p.setPen( oldPen ); 00842 } 00843 if ( curTime.secsTo( toTime ) > 3600 ) 00844 curTime = curTime.addSecs( 3600 ); 00845 else curTime = toTime; 00846 currY += cellHeight / 2; 00847 } 00848 00849 TQDateTime startPrintDate = TQDateTime( qd, fromTime ); 00850 TQDateTime endPrintDate = TQDateTime( qd, toTime ); 00851 00852 // Calculate horizontal positions and widths of events taking into account 00853 // overlapping events 00854 00855 TQPtrList<KOrg::CellItem> cells; 00856 cells.setAutoDelete( true ); 00857 00858 Event::List::ConstIterator itEvents; 00859 for( itEvents = events.begin(); itEvents != events.end(); ++itEvents ) { 00860 TQValueList<TQDateTime> times = (*itEvents)->startDateTimesForDate( qd ); 00861 for ( TQValueList<TQDateTime>::ConstIterator it = times.begin(); 00862 it != times.end(); ++it ) { 00863 cells.append( new PrintCellItem( *itEvents, (*it), (*itEvents)->endDateForStart( *it ) ) ); 00864 } 00865 } 00866 00867 TQPtrListIterator<KOrg::CellItem> it1( cells ); 00868 for( it1.toFirst(); it1.current(); ++it1 ) { 00869 KOrg::CellItem *placeItem = it1.current(); 00870 KOrg::CellItem::placeItem( cells, placeItem ); 00871 } 00872 00873 // p.setFont( TQFont( "sans-serif", 10 ) ); 00874 00875 for( it1.toFirst(); it1.current(); ++it1 ) { 00876 PrintCellItem *placeItem = static_cast<PrintCellItem *>( it1.current() ); 00877 drawAgendaItem( placeItem, p, startPrintDate, endPrintDate, minlen, box ); 00878 } 00879 // p.setFont( oldFont ); 00880 } 00881 00882 00883 00884 void CalPrintPluginBase::drawAgendaItem( PrintCellItem *item, TQPainter &p, 00885 const TQDateTime &startPrintDate, 00886 const TQDateTime &endPrintDate, 00887 float minlen, const TQRect &box ) 00888 { 00889 Event *event = item->event(); 00890 00891 // start/end of print area for event 00892 TQDateTime startTime = item->start(); 00893 TQDateTime endTime = item->end(); 00894 if ( ( startTime < endPrintDate && endTime > startPrintDate ) || 00895 ( endTime > startPrintDate && startTime < endPrintDate ) ) { 00896 if ( startTime < startPrintDate ) startTime = startPrintDate; 00897 if ( endTime > endPrintDate ) endTime = endPrintDate; 00898 int currentWidth = box.width() / item->subCells(); 00899 int currentX = box.left() + item->subCell() * currentWidth; 00900 int currentYPos = int( box.top() + startPrintDate.secsTo( startTime ) * 00901 minlen / 60. ); 00902 int currentHeight = int( box.top() + startPrintDate.secsTo( endTime ) * minlen / 60. ) - currentYPos; 00903 00904 TQRect eventBox( currentX, currentYPos, currentWidth, currentHeight ); 00905 TQString str; 00906 if ( event->location().isEmpty() ) { 00907 str = i18n( "starttime - endtime summary", 00908 "%1-%2 %3" ). 00909 arg( KGlobal::locale()->formatTime( startTime.time() ) ). 00910 arg( KGlobal::locale()->formatTime( endTime.time() ) ). 00911 arg( cleanStr( event->summary() ) ); 00912 } else { 00913 str = i18n( "starttime - endtime summary, location", 00914 "%1-%2 %3, %4" ). 00915 arg( KGlobal::locale()->formatTime( startTime.time() ) ). 00916 arg( KGlobal::locale()->formatTime( endTime.time() ) ). 00917 arg( cleanStr( event->summary() ) ). 00918 arg( cleanStr( event->location() ) ); 00919 } 00920 showEventBox( p, EVENT_BORDER_WIDTH, eventBox, event, str ); 00921 } 00922 } 00923 00924 //TODO TODO TODO 00925 void CalPrintPluginBase::drawDayBox( TQPainter &p, const TQDate &qd, 00926 const TQRect &box, 00927 bool fullDate, bool printRecurDaily, bool printRecurWeekly ) 00928 { 00929 TQString dayNumStr; 00930 const KLocale*local = KGlobal::locale(); 00931 00932 // This has to be localized 00933 if ( fullDate && mCalSys ) { 00934 00935 dayNumStr = i18n("weekday month date", "%1 %2 %3") 00936 .arg( mCalSys->weekDayName( qd ) ) 00937 .arg( mCalSys->monthName( qd ) ) 00938 .arg( qd.day() ); 00939 // dayNumStr = local->formatDate(qd); 00940 } else { 00941 dayNumStr = TQString::number( qd.day() ); 00942 } 00943 00944 TQRect subHeaderBox( box ); 00945 subHeaderBox.setHeight( mSubHeaderHeight ); 00946 drawShadedBox( p, BOX_BORDER_WIDTH, p.backgroundColor(), box ); 00947 drawShadedBox( p, 0, TQColor( 232, 232, 232 ), subHeaderBox ); 00948 drawBox( p, BOX_BORDER_WIDTH, box ); 00949 TQString hstring( holidayString( qd ) ); 00950 TQFont oldFont( p.font() ); 00951 00952 TQRect headerTextBox( subHeaderBox ); 00953 headerTextBox.setLeft( subHeaderBox.left()+5 ); 00954 headerTextBox.setRight( subHeaderBox.right()-5 ); 00955 if (!hstring.isEmpty()) { 00956 p.setFont( TQFont( "sans-serif", 8, TQFont::Bold, true ) ); 00957 00958 p.drawText( headerTextBox, TQt::AlignLeft | TQt::AlignVCenter, hstring ); 00959 } 00960 p.setFont(TQFont("sans-serif", 10, TQFont::Bold)); 00961 p.drawText( headerTextBox, TQt::AlignRight | TQt::AlignVCenter, dayNumStr); 00962 00963 Event::List eventList = mCalendar->events( qd, 00964 EventSortStartDate, 00965 SortDirectionAscending ); 00966 TQString timeText; 00967 p.setFont( TQFont( "sans-serif", 8 ) ); 00968 00969 int textY=mSubHeaderHeight+3; // gives the relative y-coord of the next printed entry 00970 Event::List::ConstIterator it; 00971 00972 for( it = eventList.begin(); it != eventList.end() && textY<box.height(); ++it ) { 00973 Event *currEvent = *it; 00974 if ( ( !printRecurDaily && currEvent->recurrenceType() == Recurrence::rDaily ) || 00975 ( !printRecurWeekly && currEvent->recurrenceType() == Recurrence::rWeekly ) ) { 00976 continue; 00977 } 00978 if ( currEvent->doesFloat() || currEvent->isMultiDay() ) { 00979 timeText = ""; 00980 } else { 00981 timeText = local->formatTime( currEvent->dtStart().time() ); 00982 } 00983 00984 TQString str; 00985 if ( !currEvent->location().isEmpty() ) { 00986 str = i18n( "summary, location", "%1, %2" ). 00987 arg( currEvent->summary() ).arg( currEvent->location() ); 00988 } else { 00989 str = currEvent->summary(); 00990 } 00991 drawIncidence( p, box, timeText, str, textY ); 00992 } 00993 00994 if ( textY < box.height() ) { 00995 Todo::List todos = mCalendar->todos( qd ); 00996 Todo::List::ConstIterator it2; 00997 for ( it2 = todos.begin(); it2 != todos.end() && textY <box.height(); ++it2 ) { 00998 Todo *todo = *it2; 00999 if ( ( !printRecurDaily && todo->recurrenceType() == Recurrence::rDaily ) || 01000 ( !printRecurWeekly && todo->recurrenceType() == Recurrence::rWeekly ) ) { 01001 continue; 01002 } 01003 if ( todo->hasStartDate() && !todo->doesFloat() ) { 01004 timeText = KGlobal::locale()->formatTime( todo->dtStart().time() ) + " "; 01005 } else { 01006 timeText = ""; 01007 } 01008 TQString summaryStr; 01009 if ( !todo->location().isEmpty() ) { 01010 summaryStr = i18n( "summary, location", "%1, %2" ). 01011 arg( todo->summary() ).arg( todo->location() ); 01012 } else { 01013 summaryStr = todo->summary(); 01014 } 01015 TQString str; 01016 if ( todo->hasDueDate() ) { 01017 if ( !todo->doesFloat() ) { 01018 str = i18n( "%1 (Due: %2)" ). 01019 arg( summaryStr ). 01020 arg( KGlobal::locale()->formatDateTime( todo->dtDue() ) ); 01021 } else { 01022 str = i18n( "%1 (Due: %2)" ). 01023 arg( summaryStr ). 01024 arg( KGlobal::locale()->formatDate( todo->dtDue().date(), true ) ); 01025 } 01026 } else { 01027 str = summaryStr; 01028 } 01029 drawIncidence( p, box, timeText, i18n("To-do: %1").arg( str ), textY ); 01030 } 01031 } 01032 01033 p.setFont( oldFont ); 01034 } 01035 01036 // TODO TODO TODO 01037 void CalPrintPluginBase::drawIncidence( TQPainter &p, const TQRect &dayBox, const TQString &time, const TQString &summary, int &textY ) 01038 { 01039 kdDebug(5850) << "summary = " << summary << endl; 01040 01041 int flags = TQt::AlignLeft; 01042 TQFontMetrics fm = p.fontMetrics(); 01043 TQRect timeBound = p.boundingRect( dayBox.x() + 5, dayBox.y() + textY, 01044 dayBox.width() - 10, fm.lineSpacing(), 01045 flags, time ); 01046 p.drawText( timeBound, flags, time ); 01047 01048 int summaryWidth = time.isEmpty() ? 0 : timeBound.width() + 4; 01049 TQRect summaryBound = TQRect( dayBox.x() + 5 + summaryWidth, dayBox.y() + textY, 01050 dayBox.width() - summaryWidth -5, dayBox.height() ); 01051 01052 KWordWrap *ww = KWordWrap::formatText( fm, summaryBound, flags, summary ); 01053 ww->drawText( &p, dayBox.x() + 5 + summaryWidth, dayBox.y() + textY, flags ); 01054 01055 textY += ww->boundingRect().height(); 01056 01057 delete ww; 01058 } 01059 01060 01062 01063 void CalPrintPluginBase::drawWeek(TQPainter &p, const TQDate &qd, const TQRect &box ) 01064 { 01065 TQDate weekDate = qd; 01066 bool portrait = ( box.height() > box.width() ); 01067 int cellWidth, cellHeight; 01068 int vcells; 01069 if (portrait) { 01070 cellWidth = box.width()/2; 01071 vcells=3; 01072 } else { 01073 cellWidth = box.width()/6; 01074 vcells=1; 01075 } 01076 cellHeight = box.height()/vcells; 01077 01078 // correct begin of week 01079 int weekdayCol = weekdayColumn( qd.dayOfWeek() ); 01080 weekDate = qd.addDays( -weekdayCol ); 01081 01082 for (int i = 0; i < 7; i++, weekDate = weekDate.addDays(1)) { 01083 // Saturday and sunday share a cell, so we have to special-case sunday 01084 int hpos = ((i<6)?i:(i-1)) / vcells; 01085 int vpos = ((i<6)?i:(i-1)) % vcells; 01086 TQRect dayBox( box.left()+cellWidth*hpos, box.top()+cellHeight*vpos + ((i==6)?(cellHeight/2):0), 01087 cellWidth, (i<5)?(cellHeight):(cellHeight/2) ); 01088 drawDayBox(p, weekDate, dayBox, true); 01089 } // for i through all weekdays 01090 } 01091 01092 01093 void CalPrintPluginBase::drawTimeTable(TQPainter &p, 01094 const TQDate &fromDate, const TQDate &toDate, 01095 TQTime &fromTime, TQTime &toTime, 01096 const TQRect &box) 01097 { 01098 // timeline is 1 hour: 01099 int alldayHeight = (int)( 3600.*box.height()/(fromTime.secsTo(toTime)+3600.) ); 01100 int timelineWidth = TIMELINE_WIDTH; 01101 01102 TQRect dowBox( box ); 01103 dowBox.setLeft( box.left() + timelineWidth ); 01104 dowBox.setHeight( mSubHeaderHeight ); 01105 drawDaysOfWeek( p, fromDate, toDate, dowBox ); 01106 01107 TQRect tlBox( box ); 01108 tlBox.setWidth( timelineWidth ); 01109 tlBox.setTop( dowBox.bottom() + BOX_BORDER_WIDTH + alldayHeight ); 01110 drawTimeLine( p, fromTime, toTime, tlBox ); 01111 01112 // draw each day 01113 TQDate curDate(fromDate); 01114 int i=0; 01115 double cellWidth = double(dowBox.width()) / double(fromDate.daysTo(toDate)+1); 01116 while (curDate<=toDate) { 01117 TQRect allDayBox( dowBox.left()+int(i*cellWidth), dowBox.bottom() + BOX_BORDER_WIDTH, 01118 int((i+1)*cellWidth)-int(i*cellWidth), alldayHeight ); 01119 TQRect dayBox( allDayBox ); 01120 dayBox.setTop( tlBox.top() ); 01121 dayBox.setBottom( box.bottom() ); 01122 Event::List eventList = mCalendar->events(curDate, 01123 EventSortStartDate, 01124 SortDirectionAscending); 01125 alldayHeight = drawAllDayBox( p, eventList, curDate, false, allDayBox ); 01126 drawAgendaDayBox( p, eventList, curDate, false, fromTime, toTime, dayBox ); 01127 i++; 01128 curDate=curDate.addDays(1); 01129 } 01130 01131 } 01132 01133 01135 01136 class MonthEventStruct 01137 { 01138 public: 01139 MonthEventStruct() : event(0) {} 01140 MonthEventStruct( const TQDateTime &s, const TQDateTime &e, Event *ev) 01141 { 01142 event = ev; 01143 start = s; 01144 end = e; 01145 if ( event->doesFloat() ) { 01146 start = TQDateTime( start.date(), TQTime(0,0,0) ); 01147 end = TQDateTime( end.date().addDays(1), TQTime(0,0,0) ).addSecs(-1); 01148 } 01149 } 01150 bool operator<(const MonthEventStruct &mes) { return start < mes.start; } 01151 TQDateTime start; 01152 TQDateTime end; 01153 Event *event; 01154 }; 01155 01156 void CalPrintPluginBase::drawMonth( TQPainter &p, const TQDate &dt, const TQRect &box, int maxdays, int subDailyFlags, int holidaysFlags ) 01157 { 01158 const KCalendarSystem *calsys = calendarSystem(); 01159 TQRect subheaderBox( box ); 01160 subheaderBox.setHeight( subHeaderHeight() ); 01161 TQRect borderBox( box ); 01162 borderBox.setTop( subheaderBox.bottom()+1 ); 01163 drawSubHeaderBox( p, calsys->monthName(dt), subheaderBox ); 01164 // correct for half the border width 01165 int correction = (BOX_BORDER_WIDTH/*-1*/)/2; 01166 TQRect daysBox( borderBox ); 01167 daysBox.addCoords( correction, correction, -correction, -correction ); 01168 01169 int daysinmonth = calsys->daysInMonth( dt ); 01170 if ( maxdays <= 0 ) maxdays = daysinmonth; 01171 01172 int d; 01173 float dayheight = float(daysBox.height()) / float( maxdays ); 01174 01175 TQColor holidayColor( 240, 240, 240 ); 01176 TQColor workdayColor( 255, 255, 255 ); 01177 int dayNrWidth = p.fontMetrics().width( "99" ); 01178 01179 // Fill the remaining space (if a month has less days than others) with a crossed-out pattern 01180 if ( daysinmonth<maxdays ) { 01181 TQRect dayBox( box.left(), daysBox.top() + round(dayheight*daysinmonth), box.width(), 0 ); 01182 dayBox.setBottom( daysBox.bottom() ); 01183 p.fillRect( dayBox, TQt::DiagCrossPattern ); 01184 } 01185 // Backgrounded boxes for each day, plus day numbers 01186 TQBrush oldbrush( p.brush() ); 01187 for ( d = 0; d < daysinmonth; ++d ) { 01188 TQDate day; 01189 calsys->setYMD( day, dt.year(), dt.month(), d+1 ); 01190 TQRect dayBox( daysBox.left()/*+rand()%50*/, daysBox.top() + round(dayheight*d), daysBox.width()/*-rand()%50*/, 0 ); 01191 // FIXME: When using a border width of 0 for event boxes, don't let the rectangles overlap, i.e. subtract 1 from the top or bottom! 01192 dayBox.setBottom( daysBox.top()+round(dayheight*(d+1)) - 1 ); 01193 01194 p.setBrush( isWorkingDay( day )?workdayColor:holidayColor ); 01195 p.drawRect( dayBox ); 01196 TQRect dateBox( dayBox ); 01197 dateBox.setWidth( dayNrWidth+3 ); 01198 p.drawText( dateBox, TQt::AlignRight | TQt::AlignVCenter | TQt::SingleLine, 01199 TQString::number(d+1) ); 01200 } 01201 p.setBrush( oldbrush ); 01202 int xstartcont = box.left() + dayNrWidth + 5; 01203 01204 TQDate start, end; 01205 calsys->setYMD( start, dt.year(), dt.month(), 1 ); 01206 end = calsys->addMonths( start, 1 ); 01207 end = calsys->addDays( end, -1 ); 01208 01209 Event::List events = mCalendar->events( start, end ); 01210 TQMap<int, TQStringList> textEvents; 01211 TQPtrList<KOrg::CellItem> timeboxItems; 01212 timeboxItems.setAutoDelete( true ); 01213 01214 01215 // 1) For multi-day events, show boxes spanning several cells, use CellItem 01216 // print the summary vertically 01217 // 2) For sub-day events, print the concated summaries into the remaining 01218 // space of the box (optional, depending on the given flags) 01219 // 3) Draw some kind of timeline showing free and busy times 01220 01221 // Holidays 01222 Event::List holidays; 01223 holidays.setAutoDelete( true ); 01224 for ( TQDate d(start); d <= end; d = d.addDays(1) ) { 01225 Event *e = holiday( d ); 01226 if ( e ) { 01227 holidays.append( e ); 01228 if ( holidaysFlags & TimeBoxes ) { 01229 timeboxItems.append( new PrintCellItem( e, TQDateTime(d, TQTime(0,0,0) ), 01230 TQDateTime( d.addDays(1), TQTime(0,0,0) ) ) ); 01231 } 01232 if ( holidaysFlags & Text ) { 01233 textEvents[ d.day() ] << e->summary(); 01234 } 01235 } 01236 } 01237 01238 TQValueList<MonthEventStruct> monthentries; 01239 01240 for ( Event::List::ConstIterator evit = events.begin(); 01241 evit != events.end(); ++evit ) { 01242 Event *e = (*evit); 01243 if (!e) continue; 01244 if ( e->doesRecur() ) { 01245 if ( e->recursOn( start ) ) { 01246 // This occurrence has possibly started before the beginning of the 01247 // month, so obtain the start date before the beginning of the month 01248 TQValueList<TQDateTime> starttimes = e->startDateTimesForDate( start ); 01249 TQValueList<TQDateTime>::ConstIterator it = starttimes.begin(); 01250 for ( ; it != starttimes.end(); ++it ) { 01251 monthentries.append( MonthEventStruct( *it, e->endDateForStart( *it ), e ) ); 01252 } 01253 } 01254 // Loop through all remaining days of the month and check if the event 01255 // begins on that day (don't use Event::recursOn, as that will 01256 // also return events that have started earlier. These start dates 01257 // however, have already been treated! 01258 Recurrence *recur = e->recurrence(); 01259 TQDate d1( start.addDays(1) ); 01260 while ( d1 <= end ) { 01261 if ( recur->recursOn(d1) ) { 01262 TimeList times( recur->recurTimesOn( d1 ) ); 01263 for ( TimeList::ConstIterator it = times.begin(); 01264 it != times.end(); ++it ) { 01265 TQDateTime d1start( d1, *it ); 01266 monthentries.append( MonthEventStruct( d1start, e->endDateForStart( d1start ), e ) ); 01267 } 01268 } 01269 d1 = d1.addDays(1); 01270 } 01271 } else { 01272 monthentries.append( MonthEventStruct( e->dtStart(), e->dtEnd(), e ) ); 01273 } 01274 } 01275 qHeapSort( monthentries ); 01276 01277 TQValueList<MonthEventStruct>::ConstIterator mit = monthentries.begin(); 01278 TQDateTime endofmonth( end, TQTime(0,0,0) ); 01279 endofmonth = endofmonth.addDays(1); 01280 for ( ; mit != monthentries.end(); ++mit ) { 01281 if ( (*mit).start.date() == (*mit).end.date() ) { 01282 // Show also single-day events as time line boxes 01283 if ( subDailyFlags & TimeBoxes ) { 01284 timeboxItems.append( new PrintCellItem( (*mit).event, (*mit).start, (*mit).end ) ); 01285 } 01286 // Show as text in the box 01287 if ( subDailyFlags & Text ) { 01288 textEvents[ (*mit).start.date().day() ] << (*mit).event->summary(); 01289 } 01290 } else { 01291 // Multi-day events are always shown as time line boxes 01292 TQDateTime thisstart( (*mit).start ); 01293 TQDateTime thisend( (*mit).end ); 01294 if ( thisstart.date()<start ) thisstart = start; 01295 if ( thisend>endofmonth ) thisend = endofmonth; 01296 timeboxItems.append( new PrintCellItem( (*mit).event, thisstart, thisend ) ); 01297 } 01298 } 01299 01300 // For Multi-day events, line them up nicely so that the boxes don't overlap 01301 TQPtrListIterator<KOrg::CellItem> it1( timeboxItems ); 01302 for( it1.toFirst(); it1.current(); ++it1 ) { 01303 KOrg::CellItem *placeItem = it1.current(); 01304 KOrg::CellItem::placeItem( timeboxItems, placeItem ); 01305 } 01306 TQDateTime starttime( start, TQTime( 0, 0, 0 ) ); 01307 int newxstartcont = xstartcont; 01308 01309 TQFont oldfont( p.font() ); 01310 p.setFont( TQFont( "sans-serif", 7 ) ); 01311 for( it1.toFirst(); it1.current(); ++it1 ) { 01312 PrintCellItem *placeItem = static_cast<PrintCellItem *>( it1.current() ); 01313 int minsToStart = starttime.secsTo( placeItem->start() )/60; 01314 int minsToEnd = starttime.secsTo( placeItem->end() )/60; 01315 01316 TQRect eventBox( xstartcont + placeItem->subCell()*17, 01317 daysBox.top() + round( double( minsToStart*daysBox.height()) / double(maxdays*24*60) ), 01318 14, 0 ); 01319 eventBox.setBottom( daysBox.top() + round( double( minsToEnd*daysBox.height()) / double(maxdays*24*60) ) ); 01320 drawVerticalBox( p, 0, eventBox, placeItem->event()->summary() ); 01321 newxstartcont = TQMAX( newxstartcont, eventBox.right() ); 01322 } 01323 xstartcont = newxstartcont; 01324 01325 // For Single-day events, simply print their summaries into the remaining 01326 // space of the day's cell 01327 for ( int d=0; d<daysinmonth; ++d ) { 01328 TQStringList dayEvents( textEvents[d+1] ); 01329 TQString txt = dayEvents.join(", "); 01330 TQRect dayBox( xstartcont, daysBox.top()+round(dayheight*d), 0, 0 ); 01331 dayBox.setRight( box.right() ); 01332 dayBox.setBottom( daysBox.top()+round(dayheight*(d+1)) ); 01333 printEventString(p, dayBox, txt, TQt::AlignTop | TQt::AlignLeft | TQt::BreakAnywhere ); 01334 } 01335 p.setFont( oldfont ); 01336 // p.setBrush( TQt::NoBrush ); 01337 drawBox( p, BOX_BORDER_WIDTH, borderBox ); 01338 p.restore(); 01339 } 01340 01342 01343 void CalPrintPluginBase::drawMonthTable(TQPainter &p, const TQDate &qd, bool weeknumbers, 01344 bool recurDaily, bool recurWeekly, 01345 const TQRect &box) 01346 { 01347 int yoffset = mSubHeaderHeight; 01348 int xoffset = 0; 01349 TQDate monthDate(TQDate(qd.year(), qd.month(), 1)); 01350 TQDate monthFirst(monthDate); 01351 TQDate monthLast(monthDate.addMonths(1).addDays(-1)); 01352 01353 01354 int weekdayCol = weekdayColumn( monthDate.dayOfWeek() ); 01355 monthDate = monthDate.addDays(-weekdayCol); 01356 01357 if (weeknumbers) { 01358 xoffset += 14; 01359 } 01360 01361 int rows=(weekdayCol + qd.daysInMonth() - 1)/7 +1; 01362 double cellHeight = ( box.height() - yoffset ) / (1.*rows); 01363 double cellWidth = ( box.width() - xoffset ) / 7.; 01364 01365 // Precalculate the grid... 01366 // rows is at most 6, so using 8 entries in the array is fine, too! 01367 int coledges[8], rowedges[8]; 01368 for ( int i = 0; i <= 7; i++ ) { 01369 rowedges[i] = int( box.top() + yoffset + i*cellHeight ); 01370 coledges[i] = int( box.left() + xoffset + i*cellWidth ); 01371 } 01372 01373 if (weeknumbers) { 01374 TQFont oldFont(p.font()); 01375 TQFont newFont(p.font()); 01376 newFont.setPointSize(6); 01377 p.setFont(newFont); 01378 TQDate weekDate(monthDate); 01379 for (int row = 0; row<rows; ++row ) { 01380 int calWeek = weekDate.weekNumber(); 01381 TQRect rc( box.left(), rowedges[row], coledges[0] - 3 - box.left(), rowedges[row+1]-rowedges[row] ); 01382 p.drawText( rc, TQt::AlignRight | TQt::AlignVCenter, TQString::number( calWeek ) ); 01383 weekDate = weekDate.addDays( 7 ); 01384 } 01385 p.setFont( oldFont ); 01386 } 01387 01388 TQRect daysOfWeekBox( box ); 01389 daysOfWeekBox.setHeight( mSubHeaderHeight ); 01390 daysOfWeekBox.setLeft( box.left()+xoffset ); 01391 drawDaysOfWeek( p, monthDate, monthDate.addDays( 6 ), daysOfWeekBox ); 01392 01393 TQColor back = p.backgroundColor(); 01394 bool darkbg = false; 01395 for ( int row = 0; row < rows; ++row ) { 01396 for ( int col = 0; col < 7; ++col ) { 01397 // show days from previous/next month with a grayed background 01398 if ( (monthDate < monthFirst) || (monthDate > monthLast) ) { 01399 p.setBackgroundColor( back.dark( 120 ) ); 01400 darkbg = true; 01401 } 01402 TQRect dayBox( coledges[col], rowedges[row], coledges[col+1]-coledges[col], rowedges[row+1]-rowedges[row] ); 01403 drawDayBox(p, monthDate, dayBox, false, recurDaily, recurWeekly ); 01404 if ( darkbg ) { 01405 p.setBackgroundColor( back ); 01406 darkbg = false; 01407 } 01408 monthDate = monthDate.addDays(1); 01409 } 01410 } 01411 } 01412 01413 01415 01416 void CalPrintPluginBase::drawTodo( int &count, Todo *todo, TQPainter &p, 01417 TodoSortField sortField, SortDirection sortDir, 01418 bool connectSubTodos, bool strikeoutCompleted, 01419 bool desc, int posPriority, int posSummary, 01420 int posDueDt, int posPercentComplete, 01421 int level, int x, int &y, int width, 01422 int pageHeight, const Todo::List &todoList, 01423 TodoParentStart *r ) 01424 { 01425 TQString outStr; 01426 const KLocale *local = KGlobal::locale(); 01427 TQRect rect; 01428 TodoParentStart startpt; 01429 01430 // This list keeps all starting points of the parent to-dos so the connection 01431 // lines of the tree can easily be drawn (needed if a new page is started) 01432 static TQPtrList<TodoParentStart> startPoints; 01433 if ( level < 1 ) { 01434 startPoints.clear(); 01435 } 01436 01437 // Compute the right hand side of the to-do box 01438 int rhs = posPercentComplete; 01439 if ( rhs < 0 ) rhs = posDueDt; //not printing percent completed 01440 if ( rhs < 0 ) rhs = x+width; //not printing due dates either 01441 01442 // size of to-do 01443 outStr=todo->summary(); 01444 int left = posSummary + ( level*10 ); 01445 rect = p.boundingRect( left, y, ( rhs-left-5 ), -1, TQt::WordBreak, outStr ); 01446 if ( !todo->description().isEmpty() && desc ) { 01447 outStr = todo->description(); 01448 rect = p.boundingRect( left+20, rect.bottom()+5, width-(left+10-x), -1, 01449 TQt::WordBreak, outStr ); 01450 } 01451 // if too big make new page 01452 if ( rect.bottom() > pageHeight ) { 01453 // first draw the connection lines from parent to-dos: 01454 if ( level > 0 && connectSubTodos ) { 01455 TodoParentStart *rct; 01456 for ( rct = startPoints.first(); rct; rct = startPoints.next() ) { 01457 int start; 01458 int center = rct->mRect.left() + (rct->mRect.width()/2); 01459 int to = p.viewport().bottom(); 01460 01461 // draw either from start point of parent or from top of the page 01462 if ( rct->mSamePage ) 01463 start = rct->mRect.bottom() + 1; 01464 else 01465 start = p.viewport().top(); 01466 p.moveTo( center, start ); 01467 p.lineTo( center, to ); 01468 rct->mSamePage = false; 01469 } 01470 } 01471 y=0; 01472 mPrinter->newPage(); 01473 } 01474 01475 // If this is a sub-to-do, r will not be 0, and we want the LH side 01476 // of the priority line up to the RH side of the parent to-do's priority 01477 bool showPriority = posPriority>=0; 01478 int lhs = posPriority; 01479 if ( r ) { 01480 lhs = r->mRect.right() + 1; 01481 } 01482 01483 outStr.setNum( todo->priority() ); 01484 rect = p.boundingRect( lhs, y + 10, 5, -1, TQt::AlignCenter, outStr ); 01485 // Make it a more reasonable size 01486 rect.setWidth(18); 01487 rect.setHeight(18); 01488 01489 // Draw a checkbox 01490 p.setBrush( TQBrush( TQt::NoBrush ) ); 01491 p.drawRect( rect ); 01492 if ( todo->isCompleted() ) { 01493 // cross out the rectangle for completed to-dos 01494 p.drawLine( rect.topLeft(), rect.bottomRight() ); 01495 p.drawLine( rect.topRight(), rect.bottomLeft() ); 01496 } 01497 lhs = rect.right() + 3; 01498 01499 // Priority 01500 if ( todo->priority() > 0 && showPriority ) { 01501 p.drawText( rect, TQt::AlignCenter, outStr ); 01502 } 01503 startpt.mRect = rect; //save for later 01504 01505 // Connect the dots 01506 if ( level > 0 && connectSubTodos ) { 01507 int bottom; 01508 int center( r->mRect.left() + (r->mRect.width()/2) ); 01509 if ( r->mSamePage ) 01510 bottom = r->mRect.bottom() + 1; 01511 else 01512 bottom = 0; 01513 int to( rect.top() + (rect.height()/2) ); 01514 int endx( rect.left() ); 01515 p.moveTo( center, bottom ); 01516 p.lineTo( center, to ); 01517 p.lineTo( endx, to ); 01518 } 01519 01520 // summary 01521 outStr=todo->summary(); 01522 rect = p.boundingRect( lhs, rect.top(), (rhs-(left + rect.width() + 5)), 01523 -1, TQt::WordBreak, outStr ); 01524 01525 TQRect newrect; 01526 //FIXME: the following code prints underline rather than strikeout text 01527 #if 0 01528 TQFont f( p.font() ); 01529 if ( todo->isCompleted() && strikeoutCompleted ) { 01530 f.setStrikeOut( true ); 01531 p.setFont( f ); 01532 } 01533 p.drawText( rect, TQt::WordBreak, outStr, -1, &newrect ); 01534 f.setStrikeOut( false ); 01535 p.setFont( f ); 01536 #endif 01537 //TODO: Remove this section when the code above is fixed 01538 p.drawText( rect, TQt::WordBreak, outStr, -1, &newrect ); 01539 if ( todo->isCompleted() && strikeoutCompleted ) { 01540 // strike out the summary text if to-do is complete 01541 // Note: we tried to use a strike-out font and for unknown reasons the 01542 // result was underline instead of strike-out, so draw the lines ourselves. 01543 int delta = p.fontMetrics().lineSpacing(); 01544 int lines = ( rect.height() / delta ) + 1; 01545 for ( int i=0; i<lines; i++ ) { 01546 p.moveTo( rect.left(), rect.top() + ( delta/2 ) + ( i*delta ) ); 01547 p.lineTo( rect.right(), rect.top() + ( delta/2 ) + ( i*delta ) ); 01548 } 01549 } 01550 01551 // due date 01552 if ( todo->hasDueDate() && posDueDt>=0 ) { 01553 outStr = local->formatDate( todo->dtDue().date(), true ); 01554 rect = p.boundingRect( posDueDt, y, x + width, -1, 01555 TQt::AlignTop | TQt::AlignLeft, outStr ); 01556 p.drawText( rect, TQt::AlignTop | TQt::AlignLeft, outStr ); 01557 } 01558 01559 // percentage completed 01560 bool showPercentComplete = posPercentComplete>=0; 01561 if ( showPercentComplete ) { 01562 int lwidth = 24; 01563 int lheight = 12; 01564 //first, draw the progress bar 01565 int progress = (int)(( lwidth*todo->percentComplete())/100.0 + 0.5); 01566 01567 p.setBrush( TQBrush( TQt::NoBrush ) ); 01568 p.drawRect( posPercentComplete, y+3, lwidth, lheight ); 01569 if ( progress > 0 ) { 01570 p.setBrush( TQColor( 128, 128, 128 ) ); 01571 p.drawRect( posPercentComplete, y+3, progress, lheight ); 01572 } 01573 01574 //now, write the percentage 01575 outStr = i18n( "%1%" ).arg( todo->percentComplete() ); 01576 rect = p.boundingRect( posPercentComplete+lwidth+3, y, x + width, -1, 01577 TQt::AlignTop | TQt::AlignLeft, outStr ); 01578 p.drawText( rect, TQt::AlignTop | TQt::AlignLeft, outStr ); 01579 } 01580 01581 // description 01582 if ( !todo->description().isEmpty() && desc ) { 01583 y = newrect.bottom() + 5; 01584 outStr = todo->description(); 01585 rect = p.boundingRect( left+20, y, x+width-(left+10), -1, 01586 TQt::WordBreak, outStr ); 01587 p.drawText( rect, TQt::WordBreak, outStr, -1, &newrect ); 01588 } 01589 01590 // Set the new line position 01591 y = newrect.bottom() + 10; //set the line position 01592 01593 // If the to-do has sub-to-dos, we need to call ourselves recursively 01594 #if 0 01595 Incidence::List l = todo->relations(); 01596 Incidence::List::ConstIterator it; 01597 startPoints.append( &startpt ); 01598 for( it = l.begin(); it != l.end(); ++it ) { 01599 count++; 01600 // In the future, to-dos might also be related to events 01601 // Manually check if the sub-to-do is in the list of to-dos to print 01602 // The problem is that relations() does not apply filters, so 01603 // we need to compare manually with the complete filtered list! 01604 Todo* subtodo = dynamic_cast<Todo *>( *it ); 01605 if (subtodo && todoList.contains( subtodo ) ) { 01606 drawTodo( count, subtodo, p, connectSubTodos, strikeoutCompleted, 01607 desc, posPriority, posSummary, posDueDt, posPercentComplete, 01608 level+1, x, y, width, pageHeight, todoList, &startpt ); 01609 } 01610 } 01611 #endif 01612 // Make a list of all the sub-to-dos related to this to-do. 01613 Todo::List t; 01614 Incidence::List l = todo->relations(); 01615 Incidence::List::ConstIterator it; 01616 for( it=l.begin(); it!=l.end(); ++it ) { 01617 // In the future, to-dos might also be related to events 01618 // Manually check if the sub-to-do is in the list of to-dos to print 01619 // The problem is that relations() does not apply filters, so 01620 // we need to compare manually with the complete filtered list! 01621 Todo* subtodo = dynamic_cast<Todo *>( *it ); 01622 if ( subtodo && todoList.contains( subtodo ) ) { 01623 t.append( subtodo ); 01624 } 01625 } 01626 01627 // Sort the sub-to-dos and then print them 01628 Todo::List sl = mCalendar->sortTodos( &t, sortField, sortDir ); 01629 Todo::List::ConstIterator isl; 01630 startPoints.append( &startpt ); 01631 for( isl = sl.begin(); isl != sl.end(); ++isl ) { 01632 count++; 01633 drawTodo( count, ( *isl ), p, sortField, sortDir, 01634 connectSubTodos, strikeoutCompleted, 01635 desc, posPriority, posSummary, posDueDt, posPercentComplete, 01636 level+1, x, y, width, pageHeight, todoList, &startpt ); 01637 } 01638 startPoints.remove( &startpt ); 01639 } 01640 01641 int CalPrintPluginBase::weekdayColumn( int weekday ) 01642 { 01643 return ( weekday + 7 - KGlobal::locale()->weekStartDay() ) % 7; 01644 } 01645 01646 void CalPrintPluginBase::drawJournalField( TQPainter &p, TQString field, TQString text, 01647 int x, int &y, int width, int pageHeight ) 01648 { 01649 if ( text.isEmpty() ) return; 01650 01651 TQString entry( field.arg( text ) ); 01652 01653 TQRect rect( p.boundingRect( x, y, width, -1, TQt::WordBreak, entry) ); 01654 if ( rect.bottom() > pageHeight) { 01655 // Start new page... 01656 // FIXME: If it's a multi-line text, draw a few lines on this page, and the 01657 // remaining lines on the next page. 01658 y=0; 01659 mPrinter->newPage(); 01660 rect = p.boundingRect( x, y, width, -1, TQt::WordBreak, entry); 01661 } 01662 TQRect newrect; 01663 p.drawText( rect, TQt::WordBreak, entry, -1, &newrect ); 01664 y = newrect.bottom() + 7; 01665 } 01666 01667 void CalPrintPluginBase::drawJournal( Journal * journal, TQPainter &p, int x, int &y, 01668 int width, int pageHeight ) 01669 { 01670 TQFont oldFont( p.font() ); 01671 p.setFont( TQFont( "sans-serif", 15 ) ); 01672 TQString headerText; 01673 TQString dateText( KGlobal::locale()-> 01674 formatDate( journal->dtStart().date(), false ) ); 01675 01676 if ( journal->summary().isEmpty() ) { 01677 headerText = dateText; 01678 } else { 01679 headerText = i18n("Description - date", "%1 - %2") 01680 .arg( journal->summary() ) 01681 .arg( dateText ); 01682 } 01683 01684 TQRect rect( p.boundingRect( x, y, width, -1, TQt::WordBreak, headerText) ); 01685 if ( rect.bottom() > pageHeight) { 01686 // Start new page... 01687 y=0; 01688 mPrinter->newPage(); 01689 rect = p.boundingRect( x, y, width, -1, TQt::WordBreak, headerText ); 01690 } 01691 TQRect newrect; 01692 p.drawText( rect, TQt::WordBreak, headerText, -1, &newrect ); 01693 p.setFont( oldFont ); 01694 01695 y = newrect.bottom() + 4; 01696 01697 p.drawLine( x + 3, y, x + width - 6, y ); 01698 y += 5; 01699 01700 drawJournalField( p, i18n("Person: %1"), journal->organizer().fullName(), x, y, width, pageHeight ); 01701 drawJournalField( p, i18n("%1"), journal->description(), x, y, width, pageHeight ); 01702 y += 10; 01703 } 01704 01705 01706 void CalPrintPluginBase::drawSplitHeaderRight( TQPainter &p, const TQDate &fd, 01707 const TQDate &td, 01708 const TQDate &, 01709 int width, int ) 01710 { 01711 TQFont oldFont( p.font() ); 01712 01713 TQPen oldPen( p.pen() ); 01714 TQPen pen( TQt::black, 4 ); 01715 01716 TQString title; 01717 if ( mCalSys ) { 01718 if ( fd.month() == td.month() ) { 01719 title = i18n("Date range: Month dayStart - dayEnd", "%1 %2 - %3") 01720 .arg( mCalSys->monthName( fd.month(), false ) ) 01721 .arg( mCalSys->dayString( fd, false ) ) 01722 .arg( mCalSys->dayString( td, false ) ); 01723 } else { 01724 title = i18n("Date range: monthStart dayStart - monthEnd dayEnd", "%1 %2 - %3 %4") 01725 .arg( mCalSys->monthName( fd.month(), false ) ) 01726 .arg( mCalSys->dayString( fd, false ) ) 01727 .arg( mCalSys->monthName( td.month(), false ) ) 01728 .arg( mCalSys->dayString( td, false ) ); 01729 } 01730 } 01731 01732 TQFont serifFont("Times", 30); 01733 p.setFont(serifFont); 01734 01735 int lineSpacing = p.fontMetrics().lineSpacing(); 01736 p.drawText( 0, lineSpacing * 0, width, lineSpacing, 01737 TQt::AlignRight | TQt::AlignTop, title ); 01738 01739 title.truncate(0); 01740 01741 p.setPen( pen ); 01742 p.drawLine(300, lineSpacing * 1, width, lineSpacing * 1); 01743 p.setPen( oldPen ); 01744 01745 p.setFont(TQFont("Times", 20, TQFont::Bold, TRUE)); 01746 int newlineSpacing = p.fontMetrics().lineSpacing(); 01747 title += TQString::number(fd.year()); 01748 p.drawText( 0, lineSpacing * 1 + 4, width, newlineSpacing, 01749 TQt::AlignRight | TQt::AlignTop, title ); 01750 01751 p.setFont( oldFont ); 01752 } 01753 01754 #endif