korganizer

calprintpluginbase.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 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 
21  As a special exception, permission is given to link this program
22  with any edition of TQt, and distribute the resulting executable,
23  without including the source code for TQt in the source distribution.
24 */
25 
26 #include <tqpainter.h>
27 #include <tqlayout.h>
28 #include <tqframe.h>
29 #include <tqlabel.h>
30 
31 #include <kdebug.h>
32 #include <tdeconfig.h>
33 #include <kcalendarsystem.h>
34 #include <kwordwrap.h>
35 
36 #include "calprintpluginbase.h"
37 #include "cellitem.h"
38 
39 #ifndef KORG_NOPRINTER
40 
41 inline int roundToInt(const double x)
42 {
43  return int(x > 0.0 ? x + 0.5 : x - 0.5);
44 }
45 
46 static TQString cleanStr( const TQString &instr )
47 {
48  TQString ret = instr;
49  return ret.replace( '\n', ' ' );
50 }
51 
52 /******************************************************************
53  ** The Todo positioning structure **
54  ******************************************************************/
55 class CalPrintPluginBase::TodoParentStart
56 {
57  public:
58  TodoParentStart( TQRect pt = TQRect(), bool page = true )
59  : mRect( pt ), mSamePage( page ) {}
60 
61  TQRect mRect;
62  bool mSamePage;
63 };
64 
65 
66 /******************************************************************
67  ** The Print item **
68  ******************************************************************/
69 
70 
71 class PrintCellItem : public KOrg::CellItem
72 {
73  public:
74  PrintCellItem( Event *event, const TQDateTime &start, const TQDateTime &end )
75  : mEvent( event ), mStart( start), mEnd( end )
76  {
77  }
78 
79  Event *event() const { return mEvent; }
80 
81  TQString label() const { return mEvent->summary(); }
82 
83  TQDateTime start() const { return mStart; }
84  TQDateTime end() const { return mEnd; }
85 
88  bool overlaps( KOrg::CellItem *o ) const
89  {
90  PrintCellItem *other = static_cast<PrintCellItem *>( o );
91 
92 #if 0
93  kdDebug(5850) << "PrintCellItem::overlaps() " << event()->summary()
94  << " <-> " << other->event()->summary() << endl;
95  kdDebug(5850) << " start : " << start.toString() << endl;
96  kdDebug(5850) << " end : " << end.toString() << endl;
97  kdDebug(5850) << " otherStart: " << otherStart.toString() << endl;
98  kdDebug(5850) << " otherEnd : " << otherEnd.toString() << endl;
99 #endif
100 
101  return !( other->start() >= end() || other->end() <= start() );
102  }
103 
104  private:
105  Event *mEvent;
106  TQDateTime mStart, mEnd;
107 };
108 
109 
110 
111 
112 /******************************************************************
113  ** The Print plugin **
114  ******************************************************************/
115 
116 
117 CalPrintPluginBase::CalPrintPluginBase() : PrintPlugin(), mUseColors( true ),
118  mHeaderHeight( -1 ), mSubHeaderHeight( SUBHEADER_HEIGHT ), mFooterHeight( -1 ),
119  mMargin( MARGIN_SIZE ), mPadding( PADDING_SIZE), mCalSys( 0 )
120 {
121 }
122 CalPrintPluginBase::~CalPrintPluginBase()
123 {
124 }
125 
126 
127 
129 {
130  TQFrame *wdg = new TQFrame( w );
131  TQVBoxLayout *layout = new TQVBoxLayout( wdg );
132 
133  TQLabel *title = new TQLabel( description(), wdg );
134  TQFont titleFont( title->font() );
135  titleFont.setPointSize( 20 );
136  titleFont.setBold( true );
137  title->setFont( titleFont );
138 
139  layout->addWidget( title );
140  layout->addWidget( new TQLabel( info(), wdg ) );
141  layout->addSpacing( 20 );
142  layout->addWidget( new TQLabel( i18n("This printing style does not "
143  "have any configuration options."),
144  wdg ) );
145  layout->addStretch();
146  return wdg;
147 }
148 
149 void CalPrintPluginBase::doPrint( KPrinter *printer )
150 {
151  if ( !printer ) return;
152  mPrinter = printer;
153  TQPainter p;
154 
155  mPrinter->setColorMode( mUseColors?(KPrinter::Color):(KPrinter::GrayScale) );
156 
157  p.begin( mPrinter );
158  // TODO: Fix the margins!!!
159  // the painter initially begins at 72 dpi per the TQt docs.
160  // we want half-inch margins.
161  int margins = margin();
162  p.setViewport( margins, margins,
163  p.viewport().width() - 2*margins,
164  p.viewport().height() - 2*margins );
165 // TQRect vp( p.viewport() );
166 // vp.setRight( vp.right()*2 );
167 // vp.setBottom( vp.bottom()*2 );
168 // p.setWindow( vp );
169  int pageWidth = p.window().width();
170  int pageHeight = p.window().height();
171 // int pageWidth = p.viewport().width();
172 // int pageHeight = p.viewport().height();
173 
174  print( p, pageWidth, pageHeight );
175 
176  p.end();
177  mPrinter = 0;
178 }
179 
181 {
182  if ( mConfig ) {
183  TDEConfigGroupSaver saver( mConfig, description() );
184  mConfig->sync();
185  TQDateTime currDate( TQDate::currentDate() );
186  mFromDate = mConfig->readDateTimeEntry( "FromDate", &currDate ).date();
187  mToDate = mConfig->readDateTimeEntry( "ToDate" ).date();
188  mUseColors = mConfig->readBoolEntry( "UseColors", true );
189  setUseColors( mUseColors );
190  loadConfig();
191  } else {
192  kdDebug(5850) << "No config available in loadConfig!!!!" << endl;
193  }
194 }
195 
197 {
198  if ( mConfig ) {
199  TDEConfigGroupSaver saver( mConfig, description() );
200  saveConfig();
201  mConfig->writeEntry( "FromDate", TQDateTime( mFromDate ) );
202  mConfig->writeEntry( "ToDate", TQDateTime( mToDate ) );
203  mConfig->writeEntry( "UseColors", mUseColors );
204  mConfig->sync();
205  } else {
206  kdDebug(5850) << "No config available in saveConfig!!!!" << endl;
207  }
208 }
209 
210 
211 
212 
213 void CalPrintPluginBase::setKOrgCoreHelper( KOrg::CoreHelper*helper )
214 {
215  PrintPlugin::setKOrgCoreHelper( helper );
216  if ( helper )
217  setCalendarSystem( helper->calendarSystem() );
218 }
219 
220 bool CalPrintPluginBase::useColors() const
221 {
222  return mUseColors;
223 }
224 void CalPrintPluginBase::setUseColors( bool useColors )
225 {
226  mUseColors = useColors;
227 }
228 
229 KPrinter::Orientation CalPrintPluginBase::orientation() const
230 {
231  return (mPrinter)?(mPrinter->orientation()):(KPrinter::Portrait);
232 }
233 
234 
235 
236 TQTime CalPrintPluginBase::dayStart()
237 {
238  TQTime start( 8,0,0 );
239  if ( mCoreHelper ) start = mCoreHelper->dayStart();
240  return start;
241 }
242 
243 void CalPrintPluginBase::setCategoryColors( TQPainter &p, Incidence *incidence )
244 {
245  TQColor bgColor = categoryBgColor( incidence );
246  if ( bgColor.isValid() )
247  p.setBrush( bgColor );
248  TQColor tColor( textColor( bgColor ) );
249  if ( tColor.isValid() )
250  p.setPen( tColor );
251 }
252 
254 {
255  if (mCoreHelper && incidence)
256  return mCoreHelper->categoryColor( incidence->categories() );
257  else
258  return TQColor();
259 }
260 
261 TQColor CalPrintPluginBase::textColor( const TQColor &color )
262 {
263  return (mCoreHelper)?(mCoreHelper->textColor( color )):TQColor();
264 }
265 
266 bool CalPrintPluginBase::isWorkingDay( const TQDate &dt )
267 {
268  return (mCoreHelper)?( mCoreHelper->isWorkingDay( dt ) ):true;
269 }
270 
271 TQString CalPrintPluginBase::holidayString( const TQDate &dt )
272 {
273  return (mCoreHelper)?(mCoreHelper->holidayString(dt)):(TQString());
274 }
275 
276 
277 Event *CalPrintPluginBase::holiday( const TQDate &dt )
278 {
279  TQString hstring( holidayString( dt ) );
280  if ( !hstring.isEmpty() ) {
281  Event*holiday=new Event();
282  holiday->setSummary( hstring );
283  holiday->setDtStart( dt );
284  holiday->setDtEnd( dt );
285  holiday->setFloats( true );
286  holiday->setCategories( i18n("Holiday") );
287  return holiday;
288  }
289  return 0;
290 }
291 
292 const KCalendarSystem *CalPrintPluginBase::calendarSystem() const
293 {
294  return mCalSys;
295 }
296 void CalPrintPluginBase::setCalendarSystem( const KCalendarSystem *calsys )
297 {
298  mCalSys = calsys;
299 }
300 
302 {
303  if ( mHeaderHeight >= 0 )
304  return mHeaderHeight;
305  else if ( orientation() == KPrinter::Portrait )
306  return PORTRAIT_HEADER_HEIGHT;
307  else
308  return LANDSCAPE_HEADER_HEIGHT;
309 }
310 void CalPrintPluginBase::setHeaderHeight( const int height )
311 {
312  mHeaderHeight = height;
313 }
314 
315 int CalPrintPluginBase::subHeaderHeight() const
316 {
317  return mSubHeaderHeight;
318 }
319 void CalPrintPluginBase::setSubHeaderHeight( const int height )
320 {
321  mSubHeaderHeight = height;
322 }
323 
325 {
326  if ( mFooterHeight >= 0 )
327  return mFooterHeight;
328  else if ( orientation() == KPrinter::Portrait )
329  return PORTRAIT_FOOTER_HEIGHT;
330  else
331  return LANDSCAPE_FOOTER_HEIGHT;
332 }
333 void CalPrintPluginBase::setFooterHeight( const int height )
334 {
335  mFooterHeight = height;
336 }
337 
338 int CalPrintPluginBase::margin() const
339 {
340  return mMargin;
341 }
342 void CalPrintPluginBase::setMargin( const int margin )
343 {
344  mMargin = margin;
345 }
346 
347 int CalPrintPluginBase::padding() const
348 {
349  return mPadding;
350 }
351 void CalPrintPluginBase::setPadding( const int padding )
352 {
353  mPadding = padding;
354 }
355 
356 int CalPrintPluginBase::borderWidth() const
357 {
358  return mBorder;
359 }
360 void CalPrintPluginBase::setBorderWidth( const int borderwidth )
361 {
362  mBorder = borderwidth;
363 }
364 
365 
366 
367 
368 void CalPrintPluginBase::drawBox( TQPainter &p, int linewidth, const TQRect &rect )
369 {
370  TQPen pen( p.pen() );
371  TQPen oldpen( pen );
372  pen.setWidth( linewidth );
373  p.setPen( pen );
374  p.drawRect( rect );
375  p.setPen( oldpen );
376 }
377 
378 void CalPrintPluginBase::drawShadedBox( TQPainter &p, int linewidth, const TQBrush &brush, const TQRect &rect )
379 {
380  TQBrush oldbrush( p.brush() );
381  p.setBrush( brush );
382  drawBox( p, linewidth, rect );
383  p.setBrush( oldbrush );
384 }
385 
386 void CalPrintPluginBase::printEventString( TQPainter &p, const TQRect &box, const TQString &str, int flags )
387 {
388  TQRect newbox( box );
389  newbox.addCoords( 3, 1, -1, -1 );
390  p.drawText( newbox, (flags==-1)?(TQt::AlignTop | TQt::AlignJustify | TQt::BreakAnywhere):flags, str );
391 }
392 
393 
394 void CalPrintPluginBase::showEventBox( TQPainter &p, int linewidth, const TQRect &box,
395  Incidence *incidence, const TQString &str, int flags )
396 {
397  TQPen oldpen( p.pen() );
398  TQBrush oldbrush( p.brush() );
399  TQColor bgColor( categoryBgColor( incidence ) );
400  if ( mUseColors & bgColor.isValid() ) {
401  p.setBrush( bgColor );
402  } else {
403  p.setBrush( TQColor( 232, 232, 232 ) );
404  }
405  drawBox( p, ( linewidth > 0 ) ? linewidth : EVENT_BORDER_WIDTH, box );
406 
407  if ( mUseColors && bgColor.isValid() ) {
408  p.setPen( textColor( bgColor ) );
409  }
410  printEventString( p, box, str, flags );
411  p.setPen( oldpen );
412  p.setBrush( oldbrush );
413 }
414 
415 
416 void CalPrintPluginBase::drawSubHeaderBox(TQPainter &p, const TQString &str, const TQRect &box )
417 {
418  drawShadedBox( p, BOX_BORDER_WIDTH, TQColor( 232, 232, 232 ), box );
419  TQFont oldfont( p.font() );
420  p.setFont( TQFont( "sans-serif", 10, TQFont::Bold ) );
421  p.drawText( box, TQt::AlignCenter | TQt::AlignVCenter, str );
422  p.setFont( oldfont );
423 }
424 
425 void CalPrintPluginBase::drawVerticalBox( TQPainter &p, int linewidth, const TQRect &box,
426  const TQString &str, int flags )
427 {
428  p.save();
429  p.rotate( -90 );
430  TQRect rotatedBox( -box.top()-box.height(), box.left(), box.height(), box.width() );
431  showEventBox( p, linewidth, rotatedBox, 0, str,
432  ( flags == -1 ) ? TQt::AlignLeft | TQt::AlignVCenter | TQt::SingleLine : flags );
433 
434  p.restore();
435 }
436 
437 
438 
440 // Return value: If expand, bottom of the printed box, otherwise vertical end
441 // of the printed contents inside the box.
442 
443 int CalPrintPluginBase::drawBoxWithCaption( TQPainter &p, const TQRect &allbox,
444  const TQString &caption, const TQString &contents, bool sameLine, bool expand, const TQFont &captionFont, const TQFont &textFont )
445 {
446  TQFont oldFont( p.font() );
447 // TQFont captionFont( "sans-serif", 11, TQFont::Bold );
448 // TQFont textFont( "sans-serif", 11, TQFont::Normal );
449 // TQFont captionFont( "Tahoma", 11, TQFont::Bold );
450 // TQFont textFont( "Tahoma", 11, TQFont::Normal );
451 
452 
453  TQRect box( allbox );
454 
455  // Bounding rectangle for caption, single-line, clip on the right
456  TQRect captionBox( box.left() + padding(), box.top() + padding(), 0, 0 );
457  p.setFont( captionFont );
458  captionBox = p.boundingRect( captionBox, TQt::AlignLeft | TQt::AlignTop | TQt::SingleLine, caption );
459  p.setFont( oldFont );
460  if ( captionBox.right() > box.right() )
461  captionBox.setRight( box.right() );
462  if ( expand && captionBox.bottom() + padding() > box.bottom() )
463  box.setBottom( captionBox.bottom() + padding() );
464 
465  // Bounding rectangle for the contents (if any), word break, clip on the bottom
466  TQRect textBox( captionBox );
467  if ( !contents.isEmpty() ) {
468  if ( sameLine ) {
469  textBox.setLeft( captionBox.right() + padding() );
470  } else {
471  textBox.setTop( captionBox.bottom() + padding() );
472  }
473  textBox.setRight( box.right() );
474  textBox.setHeight( 0 );
475  p.setFont( textFont );
476  textBox = p.boundingRect( textBox, TQt::WordBreak | TQt::AlignTop | TQt::AlignLeft, contents );
477  p.setFont( oldFont );
478  if ( textBox.bottom() + padding() > box.bottom() ) {
479  if ( expand ) {
480  box.setBottom( textBox.bottom() + padding() );
481  } else {
482  textBox.setBottom( box.bottom() );
483  }
484  }
485  }
486 
487  drawBox( p, BOX_BORDER_WIDTH, box );
488  p.setFont( captionFont );
489  p.drawText( captionBox, TQt::AlignLeft | TQt::AlignTop | TQt::SingleLine, caption );
490  if ( !contents.isEmpty() ) {
491  p.setFont( textFont );
492  p.drawText( textBox, TQt::WordBreak | TQt::AlignTop | TQt::AlignLeft, contents );
493  }
494  p.setFont( oldFont );
495 
496  if ( expand ) {
497  return box.bottom();
498  } else {
499  return textBox.bottom();
500  }
501 }
502 
503 
505 
506 int CalPrintPluginBase::drawHeader( TQPainter &p, TQString title,
507  const TQDate &month1, const TQDate &month2, const TQRect &allbox, bool expand )
508 {
509  // print previous month for month view, print current for to-do, day and week
510  int smallMonthWidth = (allbox.width()/4) - 10;
511  if (smallMonthWidth>100) smallMonthWidth=100;
512 
513  int right = allbox.right();
514  if ( month1.isValid() ) right -= (20+smallMonthWidth);
515  if ( month2.isValid() ) right -= (20+smallMonthWidth);
516  TQRect box( allbox );
517  TQRect textRect( allbox );
518  textRect.addCoords( 5, 0, 0, 0 );
519  textRect.setRight( right );
520 
521 
522  TQFont oldFont( p.font() );
523  TQFont newFont("sans-serif", (textRect.height()<60)?16:18, TQFont::Bold);
524  if ( expand ) {
525  p.setFont( newFont );
526  TQRect boundingR = p.boundingRect( textRect, TQt::AlignLeft | TQt::AlignVCenter | TQt::WordBreak, title );
527  p.setFont( oldFont );
528  int h = boundingR.height();
529  if ( h > allbox.height() ) {
530  box.setHeight( h );
531  textRect.setHeight( h );
532  }
533  }
534 
535  drawShadedBox( p, BOX_BORDER_WIDTH, TQColor( 232, 232, 232 ), box );
536 
537  TQRect monthbox( box.right()-10-smallMonthWidth, box.top(), smallMonthWidth, box.height() );
538  if (month2.isValid()) {
539  drawSmallMonth( p, TQDate(month2.year(), month2.month(), 1), monthbox );
540  monthbox.moveBy( -20 - smallMonthWidth, 0 );
541  }
542  if (month1.isValid()) {
543  drawSmallMonth( p, TQDate(month1.year(), month1.month(), 1), monthbox );
544  monthbox.moveBy( -20 - smallMonthWidth, 0 );
545  }
546 
547  // Set the margins
548  p.setFont( newFont );
549  p.drawText( textRect, TQt::AlignLeft | TQt::AlignVCenter | TQt::WordBreak, title );
550  p.setFont( oldFont );
551 
552  return textRect.bottom();
553 }
554 
555 
556 int CalPrintPluginBase::drawFooter( TQPainter &p, TQRect &footbox )
557 {
558  TQFont oldfont( p.font() );
559  p.setFont( TQFont( "sans-serif", 6 ) );
560  TQFontMetrics fm( p.font() );
561  TQString dateStr = TDEGlobal::locale()->formatDateTime( TQDateTime::currentDateTime(), false );
562  p.drawText( footbox, TQt::AlignCenter | TQt::AlignVCenter | TQt::SingleLine,
563  i18n( "print date: formatted-datetime", "printed: %1" ).arg( dateStr ) );
564  p.setFont( oldfont );
565 
566  return footbox.bottom();
567 }
568 
569 void CalPrintPluginBase::drawSmallMonth(TQPainter &p, const TQDate &qd,
570  const TQRect &box )
571 {
572 
573  int weekdayCol = weekdayColumn( qd.dayOfWeek() );
574  int month = qd.month();
575  TQDate monthDate(TQDate(qd.year(), qd.month(), 1));
576  // correct begin of week
577  TQDate monthDate2( monthDate.addDays( -weekdayCol ) );
578 
579  double cellWidth = double(box.width())/double(7);
580  int rownr = 3 + ( qd.daysInMonth() + weekdayCol - 1 ) / 7;
581  // 3 Pixel after month name, 2 after day names, 1 after the calendar
582  double cellHeight = (box.height() - 5) / rownr;
583  TQFont oldFont( p.font() );
584  p.setFont(TQFont("sans-serif", int(cellHeight-1), TQFont::Normal));
585 
586  // draw the title
587  if ( mCalSys ) {
588  TQRect titleBox( box );
589  titleBox.setHeight( int(cellHeight+1) );
590  p.drawText( titleBox, TQt::AlignTop | TQt::AlignHCenter, mCalSys->monthName( qd ) );
591  }
592 
593  // draw days of week
594  TQRect wdayBox( box );
595  wdayBox.setTop( int( box.top() + 3 + cellHeight ) );
596  wdayBox.setHeight( int(2*cellHeight)-int(cellHeight) );
597 
598  if ( mCalSys ) {
599  for (int col = 0; col < 7; ++col) {
600  TQString tmpStr = mCalSys->weekDayName( monthDate2 )[0].upper();
601  wdayBox.setLeft( int(box.left() + col*cellWidth) );
602  wdayBox.setRight( int(box.left() + (col+1)*cellWidth) );
603  p.drawText( wdayBox, TQt::AlignCenter, tmpStr );
604  monthDate2 = monthDate2.addDays( 1 );
605  }
606  }
607 
608  // draw separator line
609  int calStartY = wdayBox.bottom() + 2;
610  p.drawLine( box.left(), calStartY, box.right(), calStartY );
611  monthDate = monthDate.addDays( -weekdayCol );
612 
613  for ( int row = 0; row < (rownr-2); row++ ) {
614  for ( int col = 0; col < 7; col++ ) {
615  if ( monthDate.month() == month ) {
616  TQRect dayRect( int( box.left() + col*cellWidth ), int( calStartY + row*cellHeight ), 0, 0 );
617  dayRect.setRight( int( box.left() + (col+1)*cellWidth ) );
618  dayRect.setBottom( int( calStartY + (row+1)*cellHeight ) );
619  p.drawText( dayRect, TQt::AlignCenter, TQString::number( monthDate.day() ) );
620  }
621  monthDate = monthDate.addDays(1);
622  }
623  }
624  p.setFont( oldFont );
625 }
626 
627 
628 
629 
630 
632 
633 /*
634  * This routine draws a header box over the main part of the calendar
635  * containing the days of the week.
636  */
638  const TQDate &fromDate, const TQDate &toDate, const TQRect &box )
639 {
640  double cellWidth = double(box.width()) / double(fromDate.daysTo( toDate )+1);
641  TQDate cellDate( fromDate );
642  TQRect dateBox( box );
643  int i = 0;
644 
645  while ( cellDate <= toDate ) {
646  dateBox.setLeft( box.left() + int(i*cellWidth) );
647  dateBox.setRight( box.left() + int((i+1)*cellWidth) );
648  drawDaysOfWeekBox(p, cellDate, dateBox );
649  cellDate = cellDate.addDays(1);
650  i++;
651  }
652 }
653 
654 
655 void CalPrintPluginBase::drawDaysOfWeekBox(TQPainter &p, const TQDate &qd,
656  const TQRect &box )
657 {
658  drawSubHeaderBox( p, (mCalSys)?(mCalSys->weekDayName( qd )):(TQString()), box );
659 }
660 
661 
662 void CalPrintPluginBase::drawTimeLine( TQPainter &p, const TQTime &fromTime,
663  const TQTime &toTime, const TQRect &box )
664 {
665  drawBox( p, BOX_BORDER_WIDTH, box );
666 
667  int totalsecs = fromTime.secsTo( toTime );
668  float minlen = (float)box.height() * 60. / (float)totalsecs;
669  float cellHeight = ( 60. * (float)minlen );
670  float currY = box.top();
671  // TODO: Don't use half of the width, but less, for the minutes!
672  int xcenter = box.left() + box.width() / 2;
673 
674  TQTime curTime( fromTime );
675  TQTime endTime( toTime );
676  if ( fromTime.minute() > 30 ) {
677  curTime = TQTime( fromTime.hour()+1, 0, 0 );
678  } else if ( fromTime.minute() > 0 ) {
679  curTime = TQTime( fromTime.hour(), 30, 0 );
680  float yy = currY + minlen * (float)fromTime.secsTo( curTime ) / 60.;
681  p.drawLine( xcenter, (int)yy, box.right(), (int)yy );
682  curTime = TQTime( fromTime.hour() + 1, 0, 0 );
683  }
684  currY += ( float( fromTime.secsTo( curTime ) * minlen ) / 60. );
685 
686  while ( curTime < endTime ) {
687  p.drawLine( box.left(), (int)currY, box.right(), (int)currY );
688  int newY = (int)( currY + cellHeight / 2. );
689  TQString numStr;
690  if ( newY < box.bottom() ) {
691  TQFont oldFont( p.font() );
692  // draw the time:
693  if ( !TDEGlobal::locale()->use12Clock() ) {
694  p.drawLine( xcenter, (int)newY, box.right(), (int)newY );
695  numStr.setNum( curTime.hour() );
696  if ( cellHeight > 30 ) {
697  p.setFont( TQFont( "sans-serif", 14, TQFont::Bold ) );
698  } else {
699  p.setFont( TQFont( "sans-serif", 12, TQFont::Bold ) );
700  }
701  p.drawText( box.left() + 4, (int)currY + 2, box.width() / 2 - 2, (int)cellHeight,
702  TQt::AlignTop | TQt::AlignRight, numStr );
703  p.setFont( TQFont ( "helvetica", 10, TQFont::Normal ) );
704  p.drawText( xcenter + 4, (int)currY + 2, box.width() / 2 + 2, (int)(cellHeight / 2 ) - 3,
705  TQt::AlignTop | TQt::AlignLeft, "00" );
706  } else {
707  p.drawLine( box.left(), (int)newY, box.right(), (int)newY );
708  TQTime time( curTime.hour(), 0 );
709  numStr = TDEGlobal::locale()->formatTime( time );
710  if ( box.width() < 60 ) {
711  p.setFont( TQFont( "sans-serif", 7, TQFont::Bold ) ); // for weekprint
712  } else {
713  p.setFont( TQFont( "sans-serif", 12, TQFont::Bold ) ); // for dayprint
714  }
715  p.drawText( box.left() + 2, (int)currY + 2, box.width() - 4, (int)cellHeight / 2 - 3,
716  TQt::AlignTop|TQt::AlignLeft, numStr );
717  }
718  currY += cellHeight;
719  p.setFont( oldFont );
720  } // enough space for half-hour line and time
721  if ( curTime.secsTo( endTime ) > 3600 ) {
722  curTime = curTime.addSecs( 3600 );
723  } else {
724  curTime = endTime;
725  }
726  } // currTime<endTime
727 }
728 
735 int CalPrintPluginBase::drawAllDayBox(TQPainter &p, Event::List &eventList,
736  const TQDate &qd, bool expandable, const TQRect &box )
737 {
738  Event::List::Iterator it, itold;
739 
740  int offset=box.top();
741 
742  TQString multiDayStr;
743 
744  Event*hd = holiday( qd );
745  if ( hd ) eventList.prepend( hd );
746 
747  it = eventList.begin();
748  Event *currEvent = 0;
749  // First, print all floating events
750  while( it!=eventList.end() ) {
751  currEvent=*it;
752  itold=it;
753  ++it;
754  if ( currEvent && currEvent->doesFloat() ) {
755  // set the colors according to the categories
756  if ( expandable ) {
757  TQRect eventBox( box );
758  eventBox.setTop( offset );
759  showEventBox( p, EVENT_BORDER_WIDTH, eventBox, currEvent, currEvent->summary() );
760  offset += box.height();
761  } else {
762  if ( !multiDayStr.isEmpty() ) multiDayStr += ", ";
763  multiDayStr += currEvent->summary();
764  }
765  eventList.remove( itold );
766  }
767  }
768  if ( hd ) delete hd;
769 
770  int ret = box.height();
771  TQRect eventBox( box );
772  if (!expandable) {
773  if (!multiDayStr.isEmpty()) {
774  drawShadedBox( p, BOX_BORDER_WIDTH, TQColor( 128, 128, 128 ), eventBox );
775  printEventString( p, eventBox, multiDayStr );
776  } else {
777  drawBox( p, BOX_BORDER_WIDTH, eventBox );
778  }
779  } else {
780  ret = offset - box.top();
781  eventBox.setBottom( ret );
782  drawBox( p, BOX_BORDER_WIDTH, eventBox );
783  }
784  return ret;
785 }
786 
787 
788 void CalPrintPluginBase::drawAgendaDayBox( TQPainter &p, Event::List &events,
789  const TQDate &qd, bool expandable,
790  TQTime &fromTime, TQTime &toTime,
791  const TQRect &oldbox )
792 {
793  if ( !isWorkingDay( qd ) ) {
794  drawShadedBox( p, BOX_BORDER_WIDTH, TQColor( 232, 232, 232 ), oldbox );
795  } else {
796  drawBox( p, BOX_BORDER_WIDTH, oldbox );
797  }
798  TQRect box( oldbox );
799  // Account for the border with and cut away that margin from the interior
800 // box.setRight( box.right()-BOX_BORDER_WIDTH );
801 
802  Event *event;
803 
804  if ( expandable ) {
805  // Adapt start/end times to include complete events
806  Event::List::ConstIterator it;
807  for ( it = events.begin(); it != events.end(); ++it ) {
808  event = *it;
809  if ( event->dtStart().time() < fromTime )
810  fromTime = event->dtStart().time();
811  if ( event->dtEnd().time() > toTime )
812  toTime = event->dtEnd().time();
813  }
814  }
815 
816  // Show at least one hour
817 // if ( fromTime.secsTo( toTime ) < 3600 ) {
818 // fromTime = TQTime( fromTime.hour(), 0, 0 );
819 // toTime = fromTime.addSecs( 3600 );
820 // }
821 
822  // calculate the height of a cell and of a minute
823  int totalsecs = fromTime.secsTo( toTime );
824  float minlen = box.height() * 60. / totalsecs;
825  float cellHeight = 60. * minlen;
826  float currY = box.top();
827 
828  // print grid:
829  TQTime curTime( TQTime( fromTime.hour(), 0, 0 ) );
830  currY += fromTime.secsTo( curTime ) * minlen / 60;
831 
832  while ( curTime < toTime && curTime.isValid() ) {
833  if ( currY > box.top() )
834  p.drawLine( box.left(), int( currY ), box.right(), int( currY ) );
835  currY += cellHeight / 2;
836  if ( ( currY > box.top() ) && ( currY < box.bottom() ) ) {
837  // enough space for half-hour line
838  TQPen oldPen( p.pen() );
839  p.setPen( TQColor( 192, 192, 192 ) );
840  p.drawLine( box.left(), int( currY ), box.right(), int( currY ) );
841  p.setPen( oldPen );
842  }
843  if ( curTime.secsTo( toTime ) > 3600 )
844  curTime = curTime.addSecs( 3600 );
845  else curTime = toTime;
846  currY += cellHeight / 2;
847  }
848 
849  TQDateTime startPrintDate = TQDateTime( qd, fromTime );
850  TQDateTime endPrintDate = TQDateTime( qd, toTime );
851 
852  // Calculate horizontal positions and widths of events taking into account
853  // overlapping events
854 
855  TQPtrList<KOrg::CellItem> cells;
856  cells.setAutoDelete( true );
857 
858  Event::List::ConstIterator itEvents;
859  for( itEvents = events.begin(); itEvents != events.end(); ++itEvents ) {
860  TQValueList<TQDateTime> times = (*itEvents)->startDateTimesForDate( qd );
861  for ( TQValueList<TQDateTime>::ConstIterator it = times.begin();
862  it != times.end(); ++it ) {
863  cells.append( new PrintCellItem( *itEvents, (*it), (*itEvents)->endDateForStart( *it ) ) );
864  }
865  }
866 
867  TQPtrListIterator<KOrg::CellItem> it1( cells );
868  for( it1.toFirst(); it1.current(); ++it1 ) {
869  KOrg::CellItem *placeItem = it1.current();
870  KOrg::CellItem::placeItem( cells, placeItem );
871  }
872 
873 // p.setFont( TQFont( "sans-serif", 10 ) );
874 
875  for( it1.toFirst(); it1.current(); ++it1 ) {
876  PrintCellItem *placeItem = static_cast<PrintCellItem *>( it1.current() );
877  drawAgendaItem( placeItem, p, startPrintDate, endPrintDate, minlen, box );
878  }
879 // p.setFont( oldFont );
880 }
881 
882 
883 
884 void CalPrintPluginBase::drawAgendaItem( PrintCellItem *item, TQPainter &p,
885  const TQDateTime &startPrintDate,
886  const TQDateTime &endPrintDate,
887  float minlen, const TQRect &box )
888 {
889  Event *event = item->event();
890 
891  // start/end of print area for event
892  TQDateTime startTime = item->start();
893  TQDateTime endTime = item->end();
894  if ( ( startTime < endPrintDate && endTime > startPrintDate ) ||
895  ( endTime > startPrintDate && startTime < endPrintDate ) ) {
896  if ( startTime < startPrintDate ) startTime = startPrintDate;
897  if ( endTime > endPrintDate ) endTime = endPrintDate;
898  int currentWidth = box.width() / item->subCells();
899  int currentX = box.left() + item->subCell() * currentWidth;
900  int currentYPos = int( box.top() + startPrintDate.secsTo( startTime ) *
901  minlen / 60. );
902  int currentHeight = int( box.top() + startPrintDate.secsTo( endTime ) * minlen / 60. ) - currentYPos;
903 
904  TQRect eventBox( currentX, currentYPos, currentWidth, currentHeight );
905  TQString str;
906  if ( event->location().isEmpty() ) {
907  str = i18n( "starttime - endtime summary",
908  "%1-%2 %3" ).
909  arg( TDEGlobal::locale()->formatTime( startTime.time() ) ).
910  arg( TDEGlobal::locale()->formatTime( endTime.time() ) ).
911  arg( cleanStr( event->summary() ) );
912  } else {
913  str = i18n( "starttime - endtime summary, location",
914  "%1-%2 %3, %4" ).
915  arg( TDEGlobal::locale()->formatTime( startTime.time() ) ).
916  arg( TDEGlobal::locale()->formatTime( endTime.time() ) ).
917  arg( cleanStr( event->summary() ) ).
918  arg( cleanStr( event->location() ) );
919  }
920  showEventBox( p, EVENT_BORDER_WIDTH, eventBox, event, str );
921  }
922 }
923 
924 //TODO TODO TODO
925 void CalPrintPluginBase::drawDayBox( TQPainter &p, const TQDate &qd,
926  const TQRect &box,
927  bool fullDate, bool printRecurDaily, bool printRecurWeekly )
928 {
929  TQString dayNumStr;
930  const TDELocale*local = TDEGlobal::locale();
931 
932  // This has to be localized
933  if ( fullDate && mCalSys ) {
934 
935  dayNumStr = i18n("weekday month date", "%1 %2 %3")
936  .arg( mCalSys->weekDayName( qd ) )
937  .arg( mCalSys->monthName( qd ) )
938  .arg( qd.day() );
939 // dayNumStr = local->formatDate(qd);
940  } else {
941  dayNumStr = TQString::number( qd.day() );
942  }
943 
944  TQRect subHeaderBox( box );
945  subHeaderBox.setHeight( mSubHeaderHeight );
946  drawShadedBox( p, BOX_BORDER_WIDTH, p.backgroundColor(), box );
947  drawShadedBox( p, 0, TQColor( 232, 232, 232 ), subHeaderBox );
948  drawBox( p, BOX_BORDER_WIDTH, box );
949  TQString hstring( holidayString( qd ) );
950  TQFont oldFont( p.font() );
951 
952  TQRect headerTextBox( subHeaderBox );
953  headerTextBox.setLeft( subHeaderBox.left()+5 );
954  headerTextBox.setRight( subHeaderBox.right()-5 );
955  if (!hstring.isEmpty()) {
956  p.setFont( TQFont( "sans-serif", 8, TQFont::Bold, true ) );
957 
958  p.drawText( headerTextBox, TQt::AlignLeft | TQt::AlignVCenter, hstring );
959  }
960  p.setFont(TQFont("sans-serif", 10, TQFont::Bold));
961  p.drawText( headerTextBox, TQt::AlignRight | TQt::AlignVCenter, dayNumStr);
962 
963  Event::List eventList = mCalendar->events( qd,
966  TQString timeText;
967  p.setFont( TQFont( "sans-serif", 8 ) );
968 
969  int textY=mSubHeaderHeight+3; // gives the relative y-coord of the next printed entry
970  Event::List::ConstIterator it;
971 
972  for( it = eventList.begin(); it != eventList.end() && textY<box.height(); ++it ) {
973  Event *currEvent = *it;
974  if ( ( !printRecurDaily && currEvent->recurrenceType() == Recurrence::rDaily ) ||
975  ( !printRecurWeekly && currEvent->recurrenceType() == Recurrence::rWeekly ) ) {
976  continue;
977  }
978  if ( currEvent->doesFloat() || currEvent->isMultiDay() ) {
979  timeText = "";
980  } else {
981  timeText = local->formatTime( currEvent->dtStart().time() );
982  }
983 
984  TQString str;
985  if ( !currEvent->location().isEmpty() ) {
986  str = i18n( "summary, location", "%1, %2" ).
987  arg( currEvent->summary() ).arg( currEvent->location() );
988  } else {
989  str = currEvent->summary();
990  }
991  drawIncidence( p, box, timeText, str, textY );
992  }
993 
994  if ( textY < box.height() ) {
995  Todo::List todos = mCalendar->todos( qd );
996  Todo::List::ConstIterator it2;
997  for ( it2 = todos.begin(); it2 != todos.end() && textY <box.height(); ++it2 ) {
998  Todo *todo = *it2;
999  if ( ( !printRecurDaily && todo->recurrenceType() == Recurrence::rDaily ) ||
1000  ( !printRecurWeekly && todo->recurrenceType() == Recurrence::rWeekly ) ) {
1001  continue;
1002  }
1003  if ( todo->hasStartDate() && !todo->doesFloat() ) {
1004  timeText = TDEGlobal::locale()->formatTime( todo->dtStart().time() ) + " ";
1005  } else {
1006  timeText = "";
1007  }
1008  TQString summaryStr;
1009  if ( !todo->location().isEmpty() ) {
1010  summaryStr = i18n( "summary, location", "%1, %2" ).
1011  arg( todo->summary() ).arg( todo->location() );
1012  } else {
1013  summaryStr = todo->summary();
1014  }
1015  TQString str;
1016  if ( todo->hasDueDate() ) {
1017  if ( !todo->doesFloat() ) {
1018  str = i18n( "%1 (Due: %2)" ).
1019  arg( summaryStr ).
1020  arg( TDEGlobal::locale()->formatDateTime( todo->dtDue() ) );
1021  } else {
1022  str = i18n( "%1 (Due: %2)" ).
1023  arg( summaryStr ).
1024  arg( TDEGlobal::locale()->formatDate( todo->dtDue().date(), true ) );
1025  }
1026  } else {
1027  str = summaryStr;
1028  }
1029  drawIncidence( p, box, timeText, i18n("To-do: %1").arg( str ), textY );
1030  }
1031  }
1032 
1033  p.setFont( oldFont );
1034 }
1035 
1036 // TODO TODO TODO
1037 void CalPrintPluginBase::drawIncidence( TQPainter &p, const TQRect &dayBox, const TQString &time, const TQString &summary, int &textY )
1038 {
1039  kdDebug(5850) << "summary = " << summary << endl;
1040 
1041  int flags = TQt::AlignLeft;
1042  TQFontMetrics fm = p.fontMetrics();
1043  TQRect timeBound = p.boundingRect( dayBox.x() + 5, dayBox.y() + textY,
1044  dayBox.width() - 10, fm.lineSpacing(),
1045  flags, time );
1046  p.drawText( timeBound, flags, time );
1047 
1048  int summaryWidth = time.isEmpty() ? 0 : timeBound.width() + 4;
1049  TQRect summaryBound = TQRect( dayBox.x() + 5 + summaryWidth, dayBox.y() + textY,
1050  dayBox.width() - summaryWidth -5, dayBox.height() );
1051 
1052  KWordWrap *ww = KWordWrap::formatText( fm, summaryBound, flags, summary );
1053  ww->drawText( &p, dayBox.x() + 5 + summaryWidth, dayBox.y() + textY, flags );
1054 
1055  textY += ww->boundingRect().height();
1056 
1057  delete ww;
1058 }
1059 
1060 
1062 
1063 void CalPrintPluginBase::drawWeek(TQPainter &p, const TQDate &qd, const TQRect &box )
1064 {
1065  TQDate weekDate = qd;
1066  bool portrait = ( box.height() > box.width() );
1067  int cellWidth, cellHeight;
1068  int vcells;
1069  if (portrait) {
1070  cellWidth = box.width()/2;
1071  vcells=3;
1072  } else {
1073  cellWidth = box.width()/6;
1074  vcells=1;
1075  }
1076  cellHeight = box.height()/vcells;
1077 
1078  // correct begin of week
1079  int weekdayCol = weekdayColumn( qd.dayOfWeek() );
1080  weekDate = qd.addDays( -weekdayCol );
1081 
1082  for (int i = 0; i < 7; i++, weekDate = weekDate.addDays(1)) {
1083  // Saturday and sunday share a cell, so we have to special-case sunday
1084  int hpos = ((i<6)?i:(i-1)) / vcells;
1085  int vpos = ((i<6)?i:(i-1)) % vcells;
1086  TQRect dayBox( box.left()+cellWidth*hpos, box.top()+cellHeight*vpos + ((i==6)?(cellHeight/2):0),
1087  cellWidth, (i<5)?(cellHeight):(cellHeight/2) );
1088  drawDayBox(p, weekDate, dayBox, true);
1089  } // for i through all weekdays
1090 }
1091 
1092 
1094  const TQDate &fromDate, const TQDate &toDate,
1095  TQTime &fromTime, TQTime &toTime,
1096  const TQRect &box)
1097 {
1098  // timeline is 1 hour:
1099  int alldayHeight = (int)( 3600.*box.height()/(fromTime.secsTo(toTime)+3600.) );
1100  int timelineWidth = TIMELINE_WIDTH;
1101 
1102  TQRect dowBox( box );
1103  dowBox.setLeft( box.left() + timelineWidth );
1104  dowBox.setHeight( mSubHeaderHeight );
1105  drawDaysOfWeek( p, fromDate, toDate, dowBox );
1106 
1107  TQRect tlBox( box );
1108  tlBox.setWidth( timelineWidth );
1109  tlBox.setTop( dowBox.bottom() + BOX_BORDER_WIDTH + alldayHeight );
1110  drawTimeLine( p, fromTime, toTime, tlBox );
1111 
1112  // draw each day
1113  TQDate curDate(fromDate);
1114  int i=0;
1115  double cellWidth = double(dowBox.width()) / double(fromDate.daysTo(toDate)+1);
1116  while (curDate<=toDate) {
1117  TQRect allDayBox( dowBox.left()+int(i*cellWidth), dowBox.bottom() + BOX_BORDER_WIDTH,
1118  int((i+1)*cellWidth)-int(i*cellWidth), alldayHeight );
1119  TQRect dayBox( allDayBox );
1120  dayBox.setTop( tlBox.top() );
1121  dayBox.setBottom( box.bottom() );
1122  Event::List eventList = mCalendar->events(curDate,
1125  alldayHeight = drawAllDayBox( p, eventList, curDate, false, allDayBox );
1126  drawAgendaDayBox( p, eventList, curDate, false, fromTime, toTime, dayBox );
1127  i++;
1128  curDate=curDate.addDays(1);
1129  }
1130 
1131 }
1132 
1133 
1135 
1136 class MonthEventStruct
1137 {
1138  public:
1139  MonthEventStruct() : event(0) {}
1140  MonthEventStruct( const TQDateTime &s, const TQDateTime &e, Event *ev)
1141  {
1142  event = ev;
1143  start = s;
1144  end = e;
1145  if ( event->doesFloat() ) {
1146  start = TQDateTime( start.date(), TQTime(0,0,0) );
1147  end = TQDateTime( end.date().addDays(1), TQTime(0,0,0) ).addSecs(-1);
1148  }
1149  }
1150  bool operator<(const MonthEventStruct &mes) { return start < mes.start; }
1151  TQDateTime start;
1152  TQDateTime end;
1153  Event *event;
1154 };
1155 
1156 void CalPrintPluginBase::drawMonth( TQPainter &p, const TQDate &dt, const TQRect &box, int maxdays, int subDailyFlags, int holidaysFlags )
1157 {
1158  const KCalendarSystem *calsys = calendarSystem();
1159  TQRect subheaderBox( box );
1160  subheaderBox.setHeight( subHeaderHeight() );
1161  TQRect borderBox( box );
1162  borderBox.setTop( subheaderBox.bottom()+1 );
1163  drawSubHeaderBox( p, calsys->monthName(dt), subheaderBox );
1164  // correct for half the border width
1165  int correction = (BOX_BORDER_WIDTH/*-1*/)/2;
1166  TQRect daysBox( borderBox );
1167  daysBox.addCoords( correction, correction, -correction, -correction );
1168 
1169  int daysinmonth = calsys->daysInMonth( dt );
1170  if ( maxdays <= 0 ) maxdays = daysinmonth;
1171 
1172  int d;
1173  float dayheight = float(daysBox.height()) / float( maxdays );
1174 
1175  TQColor holidayColor( 240, 240, 240 );
1176  TQColor workdayColor( 255, 255, 255 );
1177  int dayNrWidth = p.fontMetrics().width( "99" );
1178 
1179  // Fill the remaining space (if a month has less days than others) with a crossed-out pattern
1180  if ( daysinmonth<maxdays ) {
1181  TQRect dayBox( box.left(), daysBox.top() + roundToInt(dayheight*daysinmonth), box.width(), 0 );
1182  dayBox.setBottom( daysBox.bottom() );
1183  p.fillRect( dayBox, TQt::DiagCrossPattern );
1184  }
1185  // Backgrounded boxes for each day, plus day numbers
1186  TQBrush oldbrush( p.brush() );
1187  for ( d = 0; d < daysinmonth; ++d ) {
1188  TQDate day;
1189  calsys->setYMD( day, dt.year(), dt.month(), d+1 );
1190  TQRect dayBox( daysBox.left()/*+rand()%50*/, daysBox.top() + roundToInt(dayheight*d), daysBox.width()/*-rand()%50*/, 0 );
1191  // FIXME: When using a border width of 0 for event boxes, don't let the rectangles overlap, i.e. subtract 1 from the top or bottom!
1192  dayBox.setBottom( daysBox.top()+roundToInt(dayheight*(d+1)) - 1 );
1193 
1194  p.setBrush( isWorkingDay( day )?workdayColor:holidayColor );
1195  p.drawRect( dayBox );
1196  TQRect dateBox( dayBox );
1197  dateBox.setWidth( dayNrWidth+3 );
1198  p.drawText( dateBox, TQt::AlignRight | TQt::AlignVCenter | TQt::SingleLine,
1199  TQString::number(d+1) );
1200  }
1201  p.setBrush( oldbrush );
1202  int xstartcont = box.left() + dayNrWidth + 5;
1203 
1204  TQDate start, end;
1205  calsys->setYMD( start, dt.year(), dt.month(), 1 );
1206  end = calsys->addMonths( start, 1 );
1207  end = calsys->addDays( end, -1 );
1208 
1209  Event::List events = mCalendar->events( start, end );
1210  TQMap<int, TQStringList> textEvents;
1211  TQPtrList<KOrg::CellItem> timeboxItems;
1212  timeboxItems.setAutoDelete( true );
1213 
1214 
1215  // 1) For multi-day events, show boxes spanning several cells, use CellItem
1216  // print the summary vertically
1217  // 2) For sub-day events, print the concated summaries into the remaining
1218  // space of the box (optional, depending on the given flags)
1219  // 3) Draw some kind of timeline showing free and busy times
1220 
1221  // Holidays
1222  Event::List holidays;
1223  holidays.setAutoDelete( true );
1224  for ( TQDate d(start); d <= end; d = d.addDays(1) ) {
1225  Event *e = holiday( d );
1226  if ( e ) {
1227  holidays.append( e );
1228  if ( holidaysFlags & TimeBoxes ) {
1229  timeboxItems.append( new PrintCellItem( e, TQDateTime(d, TQTime(0,0,0) ),
1230  TQDateTime( d.addDays(1), TQTime(0,0,0) ) ) );
1231  }
1232  if ( holidaysFlags & Text ) {
1233  textEvents[ d.day() ] << e->summary();
1234  }
1235  }
1236  }
1237 
1238  TQValueList<MonthEventStruct> monthentries;
1239 
1240  for ( Event::List::ConstIterator evit = events.begin();
1241  evit != events.end(); ++evit ) {
1242  Event *e = (*evit);
1243  if (!e) continue;
1244  if ( e->doesRecur() ) {
1245  if ( e->recursOn( start ) ) {
1246  // This occurrence has possibly started before the beginning of the
1247  // month, so obtain the start date before the beginning of the month
1248  TQValueList<TQDateTime> starttimes = e->startDateTimesForDate( start );
1249  TQValueList<TQDateTime>::ConstIterator it = starttimes.begin();
1250  for ( ; it != starttimes.end(); ++it ) {
1251  monthentries.append( MonthEventStruct( *it, e->endDateForStart( *it ), e ) );
1252  }
1253  }
1254  // Loop through all remaining days of the month and check if the event
1255  // begins on that day (don't use Event::recursOn, as that will
1256  // also return events that have started earlier. These start dates
1257  // however, have already been treated!
1258  Recurrence *recur = e->recurrence();
1259  TQDate d1( start.addDays(1) );
1260  while ( d1 <= end ) {
1261  if ( recur->recursOn(d1) ) {
1262  TimeList times( recur->recurTimesOn( d1 ) );
1263  for ( TimeList::ConstIterator it = times.begin();
1264  it != times.end(); ++it ) {
1265  TQDateTime d1start( d1, *it );
1266  monthentries.append( MonthEventStruct( d1start, e->endDateForStart( d1start ), e ) );
1267  }
1268  }
1269  d1 = d1.addDays(1);
1270  }
1271  } else {
1272  monthentries.append( MonthEventStruct( e->dtStart(), e->dtEnd(), e ) );
1273  }
1274  }
1275  qHeapSort( monthentries );
1276 
1277  TQValueList<MonthEventStruct>::ConstIterator mit = monthentries.begin();
1278  TQDateTime endofmonth( end, TQTime(0,0,0) );
1279  endofmonth = endofmonth.addDays(1);
1280  for ( ; mit != monthentries.end(); ++mit ) {
1281  if ( (*mit).start.date() == (*mit).end.date() ) {
1282  // Show also single-day events as time line boxes
1283  if ( subDailyFlags & TimeBoxes ) {
1284  timeboxItems.append( new PrintCellItem( (*mit).event, (*mit).start, (*mit).end ) );
1285  }
1286  // Show as text in the box
1287  if ( subDailyFlags & Text ) {
1288  textEvents[ (*mit).start.date().day() ] << (*mit).event->summary();
1289  }
1290  } else {
1291  // Multi-day events are always shown as time line boxes
1292  TQDateTime thisstart( (*mit).start );
1293  TQDateTime thisend( (*mit).end );
1294  if ( thisstart.date()<start ) thisstart = start;
1295  if ( thisend>endofmonth ) thisend = endofmonth;
1296  timeboxItems.append( new PrintCellItem( (*mit).event, thisstart, thisend ) );
1297  }
1298  }
1299 
1300  // For Multi-day events, line them up nicely so that the boxes don't overlap
1301  TQPtrListIterator<KOrg::CellItem> it1( timeboxItems );
1302  for( it1.toFirst(); it1.current(); ++it1 ) {
1303  KOrg::CellItem *placeItem = it1.current();
1304  KOrg::CellItem::placeItem( timeboxItems, placeItem );
1305  }
1306  TQDateTime starttime( start, TQTime( 0, 0, 0 ) );
1307  int newxstartcont = xstartcont;
1308 
1309  TQFont oldfont( p.font() );
1310  p.setFont( TQFont( "sans-serif", 7 ) );
1311  for( it1.toFirst(); it1.current(); ++it1 ) {
1312  PrintCellItem *placeItem = static_cast<PrintCellItem *>( it1.current() );
1313  int minsToStart = starttime.secsTo( placeItem->start() )/60;
1314  int minsToEnd = starttime.secsTo( placeItem->end() )/60;
1315 
1316  TQRect eventBox( xstartcont + placeItem->subCell()*17,
1317  daysBox.top() + roundToInt( double( minsToStart*daysBox.height()) / double(maxdays*24*60) ),
1318  14, 0 );
1319  eventBox.setBottom( daysBox.top() + roundToInt( double( minsToEnd*daysBox.height()) / double(maxdays*24*60) ) );
1320  drawVerticalBox( p, 0, eventBox, placeItem->event()->summary() );
1321  newxstartcont = TQMAX( newxstartcont, eventBox.right() );
1322  }
1323  xstartcont = newxstartcont;
1324 
1325  // For Single-day events, simply print their summaries into the remaining
1326  // space of the day's cell
1327  for ( int d=0; d<daysinmonth; ++d ) {
1328  TQStringList dayEvents( textEvents[d+1] );
1329  TQString txt = dayEvents.join(", ");
1330  TQRect dayBox( xstartcont, daysBox.top()+roundToInt(dayheight*d), 0, 0 );
1331  dayBox.setRight( box.right() );
1332  dayBox.setBottom( daysBox.top()+roundToInt(dayheight*(d+1)) );
1333  printEventString(p, dayBox, txt, TQt::AlignTop | TQt::AlignLeft | TQt::BreakAnywhere );
1334  }
1335  p.setFont( oldfont );
1336 // p.setBrush( TQt::NoBrush );
1337  drawBox( p, BOX_BORDER_WIDTH, borderBox );
1338  p.restore();
1339 }
1340 
1342 
1343 void CalPrintPluginBase::drawMonthTable(TQPainter &p, const TQDate &qd, bool weeknumbers,
1344  bool recurDaily, bool recurWeekly,
1345  const TQRect &box)
1346 {
1347  int yoffset = mSubHeaderHeight;
1348  int xoffset = 0;
1349  TQDate monthDate(TQDate(qd.year(), qd.month(), 1));
1350  TQDate monthFirst(monthDate);
1351  TQDate monthLast(monthDate.addMonths(1).addDays(-1));
1352 
1353 
1354  int weekdayCol = weekdayColumn( monthDate.dayOfWeek() );
1355  monthDate = monthDate.addDays(-weekdayCol);
1356 
1357  if (weeknumbers) {
1358  xoffset += 14;
1359  }
1360 
1361  int rows=(weekdayCol + qd.daysInMonth() - 1)/7 +1;
1362  double cellHeight = ( box.height() - yoffset ) / (1.*rows);
1363  double cellWidth = ( box.width() - xoffset ) / 7.;
1364 
1365  // Precalculate the grid...
1366  // rows is at most 6, so using 8 entries in the array is fine, too!
1367  int coledges[8], rowedges[8];
1368  for ( int i = 0; i <= 7; i++ ) {
1369  rowedges[i] = int( box.top() + yoffset + i*cellHeight );
1370  coledges[i] = int( box.left() + xoffset + i*cellWidth );
1371  }
1372 
1373  if (weeknumbers) {
1374  TQFont oldFont(p.font());
1375  TQFont newFont(p.font());
1376  newFont.setPointSize(6);
1377  p.setFont(newFont);
1378  TQDate weekDate(monthDate);
1379  for (int row = 0; row<rows; ++row ) {
1380  int calWeek = weekDate.weekNumber();
1381  TQRect rc( box.left(), rowedges[row], coledges[0] - 3 - box.left(), rowedges[row+1]-rowedges[row] );
1382  p.drawText( rc, TQt::AlignRight | TQt::AlignVCenter, TQString::number( calWeek ) );
1383  weekDate = weekDate.addDays( 7 );
1384  }
1385  p.setFont( oldFont );
1386  }
1387 
1388  TQRect daysOfWeekBox( box );
1389  daysOfWeekBox.setHeight( mSubHeaderHeight );
1390  daysOfWeekBox.setLeft( box.left()+xoffset );
1391  drawDaysOfWeek( p, monthDate, monthDate.addDays( 6 ), daysOfWeekBox );
1392 
1393  TQColor back = p.backgroundColor();
1394  bool darkbg = false;
1395  for ( int row = 0; row < rows; ++row ) {
1396  for ( int col = 0; col < 7; ++col ) {
1397  // show days from previous/next month with a grayed background
1398  if ( (monthDate < monthFirst) || (monthDate > monthLast) ) {
1399  p.setBackgroundColor( back.dark( 120 ) );
1400  darkbg = true;
1401  }
1402  TQRect dayBox( coledges[col], rowedges[row], coledges[col+1]-coledges[col], rowedges[row+1]-rowedges[row] );
1403  drawDayBox(p, monthDate, dayBox, false, recurDaily, recurWeekly );
1404  if ( darkbg ) {
1405  p.setBackgroundColor( back );
1406  darkbg = false;
1407  }
1408  monthDate = monthDate.addDays(1);
1409  }
1410  }
1411 }
1412 
1413 
1415 
1416 void CalPrintPluginBase::drawTodo( int &count, Todo *todo, TQPainter &p,
1417  TodoSortField sortField, SortDirection sortDir,
1418  bool connectSubTodos, bool strikeoutCompleted,
1419  bool desc, int posPriority, int posSummary,
1420  int posDueDt, int posPercentComplete,
1421  int level, int x, int &y, int width,
1422  int pageHeight, const Todo::List &todoList,
1423  TodoParentStart *r )
1424 {
1425  TQString outStr;
1426  const TDELocale *local = TDEGlobal::locale();
1427  TQRect rect;
1428  TodoParentStart startpt;
1429 
1430  // This list keeps all starting points of the parent to-dos so the connection
1431  // lines of the tree can easily be drawn (needed if a new page is started)
1432  static TQPtrList<TodoParentStart> startPoints;
1433  if ( level < 1 ) {
1434  startPoints.clear();
1435  }
1436 
1437  // Compute the right hand side of the to-do box
1438  int rhs = posPercentComplete;
1439  if ( rhs < 0 ) rhs = posDueDt; //not printing percent completed
1440  if ( rhs < 0 ) rhs = x+width; //not printing due dates either
1441 
1442  // size of to-do
1443  outStr=todo->summary();
1444  int left = posSummary + ( level*10 );
1445  rect = p.boundingRect( left, y, ( rhs-left-5 ), -1, TQt::WordBreak, outStr );
1446  if ( !todo->description().isEmpty() && desc ) {
1447  outStr = todo->description();
1448  rect = p.boundingRect( left+20, rect.bottom()+5, width-(left+10-x), -1,
1449  TQt::WordBreak, outStr );
1450  }
1451  // if too big make new page
1452  if ( rect.bottom() > pageHeight ) {
1453  // first draw the connection lines from parent to-dos:
1454  if ( level > 0 && connectSubTodos ) {
1455  TodoParentStart *rct;
1456  for ( rct = startPoints.first(); rct; rct = startPoints.next() ) {
1457  int start;
1458  int center = rct->mRect.left() + (rct->mRect.width()/2);
1459  int to = p.viewport().bottom();
1460 
1461  // draw either from start point of parent or from top of the page
1462  if ( rct->mSamePage )
1463  start = rct->mRect.bottom() + 1;
1464  else
1465  start = p.viewport().top();
1466  p.moveTo( center, start );
1467  p.lineTo( center, to );
1468  rct->mSamePage = false;
1469  }
1470  }
1471  y=0;
1472  mPrinter->newPage();
1473  }
1474 
1475  // If this is a sub-to-do, r will not be 0, and we want the LH side
1476  // of the priority line up to the RH side of the parent to-do's priority
1477  bool showPriority = posPriority>=0;
1478  int lhs = posPriority;
1479  if ( r ) {
1480  lhs = r->mRect.right() + 1;
1481  }
1482 
1483  outStr.setNum( todo->priority() );
1484  rect = p.boundingRect( lhs, y + 10, 5, -1, TQt::AlignCenter, outStr );
1485  // Make it a more reasonable size
1486  rect.setWidth(18);
1487  rect.setHeight(18);
1488 
1489  // Draw a checkbox
1490  p.setBrush( TQBrush( TQt::NoBrush ) );
1491  p.drawRect( rect );
1492  if ( todo->isCompleted() ) {
1493  // cross out the rectangle for completed to-dos
1494  p.drawLine( rect.topLeft(), rect.bottomRight() );
1495  p.drawLine( rect.topRight(), rect.bottomLeft() );
1496  }
1497  lhs = rect.right() + 3;
1498 
1499  // Priority
1500  if ( todo->priority() > 0 && showPriority ) {
1501  p.drawText( rect, TQt::AlignCenter, outStr );
1502  }
1503  startpt.mRect = rect; //save for later
1504 
1505  // Connect the dots
1506  if ( level > 0 && connectSubTodos ) {
1507  int bottom;
1508  int center( r->mRect.left() + (r->mRect.width()/2) );
1509  if ( r->mSamePage )
1510  bottom = r->mRect.bottom() + 1;
1511  else
1512  bottom = 0;
1513  int to( rect.top() + (rect.height()/2) );
1514  int endx( rect.left() );
1515  p.moveTo( center, bottom );
1516  p.lineTo( center, to );
1517  p.lineTo( endx, to );
1518  }
1519 
1520  // summary
1521  outStr=todo->summary();
1522  rect = p.boundingRect( lhs, rect.top(), (rhs-(left + rect.width() + 5)),
1523  -1, TQt::WordBreak, outStr );
1524 
1525  TQRect newrect;
1526  //FIXME: the following code prints underline rather than strikeout text
1527 #if 0
1528  TQFont f( p.font() );
1529  if ( todo->isCompleted() && strikeoutCompleted ) {
1530  f.setStrikeOut( true );
1531  p.setFont( f );
1532  }
1533  p.drawText( rect, TQt::WordBreak, outStr, -1, &newrect );
1534  f.setStrikeOut( false );
1535  p.setFont( f );
1536 #endif
1537  //TODO: Remove this section when the code above is fixed
1538  p.drawText( rect, TQt::WordBreak, outStr, -1, &newrect );
1539  if ( todo->isCompleted() && strikeoutCompleted ) {
1540  // strike out the summary text if to-do is complete
1541  // Note: we tried to use a strike-out font and for unknown reasons the
1542  // result was underline instead of strike-out, so draw the lines ourselves.
1543  int delta = p.fontMetrics().lineSpacing();
1544  int lines = ( rect.height() / delta ) + 1;
1545  for ( int i=0; i<lines; i++ ) {
1546  p.moveTo( rect.left(), rect.top() + ( delta/2 ) + ( i*delta ) );
1547  p.lineTo( rect.right(), rect.top() + ( delta/2 ) + ( i*delta ) );
1548  }
1549  }
1550 
1551  // due date
1552  if ( todo->hasDueDate() && posDueDt>=0 ) {
1553  outStr = local->formatDate( todo->dtDue().date(), true );
1554  rect = p.boundingRect( posDueDt, y, x + width, -1,
1555  TQt::AlignTop | TQt::AlignLeft, outStr );
1556  p.drawText( rect, TQt::AlignTop | TQt::AlignLeft, outStr );
1557  }
1558 
1559  // percentage completed
1560  bool showPercentComplete = posPercentComplete>=0;
1561  if ( showPercentComplete ) {
1562  int lwidth = 24;
1563  int lheight = 12;
1564  //first, draw the progress bar
1565  int progress = (int)(( lwidth*todo->percentComplete())/100.0 + 0.5);
1566 
1567  p.setBrush( TQBrush( TQt::NoBrush ) );
1568  p.drawRect( posPercentComplete, y+3, lwidth, lheight );
1569  if ( progress > 0 ) {
1570  p.setBrush( TQColor( 128, 128, 128 ) );
1571  p.drawRect( posPercentComplete, y+3, progress, lheight );
1572  }
1573 
1574  //now, write the percentage
1575  outStr = i18n( "%1%" ).arg( todo->percentComplete() );
1576  rect = p.boundingRect( posPercentComplete+lwidth+3, y, x + width, -1,
1577  TQt::AlignTop | TQt::AlignLeft, outStr );
1578  p.drawText( rect, TQt::AlignTop | TQt::AlignLeft, outStr );
1579  }
1580 
1581  // description
1582  if ( !todo->description().isEmpty() && desc ) {
1583  y = newrect.bottom() + 5;
1584  outStr = todo->description();
1585  rect = p.boundingRect( left+20, y, x+width-(left+10), -1,
1586  TQt::WordBreak, outStr );
1587  p.drawText( rect, TQt::WordBreak, outStr, -1, &newrect );
1588  }
1589 
1590  // Set the new line position
1591  y = newrect.bottom() + 10; //set the line position
1592 
1593  // If the to-do has sub-to-dos, we need to call ourselves recursively
1594 #if 0
1595  Incidence::List l = todo->relations();
1596  Incidence::List::ConstIterator it;
1597  startPoints.append( &startpt );
1598  for( it = l.begin(); it != l.end(); ++it ) {
1599  count++;
1600  // In the future, to-dos might also be related to events
1601  // Manually check if the sub-to-do is in the list of to-dos to print
1602  // The problem is that relations() does not apply filters, so
1603  // we need to compare manually with the complete filtered list!
1604  Todo* subtodo = dynamic_cast<Todo *>( *it );
1605  if (subtodo && todoList.contains( subtodo ) ) {
1606  drawTodo( count, subtodo, p, connectSubTodos, strikeoutCompleted,
1607  desc, posPriority, posSummary, posDueDt, posPercentComplete,
1608  level+1, x, y, width, pageHeight, todoList, &startpt );
1609  }
1610  }
1611 #endif
1612  // Make a list of all the sub-to-dos related to this to-do.
1613  Todo::List t;
1614  Incidence::List l = todo->relations();
1615  Incidence::List::ConstIterator it;
1616  for( it=l.begin(); it!=l.end(); ++it ) {
1617  // In the future, to-dos might also be related to events
1618  // Manually check if the sub-to-do is in the list of to-dos to print
1619  // The problem is that relations() does not apply filters, so
1620  // we need to compare manually with the complete filtered list!
1621  Todo* subtodo = dynamic_cast<Todo *>( *it );
1622  if ( subtodo && todoList.contains( subtodo ) ) {
1623  t.append( subtodo );
1624  }
1625  }
1626 
1627  // Sort the sub-to-dos and then print them
1628  Todo::List sl = mCalendar->sortTodos( &t, sortField, sortDir );
1629  Todo::List::ConstIterator isl;
1630  startPoints.append( &startpt );
1631  for( isl = sl.begin(); isl != sl.end(); ++isl ) {
1632  count++;
1633  drawTodo( count, ( *isl ), p, sortField, sortDir,
1634  connectSubTodos, strikeoutCompleted,
1635  desc, posPriority, posSummary, posDueDt, posPercentComplete,
1636  level+1, x, y, width, pageHeight, todoList, &startpt );
1637  }
1638  startPoints.remove( &startpt );
1639 }
1640 
1642 {
1643  return ( weekday + 7 - TDEGlobal::locale()->weekStartDay() ) % 7;
1644 }
1645 
1646 void CalPrintPluginBase::drawJournalField( TQPainter &p, TQString field, TQString text,
1647  int x, int &y, int width, int pageHeight )
1648 {
1649  if ( text.isEmpty() ) return;
1650 
1651  TQString entry( field.arg( text ) );
1652 
1653  TQRect rect( p.boundingRect( x, y, width, -1, TQt::WordBreak, entry) );
1654  if ( rect.bottom() > pageHeight) {
1655  // Start new page...
1656  // FIXME: If it's a multi-line text, draw a few lines on this page, and the
1657  // remaining lines on the next page.
1658  y=0;
1659  mPrinter->newPage();
1660  rect = p.boundingRect( x, y, width, -1, TQt::WordBreak, entry);
1661  }
1662  TQRect newrect;
1663  p.drawText( rect, TQt::WordBreak, entry, -1, &newrect );
1664  y = newrect.bottom() + 7;
1665 }
1666 
1667 void CalPrintPluginBase::drawJournal( Journal * journal, TQPainter &p, int x, int &y,
1668  int width, int pageHeight )
1669 {
1670  TQFont oldFont( p.font() );
1671  p.setFont( TQFont( "sans-serif", 15 ) );
1672  TQString headerText;
1673  TQString dateText( TDEGlobal::locale()->
1674  formatDate( journal->dtStart().date(), false ) );
1675 
1676  if ( journal->summary().isEmpty() ) {
1677  headerText = dateText;
1678  } else {
1679  headerText = i18n("Description - date", "%1 - %2")
1680  .arg( journal->summary() )
1681  .arg( dateText );
1682  }
1683 
1684  TQRect rect( p.boundingRect( x, y, width, -1, TQt::WordBreak, headerText) );
1685  if ( rect.bottom() > pageHeight) {
1686  // Start new page...
1687  y=0;
1688  mPrinter->newPage();
1689  rect = p.boundingRect( x, y, width, -1, TQt::WordBreak, headerText );
1690  }
1691  TQRect newrect;
1692  p.drawText( rect, TQt::WordBreak, headerText, -1, &newrect );
1693  p.setFont( oldFont );
1694 
1695  y = newrect.bottom() + 4;
1696 
1697  p.drawLine( x + 3, y, x + width - 6, y );
1698  y += 5;
1699 
1700  drawJournalField( p, i18n("Person: %1"), journal->organizer().fullName(), x, y, width, pageHeight );
1701  drawJournalField( p, i18n("%1"), journal->description(), x, y, width, pageHeight );
1702  y += 10;
1703 }
1704 
1705 
1706 void CalPrintPluginBase::drawSplitHeaderRight( TQPainter &p, const TQDate &fd,
1707  const TQDate &td,
1708  const TQDate &,
1709  int width, int )
1710 {
1711  TQFont oldFont( p.font() );
1712 
1713  TQPen oldPen( p.pen() );
1714  TQPen pen( TQt::black, 4 );
1715 
1716  TQString title;
1717  if ( mCalSys ) {
1718  if ( fd.month() == td.month() ) {
1719  title = i18n("Date range: Month dayStart - dayEnd", "%1 %2 - %3")
1720  .arg( mCalSys->monthName( fd.month(), false ) )
1721  .arg( mCalSys->dayString( fd, false ) )
1722  .arg( mCalSys->dayString( td, false ) );
1723  } else {
1724  title = i18n("Date range: monthStart dayStart - monthEnd dayEnd", "%1 %2 - %3 %4")
1725  .arg( mCalSys->monthName( fd.month(), false ) )
1726  .arg( mCalSys->dayString( fd, false ) )
1727  .arg( mCalSys->monthName( td.month(), false ) )
1728  .arg( mCalSys->dayString( td, false ) );
1729  }
1730  }
1731 
1732  TQFont serifFont("Times", 30);
1733  p.setFont(serifFont);
1734 
1735  int lineSpacing = p.fontMetrics().lineSpacing();
1736  p.drawText( 0, lineSpacing * 0, width, lineSpacing,
1737  TQt::AlignRight | TQt::AlignTop, title );
1738 
1739  title.truncate(0);
1740 
1741  p.setPen( pen );
1742  p.drawLine(300, lineSpacing * 1, width, lineSpacing * 1);
1743  p.setPen( oldPen );
1744 
1745  p.setFont(TQFont("Times", 20, TQFont::Bold, TRUE));
1746  int newlineSpacing = p.fontMetrics().lineSpacing();
1747  title += TQString::number(fd.year());
1748  p.drawText( 0, lineSpacing * 1 + 4, width, newlineSpacing,
1749  TQt::AlignRight | TQt::AlignTop, title );
1750 
1751  p.setFont( oldFont );
1752 }
1753 
1754 #endif
void printEventString(TQPainter &p, const TQRect &box, const TQString &str, int flags=-1)
Print the given string (event summary) in the given rectangle.
void drawDaysOfWeek(TQPainter &p, const TQDate &fromDate, const TQDate &toDate, const TQRect &box)
Draw a horizontal bar with the weekday names of the given date range in the given area of the painter...
virtual void loadConfig()=0
Load print format configuration from config file.
int footerHeight() const
Returns the height of the page footer.
void doSaveConfig()
Save complete config.
void drawMonth(TQPainter &p, const TQDate &dt, const TQRect &box, int maxdays=-1, int subDailyFlags=TimeBoxes, int holidaysFlags=Text)
Draw a vertical representation of the month containing the date dt.
void drawSmallMonth(TQPainter &p, const TQDate &qd, const TQRect &box)
Draw a small calendar with the days of a month into the given area.
TQColor categoryBgColor(Incidence *incidence)
Helper functions to hide the KOrg::CoreHelper.
virtual TQWidget * createConfigWidget(TQWidget *)
Returns widget for configuring the print format.
static void drawBox(TQPainter &p, int linewidth, const TQRect &rect)
Draw a box with given width at the given coordinates.
int drawBoxWithCaption(TQPainter &p, const TQRect &box, const TQString &caption, const TQString &contents, bool sameLine, bool expand, const TQFont &captionFont, const TQFont &textFont)
Draw a component box with a heading (printed in bold).
CalPrintPluginBase()
Constructor.
int headerHeight() const
Returns the height of the page header.
void drawSubHeaderBox(TQPainter &p, const TQString &str, const TQRect &box)
Draw a subheader box with a shaded background and the given string.
void drawDayBox(TQPainter &p, const TQDate &qd, const TQRect &box, bool fullDate=false, bool printRecurDaily=true, bool printRecurWeekly=true)
Draw the box containing a list of all events of the given day (with their times, of course).
void showEventBox(TQPainter &p, int linewidth, const TQRect &box, Incidence *incidence, const TQString &str, int flags=-1)
Print the box for the given event with the given string.
virtual void doPrint(KPrinter *printer)
Start printing.
void drawTimeTable(TQPainter &p, const TQDate &fromDate, const TQDate &toDate, TQTime &fromTime, TQTime &toTime, const TQRect &box)
Draw the timetable view of the given time range from fromDate to toDate.
void drawDaysOfWeekBox(TQPainter &p, const TQDate &qd, const TQRect &box)
Draw a single weekday name in a box inside the given area of the painter.
void drawJournal(Journal *journal, TQPainter &p, int x, int &y, int width, int pageHeight)
Draws single journal item.
void drawMonthTable(TQPainter &p, const TQDate &qd, bool weeknumbers, bool recurDaily, bool recurWeekly, const TQRect &box)
Draw the month table of the month containing the date qd.
int drawAllDayBox(TQPainter &p, Event::List &eventList, const TQDate &qd, bool expandable, const TQRect &box)
Draw the all-day box for the agenda print view (the box on top which doesn't have a time on the time ...
virtual void print(TQPainter &p, int width, int height)=0
Actually do the printing.
static int weekdayColumn(int weekday)
Determines the column of the given weekday ( 1=Monday, 7=Sunday ), taking the start of the week setti...
void drawTodo(int &count, Todo *todo, TQPainter &p, TodoSortField sortField, SortDirection sortDir, bool connectSubTodos, bool strikeoutCompleted, bool desc, int posPriority, int posSummary, int posDueDt, int posPercentComplete, int level, int x, int &y, int width, int pageHeight, const Todo::List &todoList, TodoParentStart *r=0)
Draws single to-do and its (intented) sub-to-dos, optionally connects them by a tree-like line,...
static void drawShadedBox(TQPainter &p, int linewidth, const TQBrush &brush, const TQRect &rect)
Draw a shaded box with given width at the given coordinates.
int drawHeader(TQPainter &p, TQString title, const TQDate &month1, const TQDate &month2, const TQRect &box, bool expand=false)
Draw the gray header bar of the printout to the TQPainter.
void drawVerticalBox(TQPainter &p, int linewidth, const TQRect &box, const TQString &str, int flags=-1)
Draw an event box with vertical text.
void setKOrgCoreHelper(KOrg::CoreHelper *helper)
HELPER FUNCTIONS.
void drawTimeLine(TQPainter &p, const TQTime &fromTime, const TQTime &toTime, const TQRect &box)
Draw a (vertical) time scale from time fromTime to toTime inside the given area of the painter.
virtual void saveConfig()=0
Write print format configuration to config file.
void drawWeek(TQPainter &p, const TQDate &qd, const TQRect &box)
Draw the week (filofax) table of the week containing the date qd.
void doLoadConfig()
Load complete config.
int drawFooter(TQPainter &p, TQRect &box)
Draw a page footer containing the printing date and possibly other things, like a page number.
void drawAgendaDayBox(TQPainter &p, Event::List &eventList, const TQDate &qd, bool expandable, TQTime &fromTime, TQTime &toTime, const TQRect &box)
Draw the agenda box for the day print style (the box showing all events of that day).
static Todo::List sortTodos(Todo::List *todoList, TodoSortField sortField, SortDirection sortDirection)
virtual Event::List events(EventSortField sortField=EventSortUnsorted, SortDirection sortDirection=SortDirectionAscending)
virtual Todo::List todos(TodoSortField sortField=TodoSortUnsorted, SortDirection sortDirection=SortDirectionAscending)
virtual TQDateTime dtEnd() const
void setDtEnd(const TQDateTime &dtEnd)
bool isMultiDay() const
bool doesFloat() const
virtual TQDateTime dtStart() const
void setSummary(const TQString &summary)
TQString description() const
TQStringList categories() const
int priority() const
void setFloats(bool f)
bool doesRecur() const
virtual void setDtStart(const TQDateTime &dtStart)
void setCategories(const TQStringList &categories)
Incidence::List relations() const
TQString location() const
virtual TQValueList< TQDateTime > startDateTimesForDate(const TQDate &date) const
TQString summary() const
Recurrence * recurrence() const
virtual bool recursOn(const TQDate &qd) const
virtual TQDateTime endDateForStart(const TQDateTime &startDt) const
TQValueList< TQTime > recurTimesOn(const TQDate &date) const
bool recursOn(const TQDate &qd) const
bool hasDueDate() const
bool isCompleted() const
bool hasStartDate() const
TQDateTime dtStart(bool first=false) const
int percentComplete() const
TQDateTime dtDue(bool first=false) const
virtual TQString description()=0
Returns short description of print format.
virtual TQString info()=0
Returns long description of print format.
KPrinter * mPrinter
The printer object.
Definition: printplugin.h:156
TodoSortField
EventSortStartDate
SortDirection
SortDirectionAscending