korganizer

calprintdefaultplugins.cpp
1/*
2 This file is part of KOrganizer.
3
4 Copyright (c) 1998 Preston Brown <pbrown@kde.org>
5 Copyright (c) 2003 Reinhold Kainhofer <reinhold@kainhofer.com>
6 Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
7 Copyright (c) 2008 Ron Goodheart <ron.goodheart@gmail.com>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22
23 As a special exception, permission is given to link this program
24 with any edition of TQt, and distribute the resulting executable,
25 without including the source code for TQt in the source distribution.
26*/
27
28#ifndef KORG_NOPRINTER
29
30#include <tqpainter.h>
31#include <tqdatetimeedit.h>
32#include <tqcheckbox.h>
33#include <tqlineedit.h>
34#include <tqbuttongroup.h>
35
36#include <kdebug.h>
37#include <tdeconfig.h>
38#include <kcalendarsystem.h>
39#include <knuminput.h>
40#include <kcombobox.h>
41
42#include <libkcal/incidenceformatter.h>
43
44#include "calprintdefaultplugins.h"
45
46#include "calprintincidenceconfig_base.h"
47#include "calprintdayconfig_base.h"
48#include "calprintweetdeconfig_base.h"
49#include "calprintmonthconfig_base.h"
50#include "calprinttodoconfig_base.h"
51
52static TQString cleanString( const TQString &instr )
53{
54 TQString ret = instr;
55 return ret.replace( '\n', ' ' );
56}
57
58/**************************************************************
59 * Print Incidence
60 **************************************************************/
61
62CalPrintIncidence::CalPrintIncidence() : CalPrintPluginBase()
63{
64}
65
66CalPrintIncidence::~CalPrintIncidence()
67{
68}
69
70TQWidget *CalPrintIncidence::createConfigWidget( TQWidget *w )
71{
72 return new CalPrintIncidenceConfig_Base( w );
73}
74
75void CalPrintIncidence::readSettingsWidget()
76{
77 CalPrintIncidenceConfig_Base *cfg =
78 dynamic_cast<CalPrintIncidenceConfig_Base*>( mConfigWidget );
79 if ( cfg ) {
80 mUseColors = cfg->mColors->isChecked();
81 mShowOptions = cfg->mShowDetails->isChecked();
82 mShowSubitemsNotes = cfg->mShowSubitemsNotes->isChecked();
83 mShowAttendees = cfg->mShowAttendees->isChecked();
84 mShowAttachments = cfg->mShowAttachments->isChecked();
85 }
86}
87
88void CalPrintIncidence::setSettingsWidget()
89{
90 CalPrintIncidenceConfig_Base *cfg =
91 dynamic_cast<CalPrintIncidenceConfig_Base*>( mConfigWidget );
92 if ( cfg ) {
93 cfg->mColors->setChecked( mUseColors );
94 cfg->mShowDetails->setChecked(mShowOptions);
95 cfg->mShowSubitemsNotes->setChecked(mShowSubitemsNotes);
96 cfg->mShowAttendees->setChecked(mShowAttendees);
97 cfg->mShowAttachments->setChecked(mShowAttachments);
98 }
99}
100
101void CalPrintIncidence::loadConfig()
102{
103 if ( mConfig ) {
104 mUseColors = mConfig->readBoolEntry( "Use Colors", false );
105 mShowOptions = mConfig->readBoolEntry( "Show Options", false );
106 mShowSubitemsNotes = mConfig->readBoolEntry( "Show Subitems and Notes", false );
107 mShowAttendees = mConfig->readBoolEntry( "Use Attendees", false );
108 mShowAttachments = mConfig->readBoolEntry( "Use Attachments", false );
109 }
110 setSettingsWidget();
111}
112
113void CalPrintIncidence::saveConfig()
114{
115 readSettingsWidget();
116 if ( mConfig ) {
117 mConfig->writeEntry( "Use Colors", mUseColors );
118 mConfig->writeEntry( "Show Options", mShowOptions );
119 mConfig->writeEntry( "Show Subitems and Notes", mShowSubitemsNotes );
120 mConfig->writeEntry( "Use Attendees", mShowAttendees );
121 mConfig->writeEntry( "Use Attachments", mShowAttachments );
122 }
123}
124
125
126class TimePrintStringsVisitor : public IncidenceBase::Visitor
127{
128 public:
129 TimePrintStringsVisitor() {}
130
131 bool act( IncidenceBase *incidence )
132 {
133 return incidence->accept( *this );
134 }
135 TQString mStartCaption, mStartString;
136 TQString mEndCaption, mEndString;
137 TQString mDurationCaption, mDurationString;
138
139 protected:
140 bool visit( Event *event ) {
141 if ( event->dtStart().isValid() ) {
142 mStartCaption = i18n( "Start date: " );
143 mStartString = IncidenceFormatter::dateTimeToString(
144 event->dtStart(), event->doesFloat(), false );
145 } else {
146 mStartCaption = i18n( "No start date" );
147 mStartString = TQString();
148 }
149
150 if ( event->hasEndDate() ) {
151 mEndCaption = i18n( "End date: " );
152 mEndString = IncidenceFormatter::dateTimeToString(
153 event->dtEnd(), event->doesFloat(), false );
154 } else if ( event->hasDuration() ) {
155 mEndCaption = i18n("Duration: ");
156 int mins = event->duration() / 60;
157 if ( mins >= 60 ) {
158 mEndString += i18n( "1 hour ", "%n hours ", mins/60 );
159 }
160 if ( mins%60 > 0 ) {
161 mEndString += i18n( "1 minute ", "%n minutes ", mins%60 );
162 }
163 } else {
164 mEndCaption = i18n("No end date");
165 mEndString = TQString();
166 }
167 return true;
168 }
169 bool visit( Todo *todo ) {
170 if ( todo->hasStartDate() ) {
171 mStartCaption = i18n( "Start date: " );
172 mStartString = IncidenceFormatter::dateTimeToString(
173 todo->dtStart(), todo->doesFloat(), false );
174 } else {
175 mStartCaption = i18n( "No start date" );
176 mStartString = TQString();
177 }
178
179 if ( todo->hasDueDate() ) {
180 mEndCaption = i18n( "Due date: " );
181 mEndString = IncidenceFormatter::dateTimeToString(
182 todo->dtDue(), todo->doesFloat(), false );
183 } else {
184 mEndCaption = i18n("No due date");
185 mEndString = TQString();
186 }
187 return true;
188 }
189 bool visit( Journal *journal ) {
190 mStartCaption = i18n( "Start date: " );
191 mStartString = IncidenceFormatter::dateTimeToString(
192 journal->dtStart(), journal->doesFloat(), false );
193 mEndCaption = TQString();
194 mEndString = TQString();
195 return true;
196 }
197};
198
199int CalPrintIncidence::printCaptionAndText( TQPainter &p, const TQRect &box, const TQString &caption, const TQString &text, TQFont captionFont, TQFont textFont )
200{
201 TQFontMetrics captionFM( captionFont );
202 int textWd = captionFM.width( caption );
203 TQRect textRect( box );
204
205 TQFont oldFont( p.font() );
206 p.setFont( captionFont );
207 p.drawText( box, TQt::AlignLeft|TQt::AlignTop|TQt::SingleLine, caption );
208
209 if ( !text.isEmpty() ) {
210 textRect.setLeft( textRect.left() + textWd );
211 p.setFont( textFont );
212 p.drawText( textRect, TQt::AlignLeft|TQt::AlignTop|TQt::SingleLine, text );
213 }
214 p.setFont( oldFont );
215 return textRect.bottom();
216}
217
218#include <tqfontdatabase.h>
219void CalPrintIncidence::print( TQPainter &p, int width, int height )
220{
221 TQFont oldFont(p.font());
222 TQFont textFont( "sans-serif", 11, TQFont::Normal );
223 TQFont captionFont( "sans-serif", 11, TQFont::Bold );
224 p.setFont( textFont );
225 int lineHeight = p.fontMetrics().lineSpacing();
226 TQString cap, txt;
227
228
229 Incidence::List::ConstIterator it;
230 for ( it=mSelectedIncidences.begin(); it!=mSelectedIncidences.end(); ++it ) {
231 // don't do anything on a 0-pointer!
232 if ( !(*it) ) continue;
233 if ( it != mSelectedIncidences.begin() ) mPrinter->newPage();
234
235
236 // PAGE Layout (same for landscape and portrait! astonishingly, it looks good with both!):
237 // +-----------------------------------+
238 // | Header: Summary |
239 // +===================================+
240 // | start: ______ end: _________ |
241 // | repeats: ___________________ |
242 // | reminder: __________________ |
243 // +-----------------------------------+
244 // | Location: ______________________ |
245 // +------------------------+----------+
246 // | Description: | Notes or |
247 // | | Subitems |
248 // | | |
249 // | | |
250 // | | |
251 // | | |
252 // | | |
253 // | | |
254 // | | |
255 // | | |
256 // +------------------------+----------+
257 // | Attachments: | Settings |
258 // | | |
259 // +------------------------+----------+
260 // | Attendees: |
261 // | |
262 // +-----------------------------------+
263 // | Categories: _____________________ |
264 // +-----------------------------------+
265
266 TQRect box( 0, 0, width, height );
267 TQRect titleBox( box );
268 titleBox.setHeight( headerHeight() );
269 // Draw summary as header, no small calendars in title bar, expand height if needed
270 int titleBottom = drawHeader( p, (*it)->summary(), TQDate(), TQDate(), titleBox, true );
271 titleBox.setBottom( titleBottom );
272
273 TQRect timesBox( titleBox );
274 timesBox.setTop( titleBox.bottom() + padding() );
275 timesBox.setHeight( height / 8 );
276
277 TimePrintStringsVisitor stringVis;
278 int h = timesBox.top();
279 if ( stringVis.act(*it) ) {
280 TQRect textRect( timesBox.left()+padding(), timesBox.top()+padding(), 0, lineHeight );
281 textRect.setRight( timesBox.center().x() );
282 h = printCaptionAndText( p, textRect, stringVis.mStartCaption, stringVis.mStartString, captionFont, textFont );
283
284 textRect.setLeft( textRect.right() );
285 textRect.setRight( timesBox.right() - padding() );
286 h = TQMAX( printCaptionAndText( p, textRect, stringVis.mEndCaption, stringVis.mEndString, captionFont, textFont ), h );
287 }
288
289 // Convert recurrence to a string
290 if ( (*it)->doesRecur() ) {
291 TQRect recurBox( timesBox.left()+padding(), h+padding(), timesBox.right()-padding(), lineHeight );
292 KCal::Recurrence *recurs = (*it)->recurrence();
293
294 TQString displayString = IncidenceFormatter::recurrenceString((*it));
295 // exception dates
296 TQString exceptString;
297 if ( !recurs->exDates().isEmpty() ) {
298 exceptString = i18n("except for listed dates", " except");
299 for ( uint i = 0; i < recurs->exDates().size(); i++ ) {
300 exceptString.append(" ");
301 exceptString.append( TDEGlobal::locale()->formatDate(recurs->exDates()[i],
302 true) );
303 }
304 }
305 displayString.append(exceptString);
306 h = TQMAX( printCaptionAndText( p, recurBox, i18n( "Repeats: "), displayString, captionFont, textFont ), h );
307 }
308
309 // Alarms Printing
310 TQRect alarmBox( timesBox.left()+padding(), h+padding(), timesBox.right()-padding(), lineHeight );
311 Alarm::List alarms = (*it)->alarms();
312 if ( alarms.count() == 0 ) {
313 cap = i18n("No reminders");
314 txt = TQString();
315 } else {
316 cap = i18n("Reminder: ", "%n reminders: ", alarms.count() );
317
318 TQStringList alarmStrings;
319 KCal::Alarm::List::ConstIterator it;
320 for ( it = alarms.begin(); it != alarms.end(); ++it ) {
321 Alarm *alarm = *it;
322
323 // Alarm offset, copied from koeditoralarms.cpp:
324 TQString offsetstr;
325 int offset = 0;
326 if ( alarm->hasStartOffset() ) {
327 offset = alarm->startOffset().asSeconds();
328 if ( offset < 0 ) {
329 offsetstr = i18n("N days/hours/minutes before/after the start/end", "%1 before the start");
330 offset = -offset;
331 } else {
332 offsetstr = i18n("N days/hours/minutes before/after the start/end", "%1 after the start");
333 }
334 } else if ( alarm->hasEndOffset() ) {
335 offset = alarm->endOffset().asSeconds();
336 if ( offset < 0 ) {
337 offsetstr = i18n("N days/hours/minutes before/after the start/end", "%1 before the end");
338 offset = -offset;
339 } else {
340 offsetstr = i18n("N days/hours/minutes before/after the start/end", "%1 after the end");
341 }
342 }
343
344 offset = offset / 60; // make minutes
345 int useoffset = offset;
346
347 if ( offset % (24*60) == 0 && offset>0 ) { // divides evenly into days?
348 useoffset = offset / (24*60);
349 offsetstr = offsetstr.arg( i18n("1 day", "%n days", useoffset ) );
350 } else if (offset % 60 == 0 && offset>0 ) { // divides evenly into hours?
351 useoffset = offset / 60;
352 offsetstr = offsetstr.arg( i18n("1 hour", "%n hours", useoffset ) );
353 } else {
354 useoffset = offset;
355 offsetstr = offsetstr.arg( i18n("1 minute", "%n minutes", useoffset ) );
356 }
357 alarmStrings << offsetstr;
358 }
359 txt = alarmStrings.join( i18n("Spacer for the joined list of categories", ", ") );
360
361 }
362 h = TQMAX( printCaptionAndText( p, alarmBox, cap, txt, captionFont, textFont ), h );
363
364
365 TQRect organizerBox( timesBox.left()+padding(), h+padding(), timesBox.right()-padding(), lineHeight );
366 h = TQMAX( printCaptionAndText( p, organizerBox, i18n("Organizer: "), (*it)->organizer().fullName(), captionFont, textFont ), h );
367
368 // Finally, draw the frame around the time information...
369 timesBox.setBottom( TQMAX( timesBox.bottom(), h+padding() ) );
370 drawBox( p, BOX_BORDER_WIDTH, timesBox );
371
372
373 TQRect locationBox( timesBox );
374 locationBox.setTop( timesBox.bottom() + padding() );
375 locationBox.setHeight( 0 );
376 int locationBottom = drawBoxWithCaption( p, locationBox, i18n("Location: "),
377 (*it)->location(), /*sameLine=*/true, /*expand=*/true, captionFont, textFont );
378 locationBox.setBottom( locationBottom );
379
380
381 // Now start constructing the boxes from the bottom:
382 TQRect footerBox( locationBox );
383 footerBox.setBottom( box.bottom() );
384 footerBox.setTop( footerBox.bottom() - lineHeight - 2*padding() );
385
386 TQRect categoriesBox( footerBox );
387 categoriesBox.setBottom( footerBox.top() );
388 categoriesBox.setTop( categoriesBox.bottom() - lineHeight - 2*padding() );
389
390 TQRect attendeesBox( box.left(), categoriesBox.top()-padding()-box.height()/9, box.width(), box.height()/9 );
391
392 TQRect attachmentsBox( box.left(), attendeesBox.top()-padding()-box.height()/9, box.width()*3/4 - padding(), box.height()/9 );
393 TQRect optionsBox( attachmentsBox.right() + padding(), attachmentsBox.top(), 0, 0 );
394 optionsBox.setRight( box.right() );
395 optionsBox.setBottom( attachmentsBox.bottom() );
396 TQRect notesBox( optionsBox.left(), locationBox.bottom() + padding(), optionsBox.width(), 0 );
397 notesBox.setBottom( optionsBox.top() - padding() );
398
399 TQRect descriptionBox( notesBox );
400 descriptionBox.setLeft( box.left() );
401 descriptionBox.setRight( attachmentsBox.right() );
402 // Adjust boxes depending on the show options...
403 if (!mShowSubitemsNotes) {
404 descriptionBox.setRight( box.right() );
405 }
406 if (!mShowAttachments || !mShowAttendees) {
407 descriptionBox.setBottom( attachmentsBox.bottom() );
408 optionsBox.setTop( attendeesBox.top() );
409 optionsBox.setBottom( attendeesBox.bottom() );
410 notesBox.setBottom( attachmentsBox.bottom() );
411 if (mShowOptions) {
412 attendeesBox.setRight( attachmentsBox.right() );
413 }
414 if (!mShowAttachments && !mShowAttendees) {
415 if (mShowSubitemsNotes) {
416 descriptionBox.setBottom( attendeesBox.bottom() );
417 }
418 if (!mShowOptions) {
419 descriptionBox.setBottom( attendeesBox.bottom() );
420 notesBox.setBottom( attendeesBox.bottom() );
421 }
422 }
423 }
424 if (mShowAttachments) {
425 if (!mShowOptions) {
426 attachmentsBox.setRight( box.right() );
427 attachmentsBox.setRight( box.right() );
428 }
429 if (!mShowAttendees) {
430 attachmentsBox.setTop( attendeesBox.top() );
431 attachmentsBox.setBottom( attendeesBox.bottom() );
432 }
433 }
434
435 drawBoxWithCaption( p, descriptionBox, i18n("Description:"),
436 (*it)->description(), /*sameLine=*/false,
437 /*expand=*/false, captionFont, textFont );
438
439 if ( mShowSubitemsNotes ) {
440 if ( (*it)->relations().isEmpty() || (*it)->type() != "Todo" ) {
441 int notesPosition = drawBoxWithCaption( p, notesBox, i18n("Notes:"),
442 TQString(), /*sameLine=*/false, /*expand=*/false,
443 captionFont, textFont );
444 TQPen oldPen( p.pen() );
445 p.setPen( TQt::DotLine );
446 while ( (notesPosition += int(1.5*lineHeight)) < notesBox.bottom() ) {
447 p.drawLine( notesBox.left()+padding(), notesPosition, notesBox.right()-padding(), notesPosition );
448 }
449 p.setPen( oldPen );
450 } else {
451 Incidence::List relations = (*it)->relations();
452 TQString subitemCaption;
453 if ( relations.count() == 0 ) {
454 subitemCaption = i18n( "No Subitems" );
455 txt == "";
456 } else {
457 subitemCaption = i18n( "1 Subitem:",
458 "%1 Subitems:",
459 relations.count() );
460 }
461 Incidence::List::ConstIterator rit;
462 TQString subitemString;
463 TQString statusString;
464 TQString datesString;
465 int count = 0;
466 for ( rit = relations.begin(); rit != relations.end(); ++rit ) {
467 ++count;
468 if ( !(*rit) ) { // defensive, skip any zero pointers
469 continue;
470 }
471 // format the status
472 statusString = (*rit)->statusStr();
473 if ( statusString.isEmpty() ) {
474 if ( (*rit)->status() == Incidence::StatusNone ) {
475 statusString = i18n( "no status", "none" );
476 } else {
477 statusString = i18n( "unknown status", "unknown" );
478 }
479 }
480 // format the dates if provided
481 datesString = "";
482 if ( (*rit)->dtStart().isValid() ) {
483 datesString += i18n(
484 "Start Date: %1\n").arg(
485 TDEGlobal::locale()->formatDate( (*rit)->dtStart().date(),
486 true ) );
487 if ( !(*rit)->doesFloat() ) {
488 datesString += i18n(
489 "Start Time: %1\n").arg(
490 TDEGlobal::locale()->formatTime((*rit)->dtStart().time(),
491 false, false) );
492 }
493 }
494 if ( (*rit)->dtEnd().isValid() ) {
495 subitemString += i18n(
496 "Due Date: %1\n").arg(
497 TDEGlobal::locale()->formatDate( (*rit)->dtEnd().date(),
498 true ) );
499 if ( !(*rit)->doesFloat() ) {
500 subitemString += i18n(
501 "subitem due time", "Due Time: %1\n").arg(
502 TDEGlobal::locale()->formatTime((*rit)->dtEnd().time(),
503 false, false) );
504 }
505 }
506 subitemString += i18n("subitem counter", "%1: ", count);
507 subitemString += (*rit)->summary();
508 subitemString += "\n";
509 if ( !datesString.isEmpty() ) {
510 subitemString += datesString;
511 subitemString += "\n";
512 }
513 subitemString += i18n( "subitem Status: statusString",
514 "Status: %1\n").arg( statusString );
515 subitemString += IncidenceFormatter::recurrenceString((*rit)) + "\n";
516 subitemString += i18n( "subitem Priority: N",
517 "Priority: %1\n").arg( (*rit)->priority() );
518 subitemString += i18n( "subitem Secrecy: secrecyString",
519 "Secrecy: %1\n").arg( (*rit)->secrecyStr() );
520 subitemString += "\n";
521 }
522 drawBoxWithCaption( p, notesBox, i18n("Subitems:"),
523 (*it)->description(), /*sameLine=*/false,
524 /*expand=*/false, captionFont, textFont );
525 }
526 }
527
528 if ( mShowAttachments ) {
529 Attachment::List attachments = (*it)->attachments();
530 TQString attachmentCaption;
531 if ( attachments.count() == 0 ) {
532 attachmentCaption = i18n( "No Attachments" );
533 txt = TQString();
534 } else {
535 attachmentCaption = i18n( "1 Attachment:", "%1 Attachments:", attachments.count() );
536 }
537 TQString attachmentString;
538 Attachment::List::ConstIterator ait = attachments.begin();
539 for ( ; ait != attachments.end(); ++ait ) {
540 if (!attachmentString.isEmpty()) {
541 attachmentString += i18n( "Spacer for list of attachments", " " );
542 }
543 attachmentString.append((*ait)->label());
544 }
545 drawBoxWithCaption( p, attachmentsBox,
546 attachmentCaption, attachmentString,
547 /*sameLine=*/false, /*expand=*/false,
548 captionFont, textFont );
549 }
550
551 if ( mShowAttendees ) {
552 Attendee::List attendees = (*it)->attendees();
553 TQString attendeeCaption;
554 if ( attendees.count() == 0 )
555 attendeeCaption = i18n("No Attendees");
556 else
557 attendeeCaption = i18n("1 Attendee:", "%n Attendees:", attendees.count() );
558 TQString attendeeString;
559 for ( Attendee::List::ConstIterator ait = attendees.begin(); ait != attendees.end(); ++ait ) {
560 if ( !attendeeString.isEmpty() ) attendeeString += "\n";
561 attendeeString += i18n("Formatting of an attendee: "
562 "'Name (Role): Status', e.g. 'Reinhold Kainhofer "
563 "<reinhold@kainhofer.com> (Participant): Awaiting Response'",
564 "%1 (%2): %3")
565 .arg( (*ait)->fullName() )
566 .arg( (*ait)->roleStr() ).arg( (*ait)->statusStr() );
567 }
568 drawBoxWithCaption( p, attendeesBox, i18n("Attendees:"), attendeeString,
569 /*sameLine=*/false, /*expand=*/false, captionFont, textFont );
570 }
571
572 if ( mShowOptions ) {
573 TQString optionsString;
574 if ( !(*it)->statusStr().isEmpty() ) {
575 optionsString += i18n("Status: %1").arg( (*it)->statusStr() );
576 optionsString += "\n";
577 }
578 if ( !(*it)->secrecyStr().isEmpty() ) {
579 optionsString += i18n("Secrecy: %1").arg( (*it)->secrecyStr() );
580 optionsString += "\n";
581 }
582 if ( (*it)->type() == "Event" ) {
583 Event *e = static_cast<Event*>(*it);
584 if ( e->transparency() == Event::Opaque ) {
585 optionsString += i18n("Show as: Busy");
586 } else {
587 optionsString += i18n("Show as: Free");
588 }
589 optionsString += "\n";
590 } else if ( (*it)->type() == "Todo" ) {
591 Todo *t = static_cast<Todo*>(*it);
592 if ( t->isOverdue() ) {
593 optionsString += i18n("This task is overdue!");
594 optionsString += "\n";
595 }
596 } else if ( (*it)->type() == "Journal" ) {
597 //TODO: Anything Journal-specific?
598 }
599 drawBoxWithCaption( p, optionsBox, i18n("Settings: "),
600 optionsString, /*sameLine=*/false, /*expand=*/false, captionFont, textFont );
601 }
602
603 drawBoxWithCaption( p, categoriesBox, i18n("Categories: "),
604 (*it)->categories().join( i18n("Spacer for the joined list of categories", ", ") ),
605 /*sameLine=*/true, /*expand=*/false, captionFont, textFont );
606
607 drawFooter( p, footerBox );
608 }
609 p.setFont( oldFont );
610}
611
612/**************************************************************
613 * Print Day
614 **************************************************************/
615
616CalPrintDay::CalPrintDay() : CalPrintPluginBase()
617{
618}
619
620CalPrintDay::~CalPrintDay()
621{
622}
623
624TQWidget *CalPrintDay::createConfigWidget( TQWidget *w )
625{
626 return new CalPrintDayConfig_Base( w );
627}
628
629void CalPrintDay::readSettingsWidget()
630{
631 CalPrintDayConfig_Base *cfg =
632 dynamic_cast<CalPrintDayConfig_Base*>( mConfigWidget );
633 if ( cfg ) {
634 mFromDate = cfg->mFromDate->date();
635 mToDate = cfg->mToDate->date();
636
637 mStartTime = cfg->mFromTime->time();
638 mEndTime = cfg->mToTime->time();
639 mIncludeAllEvents = cfg->mIncludeAllEvents->isChecked();
640
641 mIncludeTodos = cfg->mIncludeTodos->isChecked();
642 mUseColors = cfg->mColors->isChecked();
643 }
644}
645
646void CalPrintDay::setSettingsWidget()
647{
648 CalPrintDayConfig_Base *cfg =
649 dynamic_cast<CalPrintDayConfig_Base*>( mConfigWidget );
650 if ( cfg ) {
651 cfg->mFromDate->setDate( mFromDate );
652 cfg->mToDate->setDate( mToDate );
653
654 cfg->mFromTime->setTime( mStartTime );
655 cfg->mToTime->setTime( mEndTime );
656 cfg->mIncludeAllEvents->setChecked( mIncludeAllEvents );
657
658 cfg->mIncludeTodos->setChecked( mIncludeTodos );
659 cfg->mColors->setChecked( mUseColors );
660 }
661}
662
663void CalPrintDay::loadConfig()
664{
665 if ( mConfig ) {
666 TQDate dt;
667 TQTime tm1( dayStart() );
668 TQDateTime startTm( dt, tm1 );
669 TQDateTime endTm( dt, tm1.addSecs( 12 * 60 * 60 ) );
670 mStartTime = mConfig->readDateTimeEntry( "Start time", &startTm ).time();
671 mEndTime = mConfig->readDateTimeEntry( "End time", &endTm ).time();
672 mIncludeTodos = mConfig->readBoolEntry( "Include todos", false );
673 mIncludeAllEvents = mConfig->readBoolEntry( "Include all events", false );
674 }
675 setSettingsWidget();
676}
677
678void CalPrintDay::saveConfig()
679{
680 readSettingsWidget();
681 if ( mConfig ) {
682 mConfig->writeEntry( "Start time", TQDateTime( TQDate(), mStartTime ) );
683 mConfig->writeEntry( "End time", TQDateTime( TQDate(), mEndTime ) );
684 mConfig->writeEntry( "Include todos", mIncludeTodos );
685 mConfig->writeEntry( "Include all events", mIncludeAllEvents );
686 }
687}
688
689void CalPrintDay::setDateRange( const TQDate& from, const TQDate& to )
690{
692 CalPrintDayConfig_Base *cfg =
693 dynamic_cast<CalPrintDayConfig_Base*>( mConfigWidget );
694 if ( cfg ) {
695 cfg->mFromDate->setDate( from );
696 cfg->mToDate->setDate( to );
697 }
698}
699
700void CalPrintDay::print( TQPainter &p, int width, int height )
701{
702 TQDate curDay( mFromDate );
703
704 TQRect headerBox( 0, 0, width, headerHeight() );
705 TQRect footerBox( 0, height - footerHeight(), width, footerHeight() );
706 height -= footerHeight();
707
708 TDELocale *local = TDEGlobal::locale();
709
710 do {
711 TQTime curStartTime( mStartTime );
712 TQTime curEndTime( mEndTime );
713
714 // For an invalid time range, simply show one hour, starting at the hour
715 // before the given start time
716 if ( curEndTime <= curStartTime ) {
717 curStartTime = TQTime( curStartTime.hour(), 0, 0 );
718 curEndTime = curStartTime.addSecs( 3600 );
719 }
720
721 drawHeader( p, local->formatDate( curDay ), curDay, TQDate(), headerBox );
722 Event::List eventList = mCalendar->events( curDay,
723 EventSortStartDate,
724 SortDirectionAscending );
725
726 // split out the all day events as they will be printed in a separate box
727 Event::List alldayEvents, timedEvents;
728 Event::List::ConstIterator it;
729 for ( it = eventList.begin(); it != eventList.end(); ++it ) {
730 if ( (*it)->doesFloat() ) {
731 alldayEvents.append( *it );
732 } else {
733 timedEvents.append( *it );
734 }
735 }
736
737 int fontSize = 11;
738 TQFont textFont( "sans-serif", fontSize, TQFont::Normal );
739 p.setFont( textFont );
740 uint lineSpacing = p.fontMetrics().lineSpacing();
741
742 uint maxAllDayEvents = 8; // the max we allow to be printed, sorry.
743 uint allDayHeight = TQMIN( alldayEvents.count(), maxAllDayEvents ) * lineSpacing;
744 allDayHeight = TQMAX( allDayHeight, ( 5 * lineSpacing ) ) + ( 2 * padding() );
745 TQRect allDayBox( TIMELINE_WIDTH + padding(), headerBox.bottom() + padding(),
746 width - TIMELINE_WIDTH - padding(), allDayHeight );
747 if ( alldayEvents.count() > 0 ) {
748 // draw the side bar for all-day events
749 TQFont oldFont( p.font() );
750 p.setFont( TQFont( "sans-serif", 9, TQFont::Normal ) );
751 drawVerticalBox( p,
752 BOX_BORDER_WIDTH,
753 TQRect( 0, headerBox.bottom() + padding(), TIMELINE_WIDTH, allDayHeight ),
754 i18n( "Today's Events" ),
755 TQt::AlignHCenter | TQt::AlignVCenter | TQt::WordBreak );
756 p.setFont( oldFont );
757
758 // now draw at most maxAllDayEvents in the all-day box
759 drawBox( p, BOX_BORDER_WIDTH, allDayBox );
760
761 Event::List::ConstIterator it;
762 TQRect eventBox( allDayBox );
763 eventBox.setLeft( TIMELINE_WIDTH + ( 2 * padding() ) );
764 eventBox.setTop( eventBox.top() + padding() );
765 eventBox.setBottom( eventBox.top() + lineSpacing );
766 uint count = 0;
767 for ( it = alldayEvents.begin(); it != alldayEvents.end(); ++it ) {
768 if ( count == maxAllDayEvents ) {
769 break;
770 }
771 count++;
772 TQString str;
773 if ( (*it)->location().isEmpty() ) {
774 str = cleanString( (*it)->summary() );
775 } else {
776 str = i18n( "summary, location", "%1, %2" ).
777 arg( cleanString( (*it)->summary() ), cleanString( (*it)->location() ) );
778 }
779 printEventString( p, eventBox, str );
780 eventBox.setTop( eventBox.bottom() );
781 eventBox.setBottom( eventBox.top() + lineSpacing );
782 }
783 } else {
784 allDayBox.setBottom( headerBox.bottom() );
785 }
786
787 TQRect dayBox( allDayBox );
788 dayBox.setTop( allDayBox.bottom() + padding() );
789 dayBox.setBottom( height );
790 drawAgendaDayBox( p, timedEvents, curDay, mIncludeAllEvents,
791 curStartTime, curEndTime, dayBox );
792
793 TQRect tlBox( dayBox );
794 tlBox.setLeft( 0 );
795 tlBox.setWidth( TIMELINE_WIDTH );
796 drawTimeLine( p, curStartTime, curEndTime, tlBox );
797
798 drawFooter( p, footerBox );
799
800 curDay = curDay.addDays( 1 );
801 if ( curDay <= mToDate ) {
802 mPrinter->newPage();
803 }
804 } while ( curDay <= mToDate );
805}
806
807
808
809/**************************************************************
810 * Print Week
811 **************************************************************/
812
813CalPrintWeek::CalPrintWeek() : CalPrintPluginBase()
814{
815}
816
817CalPrintWeek::~CalPrintWeek()
818{
819}
820
821TQWidget *CalPrintWeek::createConfigWidget( TQWidget *w )
822{
823 return new CalPrintWeekConfig_Base( w );
824}
825
826void CalPrintWeek::readSettingsWidget()
827{
828 CalPrintWeekConfig_Base *cfg =
829 dynamic_cast<CalPrintWeekConfig_Base*>( mConfigWidget );
830 if ( cfg ) {
831 mFromDate = cfg->mFromDate->date();
832 mToDate = cfg->mToDate->date();
833
834 mWeekPrintType = (eWeekPrintType)( cfg->mPrintType->id(
835 cfg->mPrintType->selected() ) );
836
837 mStartTime = cfg->mFromTime->time();
838 mEndTime = cfg->mToTime->time();
839
840 mIncludeTodos = cfg->mIncludeTodos->isChecked();
841 mUseColors = cfg->mColors->isChecked();
842 }
843}
844
845void CalPrintWeek::setSettingsWidget()
846{
847 CalPrintWeekConfig_Base *cfg =
848 dynamic_cast<CalPrintWeekConfig_Base*>( mConfigWidget );
849 if ( cfg ) {
850 cfg->mFromDate->setDate( mFromDate );
851 cfg->mToDate->setDate( mToDate );
852
853 cfg->mPrintType->setButton( mWeekPrintType );
854
855 cfg->mFromTime->setTime( mStartTime );
856 cfg->mToTime->setTime( mEndTime );
857
858 cfg->mIncludeTodos->setChecked( mIncludeTodos );
859 cfg->mColors->setChecked( mUseColors );
860 }
861}
862
863void CalPrintWeek::loadConfig()
864{
865 if ( mConfig ) {
866 TQDate dt;
867 TQTime tm1( dayStart() );
868 TQDateTime startTm( dt, tm1 );
869 TQDateTime endTm( dt, tm1.addSecs( 43200 ) );
870 mStartTime = mConfig->readDateTimeEntry( "Start time", &startTm ).time();
871 mEndTime = mConfig->readDateTimeEntry( "End time", &endTm ).time();
872 mIncludeTodos = mConfig->readBoolEntry( "Include todos", false );
873 mWeekPrintType =(eWeekPrintType)( mConfig->readNumEntry( "Print type", (int)Filofax ) );
874 }
875 setSettingsWidget();
876}
877
878void CalPrintWeek::saveConfig()
879{
880 readSettingsWidget();
881 if ( mConfig ) {
882 mConfig->writeEntry( "Start time", TQDateTime( TQDate(), mStartTime ) );
883 mConfig->writeEntry( "End time", TQDateTime( TQDate(), mEndTime ) );
884 mConfig->writeEntry( "Include todos", mIncludeTodos );
885 mConfig->writeEntry( "Print type", int( mWeekPrintType ) );
886 }
887}
888
889KPrinter::Orientation CalPrintWeek::defaultOrientation()
890{
891 if ( mWeekPrintType == Filofax ) return KPrinter::Portrait;
892 else if ( mWeekPrintType == SplitWeek ) return KPrinter::Portrait;
893 else return KPrinter::Landscape;
894}
895
896void CalPrintWeek::setDateRange( const TQDate &from, const TQDate &to )
897{
899 CalPrintWeekConfig_Base *cfg =
900 dynamic_cast<CalPrintWeekConfig_Base*>( mConfigWidget );
901 if ( cfg ) {
902 cfg->mFromDate->setDate( from );
903 cfg->mToDate->setDate( to );
904 }
905}
906
907void CalPrintWeek::print( TQPainter &p, int width, int height )
908{
909 TQDate curWeek, fromWeek, toWeek;
910
911 // correct begin and end to first and last day of week
912 int weekdayCol = weekdayColumn( mFromDate.dayOfWeek() );
913 fromWeek = mFromDate.addDays( -weekdayCol );
914 weekdayCol = weekdayColumn( mFromDate.dayOfWeek() );
915 toWeek = mToDate.addDays( 6 - weekdayCol );
916
917 curWeek = fromWeek.addDays( 6 );
918 TDELocale *local = TDEGlobal::locale();
919
920 TQString line1, line2, title;
921 TQRect headerBox( 0, 0, width, headerHeight() );
922 TQRect footerBox( 0, height - footerHeight(), width, footerHeight() );
923 height -= footerHeight();
924
925 TQRect weekBox( headerBox );
926 weekBox.setTop( headerBox.bottom() + padding() );
927 weekBox.setBottom( height );
928
929 switch ( mWeekPrintType ) {
930 case Filofax:
931 do {
932 line1 = local->formatDate( curWeek.addDays( -6 ) );
933 line2 = local->formatDate( curWeek );
934 if ( orientation() == KPrinter::Landscape ) {
935 title = i18n("date from-to", "%1 - %2");
936 } else {
937 title = i18n("date from-\nto", "%1 -\n%2");;
938 }
939 title = title.arg( line1 ).arg( line2 );
940 drawHeader( p, title, curWeek.addDays( -6 ), TQDate(), headerBox );
941
942 drawWeek( p, curWeek, weekBox );
943
944 drawFooter( p, footerBox );
945
946 curWeek = curWeek.addDays( 7 );
947 if ( curWeek <= toWeek )
948 mPrinter->newPage();
949 } while ( curWeek <= toWeek );
950 break;
951
952 case Timetable:
953 default:
954 do {
955 line1 = local->formatDate( curWeek.addDays( -6 ) );
956 line2 = local->formatDate( curWeek );
957 if ( orientation() == KPrinter::Landscape ) {
958 title = i18n("date from - to (week number)", "%1 - %2 (Week %3)");
959 } else {
960 title = i18n("date from -\nto (week number)", "%1 -\n%2 (Week %3)");
961 }
962 title = title.arg( line1 ).arg( line2 ).arg( curWeek.weekNumber() );
963 drawHeader( p, title, curWeek, TQDate(), headerBox );
964
965 TQRect weekBox( headerBox );
966 weekBox.setTop( headerBox.bottom() + padding() );
967 weekBox.setBottom( height );
968 drawTimeTable( p, fromWeek, curWeek, mStartTime, mEndTime, weekBox );
969
970 drawFooter( p, footerBox );
971
972 fromWeek = fromWeek.addDays( 7 );
973 curWeek = fromWeek.addDays( 6 );
974 if ( curWeek <= toWeek )
975 mPrinter->newPage();
976 } while ( curWeek <= toWeek );
977 break;
978
979 case SplitWeek: {
980 TQRect weekBox1( weekBox );
981 // On the left side there are four days (mo-th) plus the timeline,
982 // on the right there are only three days (fr-su) plus the timeline. Don't
983 // use the whole width, but rather give them the same width as on the left.
984 weekBox1.setRight( int( ( width - TIMELINE_WIDTH ) * 3. / 4. + TIMELINE_WIDTH ) );
985 do {
986 TQDate endLeft( fromWeek.addDays( 3 ) );
987 int hh = headerHeight();
988
989 drawTimeTable( p, fromWeek, endLeft,
990 mStartTime, mEndTime, weekBox );
991 mPrinter->newPage();
992 drawSplitHeaderRight( p, fromWeek, curWeek, TQDate(), width, hh );
993 drawTimeTable( p, endLeft.addDays( 1 ), curWeek,
994 mStartTime, mEndTime, weekBox1 );
995
996 drawFooter( p, footerBox );
997
998 fromWeek = fromWeek.addDays( 7 );
999 curWeek = fromWeek.addDays( 6 );
1000 if ( curWeek <= toWeek )
1001 mPrinter->newPage();
1002 } while ( curWeek <= toWeek );
1003 }
1004 break;
1005 }
1006}
1007
1008
1009
1010
1011/**************************************************************
1012 * Print Month
1013 **************************************************************/
1014
1015CalPrintMonth::CalPrintMonth() : CalPrintPluginBase()
1016{
1017}
1018
1019CalPrintMonth::~CalPrintMonth()
1020{
1021}
1022
1023TQWidget *CalPrintMonth::createConfigWidget( TQWidget *w )
1024{
1025 return new CalPrintMonthConfig_Base( w );
1026}
1027
1028void CalPrintMonth::readSettingsWidget()
1029{
1030 CalPrintMonthConfig_Base *cfg =
1031 dynamic_cast<CalPrintMonthConfig_Base *>( mConfigWidget );
1032 if ( cfg ) {
1033 mFromDate = TQDate( cfg->mFromYear->value(), cfg->mFromMonth->currentItem()+1, 1 );
1034 mToDate = TQDate( cfg->mToYear->value(), cfg->mToMonth->currentItem()+1, 1 );
1035
1036 mWeekNumbers = cfg->mWeekNumbers->isChecked();
1037 mRecurDaily = cfg->mRecurDaily->isChecked();
1038 mRecurWeekly = cfg->mRecurWeekly->isChecked();
1039 mIncludeTodos = cfg->mIncludeTodos->isChecked();
1040// mUseColors = cfg->mColors->isChecked();
1041 }
1042}
1043
1044void CalPrintMonth::setSettingsWidget()
1045{
1046 CalPrintMonthConfig_Base *cfg =
1047 dynamic_cast<CalPrintMonthConfig_Base *>( mConfigWidget );
1048 setDateRange( mFromDate, mToDate );
1049 if ( cfg ) {
1050 cfg->mWeekNumbers->setChecked( mWeekNumbers );
1051 cfg->mRecurDaily->setChecked( mRecurDaily );
1052 cfg->mRecurWeekly->setChecked( mRecurWeekly );
1053 cfg->mIncludeTodos->setChecked( mIncludeTodos );
1054// cfg->mColors->setChecked( mUseColors );
1055 }
1056}
1057
1058void CalPrintMonth::loadConfig()
1059{
1060 if ( mConfig ) {
1061 mWeekNumbers = mConfig->readBoolEntry( "Print week numbers", true );
1062 mRecurDaily = mConfig->readBoolEntry( "Print daily incidences", true );
1063 mRecurWeekly = mConfig->readBoolEntry( "Print weekly incidences", true );
1064 mIncludeTodos = mConfig->readBoolEntry( "Include todos", false );
1065 }
1066 setSettingsWidget();
1067}
1068
1069void CalPrintMonth::saveConfig()
1070{
1071 readSettingsWidget();
1072 if ( mConfig ) {
1073 mConfig->writeEntry( "Print week numbers", mWeekNumbers );
1074 mConfig->writeEntry( "Print daily incidences", mRecurDaily );
1075 mConfig->writeEntry( "Print weekly incidences", mRecurWeekly );
1076 mConfig->writeEntry( "Include todos", mIncludeTodos );
1077 }
1078}
1079
1080void CalPrintMonth::setDateRange( const TQDate &from, const TQDate &to )
1081{
1083 CalPrintMonthConfig_Base *cfg =
1084 dynamic_cast<CalPrintMonthConfig_Base *>( mConfigWidget );
1085 const KCalendarSystem *calSys = calendarSystem();
1086 if ( cfg && calSys ) {
1087 cfg->mFromMonth->clear();
1088 for ( int i=0; i<calSys->monthsInYear( mFromDate ); ++i ) {
1089 cfg->mFromMonth->insertItem( calSys->monthName( i+1, mFromDate.year() ) );
1090 }
1091 cfg->mToMonth->clear();
1092 for ( int i=0; i<calSys->monthsInYear( mToDate ); ++i ) {
1093 cfg->mToMonth->insertItem( calSys->monthName( i+1, mToDate.year() ) );
1094 }
1095 }
1096 if ( cfg ) {
1097 cfg->mFromMonth->setCurrentItem( from.month()-1 );
1098 cfg->mFromYear->setValue( to.year() );
1099 cfg->mToMonth->setCurrentItem( mToDate.month()-1 );
1100 cfg->mToYear->setValue( mToDate.year() );
1101 }
1102}
1103
1104void CalPrintMonth::print( TQPainter &p, int width, int height )
1105{
1106 TQDate curMonth, fromMonth, toMonth;
1107
1108 fromMonth = mFromDate.addDays( -( mFromDate.day() - 1 ) );
1109 toMonth = mToDate.addDays( mToDate.daysInMonth() - mToDate.day() );
1110
1111 curMonth = fromMonth;
1112 const KCalendarSystem *calSys = calendarSystem();
1113 if ( !calSys ) return;
1114
1115 TQRect headerBox( 0, 0, width, headerHeight() );
1116 TQRect footerBox( 0, height - footerHeight(), width, footerHeight() );
1117 height -= footerHeight();
1118
1119 TQRect monthBox( 0, 0, width, height );
1120 monthBox.setTop( headerBox.bottom() + padding() );
1121
1122 do {
1123 TQString title( i18n("monthname year", "%1 %2") );
1124 title = title.arg( calSys->monthName( curMonth ) )
1125 .arg( curMonth.year() );
1126 TQDate tmp( fromMonth );
1127 int weekdayCol = weekdayColumn( tmp.dayOfWeek() );
1128 tmp = tmp.addDays( -weekdayCol );
1129
1130 drawHeader( p, title, curMonth.addMonths( -1 ), curMonth.addMonths( 1 ),
1131 headerBox );
1132 drawMonthTable( p, curMonth, mWeekNumbers, mRecurDaily, mRecurWeekly, monthBox );
1133
1134 drawFooter( p, footerBox );
1135
1136 curMonth = curMonth.addDays( curMonth.daysInMonth() );
1137 if ( curMonth <= toMonth ) mPrinter->newPage();
1138 } while ( curMonth <= toMonth );
1139
1140}
1141
1142
1143
1144
1145/**************************************************************
1146 * Print Todos
1147 **************************************************************/
1148
1149CalPrintTodos::CalPrintTodos() : CalPrintPluginBase()
1150{
1151 mTodoSortField = TodoFieldUnset;
1152 mTodoSortDirection = TodoDirectionUnset;
1153}
1154
1155CalPrintTodos::~CalPrintTodos()
1156{
1157}
1158
1159TQWidget *CalPrintTodos::createConfigWidget( TQWidget *w )
1160{
1161 return new CalPrintTodoConfig_Base( w );
1162}
1163
1164void CalPrintTodos::readSettingsWidget()
1165{
1166 CalPrintTodoConfig_Base *cfg =
1167 dynamic_cast<CalPrintTodoConfig_Base *>( mConfigWidget );
1168 if ( cfg ) {
1169 mPageTitle = cfg->mTitle->text();
1170
1171 mTodoPrintType = (eTodoPrintType)( cfg->mPrintType->id(
1172 cfg->mPrintType->selected() ) );
1173
1174 mFromDate = cfg->mFromDate->date();
1175 mToDate = cfg->mToDate->date();
1176
1177 mIncludeDescription = cfg->mDescription->isChecked();
1178 mIncludePriority = cfg->mPriority->isChecked();
1179 mIncludeDueDate = cfg->mDueDate->isChecked();
1180 mIncludePercentComplete = cfg->mPercentComplete->isChecked();
1181 mConnectSubTodos = cfg->mConnectSubTodos->isChecked();
1182 mStrikeOutCompleted = cfg->mStrikeOutCompleted->isChecked();
1183
1184 mTodoSortField = (eTodoSortField)cfg->mSortField->currentItem();
1185 mTodoSortDirection = (eTodoSortDirection)cfg->mSortDirection->currentItem();
1186 }
1187}
1188
1189void CalPrintTodos::setSettingsWidget()
1190{
1191// kdDebug(5850) << "CalPrintTodos::setSettingsWidget" << endl;
1192
1193 CalPrintTodoConfig_Base *cfg =
1194 dynamic_cast<CalPrintTodoConfig_Base *>( mConfigWidget );
1195 if ( cfg ) {
1196 cfg->mTitle->setText( mPageTitle );
1197
1198 cfg->mPrintType->setButton( mTodoPrintType );
1199
1200 cfg->mFromDate->setDate( mFromDate );
1201 cfg->mToDate->setDate( mToDate );
1202
1203 cfg->mDescription->setChecked( mIncludeDescription );
1204 cfg->mPriority->setChecked( mIncludePriority );
1205 cfg->mDueDate->setChecked( mIncludeDueDate );
1206 cfg->mPercentComplete->setChecked( mIncludePercentComplete );
1207 cfg->mConnectSubTodos->setChecked( mConnectSubTodos );
1208 cfg->mStrikeOutCompleted->setChecked( mStrikeOutCompleted );
1209
1210 if ( mTodoSortField != TodoFieldUnset ) {
1211 // do not insert if already done so.
1212 cfg->mSortField->insertItem( i18n("Summary") );
1213 cfg->mSortField->insertItem( i18n("Start Date") );
1214 cfg->mSortField->insertItem( i18n("Due Date") );
1215 cfg->mSortField->insertItem( i18n("Priority") );
1216 cfg->mSortField->insertItem( i18n("Percent Complete") );
1217 cfg->mSortField->setCurrentItem( (int)mTodoSortField );
1218 }
1219
1220 if ( mTodoSortDirection != TodoDirectionUnset ) {
1221 // do not insert if already done so.
1222 cfg->mSortDirection->insertItem( i18n("Ascending") );
1223 cfg->mSortDirection->insertItem( i18n("Descending") );
1224 cfg->mSortDirection->setCurrentItem( (int)mTodoSortDirection );
1225 }
1226 }
1227}
1228
1229void CalPrintTodos::loadConfig()
1230{
1231 if ( mConfig ) {
1232 mPageTitle = mConfig->readEntry( "Page title", i18n("To-do list") );
1233 mTodoPrintType = (eTodoPrintType)mConfig->readNumEntry( "Print type", (int)TodosAll );
1234 mIncludeDescription = mConfig->readBoolEntry( "Include description", true );
1235 mIncludePriority = mConfig->readBoolEntry( "Include priority", true );
1236 mIncludeDueDate = mConfig->readBoolEntry( "Include due date", true );
1237 mIncludePercentComplete = mConfig->readBoolEntry( "Include percentage completed", true );
1238 mConnectSubTodos = mConfig->readBoolEntry( "Connect subtodos", true );
1239 mStrikeOutCompleted = mConfig->readBoolEntry( "Strike out completed summaries", true );
1240 mTodoSortField = (eTodoSortField)mConfig->readNumEntry( "Sort field", (int)TodoFieldSummary );
1241 mTodoSortDirection = (eTodoSortDirection)mConfig->readNumEntry( "Sort direction", (int)TodoDirectionAscending );
1242 }
1243 setSettingsWidget();
1244}
1245
1246void CalPrintTodos::saveConfig()
1247{
1248 readSettingsWidget();
1249 if ( mConfig ) {
1250 mConfig->writeEntry( "Page title", mPageTitle );
1251 mConfig->writeEntry( "Print type", int( mTodoPrintType ) );
1252 mConfig->writeEntry( "Include description", mIncludeDescription );
1253 mConfig->writeEntry( "Include priority", mIncludePriority );
1254 mConfig->writeEntry( "Include due date", mIncludeDueDate );
1255 mConfig->writeEntry( "Include percentage completed", mIncludePercentComplete );
1256 mConfig->writeEntry( "Connect subtodos", mConnectSubTodos );
1257 mConfig->writeEntry( "Strike out completed summaries", mStrikeOutCompleted );
1258 mConfig->writeEntry( "Sort field", mTodoSortField );
1259 mConfig->writeEntry( "Sort direction", mTodoSortDirection );
1260 }
1261}
1262
1263void CalPrintTodos::print( TQPainter &p, int width, int height )
1264{
1265 // TODO: Find a good way to guarantee a nicely designed output
1266 int pospriority = 0;
1267 int possummary = 100;
1268 int posdue = width - 65;
1269 int poscomplete = posdue - 70; //Complete column is to right of the Due column
1270 int lineSpacing = 15;
1271 int fontHeight = 10;
1272
1273 TQRect headerBox( 0, 0, width, headerHeight() );
1274 TQRect footerBox( 0, height - footerHeight(), width, footerHeight() );
1275 height -= footerHeight();
1276
1277 // Draw the First Page Header
1278 drawHeader( p, mPageTitle, mFromDate, TQDate(), headerBox );
1279
1280 // Draw the Column Headers
1281 int mCurrentLinePos = headerHeight() + 5;
1282 TQString outStr;
1283 TQFont oldFont( p.font() );
1284
1285 p.setFont( TQFont( "sans-serif", 9, TQFont::Bold ) );
1286 lineSpacing = p.fontMetrics().lineSpacing();
1287 mCurrentLinePos += lineSpacing;
1288 if ( mIncludePriority ) {
1289 outStr += i18n( "Priority" );
1290 p.drawText( pospriority, mCurrentLinePos - 2, outStr );
1291 } else {
1292 pospriority = -1;
1293 }
1294
1295 outStr.truncate( 0 );
1296 outStr += i18n( "Summary" );
1297 p.drawText( possummary, mCurrentLinePos - 2, outStr );
1298
1299 if ( mIncludePercentComplete ) {
1300 if ( !mIncludeDueDate ) //move Complete column to the right
1301 poscomplete = posdue; //if not print the Due Date column
1302 outStr.truncate( 0 );
1303 outStr += i18n( "Complete" );
1304 p.drawText( poscomplete, mCurrentLinePos - 2, outStr );
1305 } else {
1306 poscomplete = -1;
1307 }
1308
1309 if ( mIncludeDueDate ) {
1310 outStr.truncate( 0 );
1311 outStr += i18n( "Due" );
1312 p.drawText( posdue, mCurrentLinePos - 2, outStr );
1313 } else {
1314 posdue = -1;
1315 }
1316
1317 p.setFont( TQFont( "sans-serif", 10 ) );
1318 fontHeight = p.fontMetrics().height();
1319
1320 Todo::List todoList;
1321 Todo::List tempList;
1322 Todo::List::ConstIterator it;
1323
1324 // Convert sort options to the corresponding enums
1325 TodoSortField sortField = TodoSortSummary;
1326 switch( mTodoSortField ) {
1327 case TodoFieldSummary:
1328 sortField = TodoSortSummary; break;
1329 case TodoFieldStartDate:
1330 sortField = TodoSortStartDate; break;
1331 case TodoFieldDueDate:
1332 sortField = TodoSortDueDate; break;
1333 case TodoFieldPriority:
1334 sortField = TodoSortPriority; break;
1335 case TodoFieldPercentComplete:
1336 sortField = TodoSortPercentComplete; break;
1337 case TodoFieldUnset:
1338 break;
1339 }
1340
1341 SortDirection sortDirection;
1342 switch( mTodoSortDirection ) {
1343 case TodoDirectionAscending:
1344 sortDirection = SortDirectionAscending; break;
1345 case TodoDirectionDescending:
1346 sortDirection = SortDirectionDescending; break;
1347 case TodoDirectionUnset:
1348 break;
1349 }
1350
1351 // Create list of to-dos which will be printed
1352 todoList = mCalendar->todos( sortField, sortDirection );
1353 switch( mTodoPrintType ) {
1354 case TodosAll:
1355 break;
1356 case TodosUnfinished:
1357 for( it = todoList.begin(); it!= todoList.end(); ++it ) {
1358 if ( !(*it)->isCompleted() )
1359 tempList.append( *it );
1360 }
1361 todoList = tempList;
1362 break;
1363 case TodosDueRange:
1364 for( it = todoList.begin(); it!= todoList.end(); ++it ) {
1365 if ( (*it)->hasDueDate() ) {
1366 if ( (*it)->dtDue().date() >= mFromDate &&
1367 (*it)->dtDue().date() <= mToDate )
1368 tempList.append( *it );
1369 } else {
1370 tempList.append( *it );
1371 }
1372 }
1373 todoList = tempList;
1374 break;
1375 }
1376
1377 // Print to-dos
1378 int count = 0;
1379 for ( it=todoList.begin(); it!=todoList.end(); ++it ) {
1380 Todo *currEvent = *it;
1381
1382 // Skip sub-to-dos. They will be printed recursively in drawTodo()
1383 if ( !currEvent->relatedTo() ) {
1384 count++;
1385 drawTodo( count, currEvent, p,
1386 sortField, sortDirection,
1387 mConnectSubTodos,
1388 mStrikeOutCompleted, mIncludeDescription,
1389 pospriority, possummary, posdue, poscomplete,
1390 0, 0, mCurrentLinePos, width, height, todoList );
1391 }
1392 }
1393
1394 drawFooter( p, footerBox );
1395 p.setFont( oldFont );
1396}
1397
1398#endif
Base class for KOrganizer printing classes.
bool hasStartOffset() const
Duration endOffset() const
bool hasEndOffset() const
Duration startOffset() const
int asSeconds() const
virtual TQDateTime dtEnd() const
Transparency transparency() const
bool hasEndDate() const
virtual bool visit(Event *)
bool doesFloat() const
virtual TQDateTime dtStart() const
virtual bool accept(Visitor &)
Incidence * relatedTo() const
bool hasDueDate() const
bool hasStartDate() const
bool isOverdue() const
TQDateTime dtStart(bool first=false) const
TQDateTime dtDue(bool first=false) const
virtual void setDateRange(const TQDate &from, const TQDate &to)
Set date range which should be printed.
Definition: printplugin.h:141
TodoSortField
TodoSortSummary
TodoSortDueDate
TodoSortPriority
TodoSortPercentComplete
TodoSortStartDate
SortDirection
SortDirectionAscending
SortDirectionDescending