korganizer Library API Documentation

calprintbase.cpp

00001 /*
00002     This file is part of KOrganizer.
00003 
00004     Copyright (c) 1998 Preston Brown
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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00020 
00021     As a special exception, permission is given to link this program
00022     with any edition of Qt, and distribute the resulting executable,
00023     without including the source code for Qt in the source distribution.
00024 */
00025 
00026 #include <qpainter.h>
00027 #include <qlayout.h>
00028 #include <qframe.h>
00029 #include <qlabel.h>
00030 #include <qptrlist.h>
00031 #include <qintdict.h>
00032 
00033 #include <kglobal.h>
00034 #include <klocale.h>
00035 #include <kdebug.h>
00036 #include <kconfig.h>
00037 #include <kcalendarsystem.h>
00038 #include <kprinter.h>
00039 
00040 #include <libkcal/todo.h>
00041 #include <libkcal/event.h>
00042 #include <libkcal/calendar.h>
00043 
00044 #include "koprefs.h"
00045 #include "koglobals.h"
00046 #ifndef KORG_NOPLUGINS
00047 #include "kocore.h"
00048 #endif
00049 #include "cellitem.h"
00050 
00051 #include "calprintbase.h"
00052 
00053 #ifndef KORG_NOPRINTER
00054 #include "calprintbase.moc"
00055 
00056 int CalPrintBase::mHeaderHeight=72;
00057 int CalPrintBase::mSubHeaderHeight=20;
00058 int CalPrintBase::mMargin=36;
00059 
00060 
00061 class CalPrintBase::TodoParentStart
00062 {
00063   public:
00064     TodoParentStart( QRect pt = QRect(), bool page = true )
00065       : mRect( pt ), mSamePage( page ) {}
00066 
00067     QRect mRect;
00068     bool mSamePage;
00069 };
00070 
00071 class PrintCellItem : public KOrg::CellItem
00072 {
00073   public:
00074     PrintCellItem( Event *event, const QDate &day )
00075       : mEvent( event ), mDay( day )
00076     {
00077     }
00078   
00079     Event *event() const { return mEvent; }
00080 
00081     QString label() const { return mEvent->summary(); }
00082     
00083     bool overlaps( KOrg::CellItem *o ) const
00084     {
00085       PrintCellItem *other = static_cast<PrintCellItem *>( o );
00086 
00087       QDateTime start = event()->dtStart();
00088       QDateTime end = event()->dtEnd();
00089       if ( event()->doesRecur() ) {
00090         start.setDate( mDay );
00091         end.setDate( mDay );
00092       }
00093       QDateTime otherStart = other->event()->dtStart();
00094       QDateTime otherEnd = other->event()->dtEnd();
00095       if ( other->event()->doesRecur() ) {
00096         otherStart.setDate( mDay );
00097         otherEnd.setDate( mDay );
00098       }
00099 
00100 #if 0
00101       kdDebug() << "PrintCellItem::overlaps() " << event()->summary()
00102                 << " <-> " << other->event()->summary() << endl;
00103       kdDebug() << "  start     : " << start.toString() << endl;
00104       kdDebug() << "  end       : " << end.toString() << endl;
00105       kdDebug() << "  otherStart: " << otherStart.toString() << endl;
00106       kdDebug() << "  otherEnd  : " << otherEnd.toString() << endl;
00107 #endif
00108       
00109       return !( otherStart >= end || otherEnd <= start );
00110     }
00111     
00112   private:
00113     Event *mEvent;
00114     QDate mDay;
00115 };
00116 
00117 void setCategoryColors( QPainter &p, Incidence *incidence)
00118 {
00119   QColor bgColor;
00120   QStringList categories = incidence->categories();
00121   QString cat = categories.first();
00122   if (cat.isEmpty())
00123     bgColor = KOPrefs::instance()->mEventColor;
00124   else
00125     bgColor = *(KOPrefs::instance()->categoryColor(cat));
00126   QColor textColor = getTextColor(bgColor);
00127   p.setPen( textColor );
00128   p.setBrush( bgColor );
00129 }
00130 
00131 
00132 
00133 CalPrintBase::CalPrintBase( KPrinter *printer, Calendar *cal, KConfig *cfg )
00134   : QObject(), mPrinter( printer ), mCalendar( cal ), mConfig( cfg )
00135 {
00136 }
00137 
00138 CalPrintBase::~CalPrintBase()
00139 {
00140 }
00141 
00142 
00143 
00144 QWidget *CalPrintBase::configWidget( QWidget *w )
00145 {
00146   QFrame *wdg = new QFrame( w );
00147   QVBoxLayout *layout = new QVBoxLayout( wdg );
00148 
00149   QLabel *title = new QLabel( description(), wdg );
00150   QFont titleFont( title->font() );
00151   titleFont.setPointSize( 20 );
00152   titleFont.setBold( true );
00153   title->setFont( titleFont );
00154 
00155   layout->addWidget( title );
00156   layout->addWidget( new QLabel( longDescription(), wdg ) );
00157   layout->addSpacing( 20 );
00158   layout->addWidget( new QLabel( i18n("This printing style does not "
00159                                       "have any configuration options."),
00160                                  wdg ) );
00161   layout->addStretch();
00162   return wdg;
00163 }
00164 
00165 void CalPrintBase::doPrint()
00166 {
00167   QPainter p;
00168 
00169   mPrinter->setColorMode( (mUseColors)?(KPrinter::Color):(KPrinter::GrayScale));
00170 
00171   p.begin(mPrinter);
00172   // the painter initially begins at 72 dpi per the Qt docs.
00173   // we want half-inch margins.
00174   p.setViewport(mMargin, mMargin,
00175                 p.viewport().width()-mMargin,
00176                 p.viewport().height()-mMargin);
00177   int pageWidth = p.viewport().width();
00178   int pageHeight = p.viewport().height();
00179 
00180   print(p, pageWidth, pageHeight);
00181 
00182   p.end();
00183 }
00184 
00185 void CalPrintBase::doLoadConfig()
00186 {
00187   if ( mConfig ) {
00188     KConfigGroupSaver saver( mConfig, description() );
00189     mConfig->sync();
00190     QDateTime currDate( QDate::currentDate() );
00191     mFromDate = mConfig->readDateTimeEntry( "FromDate", &currDate ).date();
00192     mToDate = mConfig->readDateTimeEntry( "ToDate" ).date();
00193     mUseColors = mConfig->readBoolEntry( "UseColors", true );
00194     loadConfig();
00195   } else {
00196     kdDebug(5850) << "No config available in loadConfig!!!!" << endl;
00197   }
00198 }
00199 
00200 void CalPrintBase::doSaveConfig()
00201 {
00202   if ( mConfig ) {
00203     KConfigGroupSaver saver( mConfig, description() );
00204     saveConfig();
00205     mConfig->writeEntry( "FromDate", QDateTime( mFromDate ) );
00206     mConfig->writeEntry( "ToDate", QDateTime( mToDate ) );
00207     mConfig->writeEntry( "UseColors", mUseColors );
00208     mConfig->sync();
00209   } else {
00210     kdDebug(5850) << "No config available in saveConfig!!!!" << endl;
00211   }
00212 }
00213 
00215 
00216 void CalPrintBase::drawHeader( QPainter &p, QString title,
00217     const QDate &month1, const QDate &month2,
00218     int x, int y, int width, int height )
00219 {
00220   p.drawRect(x, y, width, height);
00221   p.fillRect( x+1, y+1,
00222               width-2,height-2,
00223               QBrush(Dense7Pattern) );
00224 
00225   QString myOwner(mCalendar->getOwner());
00226 
00227   int right=x+width;
00228 
00229   // print previous month for month view, print current for todo, day and week
00230   int smallMonthWidth=width/4-10;
00231   if (smallMonthWidth>100) smallMonthWidth=100;
00232   if (month2.isValid()) {
00233     right -= (10+smallMonthWidth);
00234     drawSmallMonth(p, QDate(month2.year(), month2.month(), 1),
00235                    right, y+2, smallMonthWidth, height-4);
00236     right-=10;
00237   }
00238   if (month1.isValid()) {
00239     right -= (10+smallMonthWidth);
00240     drawSmallMonth(p, QDate(month1.year(), month1.month(), 1),
00241                    right, y+2, smallMonthWidth, height-4);
00242     right-=10;
00243   }
00244 
00245   // Print the titles...
00246   QFont oldFont(p.font());
00247   p.setFont( QFont("helvetica", 18, QFont::Bold) );
00248   QRect textRect( x+5, y+5, right-10-x, height-10 );
00249   p.drawText( textRect, Qt::AlignLeft | Qt::AlignTop | Qt::WordBreak, title );
00250   p.setFont(oldFont);
00251 }
00252 
00253 
00254 void CalPrintBase::drawSmallMonth(QPainter &p, const QDate &qd,
00255     int x, int y, int width, int height)
00256 {
00257   bool firstCol = true;
00258   QDate monthDate(QDate(qd.year(), qd.month(), 1));
00259   QDate monthDate2;
00260   int month = monthDate.month();
00261 
00262   // draw the title
00263   QFont oldFont( p.font() );
00264   p.setFont(QFont("helvetica", 8, QFont::Bold));
00265   //  int lineSpacing = p.fontMetrics().lineSpacing();
00266   const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
00267   p.drawText(x, y, width, height/4, AlignCenter, calSys->monthName( qd ) );
00268 
00269   int cellWidth = width/7;
00270   int cellHeight = height/8;
00271   QString tmpStr;
00272 
00273   // correct begin of week
00274   int weekdayCol = weekdayColumn( qd.dayOfWeek() );
00275   monthDate2 = monthDate.addDays(-weekdayCol);
00276 
00277   // draw days of week
00278    p.setFont(QFont("helvetica", 8, QFont::Bold));
00279   for (int col = 0; col < 7; col++) {
00280     // tmpStr.sprintf("%c",(const char*)monthDate2.dayName(monthDate2.dayOfWeek()));
00281     tmpStr=calSys->weekDayName( monthDate2 )[0].upper();
00282     p.drawText(x+col*cellWidth, y+height/4, cellWidth, cellHeight,
00283                AlignCenter, tmpStr);
00284     monthDate2 = monthDate2.addDays(1);
00285   }
00286 
00287   // draw separator line
00288   p.drawLine(x, y+height/4+cellHeight, x+width, y+height/4+cellHeight);
00289 
00290   for (int row = 0; row < 5; row++) {
00291     for (int col = 0; col < 7; col++) {
00292       if (monthDate.month() != month)
00293         break;
00294       if (firstCol) {
00295         firstCol = true;
00296         col = weekdayColumn( monthDate.dayOfWeek() );
00297       }
00298       p.drawText( x+col*cellWidth,
00299                   y+height/4+cellHeight+(row*cellHeight),
00300                   cellWidth, cellHeight, AlignCenter,
00301                   tmpStr.setNum(monthDate.day()) );
00302       monthDate = monthDate.addDays(1);
00303     }
00304   }
00305   p.setFont( oldFont );
00306 }
00307 
00308 
00310 
00311 /*
00312  * This routine draws a header box over the main part of the calendar
00313  * containing the days of the week.
00314  */
00315 void CalPrintBase::drawDaysOfWeek(QPainter &p,
00316     const QDate &fromDate, const QDate &toDate,
00317     int x, int y, int width, int height)
00318 {
00319   int cellWidth = width/(fromDate.daysTo( toDate )+1);
00320   int currx=x;
00321   QDate cellDate(fromDate);
00322 
00323   while (cellDate<=toDate) {
00324     drawDaysOfWeekBox(p, cellDate, currx, y, cellWidth, height);
00325     currx+=cellWidth;
00326     cellDate = cellDate.addDays(1);
00327   }
00328 }
00329 
00330 
00331 void CalPrintBase::drawDaysOfWeekBox(QPainter &p, const QDate &qd,
00332     int x, int y, int width, int height)
00333 {
00334   const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
00335 
00336   QFont oldFont( p.font() );
00337   p.setFont( QFont( "helvetica", 10, QFont::Bold ) );
00338   p.drawRect( x, y, width, height );
00339   p.fillRect( x+1, y+1,
00340               width-2, height-2,
00341               QBrush( Dense7Pattern ) );
00342   p.drawText( x+5, y, width-10, height, AlignCenter | AlignVCenter,
00343              calSys->weekDayName( qd ) );
00344   p.setFont( oldFont );
00345 }
00346 
00347 
00348 void CalPrintBase::drawTimeLine(QPainter &p,
00349     const QTime &fromTime, const QTime &toTime,
00350     int x, int y, int width, int height)
00351 {
00352   p.drawRect(x, y, width, height);
00353 
00354   int totalsecs=fromTime.secsTo(toTime);
00355   float minlen=(float)height*60./(float)totalsecs;
00356   float cellHeight=(60.*(float)minlen);
00357   float currY=y;
00358 
00359   QTime curTime( fromTime );
00360   QTime endTime( toTime );
00361   if ( fromTime.minute() > 30 )
00362     curTime = QTime( fromTime.hour()+1, 0, 0 );
00363   else if ( fromTime.minute() > 0 ) {
00364     curTime = QTime( fromTime.hour(), 30, 0 );
00365     float yy = currY + minlen*(float)fromTime.secsTo( curTime )/60.;
00366     p.drawLine( x+width/2, (int)yy, x+width, (int)yy );
00367     curTime = QTime( fromTime.hour()+1, 0, 0 );
00368   }
00369   currY += ( fromTime.secsTo(curTime)*minlen/60 );
00370 
00371   while ( curTime < endTime ) {
00372     p.drawLine( x, (int)currY, x+width, (int)currY );
00373     int newY=(int)(currY+cellHeight/2.);
00374     QString numStr;
00375     if (newY < y+height) {
00376       QFont oldFont( p.font() );
00377       p.drawLine(x+width/2, (int)newY, x+width, (int)newY);
00378       // draw the time:
00379       if ( !KGlobal::locale()->use12Clock() ) {
00380         numStr.setNum(curTime.hour());
00381         if (cellHeight > 30) {
00382           p.setFont(QFont("helvetica", 16, QFont::Bold));
00383         } else {
00384           p.setFont(QFont("helvetica", 12, QFont::Bold));
00385         }
00386         p.drawText(x+2, (int)currY+2, width/2-2, (int)cellHeight,
00387                   AlignTop|AlignRight, numStr);
00388         p.setFont(QFont("helvetica", 10, QFont::Normal));
00389         p.drawText(x+width/2, (int)currY+2, width/2+2, (int)(cellHeight/2)-3,
00390                   AlignTop | AlignLeft, "00");
00391       } else {
00392         QTime time( curTime.hour(), 0 );
00393         numStr = KGlobal::locale()->formatTime( time );
00394         p.setFont(QFont("helvetica", 14, QFont::Bold));
00395         p.drawText(x+2, (int)currY+2, width-4, (int)cellHeight/2-3,
00396                   AlignTop|AlignLeft, numStr);
00397       }
00398       currY+=cellHeight;
00399     p.setFont( oldFont );
00400     } // enough space for half-hour line and time
00401     if (curTime.secsTo(endTime)>3600)
00402       curTime=curTime.addSecs(3600);
00403     else curTime=endTime;
00404   } // currTime<endTime
00405 }
00406 
00407 
00409 
00415 void CalPrintBase::drawAllDayBox(QPainter &p, Event::List &eventList,
00416     const QDate &qd, bool expandable,
00417     int x, int y, int width, int &height)
00418 {
00419   Event::List::Iterator it, itold;
00420 
00421   int offset=y;
00422 
00423   p.setBrush(QBrush(Dense7Pattern));
00424   QPen oldPen(p.pen());
00425   QColor oldBgColor(p.backgroundColor());
00426   QBrush oldBrush(p.brush());
00427   QString multiDayStr;
00428 
00429   it = eventList.begin();
00430 #ifndef KORG_NOPLUGINS
00431   QString hstring(KOCore::self()->holiday(qd));
00432   if (!hstring.isEmpty()) {
00433     Event*holiday=new Event();
00434     holiday->setDtStart(qd);
00435     holiday->setDtEnd(qd);
00436     holiday->setFloats(true);
00437     holiday->setCategories(i18n("Holiday"));
00438     eventList.prepend(holiday);
00439   }
00440 #endif
00441   Event *currEvent = 0;
00442   // First, print all floating events
00443   while( it!=eventList.end() ) {
00444     currEvent=*it;
00445     itold=it;
00446     ++it;
00447     if ( currEvent->doesFloat() ) {
00448       // set the colors according to the categories
00449       if (expandable) {
00450         if (mUseColors)
00451           setCategoryColors(p, currEvent);
00452 
00453         p.drawRect( x, offset, width, height );
00454         p.drawText( x+5, offset+5, width-10, height-10, 
00455                     AlignCenter | AlignVCenter | AlignJustify | WordBreak,
00456                     currEvent->summary() );
00457         // reset the colors
00458         p.setBrush( oldBrush );
00459         p.setPen( oldPen );
00460         p.setBackgroundColor(oldBgColor);
00461 
00462         offset += height;
00463       } else {
00464         if (!multiDayStr.isEmpty()) multiDayStr+=", ";
00465         multiDayStr += currEvent->summary()+"\n";
00466       }
00467       eventList.remove( itold );
00468     }
00469   }
00470 
00471   if (!expandable) {
00472     p.drawRect(x, offset, width, height);
00473     if (!multiDayStr.isEmpty()) {
00474       p.fillRect(x+1, offset+1, width-2, height-2, QBrush(Dense5Pattern) );
00475       p.drawText( x+5, offset+5, width-10, height-10, 
00476                   AlignCenter | AlignVCenter | AlignJustify | WordBreak, 
00477                   multiDayStr);
00478     }
00479   } else {
00480     height=offset-y;
00481   }
00482 }
00483 
00484 
00485 void CalPrintBase::drawAgendaDayBox( QPainter &p, Event::List &events,
00486                                      const QDate &qd, bool expandable,
00487                                      QTime &fromTime, QTime &toTime,
00488                                      int x, int y, int width, int height )
00489 {
00490   p.drawRect( x, y, width, height );
00491 
00492   Event *event;
00493 
00494   if ( expandable ) {
00495     // Adapt start/end times to include complete events
00496     Event::List::ConstIterator it;
00497     for ( it = events.begin(); it != events.end(); ++it ) {
00498       event = *it;
00499       if ( event->dtStart().time() < fromTime )
00500         fromTime = event->dtStart().time();
00501       if ( event->dtEnd().time() > toTime )
00502         toTime = event->dtEnd().time();
00503     }
00504   }
00505 
00506   // Show at least one hour
00507   if ( fromTime.secsTo( toTime ) < 3600 ) {
00508     fromTime = QTime( fromTime.hour(), 0, 0 );
00509     toTime = fromTime.addSecs( 3600 );
00510   }
00511 
00512   // calculate the height of a cell and of a minute
00513   int totalsecs = fromTime.secsTo( toTime );
00514   float minlen = height * 60. / totalsecs;
00515   float cellHeight = 60. * minlen;
00516   float currY = y;
00517 
00518   // print grid:
00519   QTime curTime( QTime( fromTime.hour(), 0, 0 ) );
00520   currY += fromTime.secsTo( curTime ) * minlen / 60;
00521 
00522   while ( curTime < toTime && curTime.isValid() ) {
00523     if ( currY > y ) p.drawLine( x, int( currY ), x + width, int( currY ) );
00524     currY += cellHeight / 2;
00525     if ( ( currY > y ) && ( currY < y + height ) ) {
00526       QPen oldPen( p.pen() );
00527       p.setPen( QColor( 192, 192, 192 ) );
00528       p.drawLine( x, int( currY ), x + width, int( currY ) );
00529       p.setPen( oldPen );
00530     } // enough space for half-hour line
00531     if ( curTime.secsTo( toTime ) > 3600 )
00532       curTime = curTime.addSecs( 3600 );
00533     else curTime = toTime;
00534     currY += cellHeight / 2;
00535   }
00536 
00537   QDateTime startPrintDate = QDateTime( qd, fromTime );
00538   QDateTime endPrintDate = QDateTime( qd, toTime );
00539 
00540   // Calculate horizontal positions and widths of events taking into account
00541   // overlapping events
00542 
00543   QPtrList<KOrg::CellItem> cells;
00544   cells.setAutoDelete( true );
00545 
00546   Event::List::ConstIterator itEvents;
00547   for( itEvents = events.begin(); itEvents != events.end(); ++itEvents ) {
00548     cells.append( new PrintCellItem( *itEvents, qd ) );
00549   }
00550 
00551   QPtrListIterator<KOrg::CellItem> it1( cells );
00552   for( it1.toFirst(); it1.current(); ++it1 ) {
00553     KOrg::CellItem *placeItem = it1.current();
00554 
00555     KOrg::CellItem::placeItem( cells, placeItem );
00556   }
00557 
00558   QPen oldPen( p.pen() );
00559   QColor oldBgColor( p.backgroundColor() );
00560   QBrush oldBrush( p.brush() );
00561   QFont oldFont( p.font() );
00562 
00563   p.setFont( QFont( "helvetica", 10 ) );
00564   p.setBrush( QBrush( Dense7Pattern ) );
00565 
00566   for( it1.toFirst(); it1.current(); ++it1 ) {
00567     PrintCellItem *placeItem = static_cast<PrintCellItem *>( it1.current() );
00568 
00569     drawAgendaItem( placeItem, p, qd, startPrintDate, endPrintDate, minlen, x,
00570                     y, width );
00571 
00572     p.setBrush( oldBrush );
00573     p.setPen( oldPen );
00574     p.setBackgroundColor( oldBgColor );
00575   }
00576   p.setFont( oldFont );
00577 //  p.setBrush( QBrush( NoBrush ) );
00578 }
00579 
00580 
00581 void CalPrintBase::drawAgendaItem( PrintCellItem *item, QPainter &p,
00582                                    const QDate &qd,
00583                                    const QDateTime &startPrintDate,
00584                                    const QDateTime &endPrintDate,
00585                                    float minlen, int x, int y, int width )
00586 {
00587   Event *event = item->event();
00588 
00589   // set the colors according to the categories
00590   if ( mUseColors ) setCategoryColors( p, event );
00591 
00592   // start/end of print area for event
00593   QDateTime startTime = event->dtStart();
00594   QDateTime endTime = event->dtEnd();
00595   if ( event->doesRecur() ) {
00596     startTime.setDate( qd );
00597     endTime.setDate( qd );
00598   }
00599   if ( ( startTime < endPrintDate && endTime > startPrintDate ) ||
00600        ( endTime > startPrintDate && startTime < endPrintDate ) ) {
00601     if ( startTime < startPrintDate ) startTime = startPrintDate;
00602     if ( endTime > endPrintDate ) endTime = endPrintDate;
00603     int eventLength = int( startTime.secsTo( endTime ) / 60. * minlen );
00604     int currentyPos = int( y + startPrintDate.secsTo( startTime ) *
00605                            minlen / 60. );
00606     int currentWidth = width / item->subCells();
00607     int currentX = x + item->subCell() * currentWidth;
00608 
00609     p.drawRect( currentX, currentyPos, currentWidth, eventLength );
00610     int offset = 4;
00611     // print the text vertically centered. If it doesn't fit inside the
00612     // box, align it at the top so the beginning is visible
00613     int flags = AlignLeft | WordBreak;
00614     QRect bound = p.boundingRect ( currentX + offset, currentyPos,
00615                                    currentWidth - 2 * offset, eventLength,
00616                                    flags, event->summary() );
00617     if ( bound.height() >= eventLength - 4 ) flags |= AlignTop;
00618     else flags |= AlignVCenter;
00619     p.drawText( currentX+offset, currentyPos+offset, currentWidth-2*offset,
00620                 eventLength-2*offset, flags, event->summary() );
00621   }
00622 }
00623 
00624 void CalPrintBase::drawDayBox(QPainter &p, const QDate &qd,
00625     int x, int y, int width, int height,
00626     bool fullDate)
00627 {
00628   QString dayNumStr;
00629   QString ampm;
00630   const KLocale*local = KGlobal::locale();
00631 
00632 
00633   // This has to be localized
00634   if (fullDate) {
00635     /*int index;
00636     dayNumStr= qd.toString();
00637     index = dayNumStr.find(' ');
00638     dayNumStr.remove(0, index);
00639     index = dayNumStr.findRev(' ');
00640     dayNumStr.truncate(index);*/
00641 
00642     const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
00643     dayNumStr = i18n("weekday month date", "%1 %2 %3")
00644         .arg( calSys->weekDayName( qd ) )
00645         .arg( calSys->monthName( qd ) )
00646         .arg( qd.day() );
00647 //    dayNumStr = local->formatDate(qd);
00648   } else {
00649     dayNumStr = QString::number( qd.day() );
00650   }
00651 
00652   p.eraseRect( x, y, width, height );
00653   p.drawRect( x, y, width, height );
00654   // p.fillRect( x+1, y+1, width-2,height, QBrush(Dense7Pattern) );
00655   p.drawRect( x, y, width, mSubHeaderHeight );
00656   p.fillRect( x+1, y+1, width-2, mSubHeaderHeight-2, QBrush(Dense7Pattern) );
00657   QString hstring;
00658 #ifndef KORG_NOPLUGINS
00659   hstring=KOCore::self()->holiday(qd);
00660 #endif
00661   QFont oldFont( p.font() );
00662 
00663   if (!hstring.isEmpty()) {
00664     p.setFont( QFont( "helvetica", 8, QFont::Bold, true ) );
00665 
00666     p.drawText( x+5, y, width-25, mSubHeaderHeight, AlignLeft | AlignVCenter,
00667                 hstring );
00668   }
00669   p.setFont(QFont("helvetica", 10, QFont::Bold));
00670   p.drawText(x+5, y, width-10, mSubHeaderHeight, AlignRight | AlignVCenter,
00671              dayNumStr);
00672 
00673   Event::List eventList = mCalendar->events( qd, true );
00674   QString outStr;
00675   p.setFont( QFont( "helvetica", 8 ) );
00676   int lineSpacing = p.fontMetrics().lineSpacing();
00677 
00678   int textY=mSubHeaderHeight+3; // gives the relative y-coord of the next printed entry
00679   Event::List::ConstIterator it;
00680   for( it = eventList.begin(); it != eventList.end() && textY<height; ++it ) {
00681     Event *currEvent = *it;
00682     if (currEvent->doesFloat() || currEvent->isMultiDay())
00683       outStr = currEvent->summary();
00684 
00685     else {
00686       QTime t1 = currEvent->dtStart().time();
00687 
00688       outStr = local->formatTime(t1);
00689       outStr += " " + currEvent->summary();
00690 
00691     } // doesFloat
00692 
00693     p.drawText(x+5, y+textY, width-10, lineSpacing,
00694                AlignLeft|AlignBottom, outStr);
00695     textY+=lineSpacing;
00696   }
00697 
00698   if ( textY<height ) {
00699     Todo::List todos = mCalendar->todos( qd );
00700     Todo::List::ConstIterator it2;
00701     for( it2 = todos.begin(); it2 != todos.end() && textY<height; ++it2 ) {
00702       Todo *todo = *it2;
00703       QString text;
00704       if (todo->hasDueDate()) {
00705         if (!todo->doesFloat()) {
00706           text += KGlobal::locale()->formatTime(todo->dtDue().time());
00707           text += " ";
00708         }
00709       }
00710       text += i18n("To-Do: %1").arg(todo->summary());
00711 
00712       p.drawText(x+5, y+textY, width-10, lineSpacing,
00713                 AlignLeft|AlignBottom, text);
00714       textY+=lineSpacing;
00715     }
00716   }
00717   p.setFont( oldFont );
00718 }
00719 
00720 
00722 
00723 void CalPrintBase::drawWeek(QPainter &p, const QDate &qd,
00724     int x, int y, int width, int height)
00725 {
00726   QDate weekDate = qd;
00727   bool portrait = ( mPrinter->orientation() == KPrinter::Portrait  );
00728   int cellWidth, cellHeight;
00729   int vcells;
00730   if (portrait) {
00731     cellWidth = width/2;
00732     vcells=3;
00733   } else {
00734     cellWidth = width/6;
00735     vcells=1;
00736   }
00737   cellHeight = height/vcells;
00738 
00739   // correct begin of week
00740   int weekdayCol = weekdayColumn( qd.dayOfWeek() );
00741   weekDate = qd.addDays( -weekdayCol );
00742 
00743   for (int i = 0; i < 7; i++, weekDate = weekDate.addDays(1)) {
00744     if (i<5) {
00745       drawDayBox(p, weekDate, x+cellWidth*(int)(i/vcells), y+cellHeight*(i%vcells),
00746         cellWidth, cellHeight, true);
00747     } else if (i==5) {
00748       drawDayBox(p, weekDate, x+cellWidth*(int)(i/vcells), y+cellHeight*(i%vcells),
00749         cellWidth, cellHeight/2, true);
00750     } else if (i==6) {
00751       drawDayBox(p, weekDate, x+cellWidth*(int)((i-1)/vcells),
00752         y+cellHeight*((i-1)%vcells)+cellHeight/2, cellWidth, cellHeight/2, true);
00753     }
00754   } // for i through all weekdays
00755 }
00756 
00757 
00758 void CalPrintBase::drawTimeTable(QPainter &p,
00759     const QDate &fromDate, const QDate &toDate,
00760     QTime &fromTime, QTime &toTime,
00761     int x, int y, int width, int height)
00762 {
00763   // timeline is 1.5 hours:
00764   int alldayHeight = (int)( 3600.*height/(fromTime.secsTo(toTime)+3600.) );
00765   int timelineWidth = 50;
00766   int cellWidth = (int)( (width-timelineWidth)/(fromDate.daysTo(toDate)+1) );
00767   int currY=y;
00768   int currX=x;
00769 
00770   drawDaysOfWeek( p, fromDate, toDate, x+timelineWidth, currY, width-timelineWidth, mSubHeaderHeight);
00771   currY+=mSubHeaderHeight;
00772   drawTimeLine( p, fromTime, toTime, x, currY+alldayHeight,
00773     timelineWidth, height-mSubHeaderHeight-alldayHeight );
00774 
00775   currX=x+timelineWidth;
00776   // draw each day
00777   QDate curDate(fromDate);
00778   while (curDate<=toDate) {
00779     Event::List eventList = mCalendar->events(curDate, true);
00780     drawAllDayBox( p, eventList, curDate, false, currX, currY, cellWidth, alldayHeight);
00781     drawAgendaDayBox( p, eventList, curDate, false, fromTime, toTime, currX,
00782       currY+alldayHeight, cellWidth, height-mSubHeaderHeight-alldayHeight );
00783     currX+=cellWidth;
00784     curDate=curDate.addDays(1);
00785   }
00786 
00787 }
00788 
00789 
00791 
00792 void CalPrintBase::drawMonth(QPainter &p, const QDate &qd, bool weeknumbers,
00793     int x, int y, int width, int height)
00794 {
00795   int yoffset = mSubHeaderHeight;
00796   int xoffset = 0;
00797   QDate monthDate(QDate(qd.year(), qd.month(), 1));
00798   QDate monthFirst(monthDate);
00799   QDate monthLast(monthDate.addMonths(1).addDays(-1));
00800   
00801 
00802   int weekdayCol = weekdayColumn( monthDate.dayOfWeek() );
00803   monthDate = monthDate.addDays(-weekdayCol);
00804 
00805   int rows=(weekdayCol + qd.daysInMonth() - 1)/7 +1;
00806   int cellHeight = (height-yoffset) / rows;
00807 
00808   if (weeknumbers) {
00809     QFont oldFont(p.font());
00810     QFont newFont(p.font());
00811     newFont.setPointSize(6);
00812     p.setFont(newFont);
00813     xoffset += 14;
00814     QDate weekDate(monthDate);
00815     for (int row = 0; row<rows; row++) {
00816       int calWeek = weekDate.weekNumber();
00817       QRect rc(x, y+yoffset+cellHeight*row, xoffset-1, cellHeight);
00818       p.drawText( rc, AlignRight|AlignVCenter, QString::number(calWeek) );
00819       weekDate = weekDate.addDays(7);
00820     }
00821     p.setFont(oldFont);
00822   }
00823 
00824   drawDaysOfWeek( p, monthDate, monthDate.addDays(6), x+xoffset, y, width-xoffset, mSubHeaderHeight );
00825   int cellWidth = (width-xoffset) / 7;
00826 
00827   QColor back = p.backgroundColor();
00828   bool darkbg = false;
00829   for (int row = 0; row < rows; row++) {
00830     for (int col = 0; col < 7; col++) {
00831       // show days from previous/next month with a grayed background
00832       if ( (monthDate < monthFirst) || (monthDate > monthLast) ) {
00833         p.setBackgroundColor( back.dark( 120 ) );
00834         darkbg = true;
00835       }
00836       drawDayBox(p, monthDate, x+xoffset+col*cellWidth, y+yoffset+row*cellHeight,
00837                  cellWidth, cellHeight);
00838       if ( darkbg ) {
00839         p.setBackgroundColor( back );
00840         darkbg = false;
00841       }
00842       monthDate = monthDate.addDays(1);
00843     }
00844   }
00845 }
00846 
00847 
00849 
00850 void CalPrintBase::drawTodo( int &count, Todo * item, QPainter &p, bool connectSubTodos,
00851     bool desc, int pospriority, int possummary, int posDueDt, int level,
00852     int x, int &y, int width, int pageHeight, const Todo::List &todoList,
00853     TodoParentStart *r )
00854 {
00855   QString outStr;
00856 //  int fontHeight = 10;
00857   const KLocale *local = KGlobal::locale();
00858   int priority=item->priority();
00859   int posdue=posDueDt;
00860   if (posdue<0) posdue=x+width;
00861   QRect rect;
00862   TodoParentStart startpt;
00863   // This list keeps all starting points of the parent todos so the connection
00864   // lines of the tree can easily be drawn (needed if a new page is started)
00865   static QPtrList<TodoParentStart> startPoints;
00866   if (level<1) {
00867     startPoints.clear();
00868   }
00869 
00870   // size of item
00871   outStr=item->summary();
00872   int left = possummary+(level*10);
00873   rect = p.boundingRect(left, y, (posdue-left-5),-1, WordBreak, outStr);
00874   if ( !item->description().isEmpty() && desc ) {
00875     outStr = item->description();
00876     rect = p.boundingRect( left+20, rect.bottom()+5, width-(left+10-x), -1,
00877                            WordBreak, outStr );
00878   }
00879   // if too big make new page
00880   if ( rect.bottom() > pageHeight) {
00881     // first draw the connection lines from parent todos:
00882     if (level > 0 && connectSubTodos) {
00883       TodoParentStart *rct;
00884       for ( rct = startPoints.first(); rct; rct = startPoints.next() ) {
00885         int start;
00886         int center = rct->mRect.left() + (rct->mRect.width()/2);
00887         int to = p.viewport().bottom();
00888 
00889         // draw either from start point of parent or from top of the page
00890         if (rct->mSamePage)
00891           start = rct->mRect.bottom() + 1;
00892         else
00893           start = p.viewport().top();
00894         p.moveTo( center, start );
00895         p.lineTo( center, to );
00896         rct->mSamePage=false;
00897       }
00898     }
00899     y=0;
00900     mPrinter->newPage();
00901   }
00902 
00903   // If this is a sub-item, r will not be 0, and we want the LH side of the priority line up
00904   //to the RH side of the parent item's priority
00905   bool showPriority = pospriority>=0;
00906   if (r) {
00907     pospriority = r->mRect.right() + 1;
00908   }
00909 
00910   outStr.setNum(priority);
00911   rect = p.boundingRect(pospriority, y + 10, 5, -1, AlignCenter, outStr);
00912   // Make it a more reasonable size
00913   rect.setWidth(18);
00914   rect.setHeight(18);
00915   
00916   // Priority
00917   if ( priority > 0 && showPriority ) {
00918     p.drawText(rect, AlignCenter, outStr);
00919     p.drawRect(rect);
00920     // cross out the rectangle for completed items
00921     if ( item->isCompleted() ) {
00922       p.drawLine( rect.topLeft(), rect.bottomRight() );
00923       p.drawLine( rect.topRight(), rect.bottomLeft() );
00924     }
00925   }
00926   startpt.mRect = rect; //save for later
00927 
00928   // Connect the dots
00929   if (level > 0 && connectSubTodos) {
00930     int bottom;
00931     int center( r->mRect.left() + (r->mRect.width()/2) );
00932     if (r->mSamePage )
00933       bottom = r->mRect.bottom() + 1;
00934     else
00935       bottom = 0;
00936     int to( rect.top() + (rect.height()/2) );
00937     int endx( rect.left() );
00938     p.moveTo(center, bottom);
00939     p.lineTo(center, to);
00940     p.lineTo(endx, to);
00941   }
00942 
00943   // if completed, use strike out font
00944   QFont ft( p.font() );
00945   ft.setStrikeOut( item->isCompleted() );
00946   p.setFont( ft );
00947   // summary
00948   outStr=item->summary();
00949   rect = p.boundingRect( left, rect.top(), (posdue-(left + rect.width() + 5)),
00950     -1, WordBreak, outStr);
00951   QRect newrect;
00952   p.drawText( rect, WordBreak, outStr, -1, &newrect );
00953   ft.setStrikeOut(false);
00954   p.setFont(ft);
00955 
00956   // due
00957   if ( item->hasDueDate() && posDueDt>=0 ) {
00958     outStr = local->formatDate(item->dtDue().date(),true);
00959     rect = p.boundingRect(posdue, y, x+width, -1, AlignTop|AlignLeft, outStr);
00960     p.drawText(rect, AlignTop|AlignLeft, outStr);
00961   }
00962 
00963   if ( !item->description().isEmpty() && desc ) {
00964     y=newrect.bottom() + 5;
00965     outStr = item->description();
00966     rect = p.boundingRect( left+20, y, x+width-(left+10), -1,
00967                            WordBreak, outStr );
00968     p.drawText( rect, WordBreak, outStr, -1, &newrect );
00969   }
00970 
00971   // Set the new line position
00972   y=newrect.bottom() + 10; //set the line position
00973 
00974   // If the item has subitems, we need to call ourselves recursively
00975   Incidence::List l = item->relations();
00976   Incidence::List::ConstIterator it;
00977   startPoints.append( &startpt );
00978   for( it = l.begin(); it != l.end(); ++it ) {
00979     count++;
00980     // In the future, todos might also be related to events
00981     // Manually check if the subtodo is in the list of todos to print
00982     // The problem is that relations() does not apply filters, so
00983     // we need to compare manually with the complete filtered list!
00984     Todo* subtodo = dynamic_cast<Todo *>( *it );
00985     if (subtodo && todoList.contains( subtodo ) ) {
00986       drawTodo( count, subtodo, p, connectSubTodos,
00987           desc, pospriority, possummary, posDueDt, level+1,
00988           x, y, width, pageHeight, todoList, &startpt);
00989     }
00990   }
00991   startPoints.remove(&startpt);
00992 }
00993 
00994 int CalPrintBase::weekdayColumn( int weekday )
00995 {
00996   return ( weekday + 7 - KGlobal::locale()->weekStartDay() ) % 7;
00997 }
00998 
00999 void CalPrintBase::drawSplitHeaderRight( QPainter &p, const QDate &fd,
01000                                          const QDate &td,
01001                                          const QDate &,
01002                                          int width, int )
01003 {
01004   QFont oldFont( p.font() );
01005   
01006   QPen oldPen( p.pen() );
01007   QPen pen( black,4);
01008   
01009   QString title;
01010   const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
01011   if ( fd.month() == td.month() ) {
01012     title = i18n("Date range: Month dayStart - dayEnd", "%1 %2 - %3")
01013       .arg( calSys->monthName( fd.month(), false ) )
01014       .arg( calSys->dayString( fd, false ) )
01015       .arg( calSys->dayString( td, false ) );
01016   } else {
01017     title = i18n("Date range: monthStart dayStart - monthEnd dayEnd", "%1 %2 - %3 %4")
01018       .arg( calSys->monthName( fd.month(), false ) )
01019       .arg( calSys->dayString( fd, false ) )
01020       .arg( calSys->monthName( td.month(), false ) )
01021       .arg( calSys->dayString( td, false ) );
01022   }
01023 
01024   QFont serifFont("Times", 30);
01025   p.setFont(serifFont);
01026 
01027   int lineSpacing = p.fontMetrics().lineSpacing();
01028   p.drawText(0, lineSpacing * 0, width, lineSpacing, AlignRight | AlignTop, title );
01029 
01030   title.truncate(0);
01031 
01032   p.setPen( pen );
01033   p.drawLine(300, lineSpacing * 1, width, lineSpacing * 1);
01034   p.setPen( oldPen );
01035 
01036   p.setFont(QFont("Times", 20, QFont::Bold, TRUE));
01037   int newlineSpacing = p.fontMetrics().lineSpacing();
01038   title += QString::number(fd.year());
01039   p.drawText( 0, lineSpacing * 1 + 4, width, newlineSpacing, AlignRight | AlignTop, title );
01040   
01041   p.setFont( oldFont );
01042 }
01043 
01044 #endif
KDE Logo
This file is part of the documentation for korganizer Library Version 3.3.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Mon Apr 4 04:49:26 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003