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 Wed Jul 28 23:58:12 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003