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.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Oct 21 19:46:55 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003