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 font("helvetica", 18, QFont::Bold);
00247   p.setFont(font);
00248   QRect textRect( x+5, y+5, right-10-x, height-10 );
00249   p.drawText( textRect, Qt::AlignLeft | Qt::AlignTop | Qt::WordBreak, title );
00250 }
00251 
00252 
00253 void CalPrintBase::drawSmallMonth(QPainter &p, const QDate &qd,
00254     int x, int y, int width, int height)
00255 {
00256   bool firstCol = true;
00257   QDate monthDate(QDate(qd.year(), qd.month(), 1));
00258   QDate monthDate2;
00259   int month = monthDate.month();
00260 
00261   // draw the title
00262   p.setFont(QFont("helvetica", 8, QFont::Bold));
00263   //  int lineSpacing = p.fontMetrics().lineSpacing();
00264   const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
00265   p.drawText(x, y, width, height/4, AlignCenter, calSys->monthName( qd ) );
00266 
00267   int cellWidth = width/7;
00268   int cellHeight = height/8;
00269   QString tmpStr;
00270 
00271   // correct begin of week
00272   int weekdayCol = weekdayColumn( qd.dayOfWeek() );
00273   monthDate2 = monthDate.addDays(-weekdayCol);
00274 
00275   // draw days of week
00276    p.setFont(QFont("helvetica", 8, QFont::Bold));
00277   for (int col = 0; col < 7; col++) {
00278     // tmpStr.sprintf("%c",(const char*)monthDate2.dayName(monthDate2.dayOfWeek()));
00279     tmpStr=calSys->weekDayName( monthDate2 )[0].upper();
00280     p.drawText(x+col*cellWidth, y+height/4, cellWidth, cellHeight,
00281                AlignCenter, tmpStr);
00282     monthDate2 = monthDate2.addDays(1);
00283   }
00284 
00285   // draw separator line
00286   p.drawLine(x, y+height/4+cellHeight, x+width, y+height/4+cellHeight);
00287 
00288   for (int row = 0; row < 5; row++) {
00289     for (int col = 0; col < 7; col++) {
00290       if (monthDate.month() != month)
00291         break;
00292       if (firstCol) {
00293         firstCol = true;
00294         col = weekdayColumn( monthDate.dayOfWeek() );
00295       }
00296       p.drawText( x+col*cellWidth,
00297                   y+height/4+cellHeight+(row*cellHeight),
00298                   cellWidth, cellHeight, AlignCenter,
00299                   tmpStr.setNum(monthDate.day()) );
00300       monthDate = monthDate.addDays(1);
00301     }
00302   }
00303 }
00304 
00305 
00307 
00308 /*
00309  * This routine draws a header box over the main part of the calendar
00310  * containing the days of the week.
00311  */
00312 void CalPrintBase::drawDaysOfWeek(QPainter &p,
00313     const QDate &fromDate, const QDate &toDate,
00314     int x, int y, int width, int height)
00315 {
00316   int cellWidth = width/(fromDate.daysTo( toDate )+1);
00317   int currx=x;
00318   QDate cellDate(fromDate);
00319 
00320   while (cellDate<=toDate) {
00321     drawDaysOfWeekBox(p, cellDate, currx, y, cellWidth, height);
00322     currx+=cellWidth;
00323     cellDate = cellDate.addDays(1);
00324   }
00325 }
00326 
00327 
00328 void CalPrintBase::drawDaysOfWeekBox(QPainter &p, const QDate &qd,
00329     int x, int y, int width, int height)
00330 {
00331   const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
00332 
00333   p.setFont( QFont( "helvetica", 10, QFont::Bold ) );
00334   p.drawRect( x, y, width, height );
00335   p.fillRect( x+1, y+1,
00336               width-2, height-2,
00337               QBrush( Dense7Pattern ) );
00338   p.drawText( x+5, y, width-10, height, AlignCenter | AlignVCenter,
00339              calSys->weekDayName( qd ) );
00340 }
00341 
00342 
00343 void CalPrintBase::drawTimeLine(QPainter &p,
00344     const QTime &fromTime, const QTime &toTime,
00345     int x, int y, int width, int height)
00346 {
00347   p.drawRect(x, y, width, height);
00348 
00349   int totalsecs=fromTime.secsTo(toTime);
00350   float minlen=(float)height*60./(float)totalsecs;
00351   float cellHeight=(60.*(float)minlen);
00352   float currY=y;
00353 
00354   QTime curTime( fromTime );
00355   QTime endTime( toTime );
00356   if ( fromTime.minute() > 30 )
00357     curTime = QTime( fromTime.hour()+1, 0, 0 );
00358   else if ( fromTime.minute() > 0 ) {
00359     curTime = QTime( fromTime.hour(), 30, 0 );
00360     float yy = currY + minlen*(float)fromTime.secsTo( curTime )/60.;
00361     p.drawLine( x+width/2, (int)yy, x+width, (int)yy );
00362     curTime = QTime( fromTime.hour()+1, 0, 0 );
00363   }
00364   currY += ( fromTime.secsTo(curTime)*minlen/60 );
00365 
00366   while ( curTime < endTime ) {
00367     p.drawLine( x, (int)currY, x+width, (int)currY );
00368     int newY=(int)(currY+cellHeight/2.);
00369     QString numStr;
00370     if (newY < y+height) {
00371       p.drawLine(x+width/2, (int)newY, x+width, (int)newY);
00372       // draw the time:
00373       if ( !KGlobal::locale()->use12Clock() ) {
00374         numStr.setNum(curTime.hour());
00375         if (cellHeight > 30) {
00376           p.setFont(QFont("helvetica", 16, QFont::Bold));
00377         } else {
00378           p.setFont(QFont("helvetica", 12, QFont::Bold));
00379         }
00380         p.drawText(x+2, (int)currY+2, width/2-2, (int)cellHeight,
00381                   AlignTop|AlignRight, numStr);
00382         p.setFont(QFont("helvetica", 10, QFont::Normal));
00383         p.drawText(x+width/2, (int)currY+2, width/2+2, (int)(cellHeight/2)-3,
00384                   AlignTop | AlignLeft, "00");
00385       } else {
00386         QTime time( curTime.hour(), 0 );
00387         numStr = KGlobal::locale()->formatTime( time );
00388         p.setFont(QFont("helvetica", 14, QFont::Bold));
00389         p.drawText(x+2, (int)currY+2, width-4, (int)cellHeight/2-3,
00390                   AlignTop|AlignLeft, numStr);
00391       }
00392       currY+=cellHeight;
00393     } // enough space for half-hour line and time
00394     if (curTime.secsTo(endTime)>3600)
00395       curTime=curTime.addSecs(3600);
00396     else curTime=endTime;
00397   } // currTime<endTime
00398 }
00399 
00400 
00402 
00408 void CalPrintBase::drawAllDayBox(QPainter &p, Event::List &eventList,
00409     const QDate &qd, bool expandable,
00410     int x, int y, int width, int &height)
00411 {
00412   Event::List::Iterator it, itold;
00413 
00414   int offset=y;
00415 
00416   p.setBrush(QBrush(Dense7Pattern));
00417   QPen oldPen(p.pen());
00418   QColor oldBgColor(p.backgroundColor());
00419   QBrush oldBrush(p.brush());
00420   QString multiDayStr;
00421 
00422   it = eventList.begin();
00423 #ifndef KORG_NOPLUGINS
00424   QString hstring(KOCore::self()->holiday(qd));
00425   if (!hstring.isEmpty()) {
00426     Event*holiday=new Event();
00427     holiday->setDtStart(qd);
00428     holiday->setDtEnd(qd);
00429     holiday->setFloats(true);
00430     holiday->setCategories(i18n("Holiday"));
00431     eventList.prepend(holiday);
00432   }
00433 #endif
00434   Event *currEvent = 0;
00435   // First, print all floating events
00436   while( it!=eventList.end() ) {
00437     currEvent=*it;
00438     itold=it;
00439     ++it;
00440     if ( currEvent->doesFloat() ) {
00441       // set the colors according to the categories
00442       if (expandable) {
00443         if (mUseColors)
00444           setCategoryColors(p, currEvent);
00445 
00446         p.drawRect( x, offset, width, height );
00447         p.drawText( x+5, offset+5, width-10, height-10, 
00448                     AlignCenter | AlignVCenter | AlignJustify | WordBreak,
00449                     currEvent->summary() );
00450         // reset the colors
00451         p.setBrush( oldBrush );
00452         p.setPen( oldPen );
00453         p.setBackgroundColor(oldBgColor);
00454 
00455         offset += height;
00456       } else {
00457         if (!multiDayStr.isEmpty()) multiDayStr+=", ";
00458         multiDayStr += currEvent->summary()+"\n";
00459       }
00460       eventList.remove( itold );
00461     }
00462   }
00463 
00464   if (!expandable) {
00465     p.drawRect(x, offset, width, height);
00466     if (!multiDayStr.isEmpty()) {
00467       p.fillRect(x+1, offset+1, width-2, height-2, QBrush(Dense5Pattern) );
00468       p.drawText( x+5, offset+5, width-10, height-10, 
00469                   AlignCenter | AlignVCenter | AlignJustify | WordBreak, 
00470                   multiDayStr);
00471     }
00472   } else {
00473     height=offset-y;
00474   }
00475 }
00476 
00477 
00478 void CalPrintBase::drawAgendaDayBox( QPainter &p, Event::List &events,
00479                                      const QDate &qd, bool expandable,
00480                                      QTime &fromTime, QTime &toTime,
00481                                      int x, int y, int width, int height )
00482 {
00483   p.drawRect( x, y, width, height );
00484 
00485   Event *event;
00486 
00487   if ( expandable ) {
00488     // Adapt start/end times to include complete events
00489     Event::List::ConstIterator it;
00490     for ( it = events.begin(); it != events.end(); ++it ) {
00491       event = *it;
00492       if ( event->dtStart().time() < fromTime )
00493         fromTime = event->dtStart().time();
00494       if ( event->dtEnd().time() > toTime )
00495         toTime = event->dtEnd().time();
00496     }
00497   }
00498 
00499   // Show at least one hour
00500   if ( fromTime.secsTo( toTime ) < 3600 ) {
00501     fromTime = QTime( fromTime.hour(), 0, 0 );
00502     toTime = fromTime.addSecs( 3600 );
00503   }
00504 
00505   // calculate the height of a cell and of a minute
00506   int totalsecs = fromTime.secsTo( toTime );
00507   float minlen = height * 60. / totalsecs;
00508   float cellHeight = 60. * minlen;
00509   float currY = y;
00510 
00511   // print grid:
00512   QTime curTime( QTime( fromTime.hour(), 0, 0 ) );
00513   currY += fromTime.secsTo( curTime ) * minlen / 60;
00514 
00515   while ( curTime < toTime && curTime.isValid() ) {
00516     if ( currY > y ) p.drawLine( x, int( currY ), x + width, int( currY ) );
00517     currY += cellHeight / 2;
00518     if ( ( currY > y ) && ( currY < y + height ) ) {
00519       QPen oldPen( p.pen() );
00520       p.setPen( QColor( 192, 192, 192 ) );
00521       p.drawLine( x, int( currY ), x + width, int( currY ) );
00522       p.setPen( oldPen );
00523     } // enough space for half-hour line
00524     if ( curTime.secsTo( toTime ) > 3600 )
00525       curTime = curTime.addSecs( 3600 );
00526     else curTime = toTime;
00527     currY += cellHeight / 2;
00528   }
00529 
00530   QDateTime startPrintDate = QDateTime( qd, fromTime );
00531   QDateTime endPrintDate = QDateTime( qd, toTime );
00532 
00533   // Calculate horizontal positions and widths of events taking into account
00534   // overlapping events
00535 
00536   QPtrList<KOrg::CellItem> cells;
00537   cells.setAutoDelete( true );
00538 
00539   Event::List::ConstIterator itEvents;
00540   for( itEvents = events.begin(); itEvents != events.end(); ++itEvents ) {
00541     cells.append( new PrintCellItem( *itEvents, qd ) );
00542   }
00543 
00544   QPtrListIterator<KOrg::CellItem> it1( cells );
00545   for( it1.toFirst(); it1.current(); ++it1 ) {
00546     KOrg::CellItem *placeItem = it1.current();
00547 
00548     KOrg::CellItem::placeItem( cells, placeItem );
00549   }
00550 
00551   QPen oldPen = p.pen();
00552   QColor oldBgColor = p.backgroundColor();
00553   QBrush oldBrush = p.brush();
00554 
00555   p.setFont( QFont( "helvetica", 10 ) );
00556   p.setBrush( QBrush( Dense7Pattern ) );
00557 
00558   for( it1.toFirst(); it1.current(); ++it1 ) {
00559     PrintCellItem *placeItem = static_cast<PrintCellItem *>( it1.current() );
00560 
00561     drawAgendaItem( placeItem, p, qd, startPrintDate, endPrintDate, minlen, x,
00562                     y, width );
00563 
00564     p.setBrush( oldBrush );
00565     p.setPen( oldPen );
00566     p.setBackgroundColor( oldBgColor );
00567   }
00568   
00569   p.setBrush( QBrush( NoBrush ) );
00570 }
00571 
00572 
00573 void CalPrintBase::drawAgendaItem( PrintCellItem *item, QPainter &p,
00574                                    const QDate &qd,
00575                                    const QDateTime &startPrintDate,
00576                                    const QDateTime &endPrintDate,
00577                                    float minlen, int x, int y, int width )
00578 {
00579   Event *event = item->event();
00580 
00581   // set the colors according to the categories
00582   if ( mUseColors ) setCategoryColors( p, event );
00583 
00584   // start/end of print area for event
00585   QDateTime startTime = event->dtStart();
00586   QDateTime endTime = event->dtEnd();
00587   if ( event->doesRecur() ) {
00588     startTime.setDate( qd );
00589     endTime.setDate( qd );
00590   }
00591   if ( ( startTime < endPrintDate && endTime > startPrintDate ) ||
00592        ( endTime > startPrintDate && startTime < endPrintDate ) ) {
00593     if ( startTime < startPrintDate ) startTime = startPrintDate;
00594     if ( endTime > endPrintDate ) endTime = endPrintDate;
00595     int eventLength = int( startTime.secsTo( endTime ) / 60. * minlen );
00596     int currentyPos = int( y + startPrintDate.secsTo( startTime ) *
00597                            minlen / 60. );
00598     int currentWidth = width / item->subCells();
00599     int currentX = x + item->subCell() * currentWidth;
00600 
00601     p.drawRect( currentX, currentyPos, currentWidth, eventLength );
00602     p.drawText( currentX, currentyPos, currentWidth, eventLength,
00603                 AlignCenter | AlignVCenter | AlignJustify | WordBreak,
00604                 event->summary() );
00605   }
00606 }
00607 
00608 void CalPrintBase::drawDayBox(QPainter &p, const QDate &qd,
00609     int x, int y, int width, int height,
00610     bool fullDate)
00611 {
00612   QString dayNumStr;
00613   QString ampm;
00614   const KLocale*local = KGlobal::locale();
00615 
00616 
00617   // This has to be localized
00618   if (fullDate) {
00619     /*int index;
00620     dayNumStr= qd.toString();
00621     index = dayNumStr.find(' ');
00622     dayNumStr.remove(0, index);
00623     index = dayNumStr.findRev(' ');
00624     dayNumStr.truncate(index);*/
00625 
00626     const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
00627     dayNumStr = i18n("weekday month date", "%1 %2 %3")
00628         .arg( calSys->weekDayName( qd ) )
00629         .arg( calSys->monthName( qd ) )
00630         .arg( qd.day() );
00631 //    dayNumStr = local->formatDate(qd);
00632   } else {
00633     dayNumStr = QString::number( qd.day() );
00634   }
00635 
00636   p.drawRect( x, y, width, height );
00637   // p.fillRect( x+1, y+1, width-2,height, QBrush(Dense7Pattern) );
00638   p.drawRect( x, y, width, mSubHeaderHeight );
00639   p.fillRect( x+1, y+1, width-2, mSubHeaderHeight-2, QBrush(Dense7Pattern) );
00640   QString hstring;
00641 #ifndef KORG_NOPLUGINS
00642   hstring=KOCore::self()->holiday(qd);
00643 #endif
00644 
00645   if (!hstring.isEmpty()) {
00646     p.setFont( QFont( "helvetica", 8, QFont::Bold, true ) );
00647 
00648     p.drawText( x+5, y, width-25, mSubHeaderHeight, AlignLeft | AlignVCenter,
00649                 hstring );
00650   }
00651   p.setFont(QFont("helvetica", 10, QFont::Bold));
00652   p.drawText(x+5, y, width-10, mSubHeaderHeight, AlignRight | AlignVCenter,
00653              dayNumStr);
00654 
00655   Event::List eventList = mCalendar->events( qd, true );
00656   QString outStr;
00657   p.setFont( QFont( "helvetica", 8 ) );
00658   int lineSpacing = p.fontMetrics().lineSpacing();
00659 
00660   int textY=mSubHeaderHeight+3; // gives the relative y-coord of the next printed entry
00661   Event::List::ConstIterator it;
00662   for( it = eventList.begin(); it != eventList.end() && textY<height; ++it ) {
00663     Event *currEvent = *it;
00664     if (currEvent->doesFloat() || currEvent->isMultiDay())
00665       outStr = currEvent->summary();
00666 
00667     else {
00668       QTime t1 = currEvent->dtStart().time();
00669 
00670       outStr = local->formatTime(t1);
00671       outStr += " " + currEvent->summary();
00672 
00673     } // doesFloat
00674 
00675     p.drawText(x+5, y+textY, width-10, lineSpacing,
00676                AlignLeft|AlignBottom, outStr);
00677     textY+=lineSpacing;
00678   }
00679 
00680   if ( textY<height ) {
00681     Todo::List todos = mCalendar->todos( qd );
00682     Todo::List::ConstIterator it2;
00683     for( it2 = todos.begin(); it2 != todos.end() && textY<height; ++it2 ) {
00684       Todo *todo = *it2;
00685       QString text;
00686       if (todo->hasDueDate()) {
00687         if (!todo->doesFloat()) {
00688           text += KGlobal::locale()->formatTime(todo->dtDue().time());
00689           text += " ";
00690         }
00691       }
00692       text += i18n("To-Do: %1").arg(todo->summary());
00693 
00694       p.drawText(x+5, y+textY, width-10, lineSpacing,
00695                 AlignLeft|AlignBottom, text);
00696       textY+=lineSpacing;
00697     }
00698   }
00699 }
00700 
00701 
00703 
00704 void CalPrintBase::drawWeek(QPainter &p, const QDate &qd,
00705     int x, int y, int width, int height)
00706 {
00707   QDate weekDate = qd;
00708   bool portrait = ( mPrinter->orientation() == KPrinter::Portrait  );
00709   int cellWidth, cellHeight;
00710   int vcells;
00711   if (portrait) {
00712     cellWidth = width/2;
00713     vcells=3;
00714   } else {
00715     cellWidth = width/6;
00716     vcells=1;
00717   }
00718   cellHeight = height/vcells;
00719 
00720   // correct begin of week
00721   int weekdayCol = weekdayColumn( qd.dayOfWeek() );
00722   weekDate = qd.addDays( -weekdayCol );
00723 
00724   for (int i = 0; i < 7; i++, weekDate = weekDate.addDays(1)) {
00725     if (i<5) {
00726       drawDayBox(p, weekDate, x+cellWidth*(int)(i/vcells), y+cellHeight*(i%vcells),
00727         cellWidth, cellHeight, true);
00728     } else if (i==5) {
00729       drawDayBox(p, weekDate, x+cellWidth*(int)(i/vcells), y+cellHeight*(i%vcells),
00730         cellWidth, cellHeight/2, true);
00731     } else if (i==6) {
00732       drawDayBox(p, weekDate, x+cellWidth*(int)((i-1)/vcells),
00733         y+cellHeight*((i-1)%vcells)+cellHeight/2, cellWidth, cellHeight/2, true);
00734     }
00735   } // for i through all weekdays
00736 }
00737 
00738 
00739 void CalPrintBase::drawTimeTable(QPainter &p,
00740     const QDate &fromDate, const QDate &toDate,
00741     QTime &fromTime, QTime &toTime,
00742     int x, int y, int width, int height)
00743 {
00744   // timeline is 1.5 hours:
00745   int alldayHeight = (int)( 3600.*height/(fromTime.secsTo(toTime)+3600.) );
00746   int timelineWidth = 50;
00747   int cellWidth = (int)( (width-timelineWidth)/(fromDate.daysTo(toDate)+1) );
00748   int currY=y;
00749   int currX=x;
00750 
00751   drawDaysOfWeek( p, fromDate, toDate, x+timelineWidth, currY, width-timelineWidth, mSubHeaderHeight);
00752   currY+=mSubHeaderHeight;
00753   drawTimeLine( p, fromTime, toTime, x, currY+alldayHeight,
00754     timelineWidth, height-mSubHeaderHeight-alldayHeight );
00755 
00756   currX=x+timelineWidth;
00757   // draw each day
00758   QDate curDate(fromDate);
00759   while (curDate<=toDate) {
00760     Event::List eventList = mCalendar->events(curDate, true);
00761     drawAllDayBox( p, eventList, curDate, false, currX, currY, cellWidth, alldayHeight);
00762     drawAgendaDayBox( p, eventList, curDate, false, fromTime, toTime, currX,
00763       currY+alldayHeight, cellWidth, height-mSubHeaderHeight-alldayHeight );
00764     currX+=cellWidth;
00765     curDate=curDate.addDays(1);
00766   }
00767 
00768 }
00769 
00770 
00772 
00773 void CalPrintBase::drawMonth(QPainter &p, const QDate &qd, bool weeknumbers,
00774     int x, int y, int width, int height)
00775 {
00776   int yoffset = mSubHeaderHeight;
00777   int xoffset = 0;
00778   QDate monthDate(QDate(qd.year(), qd.month(), 1));
00779 
00780   int weekdayCol = weekdayColumn( monthDate.dayOfWeek() );
00781   monthDate = monthDate.addDays(-weekdayCol);
00782 
00783   int rows=(weekdayCol + qd.daysInMonth() - 1)/7 +1;
00784   int cellHeight = (height-yoffset) / rows;
00785 
00786   if (weeknumbers) {
00787     QFont oldFont(p.font());
00788     QFont newFont(p.font());
00789     newFont.setPointSize(6);
00790     p.setFont(newFont);
00791     xoffset += 14;
00792     QDate weekDate(monthDate);
00793     for (int row = 0; row<rows; row++) {
00794       int calWeek = weekDate.weekNumber();
00795       QRect rc(x, y+yoffset+cellHeight*row, xoffset-1, cellHeight);
00796       p.drawText( rc, AlignRight|AlignVCenter, QString::number(calWeek) );
00797       weekDate = weekDate.addDays(7);
00798     }
00799     p.setFont(oldFont);
00800   }
00801 
00802   drawDaysOfWeek( p, monthDate, monthDate.addDays(6), x+xoffset, y, width-xoffset, mSubHeaderHeight );
00803   int cellWidth = (width-xoffset) / 7;
00804 
00805   for (int row = 0; row < rows; row++) {
00806     for (int col = 0; col < 7; col++) {
00807       drawDayBox(p, monthDate, x+xoffset+col*cellWidth, y+yoffset+row*cellHeight,
00808                  cellWidth, cellHeight);
00809       monthDate = monthDate.addDays(1);
00810     }
00811   }
00812 }
00813 
00814 
00816 
00817 void CalPrintBase::drawTodo( int &count, Todo * item, QPainter &p, bool connectSubTodos,
00818     bool desc, int pospriority, int possummary, int posDueDt, int level,
00819     int x, int &y, int width, int &height, int pageHeight,
00820     TodoParentStart *r )
00821 {
00822   QString outStr;
00823 //  int fontHeight = 10;
00824   const KLocale *local = KGlobal::locale();
00825   int priority=item->priority();
00826   int posdue=posDueDt;
00827   if (posdue<0) posdue=x+width;
00828   QRect rect;
00829   TodoParentStart startpt;
00830   // This list keeps all starting points of the parent todos so the connection
00831   // lines of the tree can easily be drawn (needed if a new page is started)
00832   static QPtrList<TodoParentStart> startPoints;
00833   if (level<1) {
00834     startPoints.clear();
00835   }
00836 
00837   // size of item
00838   outStr=item->summary();
00839   int left = possummary+(level*10);
00840   rect = p.boundingRect(left, y, (posdue-left-5),-1, WordBreak, outStr);
00841   if ( !item->description().isEmpty() && !desc ) {
00842     outStr = item->description();
00843     rect = p.boundingRect( left+20, rect.bottom()+5, width-(left+10-x), -1,
00844                            WordBreak, outStr );
00845   }
00846   // if too big make new page
00847   if ( rect.bottom() > y+height) {
00848     // first draw the connection lines from parent todos:
00849     if (level > 0 && connectSubTodos) {
00850       TodoParentStart *rct;
00851       for ( rct = startPoints.first(); rct; rct = startPoints.next() ) {
00852         int start;
00853         int center = rct->mRect.left() + (rct->mRect.width()/2);
00854         int to = p.viewport().bottom();
00855 
00856         // draw either from start point of parent or from top of the page
00857         if (rct->mSamePage)
00858           start = rct->mRect.bottom() + 1;
00859         else
00860           start = p.viewport().top();
00861         p.moveTo( center, start );
00862         p.lineTo( center, to );
00863         rct->mSamePage=false;
00864       }
00865     }
00866     y=0;
00867     height=pageHeight-y;
00868     mPrinter->newPage();
00869   }
00870 
00871   // If this is a sub-item, r will not be 0, and we want the LH side of the priority line up
00872   //to the RH side of the parent item's priority
00873   if (r) {
00874     pospriority = r->mRect.right() + 1;
00875   }
00876 
00877   // Priority
00878   outStr.setNum(priority);
00879   rect = p.boundingRect(pospriority, y + 10, 5, -1, AlignCenter, outStr);
00880   // Make it a more reasonable size
00881   rect.setWidth(18);
00882   rect.setHeight(18);
00883   if ( priority > 0 && pospriority>=0 ) {
00884     p.drawText(rect, AlignCenter, outStr);
00885     p.drawRect(rect);
00886     // cross out the rectangle for completed items
00887     if ( item->isCompleted() ) {
00888       p.drawLine( rect.topLeft(), rect.bottomRight() );
00889       p.drawLine( rect.topRight(), rect.bottomLeft() );
00890     }
00891     }
00892   startpt.mRect = rect; //save for later
00893 
00894   // Connect the dots
00895   if (level > 0 && connectSubTodos) {
00896     int bottom;
00897     int center( r->mRect.left() + (r->mRect.width()/2) );
00898     if (r->mSamePage )
00899       bottom = r->mRect.bottom() + 1;
00900     else
00901       bottom = 0;
00902     int to( rect.top() + (rect.height()/2) );
00903     int endx( rect.left() );
00904     p.moveTo(center, bottom);
00905     p.lineTo(center, to);
00906     p.lineTo(endx, to);
00907   }
00908 
00909   // if completed, use strike out font
00910   QFont ft=p.font();
00911   ft.setStrikeOut( item->isCompleted() );
00912   p.setFont( ft );
00913   // summary
00914   outStr=item->summary();
00915   rect = p.boundingRect( left, rect.top(), (posdue-(left + rect.width() + 5)),
00916     -1, WordBreak, outStr);
00917   QRect newrect;
00918   p.drawText( rect, WordBreak, outStr, -1, &newrect );
00919   ft.setStrikeOut(false);
00920   p.setFont(ft);
00921 
00922   // due
00923   if ( item->hasDueDate() && posDueDt>=0 ) {
00924     outStr = local->formatDate(item->dtDue().date(),true);
00925     rect = p.boundingRect(posdue, y, x+width, -1, AlignTop|AlignLeft, outStr);
00926     p.drawText(rect, AlignTop|AlignLeft, outStr);
00927   }
00928 
00929   if ( !item->description().isEmpty() && desc ) {
00930     y=newrect.bottom() + 5;
00931     outStr = item->description();
00932     rect = p.boundingRect( left+20, y, x+width-(left+10), -1,
00933                            WordBreak, outStr );
00934     p.drawText( rect, WordBreak, outStr, -1, &newrect );
00935   }
00936 
00937   // Set the new line position
00938   y=newrect.bottom() + 10; //set the line position
00939 
00940   // If the item has subitems, we need to call ourselves recursively
00941   Incidence::List l = item->relations();
00942   Incidence::List::ConstIterator it;
00943   startPoints.append( &startpt );
00944   for( it = l.begin(); it != l.end(); ++it ) {
00945     count++;
00946     drawTodo( count, static_cast<Todo *>( *it ), p, connectSubTodos,
00947         desc, pospriority, possummary, posDueDt, level+1,
00948         x, y, width, height, pageHeight, &startpt);
00949   }
00950   startPoints.remove(&startpt);
00951 }
00952 
00953 int CalPrintBase::weekdayColumn( int weekday )
00954 {
00955   return ( weekday + 7 - KGlobal::locale()->weekStartDay() ) % 7;
00956 }
00957 
00958 #endif
KDE Logo
This file is part of the documentation for korganizer Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat May 1 11:38:26 2004 by doxygen 1.2.15 written by Dimitri van Heesch, © 1997-2003