korganizer

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 <tdeconfig.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     TDEConfigGroupSaver 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     TDEConfigGroupSaver 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 = TDEGlobal::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 ( !TDEGlobal::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 = TDEGlobal::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( TDEGlobal::locale()->formatTime( startTime.time() ) ).
00910             arg( TDEGlobal::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( TDEGlobal::locale()->formatTime( startTime.time() ) ).
00916             arg( TDEGlobal::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 TDELocale*local = TDEGlobal::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 = TDEGlobal::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( TDEGlobal::locale()->formatDateTime( todo->dtDue() ) );
01021         } else {
01022           str = i18n( "%1 (Due: %2)" ).
01023                 arg( summaryStr ).
01024                 arg( TDEGlobal::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 TDELocale *local = TDEGlobal::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 - TDEGlobal::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( TDEGlobal::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