calprintdefaultplugins.cpp
00001 /* 00002 This file is part of KOrganizer. 00003 00004 Copyright (c) 1998 Preston Brown <pbrown@kde.org> 00005 Copyright (c) 2003 Reinhold Kainhofer <reinhold@kainhofer.com> 00006 Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org> 00007 Copyright (c) 2008 Ron Goodheart <ron.goodheart@gmail.com> 00008 00009 This program is free software; you can redistribute it and/or modify 00010 it under the terms of the GNU General Public License as published by 00011 the Free Software Foundation; either version 2 of the License, or 00012 (at your option) any later version. 00013 00014 This program is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 GNU General Public License for more details. 00018 00019 You should have received a copy of the GNU General Public License 00020 along with this program; if not, write to the Free Software 00021 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00022 00023 As a special exception, permission is given to link this program 00024 with any edition of TQt, and distribute the resulting executable, 00025 without including the source code for TQt in the source distribution. 00026 */ 00027 00028 #ifndef KORG_NOPRINTER 00029 00030 #include <tqpainter.h> 00031 #include <tqdatetimeedit.h> 00032 #include <tqcheckbox.h> 00033 #include <tqlineedit.h> 00034 #include <tqbuttongroup.h> 00035 00036 #include <kdebug.h> 00037 #include <tdeconfig.h> 00038 #include <kcalendarsystem.h> 00039 #include <knuminput.h> 00040 #include <kcombobox.h> 00041 00042 #include <libkcal/incidenceformatter.h> 00043 00044 #include "calprintdefaultplugins.h" 00045 00046 #include "calprintincidenceconfig_base.h" 00047 #include "calprintdayconfig_base.h" 00048 #include "calprintweetdeconfig_base.h" 00049 #include "calprintmonthconfig_base.h" 00050 #include "calprinttodoconfig_base.h" 00051 00052 static TQString cleanString( const TQString &instr ) 00053 { 00054 TQString ret = instr; 00055 return ret.replace( '\n', ' ' ); 00056 } 00057 00058 /************************************************************** 00059 * Print Incidence 00060 **************************************************************/ 00061 00062 CalPrintIncidence::CalPrintIncidence() : CalPrintPluginBase() 00063 { 00064 } 00065 00066 CalPrintIncidence::~CalPrintIncidence() 00067 { 00068 } 00069 00070 TQWidget *CalPrintIncidence::createConfigWidget( TQWidget *w ) 00071 { 00072 return new CalPrintIncidenceConfig_Base( w ); 00073 } 00074 00075 void CalPrintIncidence::readSettingsWidget() 00076 { 00077 CalPrintIncidenceConfig_Base *cfg = 00078 dynamic_cast<CalPrintIncidenceConfig_Base*>( mConfigWidget ); 00079 if ( cfg ) { 00080 mUseColors = cfg->mColors->isChecked(); 00081 mShowOptions = cfg->mShowDetails->isChecked(); 00082 mShowSubitemsNotes = cfg->mShowSubitemsNotes->isChecked(); 00083 mShowAttendees = cfg->mShowAttendees->isChecked(); 00084 mShowAttachments = cfg->mShowAttachments->isChecked(); 00085 } 00086 } 00087 00088 void CalPrintIncidence::setSettingsWidget() 00089 { 00090 CalPrintIncidenceConfig_Base *cfg = 00091 dynamic_cast<CalPrintIncidenceConfig_Base*>( mConfigWidget ); 00092 if ( cfg ) { 00093 cfg->mColors->setChecked( mUseColors ); 00094 cfg->mShowDetails->setChecked(mShowOptions); 00095 cfg->mShowSubitemsNotes->setChecked(mShowSubitemsNotes); 00096 cfg->mShowAttendees->setChecked(mShowAttendees); 00097 cfg->mShowAttachments->setChecked(mShowAttachments); 00098 } 00099 } 00100 00101 void CalPrintIncidence::loadConfig() 00102 { 00103 if ( mConfig ) { 00104 mUseColors = mConfig->readBoolEntry( "Use Colors", false ); 00105 mShowOptions = mConfig->readBoolEntry( "Show Options", false ); 00106 mShowSubitemsNotes = mConfig->readBoolEntry( "Show Subitems and Notes", false ); 00107 mShowAttendees = mConfig->readBoolEntry( "Use Attendees", false ); 00108 mShowAttachments = mConfig->readBoolEntry( "Use Attachments", false ); 00109 } 00110 setSettingsWidget(); 00111 } 00112 00113 void CalPrintIncidence::saveConfig() 00114 { 00115 readSettingsWidget(); 00116 if ( mConfig ) { 00117 mConfig->writeEntry( "Use Colors", mUseColors ); 00118 mConfig->writeEntry( "Show Options", mShowOptions ); 00119 mConfig->writeEntry( "Show Subitems and Notes", mShowSubitemsNotes ); 00120 mConfig->writeEntry( "Use Attendees", mShowAttendees ); 00121 mConfig->writeEntry( "Use Attachments", mShowAttachments ); 00122 } 00123 } 00124 00125 00126 class TimePrintStringsVisitor : public IncidenceBase::Visitor 00127 { 00128 public: 00129 TimePrintStringsVisitor() {} 00130 00131 bool act( IncidenceBase *incidence ) 00132 { 00133 return incidence->accept( *this ); 00134 } 00135 TQString mStartCaption, mStartString; 00136 TQString mEndCaption, mEndString; 00137 TQString mDurationCaption, mDurationString; 00138 00139 protected: 00140 bool visit( Event *event ) { 00141 if ( event->dtStart().isValid() ) { 00142 mStartCaption = i18n( "Start date: " ); 00143 mStartString = IncidenceFormatter::dateTimeToString( 00144 event->dtStart(), event->doesFloat(), false ); 00145 } else { 00146 mStartCaption = i18n( "No start date" ); 00147 mStartString = TQString(); 00148 } 00149 00150 if ( event->hasEndDate() ) { 00151 mEndCaption = i18n( "End date: " ); 00152 mEndString = IncidenceFormatter::dateTimeToString( 00153 event->dtEnd(), event->doesFloat(), false ); 00154 } else if ( event->hasDuration() ) { 00155 mEndCaption = i18n("Duration: "); 00156 int mins = event->duration() / 60; 00157 if ( mins >= 60 ) { 00158 mEndString += i18n( "1 hour ", "%n hours ", mins/60 ); 00159 } 00160 if ( mins%60 > 0 ) { 00161 mEndString += i18n( "1 minute ", "%n minutes ", mins%60 ); 00162 } 00163 } else { 00164 mEndCaption = i18n("No end date"); 00165 mEndString = TQString(); 00166 } 00167 return true; 00168 } 00169 bool visit( Todo *todo ) { 00170 if ( todo->hasStartDate() ) { 00171 mStartCaption = i18n( "Start date: " ); 00172 mStartString = IncidenceFormatter::dateTimeToString( 00173 todo->dtStart(), todo->doesFloat(), false ); 00174 } else { 00175 mStartCaption = i18n( "No start date" ); 00176 mStartString = TQString(); 00177 } 00178 00179 if ( todo->hasDueDate() ) { 00180 mEndCaption = i18n( "Due date: " ); 00181 mEndString = IncidenceFormatter::dateTimeToString( 00182 todo->dtDue(), todo->doesFloat(), false ); 00183 } else { 00184 mEndCaption = i18n("No due date"); 00185 mEndString = TQString(); 00186 } 00187 return true; 00188 } 00189 bool visit( Journal *journal ) { 00190 mStartCaption = i18n( "Start date: " ); 00191 mStartString = IncidenceFormatter::dateTimeToString( 00192 journal->dtStart(), journal->doesFloat(), false ); 00193 mEndCaption = TQString(); 00194 mEndString = TQString(); 00195 return true; 00196 } 00197 }; 00198 00199 int CalPrintIncidence::printCaptionAndText( TQPainter &p, const TQRect &box, const TQString &caption, const TQString &text, TQFont captionFont, TQFont textFont ) 00200 { 00201 TQFontMetrics captionFM( captionFont ); 00202 int textWd = captionFM.width( caption ); 00203 TQRect textRect( box ); 00204 00205 TQFont oldFont( p.font() ); 00206 p.setFont( captionFont ); 00207 p.drawText( box, TQt::AlignLeft|TQt::AlignTop|TQt::SingleLine, caption ); 00208 00209 if ( !text.isEmpty() ) { 00210 textRect.setLeft( textRect.left() + textWd ); 00211 p.setFont( textFont ); 00212 p.drawText( textRect, TQt::AlignLeft|TQt::AlignTop|TQt::SingleLine, text ); 00213 } 00214 p.setFont( oldFont ); 00215 return textRect.bottom(); 00216 } 00217 00218 #include <tqfontdatabase.h> 00219 void CalPrintIncidence::print( TQPainter &p, int width, int height ) 00220 { 00221 TQFont oldFont(p.font()); 00222 TQFont textFont( "sans-serif", 11, TQFont::Normal ); 00223 TQFont captionFont( "sans-serif", 11, TQFont::Bold ); 00224 p.setFont( textFont ); 00225 int lineHeight = p.fontMetrics().lineSpacing(); 00226 TQString cap, txt; 00227 00228 00229 Incidence::List::ConstIterator it; 00230 for ( it=mSelectedIncidences.begin(); it!=mSelectedIncidences.end(); ++it ) { 00231 // don't do anything on a 0-pointer! 00232 if ( !(*it) ) continue; 00233 if ( it != mSelectedIncidences.begin() ) mPrinter->newPage(); 00234 00235 00236 // PAGE Layout (same for landscape and portrait! astonishingly, it looks good with both!): 00237 // +-----------------------------------+ 00238 // | Header: Summary | 00239 // +===================================+ 00240 // | start: ______ end: _________ | 00241 // | repeats: ___________________ | 00242 // | reminder: __________________ | 00243 // +-----------------------------------+ 00244 // | Location: ______________________ | 00245 // +------------------------+----------+ 00246 // | Description: | Notes or | 00247 // | | Subitems | 00248 // | | | 00249 // | | | 00250 // | | | 00251 // | | | 00252 // | | | 00253 // | | | 00254 // | | | 00255 // | | | 00256 // +------------------------+----------+ 00257 // | Attachments: | Settings | 00258 // | | | 00259 // +------------------------+----------+ 00260 // | Attendees: | 00261 // | | 00262 // +-----------------------------------+ 00263 // | Categories: _____________________ | 00264 // +-----------------------------------+ 00265 00266 TQRect box( 0, 0, width, height ); 00267 TQRect titleBox( box ); 00268 titleBox.setHeight( headerHeight() ); 00269 // Draw summary as header, no small calendars in title bar, expand height if needed 00270 int titleBottom = drawHeader( p, (*it)->summary(), TQDate(), TQDate(), titleBox, true ); 00271 titleBox.setBottom( titleBottom ); 00272 00273 TQRect timesBox( titleBox ); 00274 timesBox.setTop( titleBox.bottom() + padding() ); 00275 timesBox.setHeight( height / 8 ); 00276 00277 TimePrintStringsVisitor stringVis; 00278 int h = timesBox.top(); 00279 if ( stringVis.act(*it) ) { 00280 TQRect textRect( timesBox.left()+padding(), timesBox.top()+padding(), 0, lineHeight ); 00281 textRect.setRight( timesBox.center().x() ); 00282 h = printCaptionAndText( p, textRect, stringVis.mStartCaption, stringVis.mStartString, captionFont, textFont ); 00283 00284 textRect.setLeft( textRect.right() ); 00285 textRect.setRight( timesBox.right() - padding() ); 00286 h = TQMAX( printCaptionAndText( p, textRect, stringVis.mEndCaption, stringVis.mEndString, captionFont, textFont ), h ); 00287 } 00288 00289 // Convert recurrence to a string 00290 if ( (*it)->doesRecur() ) { 00291 TQRect recurBox( timesBox.left()+padding(), h+padding(), timesBox.right()-padding(), lineHeight ); 00292 KCal::Recurrence *recurs = (*it)->recurrence(); 00293 00294 TQString displayString = IncidenceFormatter::recurrenceString((*it)); 00295 // exception dates 00296 TQString exceptString; 00297 if ( !recurs->exDates().isEmpty() ) { 00298 exceptString = i18n("except for listed dates", " except"); 00299 for ( uint i = 0; i < recurs->exDates().size(); i++ ) { 00300 exceptString.append(" "); 00301 exceptString.append( TDEGlobal::locale()->formatDate(recurs->exDates()[i], 00302 true) ); 00303 } 00304 } 00305 displayString.append(exceptString); 00306 h = TQMAX( printCaptionAndText( p, recurBox, i18n( "Repeats: "), displayString, captionFont, textFont ), h ); 00307 } 00308 00309 // Alarms Printing 00310 TQRect alarmBox( timesBox.left()+padding(), h+padding(), timesBox.right()-padding(), lineHeight ); 00311 Alarm::List alarms = (*it)->alarms(); 00312 if ( alarms.count() == 0 ) { 00313 cap = i18n("No reminders"); 00314 txt = TQString(); 00315 } else { 00316 cap = i18n("Reminder: ", "%n reminders: ", alarms.count() ); 00317 00318 TQStringList alarmStrings; 00319 KCal::Alarm::List::ConstIterator it; 00320 for ( it = alarms.begin(); it != alarms.end(); ++it ) { 00321 Alarm *alarm = *it; 00322 00323 // Alarm offset, copied from koeditoralarms.cpp: 00324 TQString offsetstr; 00325 int offset = 0; 00326 if ( alarm->hasStartOffset() ) { 00327 offset = alarm->startOffset().asSeconds(); 00328 if ( offset < 0 ) { 00329 offsetstr = i18n("N days/hours/minutes before/after the start/end", "%1 before the start"); 00330 offset = -offset; 00331 } else { 00332 offsetstr = i18n("N days/hours/minutes before/after the start/end", "%1 after the start"); 00333 } 00334 } else if ( alarm->hasEndOffset() ) { 00335 offset = alarm->endOffset().asSeconds(); 00336 if ( offset < 0 ) { 00337 offsetstr = i18n("N days/hours/minutes before/after the start/end", "%1 before the end"); 00338 offset = -offset; 00339 } else { 00340 offsetstr = i18n("N days/hours/minutes before/after the start/end", "%1 after the end"); 00341 } 00342 } 00343 00344 offset = offset / 60; // make minutes 00345 int useoffset = offset; 00346 00347 if ( offset % (24*60) == 0 && offset>0 ) { // divides evenly into days? 00348 useoffset = offset / (24*60); 00349 offsetstr = offsetstr.arg( i18n("1 day", "%n days", useoffset ) ); 00350 } else if (offset % 60 == 0 && offset>0 ) { // divides evenly into hours? 00351 useoffset = offset / 60; 00352 offsetstr = offsetstr.arg( i18n("1 hour", "%n hours", useoffset ) ); 00353 } else { 00354 useoffset = offset; 00355 offsetstr = offsetstr.arg( i18n("1 minute", "%n minutes", useoffset ) ); 00356 } 00357 alarmStrings << offsetstr; 00358 } 00359 txt = alarmStrings.join( i18n("Spacer for the joined list of categories", ", ") ); 00360 00361 } 00362 h = TQMAX( printCaptionAndText( p, alarmBox, cap, txt, captionFont, textFont ), h ); 00363 00364 00365 TQRect organizerBox( timesBox.left()+padding(), h+padding(), timesBox.right()-padding(), lineHeight ); 00366 h = TQMAX( printCaptionAndText( p, organizerBox, i18n("Organizer: "), (*it)->organizer().fullName(), captionFont, textFont ), h ); 00367 00368 // Finally, draw the frame around the time information... 00369 timesBox.setBottom( TQMAX( timesBox.bottom(), h+padding() ) ); 00370 drawBox( p, BOX_BORDER_WIDTH, timesBox ); 00371 00372 00373 TQRect locationBox( timesBox ); 00374 locationBox.setTop( timesBox.bottom() + padding() ); 00375 locationBox.setHeight( 0 ); 00376 int locationBottom = drawBoxWithCaption( p, locationBox, i18n("Location: "), 00377 (*it)->location(), /*sameLine=*/true, /*expand=*/true, captionFont, textFont ); 00378 locationBox.setBottom( locationBottom ); 00379 00380 00381 // Now start constructing the boxes from the bottom: 00382 TQRect footerBox( locationBox ); 00383 footerBox.setBottom( box.bottom() ); 00384 footerBox.setTop( footerBox.bottom() - lineHeight - 2*padding() ); 00385 00386 TQRect categoriesBox( footerBox ); 00387 categoriesBox.setBottom( footerBox.top() ); 00388 categoriesBox.setTop( categoriesBox.bottom() - lineHeight - 2*padding() ); 00389 00390 TQRect attendeesBox( box.left(), categoriesBox.top()-padding()-box.height()/9, box.width(), box.height()/9 ); 00391 00392 TQRect attachmentsBox( box.left(), attendeesBox.top()-padding()-box.height()/9, box.width()*3/4 - padding(), box.height()/9 ); 00393 TQRect optionsBox( attachmentsBox.right() + padding(), attachmentsBox.top(), 0, 0 ); 00394 optionsBox.setRight( box.right() ); 00395 optionsBox.setBottom( attachmentsBox.bottom() ); 00396 TQRect notesBox( optionsBox.left(), locationBox.bottom() + padding(), optionsBox.width(), 0 ); 00397 notesBox.setBottom( optionsBox.top() - padding() ); 00398 00399 TQRect descriptionBox( notesBox ); 00400 descriptionBox.setLeft( box.left() ); 00401 descriptionBox.setRight( attachmentsBox.right() ); 00402 // Adjust boxes depending on the show options... 00403 if (!mShowSubitemsNotes) { 00404 descriptionBox.setRight( box.right() ); 00405 } 00406 if (!mShowAttachments || !mShowAttendees) { 00407 descriptionBox.setBottom( attachmentsBox.bottom() ); 00408 optionsBox.setTop( attendeesBox.top() ); 00409 optionsBox.setBottom( attendeesBox.bottom() ); 00410 notesBox.setBottom( attachmentsBox.bottom() ); 00411 if (mShowOptions) { 00412 attendeesBox.setRight( attachmentsBox.right() ); 00413 } 00414 if (!mShowAttachments && !mShowAttendees) { 00415 if (mShowSubitemsNotes) { 00416 descriptionBox.setBottom( attendeesBox.bottom() ); 00417 } 00418 if (!mShowOptions) { 00419 descriptionBox.setBottom( attendeesBox.bottom() ); 00420 notesBox.setBottom( attendeesBox.bottom() ); 00421 } 00422 } 00423 } 00424 if (mShowAttachments) { 00425 if (!mShowOptions) { 00426 attachmentsBox.setRight( box.right() ); 00427 attachmentsBox.setRight( box.right() ); 00428 } 00429 if (!mShowAttendees) { 00430 attachmentsBox.setTop( attendeesBox.top() ); 00431 attachmentsBox.setBottom( attendeesBox.bottom() ); 00432 } 00433 } 00434 00435 drawBoxWithCaption( p, descriptionBox, i18n("Description:"), 00436 (*it)->description(), /*sameLine=*/false, 00437 /*expand=*/false, captionFont, textFont ); 00438 00439 if ( mShowSubitemsNotes ) { 00440 if ( (*it)->relations().isEmpty() || (*it)->type() != "Todo" ) { 00441 int notesPosition = drawBoxWithCaption( p, notesBox, i18n("Notes:"), 00442 TQString(), /*sameLine=*/false, /*expand=*/false, 00443 captionFont, textFont ); 00444 TQPen oldPen( p.pen() ); 00445 p.setPen( TQt::DotLine ); 00446 while ( (notesPosition += int(1.5*lineHeight)) < notesBox.bottom() ) { 00447 p.drawLine( notesBox.left()+padding(), notesPosition, notesBox.right()-padding(), notesPosition ); 00448 } 00449 p.setPen( oldPen ); 00450 } else { 00451 Incidence::List relations = (*it)->relations(); 00452 TQString subitemCaption; 00453 if ( relations.count() == 0 ) { 00454 subitemCaption = i18n( "No Subitems" ); 00455 txt == ""; 00456 } else { 00457 subitemCaption = i18n( "1 Subitem:", 00458 "%1 Subitems:", 00459 relations.count() ); 00460 } 00461 Incidence::List::ConstIterator rit; 00462 TQString subitemString; 00463 TQString statusString; 00464 TQString datesString; 00465 int count = 0; 00466 for ( rit = relations.begin(); rit != relations.end(); ++rit ) { 00467 ++count; 00468 if ( !(*rit) ) { // defensive, skip any zero pointers 00469 continue; 00470 } 00471 // format the status 00472 statusString = (*rit)->statusStr(); 00473 if ( statusString.isEmpty() ) { 00474 if ( (*rit)->status() == Incidence::StatusNone ) { 00475 statusString = i18n( "no status", "none" ); 00476 } else { 00477 statusString = i18n( "unknown status", "unknown" ); 00478 } 00479 } 00480 // format the dates if provided 00481 datesString = ""; 00482 if ( (*rit)->dtStart().isValid() ) { 00483 datesString += i18n( 00484 "Start Date: %1\n").arg( 00485 TDEGlobal::locale()->formatDate( (*rit)->dtStart().date(), 00486 true ) ); 00487 if ( !(*rit)->doesFloat() ) { 00488 datesString += i18n( 00489 "Start Time: %1\n").arg( 00490 TDEGlobal::locale()->formatTime((*rit)->dtStart().time(), 00491 false, false) ); 00492 } 00493 } 00494 if ( (*rit)->dtEnd().isValid() ) { 00495 subitemString += i18n( 00496 "Due Date: %1\n").arg( 00497 TDEGlobal::locale()->formatDate( (*rit)->dtEnd().date(), 00498 true ) ); 00499 if ( !(*rit)->doesFloat() ) { 00500 subitemString += i18n( 00501 "subitem due time", "Due Time: %1\n").arg( 00502 TDEGlobal::locale()->formatTime((*rit)->dtEnd().time(), 00503 false, false) ); 00504 } 00505 } 00506 subitemString += i18n("subitem counter", "%1: ", count); 00507 subitemString += (*rit)->summary(); 00508 subitemString += "\n"; 00509 if ( !datesString.isEmpty() ) { 00510 subitemString += datesString; 00511 subitemString += "\n"; 00512 } 00513 subitemString += i18n( "subitem Status: statusString", 00514 "Status: %1\n").arg( statusString ); 00515 subitemString += IncidenceFormatter::recurrenceString((*rit)) + "\n"; 00516 subitemString += i18n( "subitem Priority: N", 00517 "Priority: %1\n").arg( (*rit)->priority() ); 00518 subitemString += i18n( "subitem Secrecy: secrecyString", 00519 "Secrecy: %1\n").arg( (*rit)->secrecyStr() ); 00520 subitemString += "\n"; 00521 } 00522 drawBoxWithCaption( p, notesBox, i18n("Subitems:"), 00523 (*it)->description(), /*sameLine=*/false, 00524 /*expand=*/false, captionFont, textFont ); 00525 } 00526 } 00527 00528 if ( mShowAttachments ) { 00529 Attachment::List attachments = (*it)->attachments(); 00530 TQString attachmentCaption; 00531 if ( attachments.count() == 0 ) { 00532 attachmentCaption = i18n( "No Attachments" ); 00533 txt = TQString(); 00534 } else { 00535 attachmentCaption = i18n( "1 Attachment:", "%1 Attachments:", attachments.count() ); 00536 } 00537 TQString attachmentString; 00538 Attachment::List::ConstIterator ait = attachments.begin(); 00539 for ( ; ait != attachments.end(); ++ait ) { 00540 if (!attachmentString.isEmpty()) { 00541 attachmentString += i18n( "Spacer for list of attachments", " " ); 00542 } 00543 attachmentString.append((*ait)->label()); 00544 } 00545 drawBoxWithCaption( p, attachmentsBox, 00546 attachmentCaption, attachmentString, 00547 /*sameLine=*/false, /*expand=*/false, 00548 captionFont, textFont ); 00549 } 00550 00551 if ( mShowAttendees ) { 00552 Attendee::List attendees = (*it)->attendees(); 00553 TQString attendeeCaption; 00554 if ( attendees.count() == 0 ) 00555 attendeeCaption = i18n("No Attendees"); 00556 else 00557 attendeeCaption = i18n("1 Attendee:", "%n Attendees:", attendees.count() ); 00558 TQString attendeeString; 00559 for ( Attendee::List::ConstIterator ait = attendees.begin(); ait != attendees.end(); ++ait ) { 00560 if ( !attendeeString.isEmpty() ) attendeeString += "\n"; 00561 attendeeString += i18n("Formatting of an attendee: " 00562 "'Name (Role): Status', e.g. 'Reinhold Kainhofer " 00563 "<reinhold@kainhofer.com> (Participant): Awaiting Response'", 00564 "%1 (%2): %3") 00565 .arg( (*ait)->fullName() ) 00566 .arg( (*ait)->roleStr() ).arg( (*ait)->statusStr() ); 00567 } 00568 drawBoxWithCaption( p, attendeesBox, i18n("Attendees:"), attendeeString, 00569 /*sameLine=*/false, /*expand=*/false, captionFont, textFont ); 00570 } 00571 00572 if ( mShowOptions ) { 00573 TQString optionsString; 00574 if ( !(*it)->statusStr().isEmpty() ) { 00575 optionsString += i18n("Status: %1").arg( (*it)->statusStr() ); 00576 optionsString += "\n"; 00577 } 00578 if ( !(*it)->secrecyStr().isEmpty() ) { 00579 optionsString += i18n("Secrecy: %1").arg( (*it)->secrecyStr() ); 00580 optionsString += "\n"; 00581 } 00582 if ( (*it)->type() == "Event" ) { 00583 Event *e = static_cast<Event*>(*it); 00584 if ( e->transparency() == Event::Opaque ) { 00585 optionsString += i18n("Show as: Busy"); 00586 } else { 00587 optionsString += i18n("Show as: Free"); 00588 } 00589 optionsString += "\n"; 00590 } else if ( (*it)->type() == "Todo" ) { 00591 Todo *t = static_cast<Todo*>(*it); 00592 if ( t->isOverdue() ) { 00593 optionsString += i18n("This task is overdue!"); 00594 optionsString += "\n"; 00595 } 00596 } else if ( (*it)->type() == "Journal" ) { 00597 //TODO: Anything Journal-specific? 00598 } 00599 drawBoxWithCaption( p, optionsBox, i18n("Settings: "), 00600 optionsString, /*sameLine=*/false, /*expand=*/false, captionFont, textFont ); 00601 } 00602 00603 drawBoxWithCaption( p, categoriesBox, i18n("Categories: "), 00604 (*it)->categories().join( i18n("Spacer for the joined list of categories", ", ") ), 00605 /*sameLine=*/true, /*expand=*/false, captionFont, textFont ); 00606 00607 drawFooter( p, footerBox ); 00608 } 00609 p.setFont( oldFont ); 00610 } 00611 00612 /************************************************************** 00613 * Print Day 00614 **************************************************************/ 00615 00616 CalPrintDay::CalPrintDay() : CalPrintPluginBase() 00617 { 00618 } 00619 00620 CalPrintDay::~CalPrintDay() 00621 { 00622 } 00623 00624 TQWidget *CalPrintDay::createConfigWidget( TQWidget *w ) 00625 { 00626 return new CalPrintDayConfig_Base( w ); 00627 } 00628 00629 void CalPrintDay::readSettingsWidget() 00630 { 00631 CalPrintDayConfig_Base *cfg = 00632 dynamic_cast<CalPrintDayConfig_Base*>( mConfigWidget ); 00633 if ( cfg ) { 00634 mFromDate = cfg->mFromDate->date(); 00635 mToDate = cfg->mToDate->date(); 00636 00637 mStartTime = cfg->mFromTime->time(); 00638 mEndTime = cfg->mToTime->time(); 00639 mIncludeAllEvents = cfg->mIncludeAllEvents->isChecked(); 00640 00641 mIncludeTodos = cfg->mIncludeTodos->isChecked(); 00642 mUseColors = cfg->mColors->isChecked(); 00643 } 00644 } 00645 00646 void CalPrintDay::setSettingsWidget() 00647 { 00648 CalPrintDayConfig_Base *cfg = 00649 dynamic_cast<CalPrintDayConfig_Base*>( mConfigWidget ); 00650 if ( cfg ) { 00651 cfg->mFromDate->setDate( mFromDate ); 00652 cfg->mToDate->setDate( mToDate ); 00653 00654 cfg->mFromTime->setTime( mStartTime ); 00655 cfg->mToTime->setTime( mEndTime ); 00656 cfg->mIncludeAllEvents->setChecked( mIncludeAllEvents ); 00657 00658 cfg->mIncludeTodos->setChecked( mIncludeTodos ); 00659 cfg->mColors->setChecked( mUseColors ); 00660 } 00661 } 00662 00663 void CalPrintDay::loadConfig() 00664 { 00665 if ( mConfig ) { 00666 TQDate dt; 00667 TQTime tm1( dayStart() ); 00668 TQDateTime startTm( dt, tm1 ); 00669 TQDateTime endTm( dt, tm1.addSecs( 12 * 60 * 60 ) ); 00670 mStartTime = mConfig->readDateTimeEntry( "Start time", &startTm ).time(); 00671 mEndTime = mConfig->readDateTimeEntry( "End time", &endTm ).time(); 00672 mIncludeTodos = mConfig->readBoolEntry( "Include todos", false ); 00673 mIncludeAllEvents = mConfig->readBoolEntry( "Include all events", false ); 00674 } 00675 setSettingsWidget(); 00676 } 00677 00678 void CalPrintDay::saveConfig() 00679 { 00680 readSettingsWidget(); 00681 if ( mConfig ) { 00682 mConfig->writeEntry( "Start time", TQDateTime( TQDate(), mStartTime ) ); 00683 mConfig->writeEntry( "End time", TQDateTime( TQDate(), mEndTime ) ); 00684 mConfig->writeEntry( "Include todos", mIncludeTodos ); 00685 mConfig->writeEntry( "Include all events", mIncludeAllEvents ); 00686 } 00687 } 00688 00689 void CalPrintDay::setDateRange( const TQDate& from, const TQDate& to ) 00690 { 00691 CalPrintPluginBase::setDateRange( from, to ); 00692 CalPrintDayConfig_Base *cfg = 00693 dynamic_cast<CalPrintDayConfig_Base*>( mConfigWidget ); 00694 if ( cfg ) { 00695 cfg->mFromDate->setDate( from ); 00696 cfg->mToDate->setDate( to ); 00697 } 00698 } 00699 00700 void CalPrintDay::print( TQPainter &p, int width, int height ) 00701 { 00702 TQDate curDay( mFromDate ); 00703 00704 TQRect headerBox( 0, 0, width, headerHeight() ); 00705 TQRect footerBox( 0, height - footerHeight(), width, footerHeight() ); 00706 height -= footerHeight(); 00707 00708 TDELocale *local = TDEGlobal::locale(); 00709 00710 do { 00711 TQTime curStartTime( mStartTime ); 00712 TQTime curEndTime( mEndTime ); 00713 00714 // For an invalid time range, simply show one hour, starting at the hour 00715 // before the given start time 00716 if ( curEndTime <= curStartTime ) { 00717 curStartTime = TQTime( curStartTime.hour(), 0, 0 ); 00718 curEndTime = curStartTime.addSecs( 3600 ); 00719 } 00720 00721 drawHeader( p, local->formatDate( curDay ), curDay, TQDate(), headerBox ); 00722 Event::List eventList = mCalendar->events( curDay, 00723 EventSortStartDate, 00724 SortDirectionAscending ); 00725 00726 // split out the all day events as they will be printed in a separate box 00727 Event::List alldayEvents, timedEvents; 00728 Event::List::ConstIterator it; 00729 for ( it = eventList.begin(); it != eventList.end(); ++it ) { 00730 if ( (*it)->doesFloat() ) { 00731 alldayEvents.append( *it ); 00732 } else { 00733 timedEvents.append( *it ); 00734 } 00735 } 00736 00737 int fontSize = 11; 00738 TQFont textFont( "sans-serif", fontSize, TQFont::Normal ); 00739 p.setFont( textFont ); 00740 uint lineSpacing = p.fontMetrics().lineSpacing(); 00741 00742 uint maxAllDayEvents = 8; // the max we allow to be printed, sorry. 00743 uint allDayHeight = TQMIN( alldayEvents.count(), maxAllDayEvents ) * lineSpacing; 00744 allDayHeight = TQMAX( allDayHeight, ( 5 * lineSpacing ) ) + ( 2 * padding() ); 00745 TQRect allDayBox( TIMELINE_WIDTH + padding(), headerBox.bottom() + padding(), 00746 width - TIMELINE_WIDTH - padding(), allDayHeight ); 00747 if ( alldayEvents.count() > 0 ) { 00748 // draw the side bar for all-day events 00749 TQFont oldFont( p.font() ); 00750 p.setFont( TQFont( "sans-serif", 9, TQFont::Normal ) ); 00751 drawVerticalBox( p, 00752 BOX_BORDER_WIDTH, 00753 TQRect( 0, headerBox.bottom() + padding(), TIMELINE_WIDTH, allDayHeight ), 00754 i18n( "Today's Events" ), 00755 TQt::AlignHCenter | TQt::AlignVCenter | TQt::WordBreak ); 00756 p.setFont( oldFont ); 00757 00758 // now draw at most maxAllDayEvents in the all-day box 00759 drawBox( p, BOX_BORDER_WIDTH, allDayBox ); 00760 00761 Event::List::ConstIterator it; 00762 TQRect eventBox( allDayBox ); 00763 eventBox.setLeft( TIMELINE_WIDTH + ( 2 * padding() ) ); 00764 eventBox.setTop( eventBox.top() + padding() ); 00765 eventBox.setBottom( eventBox.top() + lineSpacing ); 00766 uint count = 0; 00767 for ( it = alldayEvents.begin(); it != alldayEvents.end(); ++it ) { 00768 if ( count == maxAllDayEvents ) { 00769 break; 00770 } 00771 count++; 00772 TQString str; 00773 if ( (*it)->location().isEmpty() ) { 00774 str = cleanString( (*it)->summary() ); 00775 } else { 00776 str = i18n( "summary, location", "%1, %2" ). 00777 arg( cleanString( (*it)->summary() ), cleanString( (*it)->location() ) ); 00778 } 00779 printEventString( p, eventBox, str ); 00780 eventBox.setTop( eventBox.bottom() ); 00781 eventBox.setBottom( eventBox.top() + lineSpacing ); 00782 } 00783 } else { 00784 allDayBox.setBottom( headerBox.bottom() ); 00785 } 00786 00787 TQRect dayBox( allDayBox ); 00788 dayBox.setTop( allDayBox.bottom() + padding() ); 00789 dayBox.setBottom( height ); 00790 drawAgendaDayBox( p, timedEvents, curDay, mIncludeAllEvents, 00791 curStartTime, curEndTime, dayBox ); 00792 00793 TQRect tlBox( dayBox ); 00794 tlBox.setLeft( 0 ); 00795 tlBox.setWidth( TIMELINE_WIDTH ); 00796 drawTimeLine( p, curStartTime, curEndTime, tlBox ); 00797 00798 drawFooter( p, footerBox ); 00799 00800 curDay = curDay.addDays( 1 ); 00801 if ( curDay <= mToDate ) { 00802 mPrinter->newPage(); 00803 } 00804 } while ( curDay <= mToDate ); 00805 } 00806 00807 00808 00809 /************************************************************** 00810 * Print Week 00811 **************************************************************/ 00812 00813 CalPrintWeek::CalPrintWeek() : CalPrintPluginBase() 00814 { 00815 } 00816 00817 CalPrintWeek::~CalPrintWeek() 00818 { 00819 } 00820 00821 TQWidget *CalPrintWeek::createConfigWidget( TQWidget *w ) 00822 { 00823 return new CalPrintWeekConfig_Base( w ); 00824 } 00825 00826 void CalPrintWeek::readSettingsWidget() 00827 { 00828 CalPrintWeekConfig_Base *cfg = 00829 dynamic_cast<CalPrintWeekConfig_Base*>( mConfigWidget ); 00830 if ( cfg ) { 00831 mFromDate = cfg->mFromDate->date(); 00832 mToDate = cfg->mToDate->date(); 00833 00834 mWeekPrintType = (eWeekPrintType)( cfg->mPrintType->id( 00835 cfg->mPrintType->selected() ) ); 00836 00837 mStartTime = cfg->mFromTime->time(); 00838 mEndTime = cfg->mToTime->time(); 00839 00840 mIncludeTodos = cfg->mIncludeTodos->isChecked(); 00841 mUseColors = cfg->mColors->isChecked(); 00842 } 00843 } 00844 00845 void CalPrintWeek::setSettingsWidget() 00846 { 00847 CalPrintWeekConfig_Base *cfg = 00848 dynamic_cast<CalPrintWeekConfig_Base*>( mConfigWidget ); 00849 if ( cfg ) { 00850 cfg->mFromDate->setDate( mFromDate ); 00851 cfg->mToDate->setDate( mToDate ); 00852 00853 cfg->mPrintType->setButton( mWeekPrintType ); 00854 00855 cfg->mFromTime->setTime( mStartTime ); 00856 cfg->mToTime->setTime( mEndTime ); 00857 00858 cfg->mIncludeTodos->setChecked( mIncludeTodos ); 00859 cfg->mColors->setChecked( mUseColors ); 00860 } 00861 } 00862 00863 void CalPrintWeek::loadConfig() 00864 { 00865 if ( mConfig ) { 00866 TQDate dt; 00867 TQTime tm1( dayStart() ); 00868 TQDateTime startTm( dt, tm1 ); 00869 TQDateTime endTm( dt, tm1.addSecs( 43200 ) ); 00870 mStartTime = mConfig->readDateTimeEntry( "Start time", &startTm ).time(); 00871 mEndTime = mConfig->readDateTimeEntry( "End time", &endTm ).time(); 00872 mIncludeTodos = mConfig->readBoolEntry( "Include todos", false ); 00873 mWeekPrintType =(eWeekPrintType)( mConfig->readNumEntry( "Print type", (int)Filofax ) ); 00874 } 00875 setSettingsWidget(); 00876 } 00877 00878 void CalPrintWeek::saveConfig() 00879 { 00880 readSettingsWidget(); 00881 if ( mConfig ) { 00882 mConfig->writeEntry( "Start time", TQDateTime( TQDate(), mStartTime ) ); 00883 mConfig->writeEntry( "End time", TQDateTime( TQDate(), mEndTime ) ); 00884 mConfig->writeEntry( "Include todos", mIncludeTodos ); 00885 mConfig->writeEntry( "Print type", int( mWeekPrintType ) ); 00886 } 00887 } 00888 00889 KPrinter::Orientation CalPrintWeek::defaultOrientation() 00890 { 00891 if ( mWeekPrintType == Filofax ) return KPrinter::Portrait; 00892 else if ( mWeekPrintType == SplitWeek ) return KPrinter::Portrait; 00893 else return KPrinter::Landscape; 00894 } 00895 00896 void CalPrintWeek::setDateRange( const TQDate &from, const TQDate &to ) 00897 { 00898 CalPrintPluginBase::setDateRange( from, to ); 00899 CalPrintWeekConfig_Base *cfg = 00900 dynamic_cast<CalPrintWeekConfig_Base*>( mConfigWidget ); 00901 if ( cfg ) { 00902 cfg->mFromDate->setDate( from ); 00903 cfg->mToDate->setDate( to ); 00904 } 00905 } 00906 00907 void CalPrintWeek::print( TQPainter &p, int width, int height ) 00908 { 00909 TQDate curWeek, fromWeek, toWeek; 00910 00911 // correct begin and end to first and last day of week 00912 int weekdayCol = weekdayColumn( mFromDate.dayOfWeek() ); 00913 fromWeek = mFromDate.addDays( -weekdayCol ); 00914 weekdayCol = weekdayColumn( mFromDate.dayOfWeek() ); 00915 toWeek = mToDate.addDays( 6 - weekdayCol ); 00916 00917 curWeek = fromWeek.addDays( 6 ); 00918 TDELocale *local = TDEGlobal::locale(); 00919 00920 TQString line1, line2, title; 00921 TQRect headerBox( 0, 0, width, headerHeight() ); 00922 TQRect footerBox( 0, height - footerHeight(), width, footerHeight() ); 00923 height -= footerHeight(); 00924 00925 TQRect weekBox( headerBox ); 00926 weekBox.setTop( headerBox.bottom() + padding() ); 00927 weekBox.setBottom( height ); 00928 00929 switch ( mWeekPrintType ) { 00930 case Filofax: 00931 do { 00932 line1 = local->formatDate( curWeek.addDays( -6 ) ); 00933 line2 = local->formatDate( curWeek ); 00934 if ( orientation() == KPrinter::Landscape ) { 00935 title = i18n("date from-to", "%1 - %2"); 00936 } else { 00937 title = i18n("date from-\nto", "%1 -\n%2");; 00938 } 00939 title = title.arg( line1 ).arg( line2 ); 00940 drawHeader( p, title, curWeek.addDays( -6 ), TQDate(), headerBox ); 00941 00942 drawWeek( p, curWeek, weekBox ); 00943 00944 drawFooter( p, footerBox ); 00945 00946 curWeek = curWeek.addDays( 7 ); 00947 if ( curWeek <= toWeek ) 00948 mPrinter->newPage(); 00949 } while ( curWeek <= toWeek ); 00950 break; 00951 00952 case Timetable: 00953 default: 00954 do { 00955 line1 = local->formatDate( curWeek.addDays( -6 ) ); 00956 line2 = local->formatDate( curWeek ); 00957 if ( orientation() == KPrinter::Landscape ) { 00958 title = i18n("date from - to (week number)", "%1 - %2 (Week %3)"); 00959 } else { 00960 title = i18n("date from -\nto (week number)", "%1 -\n%2 (Week %3)"); 00961 } 00962 title = title.arg( line1 ).arg( line2 ).arg( curWeek.weekNumber() ); 00963 drawHeader( p, title, curWeek, TQDate(), headerBox ); 00964 00965 TQRect weekBox( headerBox ); 00966 weekBox.setTop( headerBox.bottom() + padding() ); 00967 weekBox.setBottom( height ); 00968 drawTimeTable( p, fromWeek, curWeek, mStartTime, mEndTime, weekBox ); 00969 00970 drawFooter( p, footerBox ); 00971 00972 fromWeek = fromWeek.addDays( 7 ); 00973 curWeek = fromWeek.addDays( 6 ); 00974 if ( curWeek <= toWeek ) 00975 mPrinter->newPage(); 00976 } while ( curWeek <= toWeek ); 00977 break; 00978 00979 case SplitWeek: { 00980 TQRect weekBox1( weekBox ); 00981 // On the left side there are four days (mo-th) plus the timeline, 00982 // on the right there are only three days (fr-su) plus the timeline. Don't 00983 // use the whole width, but rather give them the same width as on the left. 00984 weekBox1.setRight( int( ( width - TIMELINE_WIDTH ) * 3. / 4. + TIMELINE_WIDTH ) ); 00985 do { 00986 TQDate endLeft( fromWeek.addDays( 3 ) ); 00987 int hh = headerHeight(); 00988 00989 drawTimeTable( p, fromWeek, endLeft, 00990 mStartTime, mEndTime, weekBox ); 00991 mPrinter->newPage(); 00992 drawSplitHeaderRight( p, fromWeek, curWeek, TQDate(), width, hh ); 00993 drawTimeTable( p, endLeft.addDays( 1 ), curWeek, 00994 mStartTime, mEndTime, weekBox1 ); 00995 00996 drawFooter( p, footerBox ); 00997 00998 fromWeek = fromWeek.addDays( 7 ); 00999 curWeek = fromWeek.addDays( 6 ); 01000 if ( curWeek <= toWeek ) 01001 mPrinter->newPage(); 01002 } while ( curWeek <= toWeek ); 01003 } 01004 break; 01005 } 01006 } 01007 01008 01009 01010 01011 /************************************************************** 01012 * Print Month 01013 **************************************************************/ 01014 01015 CalPrintMonth::CalPrintMonth() : CalPrintPluginBase() 01016 { 01017 } 01018 01019 CalPrintMonth::~CalPrintMonth() 01020 { 01021 } 01022 01023 TQWidget *CalPrintMonth::createConfigWidget( TQWidget *w ) 01024 { 01025 return new CalPrintMonthConfig_Base( w ); 01026 } 01027 01028 void CalPrintMonth::readSettingsWidget() 01029 { 01030 CalPrintMonthConfig_Base *cfg = 01031 dynamic_cast<CalPrintMonthConfig_Base *>( mConfigWidget ); 01032 if ( cfg ) { 01033 mFromDate = TQDate( cfg->mFromYear->value(), cfg->mFromMonth->currentItem()+1, 1 ); 01034 mToDate = TQDate( cfg->mToYear->value(), cfg->mToMonth->currentItem()+1, 1 ); 01035 01036 mWeekNumbers = cfg->mWeekNumbers->isChecked(); 01037 mRecurDaily = cfg->mRecurDaily->isChecked(); 01038 mRecurWeekly = cfg->mRecurWeekly->isChecked(); 01039 mIncludeTodos = cfg->mIncludeTodos->isChecked(); 01040 // mUseColors = cfg->mColors->isChecked(); 01041 } 01042 } 01043 01044 void CalPrintMonth::setSettingsWidget() 01045 { 01046 CalPrintMonthConfig_Base *cfg = 01047 dynamic_cast<CalPrintMonthConfig_Base *>( mConfigWidget ); 01048 setDateRange( mFromDate, mToDate ); 01049 if ( cfg ) { 01050 cfg->mWeekNumbers->setChecked( mWeekNumbers ); 01051 cfg->mRecurDaily->setChecked( mRecurDaily ); 01052 cfg->mRecurWeekly->setChecked( mRecurWeekly ); 01053 cfg->mIncludeTodos->setChecked( mIncludeTodos ); 01054 // cfg->mColors->setChecked( mUseColors ); 01055 } 01056 } 01057 01058 void CalPrintMonth::loadConfig() 01059 { 01060 if ( mConfig ) { 01061 mWeekNumbers = mConfig->readBoolEntry( "Print week numbers", true ); 01062 mRecurDaily = mConfig->readBoolEntry( "Print daily incidences", true ); 01063 mRecurWeekly = mConfig->readBoolEntry( "Print weekly incidences", true ); 01064 mIncludeTodos = mConfig->readBoolEntry( "Include todos", false ); 01065 } 01066 setSettingsWidget(); 01067 } 01068 01069 void CalPrintMonth::saveConfig() 01070 { 01071 readSettingsWidget(); 01072 if ( mConfig ) { 01073 mConfig->writeEntry( "Print week numbers", mWeekNumbers ); 01074 mConfig->writeEntry( "Print daily incidences", mRecurDaily ); 01075 mConfig->writeEntry( "Print weekly incidences", mRecurWeekly ); 01076 mConfig->writeEntry( "Include todos", mIncludeTodos ); 01077 } 01078 } 01079 01080 void CalPrintMonth::setDateRange( const TQDate &from, const TQDate &to ) 01081 { 01082 CalPrintPluginBase::setDateRange( from, to ); 01083 CalPrintMonthConfig_Base *cfg = 01084 dynamic_cast<CalPrintMonthConfig_Base *>( mConfigWidget ); 01085 const KCalendarSystem *calSys = calendarSystem(); 01086 if ( cfg && calSys ) { 01087 cfg->mFromMonth->clear(); 01088 for ( int i=0; i<calSys->monthsInYear( mFromDate ); ++i ) { 01089 cfg->mFromMonth->insertItem( calSys->monthName( i+1, mFromDate.year() ) ); 01090 } 01091 cfg->mToMonth->clear(); 01092 for ( int i=0; i<calSys->monthsInYear( mToDate ); ++i ) { 01093 cfg->mToMonth->insertItem( calSys->monthName( i+1, mToDate.year() ) ); 01094 } 01095 } 01096 if ( cfg ) { 01097 cfg->mFromMonth->setCurrentItem( from.month()-1 ); 01098 cfg->mFromYear->setValue( to.year() ); 01099 cfg->mToMonth->setCurrentItem( mToDate.month()-1 ); 01100 cfg->mToYear->setValue( mToDate.year() ); 01101 } 01102 } 01103 01104 void CalPrintMonth::print( TQPainter &p, int width, int height ) 01105 { 01106 TQDate curMonth, fromMonth, toMonth; 01107 01108 fromMonth = mFromDate.addDays( -( mFromDate.day() - 1 ) ); 01109 toMonth = mToDate.addDays( mToDate.daysInMonth() - mToDate.day() ); 01110 01111 curMonth = fromMonth; 01112 const KCalendarSystem *calSys = calendarSystem(); 01113 if ( !calSys ) return; 01114 01115 TQRect headerBox( 0, 0, width, headerHeight() ); 01116 TQRect footerBox( 0, height - footerHeight(), width, footerHeight() ); 01117 height -= footerHeight(); 01118 01119 TQRect monthBox( 0, 0, width, height ); 01120 monthBox.setTop( headerBox.bottom() + padding() ); 01121 01122 do { 01123 TQString title( i18n("monthname year", "%1 %2") ); 01124 title = title.arg( calSys->monthName( curMonth ) ) 01125 .arg( curMonth.year() ); 01126 TQDate tmp( fromMonth ); 01127 int weekdayCol = weekdayColumn( tmp.dayOfWeek() ); 01128 tmp = tmp.addDays( -weekdayCol ); 01129 01130 drawHeader( p, title, curMonth.addMonths( -1 ), curMonth.addMonths( 1 ), 01131 headerBox ); 01132 drawMonthTable( p, curMonth, mWeekNumbers, mRecurDaily, mRecurWeekly, monthBox ); 01133 01134 drawFooter( p, footerBox ); 01135 01136 curMonth = curMonth.addDays( curMonth.daysInMonth() ); 01137 if ( curMonth <= toMonth ) mPrinter->newPage(); 01138 } while ( curMonth <= toMonth ); 01139 01140 } 01141 01142 01143 01144 01145 /************************************************************** 01146 * Print Todos 01147 **************************************************************/ 01148 01149 CalPrintTodos::CalPrintTodos() : CalPrintPluginBase() 01150 { 01151 mTodoSortField = TodoFieldUnset; 01152 mTodoSortDirection = TodoDirectionUnset; 01153 } 01154 01155 CalPrintTodos::~CalPrintTodos() 01156 { 01157 } 01158 01159 TQWidget *CalPrintTodos::createConfigWidget( TQWidget *w ) 01160 { 01161 return new CalPrintTodoConfig_Base( w ); 01162 } 01163 01164 void CalPrintTodos::readSettingsWidget() 01165 { 01166 CalPrintTodoConfig_Base *cfg = 01167 dynamic_cast<CalPrintTodoConfig_Base *>( mConfigWidget ); 01168 if ( cfg ) { 01169 mPageTitle = cfg->mTitle->text(); 01170 01171 mTodoPrintType = (eTodoPrintType)( cfg->mPrintType->id( 01172 cfg->mPrintType->selected() ) ); 01173 01174 mFromDate = cfg->mFromDate->date(); 01175 mToDate = cfg->mToDate->date(); 01176 01177 mIncludeDescription = cfg->mDescription->isChecked(); 01178 mIncludePriority = cfg->mPriority->isChecked(); 01179 mIncludeDueDate = cfg->mDueDate->isChecked(); 01180 mIncludePercentComplete = cfg->mPercentComplete->isChecked(); 01181 mConnectSubTodos = cfg->mConnectSubTodos->isChecked(); 01182 mStrikeOutCompleted = cfg->mStrikeOutCompleted->isChecked(); 01183 01184 mTodoSortField = (eTodoSortField)cfg->mSortField->currentItem(); 01185 mTodoSortDirection = (eTodoSortDirection)cfg->mSortDirection->currentItem(); 01186 } 01187 } 01188 01189 void CalPrintTodos::setSettingsWidget() 01190 { 01191 // kdDebug(5850) << "CalPrintTodos::setSettingsWidget" << endl; 01192 01193 CalPrintTodoConfig_Base *cfg = 01194 dynamic_cast<CalPrintTodoConfig_Base *>( mConfigWidget ); 01195 if ( cfg ) { 01196 cfg->mTitle->setText( mPageTitle ); 01197 01198 cfg->mPrintType->setButton( mTodoPrintType ); 01199 01200 cfg->mFromDate->setDate( mFromDate ); 01201 cfg->mToDate->setDate( mToDate ); 01202 01203 cfg->mDescription->setChecked( mIncludeDescription ); 01204 cfg->mPriority->setChecked( mIncludePriority ); 01205 cfg->mDueDate->setChecked( mIncludeDueDate ); 01206 cfg->mPercentComplete->setChecked( mIncludePercentComplete ); 01207 cfg->mConnectSubTodos->setChecked( mConnectSubTodos ); 01208 cfg->mStrikeOutCompleted->setChecked( mStrikeOutCompleted ); 01209 01210 if ( mTodoSortField != TodoFieldUnset ) { 01211 // do not insert if already done so. 01212 cfg->mSortField->insertItem( i18n("Summary") ); 01213 cfg->mSortField->insertItem( i18n("Start Date") ); 01214 cfg->mSortField->insertItem( i18n("Due Date") ); 01215 cfg->mSortField->insertItem( i18n("Priority") ); 01216 cfg->mSortField->insertItem( i18n("Percent Complete") ); 01217 cfg->mSortField->setCurrentItem( (int)mTodoSortField ); 01218 } 01219 01220 if ( mTodoSortDirection != TodoDirectionUnset ) { 01221 // do not insert if already done so. 01222 cfg->mSortDirection->insertItem( i18n("Ascending") ); 01223 cfg->mSortDirection->insertItem( i18n("Descending") ); 01224 cfg->mSortDirection->setCurrentItem( (int)mTodoSortDirection ); 01225 } 01226 } 01227 } 01228 01229 void CalPrintTodos::loadConfig() 01230 { 01231 if ( mConfig ) { 01232 mPageTitle = mConfig->readEntry( "Page title", i18n("To-do list") ); 01233 mTodoPrintType = (eTodoPrintType)mConfig->readNumEntry( "Print type", (int)TodosAll ); 01234 mIncludeDescription = mConfig->readBoolEntry( "Include description", true ); 01235 mIncludePriority = mConfig->readBoolEntry( "Include priority", true ); 01236 mIncludeDueDate = mConfig->readBoolEntry( "Include due date", true ); 01237 mIncludePercentComplete = mConfig->readBoolEntry( "Include percentage completed", true ); 01238 mConnectSubTodos = mConfig->readBoolEntry( "Connect subtodos", true ); 01239 mStrikeOutCompleted = mConfig->readBoolEntry( "Strike out completed summaries", true ); 01240 mTodoSortField = (eTodoSortField)mConfig->readNumEntry( "Sort field", (int)TodoFieldSummary ); 01241 mTodoSortDirection = (eTodoSortDirection)mConfig->readNumEntry( "Sort direction", (int)TodoDirectionAscending ); 01242 } 01243 setSettingsWidget(); 01244 } 01245 01246 void CalPrintTodos::saveConfig() 01247 { 01248 readSettingsWidget(); 01249 if ( mConfig ) { 01250 mConfig->writeEntry( "Page title", mPageTitle ); 01251 mConfig->writeEntry( "Print type", int( mTodoPrintType ) ); 01252 mConfig->writeEntry( "Include description", mIncludeDescription ); 01253 mConfig->writeEntry( "Include priority", mIncludePriority ); 01254 mConfig->writeEntry( "Include due date", mIncludeDueDate ); 01255 mConfig->writeEntry( "Include percentage completed", mIncludePercentComplete ); 01256 mConfig->writeEntry( "Connect subtodos", mConnectSubTodos ); 01257 mConfig->writeEntry( "Strike out completed summaries", mStrikeOutCompleted ); 01258 mConfig->writeEntry( "Sort field", mTodoSortField ); 01259 mConfig->writeEntry( "Sort direction", mTodoSortDirection ); 01260 } 01261 } 01262 01263 void CalPrintTodos::print( TQPainter &p, int width, int height ) 01264 { 01265 // TODO: Find a good way to guarantee a nicely designed output 01266 int pospriority = 0; 01267 int possummary = 100; 01268 int posdue = width - 65; 01269 int poscomplete = posdue - 70; //Complete column is to right of the Due column 01270 int lineSpacing = 15; 01271 int fontHeight = 10; 01272 01273 TQRect headerBox( 0, 0, width, headerHeight() ); 01274 TQRect footerBox( 0, height - footerHeight(), width, footerHeight() ); 01275 height -= footerHeight(); 01276 01277 // Draw the First Page Header 01278 drawHeader( p, mPageTitle, mFromDate, TQDate(), headerBox ); 01279 01280 // Draw the Column Headers 01281 int mCurrentLinePos = headerHeight() + 5; 01282 TQString outStr; 01283 TQFont oldFont( p.font() ); 01284 01285 p.setFont( TQFont( "sans-serif", 9, TQFont::Bold ) ); 01286 lineSpacing = p.fontMetrics().lineSpacing(); 01287 mCurrentLinePos += lineSpacing; 01288 if ( mIncludePriority ) { 01289 outStr += i18n( "Priority" ); 01290 p.drawText( pospriority, mCurrentLinePos - 2, outStr ); 01291 } else { 01292 pospriority = -1; 01293 } 01294 01295 outStr.truncate( 0 ); 01296 outStr += i18n( "Summary" ); 01297 p.drawText( possummary, mCurrentLinePos - 2, outStr ); 01298 01299 if ( mIncludePercentComplete ) { 01300 if ( !mIncludeDueDate ) //move Complete column to the right 01301 poscomplete = posdue; //if not print the Due Date column 01302 outStr.truncate( 0 ); 01303 outStr += i18n( "Complete" ); 01304 p.drawText( poscomplete, mCurrentLinePos - 2, outStr ); 01305 } else { 01306 poscomplete = -1; 01307 } 01308 01309 if ( mIncludeDueDate ) { 01310 outStr.truncate( 0 ); 01311 outStr += i18n( "Due" ); 01312 p.drawText( posdue, mCurrentLinePos - 2, outStr ); 01313 } else { 01314 posdue = -1; 01315 } 01316 01317 p.setFont( TQFont( "sans-serif", 10 ) ); 01318 fontHeight = p.fontMetrics().height(); 01319 01320 Todo::List todoList; 01321 Todo::List tempList; 01322 Todo::List::ConstIterator it; 01323 01324 // Convert sort options to the corresponding enums 01325 TodoSortField sortField = TodoSortSummary; 01326 switch( mTodoSortField ) { 01327 case TodoFieldSummary: 01328 sortField = TodoSortSummary; break; 01329 case TodoFieldStartDate: 01330 sortField = TodoSortStartDate; break; 01331 case TodoFieldDueDate: 01332 sortField = TodoSortDueDate; break; 01333 case TodoFieldPriority: 01334 sortField = TodoSortPriority; break; 01335 case TodoFieldPercentComplete: 01336 sortField = TodoSortPercentComplete; break; 01337 case TodoFieldUnset: 01338 break; 01339 } 01340 01341 SortDirection sortDirection; 01342 switch( mTodoSortDirection ) { 01343 case TodoDirectionAscending: 01344 sortDirection = SortDirectionAscending; break; 01345 case TodoDirectionDescending: 01346 sortDirection = SortDirectionDescending; break; 01347 case TodoDirectionUnset: 01348 break; 01349 } 01350 01351 // Create list of to-dos which will be printed 01352 todoList = mCalendar->todos( sortField, sortDirection ); 01353 switch( mTodoPrintType ) { 01354 case TodosAll: 01355 break; 01356 case TodosUnfinished: 01357 for( it = todoList.begin(); it!= todoList.end(); ++it ) { 01358 if ( !(*it)->isCompleted() ) 01359 tempList.append( *it ); 01360 } 01361 todoList = tempList; 01362 break; 01363 case TodosDueRange: 01364 for( it = todoList.begin(); it!= todoList.end(); ++it ) { 01365 if ( (*it)->hasDueDate() ) { 01366 if ( (*it)->dtDue().date() >= mFromDate && 01367 (*it)->dtDue().date() <= mToDate ) 01368 tempList.append( *it ); 01369 } else { 01370 tempList.append( *it ); 01371 } 01372 } 01373 todoList = tempList; 01374 break; 01375 } 01376 01377 // Print to-dos 01378 int count = 0; 01379 for ( it=todoList.begin(); it!=todoList.end(); ++it ) { 01380 Todo *currEvent = *it; 01381 01382 // Skip sub-to-dos. They will be printed recursively in drawTodo() 01383 if ( !currEvent->relatedTo() ) { 01384 count++; 01385 drawTodo( count, currEvent, p, 01386 sortField, sortDirection, 01387 mConnectSubTodos, 01388 mStrikeOutCompleted, mIncludeDescription, 01389 pospriority, possummary, posdue, poscomplete, 01390 0, 0, mCurrentLinePos, width, height, todoList ); 01391 } 01392 } 01393 01394 drawFooter( p, footerBox ); 01395 p.setFont( oldFont ); 01396 } 01397 01398 #endif