• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

korganizer

  • sources
  • kde-4.12
  • kdepim
  • korganizer
  • printing
calprintpluginbase.cpp
Go to the documentation of this file.
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) 2008 Ron Goodheart <rong.dev@gmail.com>
7  Copyright (c) 2012 Allen Winter <winter@kde.org>
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 along
20  with this program; if not, write to the Free Software Foundation, Inc.,
21  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 Qt, and distribute the resulting executable,
25  without including the source code for Qt in the source distribution.
26 */
27 
28 #include "calprintpluginbase.h"
29 #include "koprefs.h"
30 #include "kohelper.h"
31 #include "koglobals.h"
32 
33 #include <Akonadi/Calendar/ETMCalendar>
34 #include <calendarsupport/utils.h>
35 #include <calendarviews/agenda/cellitem.h>
36 
37 #include <KCalendarSystem>
38 #include <KConfigGroup>
39 #include <KDebug>
40 #include <KSystemTimeZones>
41 #include <KWordWrap>
42 
43 #include <QAbstractTextDocumentLayout>
44 #include <QFrame>
45 #include <QLabel>
46 #include <QLayout>
47 #include <QPainter>
48 #include <QTextCursor>
49 #include <QTextDocument>
50 #include <QTextDocumentFragment>
51 #include <qmath.h> // qCeil krazy:exclude=camelcase since no QMath
52 
53 using namespace KCalCore;
54 
55 static QString cleanStr( const QString &instr )
56 {
57  QString ret = instr;
58  return ret.replace( QLatin1Char('\n'), QLatin1Char(' ') );
59 }
60 
61 /******************************************************************
62  ** The Todo positioning structure **
63  ******************************************************************/
64 class CalPrintPluginBase::TodoParentStart
65 {
66  public:
67  TodoParentStart( const QRect &pt = QRect(), bool hasLine = false, bool page = true )
68  : mRect( pt ), mHasLine( hasLine ), mSamePage( page ) {}
69 
70  QRect mRect;
71  bool mHasLine;
72  bool mSamePage;
73 };
74 
75 /******************************************************************
76  ** The Print item **
77  ******************************************************************/
78 
79 class PrintCellItem : public EventViews::CellItem
80 {
81  public:
82  PrintCellItem( const Event::Ptr &event, const KDateTime &start, const KDateTime &end )
83  : mEvent( event ), mStart( start ), mEnd( end )
84  {
85  }
86 
87  Event::Ptr event() const { return mEvent; }
88 
89  QString label() const { return mEvent->summary(); }
90 
91  KDateTime start() const { return mStart; }
92  KDateTime end() const { return mEnd; }
93 
96  bool overlaps( EventViews::CellItem *o ) const
97  {
98  PrintCellItem *other = static_cast<PrintCellItem *>( o );
99  return !( other->start() >= end() || other->end() <= start() );
100  }
101 
102  private:
103  Event::Ptr mEvent;
104  KDateTime mStart, mEnd;
105 };
106 
107 /******************************************************************
108  ** The Print plugin **
109  ******************************************************************/
110 
111 CalPrintPluginBase::CalPrintPluginBase()
112  : PrintPlugin(), mUseColors( true ), mPrintFooter( true ),
113  mHeaderHeight( -1 ), mSubHeaderHeight( SUBHEADER_HEIGHT ), mFooterHeight( -1 ),
114  mMargin( MARGIN_SIZE ), mPadding( PADDING_SIZE ), mCalSys( 0 )
115 {
116 }
117 
118 CalPrintPluginBase::~CalPrintPluginBase()
119 {
120 }
121 
122 QWidget *CalPrintPluginBase::createConfigWidget( QWidget *w )
123 {
124  QFrame *wdg = new QFrame( w );
125  QVBoxLayout *layout = new QVBoxLayout( wdg );
126 
127  QLabel *title = new QLabel( description(), wdg );
128  QFont titleFont( title->font() );
129  titleFont.setPointSize( 20 );
130  titleFont.setBold( true );
131  title->setFont( titleFont );
132 
133  layout->addWidget( title );
134  layout->addWidget( new QLabel( info(), wdg ) );
135  layout->addSpacing( 20 );
136  layout->addWidget(
137  new QLabel( i18n( "This printing style does not have any configuration options." ), wdg ) );
138  layout->addStretch();
139  return wdg;
140 }
141 
142 void CalPrintPluginBase::doPrint( QPrinter *printer )
143 {
144  if ( !printer ) {
145  return;
146  }
147  mPrinter = printer;
148  QPainter p;
149 
150  mPrinter->setColorMode( mUseColors ? QPrinter::Color : QPrinter::GrayScale );
151 
152  p.begin( mPrinter );
153  // TODO: Fix the margins!!!
154  // the painter initially begins at 72 dpi per the Qt docs.
155  // we want half-inch margins.
156  int margins = margin();
157  p.setViewport( margins, margins,
158  p.viewport().width() - 2 * margins,
159  p.viewport().height() - 2 * margins );
160 // QRect vp( p.viewport() );
161 // vp.setRight( vp.right()*2 );
162 // vp.setBottom( vp.bottom()*2 );
163 // p.setWindow( vp );
164  int pageWidth = p.window().width();
165  int pageHeight = p.window().height();
166 // int pageWidth = p.viewport().width();
167 // int pageHeight = p.viewport().height();
168 
169  print( p, pageWidth, pageHeight );
170 
171  p.end();
172  mPrinter = 0;
173 }
174 
175 void CalPrintPluginBase::doLoadConfig()
176 {
177  if ( mConfig ) {
178  KConfigGroup group( mConfig, groupName() );
179  mConfig->sync();
180  QDateTime dt = QDateTime::currentDateTime();
181  mFromDate = group.readEntry( "FromDate", dt ).date();
182  mToDate = group.readEntry( "ToDate", dt ).date();
183  mUseColors = group.readEntry( "UseColors", true );
184  mPrintFooter = group.readEntry( "PrintFooter", true );
185  mExcludeConfidential = group.readEntry( "Exclude confidential", true );
186  mExcludePrivate = group.readEntry( "Exclude private", true );
187  loadConfig();
188  } else {
189  kDebug() << "No config available in loadConfig!!!!";
190  }
191 }
192 
193 void CalPrintPluginBase::doSaveConfig()
194 {
195  if ( mConfig ) {
196  KConfigGroup group( mConfig, groupName() );
197  saveConfig();
198  QDateTime dt = QDateTime::currentDateTime(); // any valid QDateTime will do
199  dt.setDate( mFromDate );
200  group.writeEntry( "FromDate", dt );
201  dt.setDate( mToDate );
202  group.writeEntry( "ToDate", dt );
203  group.writeEntry( "UseColors", mUseColors );
204  group.writeEntry( "PrintFooter", mPrintFooter );
205  group.writeEntry( "Exclude confidential", mExcludeConfidential );
206  group.writeEntry( "Exclude private", mExcludePrivate );
207  mConfig->sync();
208  } else {
209  kDebug() << "No config available in saveConfig!!!!";
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 
221 bool CalPrintPluginBase::useColors() const
222 {
223  return mUseColors;
224 }
225 
226 void CalPrintPluginBase::setUseColors( bool useColors )
227 {
228  mUseColors = useColors;
229 }
230 
231 bool CalPrintPluginBase::printFooter() const
232 {
233  return mPrintFooter;
234 }
235 
236 void CalPrintPluginBase::setPrintFooter( bool printFooter )
237 {
238  mPrintFooter = printFooter;
239 }
240 
241 QPrinter::Orientation CalPrintPluginBase::orientation() const
242 {
243  return mPrinter ? mPrinter->orientation() : QPrinter::Portrait;
244 }
245 
246 QTime CalPrintPluginBase::dayStart()
247 {
248  QTime start( 8, 0, 0 );
249  if ( mCoreHelper ) {
250  start = mCoreHelper->dayStart();
251  }
252  return start;
253 }
254 
255 void CalPrintPluginBase::setCategoryColors( QPainter &p, const Incidence::Ptr &incidence )
256 {
257  QColor bgColor = categoryBgColor( incidence );
258  if ( bgColor.isValid() ) {
259  p.setBrush( bgColor );
260  }
261  QColor tColor( KOHelper::getTextColor( bgColor ) );
262  if ( tColor.isValid() ) {
263  p.setPen( tColor );
264  }
265 }
266 
267 QColor CalPrintPluginBase::categoryBgColor( const Incidence::Ptr &incidence )
268 {
269  if ( mCoreHelper && incidence ) {
270  QColor backColor = mCoreHelper->categoryColor( incidence->categories() );
271  if ( incidence->type() == Incidence::TypeTodo ) {
272  if ( ( incidence.staticCast<Todo>() )->isOverdue() ) {
273  backColor = KOPrefs::instance()->todoOverdueColor();
274  }
275  }
276  return backColor;
277  } else {
278  return QColor();
279  }
280 }
281 
282 QString CalPrintPluginBase::holidayString( const QDate &dt )
283 {
284  return mCoreHelper ? mCoreHelper->holidayString(dt) : QString();
285 }
286 
287 Event::Ptr CalPrintPluginBase::holiday( const QDate &dt )
288 {
289  QString hstring( holidayString( dt ) );
290  if ( !hstring.isEmpty() ) {
291  //FIXME: KOPrefs::instance()->timeSpec()?
292  KDateTime::Spec timeSpec = KSystemTimeZones::local();
293  KDateTime kdt( dt, QTime(), timeSpec );
294  Event::Ptr holiday( new Event );
295  holiday->setSummary( hstring );
296  holiday->setDtStart( kdt );
297  holiday->setDtEnd( kdt );
298  holiday->setAllDay( true );
299  holiday->setCategories( i18n( "Holiday" ) );
300  return holiday;
301  }
302  return Event::Ptr();
303 }
304 
305 const KCalendarSystem *CalPrintPluginBase::calendarSystem() const
306 {
307  return mCalSys;
308 }
309 
310 void CalPrintPluginBase::setCalendarSystem( const KCalendarSystem *calsys )
311 {
312  mCalSys = calsys;
313 }
314 
315 int CalPrintPluginBase::headerHeight() const
316 {
317  if ( mHeaderHeight >= 0 ) {
318  return mHeaderHeight;
319  } else if ( orientation() == QPrinter::Portrait ) {
320  return PORTRAIT_HEADER_HEIGHT;
321  } else {
322  return LANDSCAPE_HEADER_HEIGHT;
323  }
324 }
325 
326 void CalPrintPluginBase::setHeaderHeight( const int height )
327 {
328  mHeaderHeight = height;
329 }
330 
331 int CalPrintPluginBase::subHeaderHeight() const
332 {
333  return mSubHeaderHeight;
334 }
335 
336 void CalPrintPluginBase::setSubHeaderHeight( const int height )
337 {
338  mSubHeaderHeight = height;
339 }
340 
341 int CalPrintPluginBase::footerHeight() const
342 {
343  if ( !mPrintFooter ) {
344  return 0;
345  }
346 
347  if ( mFooterHeight >= 0 ) {
348  return mFooterHeight;
349  } else if ( orientation() == QPrinter::Portrait ) {
350  return PORTRAIT_FOOTER_HEIGHT;
351  } else {
352  return LANDSCAPE_FOOTER_HEIGHT;
353  }
354 }
355 
356 void CalPrintPluginBase::setFooterHeight( const int height )
357 {
358  mFooterHeight = height;
359 }
360 
361 int CalPrintPluginBase::margin() const
362 {
363  return mMargin;
364 }
365 
366 void CalPrintPluginBase::setMargin( const int margin )
367 {
368  mMargin = margin;
369 }
370 
371 int CalPrintPluginBase::padding() const
372 {
373  return mPadding;
374 }
375 
376 void CalPrintPluginBase::setPadding( const int padding )
377 {
378  mPadding = padding;
379 }
380 
381 int CalPrintPluginBase::borderWidth() const
382 {
383  return mBorder;
384 }
385 
386 void CalPrintPluginBase::setBorderWidth( const int borderwidth )
387 {
388  mBorder = borderwidth;
389 }
390 
391 void CalPrintPluginBase::drawBox( QPainter &p, int linewidth, const QRect &rect )
392 {
393  QPen pen( p.pen() );
394  QPen oldpen( pen );
395  // no border
396  if ( linewidth >= 0 ) {
397  pen.setWidth( linewidth );
398  p.setPen( pen );
399  } else {
400  p.setPen( Qt::NoPen );
401  }
402  p.drawRect( rect );
403  p.setPen( oldpen );
404 }
405 
406 void CalPrintPluginBase::drawShadedBox( QPainter &p, int linewidth,
407  const QBrush &brush, const QRect &rect )
408 {
409  QBrush oldbrush( p.brush() );
410  p.setBrush( brush );
411  drawBox( p, linewidth, rect );
412  p.setBrush( oldbrush );
413 }
414 
415 void CalPrintPluginBase::printEventString( QPainter &p, const QRect &box,
416  const QString &str, int flags )
417 {
418  QRect newbox( box );
419  newbox.adjust( 3, 1, -1, -1 );
420  p.drawText( newbox, ( flags == -1 ) ?
421  ( Qt::AlignTop | Qt::AlignLeft | Qt::TextWordWrap ) : flags, str );
422 }
423 
424 void CalPrintPluginBase::showEventBox( QPainter &p, int linewidth, const QRect &box,
425  const Incidence::Ptr &incidence, const QString &str,
426  int flags )
427 {
428  QPen oldpen( p.pen() );
429  QBrush oldbrush( p.brush() );
430  QColor bgColor( categoryBgColor( incidence ) );
431  if ( mUseColors & bgColor.isValid() ) {
432  p.setBrush( bgColor );
433  } else {
434  p.setBrush( QColor( 232, 232, 232 ) );
435  }
436  drawBox( p, ( linewidth > 0 ) ? linewidth : EVENT_BORDER_WIDTH, box );
437  if ( mUseColors && bgColor.isValid() ) {
438  p.setPen( KOHelper::getTextColor( bgColor ) );
439  }
440  printEventString( p, box, str, flags );
441  p.setPen( oldpen );
442  p.setBrush( oldbrush );
443 }
444 
445 void CalPrintPluginBase::drawSubHeaderBox( QPainter &p, const QString &str, const QRect &box )
446 {
447  drawShadedBox( p, BOX_BORDER_WIDTH, QColor( 232, 232, 232 ), box );
448  QFont oldfont( p.font() );
449  p.setFont( QFont( QLatin1String("sans-serif"), 10, QFont::Bold ) );
450  p.drawText( box, Qt::AlignCenter | Qt::AlignVCenter, str );
451  p.setFont( oldfont );
452 }
453 
454 void CalPrintPluginBase::drawVerticalBox( QPainter &p, int linewidth, const QRect &box,
455  const QString &str, int flags )
456 {
457  p.save();
458  p.rotate( -90 );
459  QRect rotatedBox( -box.top() - box.height(), box.left(), box.height(), box.width() );
460  showEventBox( p, linewidth, rotatedBox, Incidence::Ptr(), str,
461  ( flags == -1 ) ? Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine : flags );
462 
463  p.restore();
464 }
465 
466 /*
467  * Return value: If expand, bottom of the printed box, otherwise vertical end
468  * of the printed contents inside the box.
469  */
470 int CalPrintPluginBase::drawBoxWithCaption( QPainter &p, const QRect &allbox,
471  const QString &caption,
472  const QString &contents,
473  bool sameLine, bool expand,
474  const QFont &captionFont,
475  const QFont &textFont,
476  bool richContents )
477 {
478  QFont oldFont( p.font() );
479 // QFont captionFont( "sans-serif", 11, QFont::Bold );
480 // QFont textFont( "sans-serif", 11, QFont::Normal );
481 // QFont captionFont( "Tahoma", 11, QFont::Bold );
482 // QFont textFont( "Tahoma", 11, QFont::Normal );
483 
484  QRect box( allbox );
485 
486  // Bounding rectangle for caption, single-line, clip on the right
487  QRect captionBox( box.left() + padding(), box.top() + padding(), 0, 0 );
488  p.setFont( captionFont );
489  captionBox = p.boundingRect( captionBox,
490  Qt::AlignLeft | Qt::AlignTop | Qt::TextSingleLine,
491  caption );
492  p.setFont( oldFont );
493  if ( captionBox.right() > box.right() ) {
494  captionBox.setRight( box.right() );
495  }
496  if ( expand && captionBox.bottom() + padding() > box.bottom() ) {
497  box.setBottom( captionBox.bottom() + padding() );
498  }
499 
500  // Bounding rectangle for the contents (if any), word break, clip on the bottom
501  QRect textBox( captionBox );
502  if ( !contents.isEmpty() ) {
503  if ( sameLine ) {
504  textBox.setLeft( captionBox.right() + padding() );
505  } else {
506  textBox.setTop( captionBox.bottom() + padding() );
507  }
508  textBox.setRight( box.right() );
509  }
510  drawBox( p, BOX_BORDER_WIDTH, box );
511  p.setFont( captionFont );
512  p.drawText( captionBox, Qt::AlignLeft | Qt::AlignTop | Qt::TextSingleLine,
513  caption );
514 
515  if ( !contents.isEmpty() ) {
516  if ( sameLine ) {
517  QString contentText = toPlainText( contents );
518  p.setFont( textFont );
519  p.drawText( textBox, Qt::AlignLeft | Qt::AlignTop | Qt::TextSingleLine,
520  contents );
521  } else {
522  QTextDocument rtb;
523  int borderWidth = 2 * BOX_BORDER_WIDTH;
524  if ( richContents ) {
525  rtb.setHtml( contents );
526  } else {
527  rtb.setPlainText( contents );
528  }
529  int boxHeight = allbox.height();
530  if ( !sameLine ) {
531  boxHeight -= captionBox.height();
532  }
533  rtb.setPageSize( QSize( textBox.width(), boxHeight ) );
534  rtb.setDefaultFont( textFont );
535  p.save();
536  p.translate( textBox.x() - borderWidth, textBox.y() );
537  QRect clipBox( 0, 0, box.width(), boxHeight );
538  rtb.drawContents( &p, clipBox );
539  p.restore();
540  textBox.setBottom( textBox.y() +
541  rtb.documentLayout()->documentSize().height() );
542  }
543  }
544  p.setFont( oldFont );
545 
546  if ( expand ) {
547  return box.bottom();
548  } else {
549  return textBox.bottom();
550  }
551 }
552 
553 int CalPrintPluginBase::drawHeader( QPainter &p, const QString &title,
554  const QDate &month1, const QDate &month2, const QRect &allbox,
555  bool expand, QColor backColor )
556 {
557  // print previous month for month view, print current for to-do, day and week
558  int smallMonthWidth = ( allbox.width() / 4 ) - 10;
559  if ( smallMonthWidth > 100 ) {
560  smallMonthWidth = 100;
561  }
562 
563  QRect box( allbox );
564  QRect textRect( allbox );
565 
566  QFont oldFont( p.font() );
567  QFont newFont( QLatin1String("sans-serif"), ( textRect.height() < 60 ) ? 16 : 18, QFont::Bold );
568  if ( expand ) {
569  p.setFont( newFont );
570  QRect boundingR =
571  p.boundingRect( textRect, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextWordWrap, title );
572  p.setFont( oldFont );
573  int h = boundingR.height();
574  if ( h > allbox.height() ) {
575  box.setHeight( h );
576  textRect.setHeight( h );
577  }
578  }
579 
580  if ( !backColor.isValid() ) {
581  backColor = QColor( 232, 232, 232 );
582  }
583 
584  drawShadedBox( p, BOX_BORDER_WIDTH, backColor, box );
585 
586 #if 0
587  // current month title left justified, prev month, next month right justified
588  QRect monthbox2( box.right()-10-smallMonthWidth, box.top(),
589  smallMonthWidth, box.height() );
590  if ( month2.isValid() ) {
591  drawSmallMonth( p, QDate( month2.year(), month2.month(), 1 ), monthbox2 );
592  textRect.setRight( monthbox2.left() );
593  }
594  QRect monthbox1( monthbox2.left()-10-smallMonthWidth, box.top(),
595  smallMonthWidth, box.height() );
596  if ( month1.isValid() ) {
597  drawSmallMonth( p, QDate( month1.year(), month1.month(), 1 ), monthbox1 );
598  textRect.setRight( monthbox1.left() );
599  }
600 
601  // Set the margins
602  p.setFont( newFont );
603  textRect.adjust( 5, 0, 0, 0 );
604  p.drawText( textRect, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextWordWrap, title );
605  p.setFont( oldFont );
606 #endif
607  // prev month left, current month centered, next month right
608  QRect monthbox2( box.right()-10-smallMonthWidth, box.top(),
609  smallMonthWidth, box.height() );
610  if ( month2.isValid() ) {
611  drawSmallMonth( p, QDate( month2.year(), month2.month(), 1 ), monthbox2 );
612  textRect.setRight( monthbox2.left() );
613  }
614  QRect monthbox1( box.left()+10, box.top(), smallMonthWidth, box.height() );
615  if ( month1.isValid() ) {
616  drawSmallMonth( p, QDate( month1.year(), month1.month(), 1 ), monthbox1 );
617  textRect.setLeft( monthbox1.right() );
618  }
619 
620  // Set the margins
621  p.setFont( newFont );
622  p.drawText( textRect, Qt::AlignCenter | Qt::AlignVCenter | Qt::TextWordWrap, title );
623  p.setFont( oldFont );
624 
625  return textRect.bottom();
626 }
627 
628 int CalPrintPluginBase::drawFooter( QPainter &p, const QRect &footbox )
629 {
630  QFont oldfont( p.font() );
631  p.setFont( QFont( QLatin1String("sans-serif"), 6 ) );
632  QFontMetrics fm( p.font() );
633  QString dateStr =
634  KGlobal::locale()->formatDateTime( QDateTime::currentDateTime(), KLocale::LongDate );
635  p.drawText( footbox, Qt::AlignCenter | Qt::AlignVCenter | Qt::TextSingleLine,
636  i18nc( "print date: formatted-datetime", "printed: %1", dateStr ) );
637  p.setFont( oldfont );
638 
639  return footbox.bottom();
640 }
641 
642 void CalPrintPluginBase::drawSmallMonth( QPainter &p, const QDate &qd, const QRect &box )
643 {
644  int weekdayCol = weekdayColumn( qd.dayOfWeek() );
645  int month = qd.month();
646  QDate monthDate( QDate( qd.year(), qd.month(), 1 ) );
647  // correct begin of week
648  QDate monthDate2( monthDate.addDays( -weekdayCol ) );
649 
650  double cellWidth = double( box.width() ) / double( 7 );
651  int rownr = 3 + ( qd.daysInMonth() + weekdayCol - 1 ) / 7;
652  // 3 Pixel after month name, 2 after day names, 1 after the calendar
653  double cellHeight = ( box.height() - 5 ) / rownr;
654  QFont oldFont( p.font() );
655  p.setFont( QFont( QLatin1String("sans-serif"), int(cellHeight-2), QFont::Normal ) );
656 
657  // draw the title
658  if ( mCalSys ) {
659  QRect titleBox( box );
660  titleBox.setHeight( int( cellHeight + 1 ) );
661  p.drawText( titleBox, Qt::AlignTop | Qt::AlignHCenter, mCalSys->monthName( qd ) );
662  }
663 
664  // draw days of week
665  QRect wdayBox( box );
666  wdayBox.setTop( int( box.top() + 3 + cellHeight ) );
667  wdayBox.setHeight( int( 2 * cellHeight ) - int( cellHeight ) );
668 
669  if ( mCalSys ) {
670  for ( int col = 0; col < 7; ++col ) {
671  QString tmpStr = mCalSys->weekDayName( monthDate2 )[0].toUpper();
672  wdayBox.setLeft( int( box.left() + col * cellWidth ) );
673  wdayBox.setRight( int( box.left() + ( col + 1 ) * cellWidth ) );
674  p.drawText( wdayBox, Qt::AlignCenter, tmpStr );
675  monthDate2 = monthDate2.addDays( 1 );
676  }
677  }
678 
679  // draw separator line
680  int calStartY = wdayBox.bottom() + 2;
681  p.drawLine( box.left(), calStartY, box.right(), calStartY );
682  monthDate = monthDate.addDays( -weekdayCol );
683 
684  for ( int row = 0; row < (rownr-2); row++ ) {
685  for ( int col = 0; col < 7; col++ ) {
686  if ( monthDate.month() == month ) {
687  QRect dayRect( int( box.left() + col * cellWidth ),
688  int( calStartY + row * cellHeight ), 0, 0 );
689  dayRect.setRight( int( box.left() + ( col + 1 ) * cellWidth ) );
690  dayRect.setBottom( int( calStartY + ( row + 1 ) * cellHeight ) );
691  p.drawText( dayRect, Qt::AlignCenter, QString::number( monthDate.day() ) );
692  }
693  monthDate = monthDate.addDays(1);
694  }
695  }
696  p.setFont( oldFont );
697 }
698 
699 /*
700  * This routine draws a header box over the main part of the calendar
701  * containing the days of the week.
702  */
703 void CalPrintPluginBase::drawDaysOfWeek( QPainter &p,
704  const QDate &fromDate,
705  const QDate &toDate, const QRect &box )
706 {
707  double cellWidth = double( box.width() ) / double( fromDate.daysTo( toDate ) + 1 );
708  QDate cellDate( fromDate );
709  QRect dateBox( box );
710  int i = 0;
711 
712  while ( cellDate <= toDate ) {
713  dateBox.setLeft( box.left() + int( i * cellWidth ) );
714  dateBox.setRight( box.left() + int( ( i + 1 ) * cellWidth ) );
715  drawDaysOfWeekBox( p, cellDate, dateBox );
716  cellDate = cellDate.addDays( 1 );
717  ++i;
718  }
719 }
720 
721 void CalPrintPluginBase::drawDaysOfWeekBox( QPainter &p, const QDate &qd, const QRect &box )
722 {
723  drawSubHeaderBox( p, ( mCalSys ) ? ( mCalSys->weekDayName( qd ) ) : QString(), box );
724 }
725 
726 void CalPrintPluginBase::drawTimeLine( QPainter &p, const QTime &fromTime,
727  const QTime &toTime, const QRect &box )
728 {
729  drawBox( p, BOX_BORDER_WIDTH, box );
730 
731  int totalsecs = fromTime.secsTo( toTime );
732  float minlen = (float)box.height() * 60. / (float)totalsecs;
733  float cellHeight = ( 60. * (float)minlen );
734  float currY = box.top();
735  // TODO: Don't use half of the width, but less, for the minutes!
736  int xcenter = box.left() + box.width() / 2;
737 
738  QTime curTime( fromTime );
739  QTime endTime( toTime );
740  if ( fromTime.minute() > 30 ) {
741  curTime = QTime( fromTime.hour()+1, 0, 0 );
742  } else if ( fromTime.minute() > 0 ) {
743  curTime = QTime( fromTime.hour(), 30, 0 );
744  float yy = currY + minlen * (float)fromTime.secsTo( curTime ) / 60.;
745  p.drawLine( xcenter, (int)yy, box.right(), (int)yy );
746  curTime = QTime( fromTime.hour() + 1, 0, 0 );
747  }
748  currY += ( float( fromTime.secsTo( curTime ) * minlen ) / 60. );
749 
750  while ( curTime < endTime ) {
751  p.drawLine( box.left(), (int)currY, box.right(), (int)currY );
752  int newY = (int)( currY + cellHeight / 2. );
753  QString numStr;
754  if ( newY < box.bottom() ) {
755  QFont oldFont( p.font() );
756  // draw the time:
757  if ( !KGlobal::locale()->use12Clock() ) {
758  p.drawLine( xcenter, (int)newY, box.right(), (int)newY );
759  numStr.setNum( curTime.hour() );
760  if ( cellHeight > 30 ) {
761  p.setFont( QFont( QLatin1String("sans-serif"), 14, QFont::Bold ) );
762  } else {
763  p.setFont( QFont( QLatin1String("sans-serif"), 12, QFont::Bold ) );
764  }
765  p.drawText( box.left() + 4, (int)currY + 2, box.width() / 2 - 2, (int)cellHeight,
766  Qt::AlignTop | Qt::AlignRight, numStr );
767  p.setFont( QFont( QLatin1String("helvetica"), 10, QFont::Normal ) );
768  p.drawText( xcenter + 4, (int)currY+2, box.width() / 2 + 2, (int)( cellHeight / 2 ) - 3,
769  Qt::AlignTop | Qt::AlignLeft, QLatin1String("00") );
770  } else {
771  p.drawLine( box.left(), (int)newY, box.right(), (int)newY );
772  QTime time( curTime.hour(), 0 );
773  numStr = KGlobal::locale()->formatTime( time );
774  if ( box.width() < 60 ) {
775  p.setFont( QFont( QLatin1String("sans-serif"), 7, QFont::Bold ) ); // for weekprint
776  } else {
777  p.setFont( QFont( QLatin1String("sans-serif"), 12, QFont::Bold ) ); // for dayprint
778  }
779  p.drawText( box.left() + 2, (int)currY + 2, box.width() - 4, (int)cellHeight / 2 - 3,
780  Qt::AlignTop|Qt::AlignLeft, numStr );
781  }
782  currY += cellHeight;
783  p.setFont( oldFont );
784  } // enough space for half-hour line and time
785  if ( curTime.secsTo( endTime ) > 3600 ) {
786  curTime = curTime.addSecs( 3600 );
787  } else {
788  curTime = endTime;
789  }
790  }
791 }
792 
799 int CalPrintPluginBase::drawAllDayBox( QPainter &p, const Event::List &eventList_,
800  const QDate &qd, bool expandable,
801  const QRect &box,
802  bool excludeConfidential,
803  bool excludePrivate )
804 {
805  Event::List::Iterator it;
806  int offset = box.top();
807  QString multiDayStr;
808 
809  Event::List eventList = eventList_;
810  Event::Ptr hd = holiday( qd );
811  if ( hd ) {
812  eventList.prepend( hd );
813  }
814 
815  it = eventList.begin();
816  while ( it != eventList.end() ) {
817  Event::Ptr currEvent = *it;
818  if ( ( excludeConfidential && currEvent->secrecy() == Incidence::SecrecyConfidential ) ||
819  ( excludePrivate && currEvent->secrecy() == Incidence::SecrecyPrivate ) ) {
820  continue;
821  }
822  if ( currEvent && currEvent->allDay() ) {
823  // set the colors according to the categories
824  if ( expandable ) {
825  QRect eventBox( box );
826  eventBox.setTop( offset );
827  showEventBox( p, EVENT_BORDER_WIDTH, eventBox, currEvent, currEvent->summary() );
828  offset += box.height();
829  } else {
830  if ( !multiDayStr.isEmpty() ) {
831  multiDayStr += QLatin1String(", ");
832  }
833  multiDayStr += currEvent->summary();
834  }
835  it = eventList.erase( it );
836  } else {
837  ++it;
838  }
839  }
840 
841  int ret = box.height();
842  QRect eventBox( box );
843  if ( !expandable ) {
844  if ( !multiDayStr.isEmpty() ) {
845  drawShadedBox( p, BOX_BORDER_WIDTH, QColor( 180, 180, 180 ), eventBox );
846  printEventString( p, eventBox, multiDayStr );
847  } else {
848  drawBox( p, BOX_BORDER_WIDTH, eventBox );
849  }
850  } else {
851  ret = offset - box.top();
852  eventBox.setBottom( ret );
853  drawBox( p, BOX_BORDER_WIDTH, eventBox );
854  }
855  return ret;
856 }
857 
858 void CalPrintPluginBase::drawAgendaDayBox( QPainter &p, const KCalCore::Event::List &events,
859  const QDate &qd, bool expandable,
860  const QTime &fromTime,
861  const QTime &toTime,
862  const QRect &oldbox,
863  bool includeDescription,
864  bool excludeTime,
865  bool excludeConfidential,
866  bool excludePrivate,
867  const QList<QDate> &workDays )
868 {
869  QTime myFromTime, myToTime;
870  if ( fromTime.isValid() ) {
871  myFromTime = fromTime;
872  } else {
873  myFromTime = QTime( 0, 0, 0 );
874  }
875  if ( toTime.isValid() ) {
876  myToTime = toTime;
877  } else {
878  myToTime = QTime( 23, 59, 59 );
879  }
880 
881  if ( !workDays.contains( qd ) ) {
882  drawShadedBox( p, BOX_BORDER_WIDTH, QColor( 232, 232, 232 ), oldbox );
883  } else {
884  drawBox( p, BOX_BORDER_WIDTH, oldbox );
885  }
886  QRect box( oldbox );
887  // Account for the border with and cut away that margin from the interior
888 // box.setRight( box.right()-BOX_BORDER_WIDTH );
889 
890  if ( expandable ) {
891  // Adapt start/end times to include complete events
892  Q_FOREACH ( const KCalCore::Event::Ptr &event, events ) {
893  Q_ASSERT( event );
894  if ( ( excludeConfidential && event->secrecy() == Incidence::SecrecyConfidential ) ||
895  ( excludePrivate && event->secrecy() == Incidence::SecrecyPrivate ) ) {
896  continue;
897  }
898  // skip items without times so that we do not adjust for all day items
899  if ( event->allDay() ) {
900  continue;
901  }
902  if ( event->dtStart().time() < myFromTime ) {
903  myFromTime = event->dtStart().time();
904  }
905  if ( event->dtEnd().time() > myToTime ) {
906  myToTime = event->dtEnd().time();
907  }
908  }
909  }
910 
911  // calculate the height of a cell and of a minute
912  int totalsecs = myFromTime.secsTo( myToTime );
913  float minlen = box.height() * 60. / totalsecs;
914  float cellHeight = 60. * minlen;
915  float currY = box.top();
916 
917  // print grid:
918  QTime curTime( QTime( myFromTime.hour(), 0, 0 ) );
919  currY += myFromTime.secsTo( curTime ) * minlen / 60;
920 
921  while ( curTime < myToTime && curTime.isValid() ) {
922  if ( currY > box.top() ) {
923  p.drawLine( box.left(), int( currY ), box.right(), int( currY ) );
924  }
925  currY += cellHeight / 2;
926  if ( ( currY > box.top() ) && ( currY < box.bottom() ) ) {
927  // enough space for half-hour line
928  QPen oldPen( p.pen() );
929  p.setPen( QColor( 192, 192, 192 ) );
930  p.drawLine( box.left(), int( currY ), box.right(), int( currY ) );
931  p.setPen( oldPen );
932  }
933  if ( curTime.secsTo( myToTime ) > 3600 ) {
934  curTime = curTime.addSecs( 3600 );
935  } else {
936  curTime = myToTime;
937  }
938  currY += cellHeight / 2;
939  }
940 
941  KDateTime startPrintDate = KDateTime( qd, myFromTime );
942  KDateTime endPrintDate = KDateTime( qd, myToTime );
943 
944  // Calculate horizontal positions and widths of events taking into account
945  // overlapping events
946 
947  QList<EventViews::CellItem *> cells;
948 
949  Akonadi::Item::List::ConstIterator itEvents;
950  foreach ( const Event::Ptr &event, events ) {
951  if ( event->allDay() ) {
952  continue;
953  }
954  QList<KDateTime> times = event->startDateTimesForDate( qd );
955  for ( QList<KDateTime>::ConstIterator it = times.constBegin();
956  it != times.constEnd(); ++it ) {
957  cells.append( new PrintCellItem( event, (*it), event->endDateForStart( *it ) ) );
958  }
959  }
960 
961  QListIterator<EventViews::CellItem *> it1( cells );
962  while ( it1.hasNext() ) {
963  EventViews::CellItem *placeItem = it1.next();
964  EventViews::CellItem::placeItem( cells, placeItem );
965  }
966 
967  QListIterator<EventViews::CellItem *> it2( cells );
968  while ( it2.hasNext() ) {
969  PrintCellItem *placeItem = static_cast<PrintCellItem *>( it2.next() );
970  drawAgendaItem( placeItem, p, startPrintDate, endPrintDate, minlen, box,
971  includeDescription, excludeTime );
972  }
973 }
974 
975 void CalPrintPluginBase::drawAgendaItem( PrintCellItem *item, QPainter &p,
976  const KDateTime &startPrintDate,
977  const KDateTime &endPrintDate,
978  float minlen, const QRect &box,
979  bool includeDescription,
980  bool excludeTime )
981 {
982  Event::Ptr event = item->event();
983 
984  // start/end of print area for event
985  KDateTime startTime = item->start();
986  KDateTime endTime = item->end();
987  if ( ( startTime < endPrintDate && endTime > startPrintDate ) ||
988  ( endTime > startPrintDate && startTime < endPrintDate ) ) {
989  if ( startTime < startPrintDate ) {
990  startTime = startPrintDate;
991  }
992  if ( endTime > endPrintDate ) {
993  endTime = endPrintDate;
994  }
995  int currentWidth = box.width() / item->subCells();
996  int currentX = box.left() + item->subCell() * currentWidth;
997  int currentYPos =
998  int( box.top() + startPrintDate.secsTo( startTime ) * minlen / 60. );
999  int currentHeight =
1000  int( box.top() + startPrintDate.secsTo( endTime ) * minlen / 60. ) - currentYPos;
1001 
1002  QRect eventBox( currentX, currentYPos, currentWidth, currentHeight );
1003  QString str;
1004  if ( excludeTime ) {
1005  if ( event->location().isEmpty() ) {
1006  str = cleanStr( event->summary() );
1007  } else {
1008  str = i18nc( "summary, location", "%1, %2",
1009  cleanStr( event->summary() ), cleanStr( event->location() ) );
1010  }
1011  } else {
1012  if ( event->location().isEmpty() ) {
1013  str = i18nc( "starttime - endtime summary",
1014  "%1-%2 %3",
1015  KGlobal::locale()->formatTime( item->start().toLocalZone().time() ),
1016  KGlobal::locale()->formatTime( item->end().toLocalZone().time() ),
1017  cleanStr( event->summary() ) );
1018  } else {
1019  str = i18nc( "starttime - endtime summary, location",
1020  "%1-%2 %3, %4",
1021  KGlobal::locale()->formatTime( item->start().toLocalZone().time() ),
1022  KGlobal::locale()->formatTime( item->end().toLocalZone().time() ),
1023  cleanStr( event->summary() ),
1024  cleanStr( event->location() ) );
1025  }
1026  }
1027  if ( includeDescription && !event->description().isEmpty() ) {
1028  str += QLatin1Char('\n');
1029  if ( event->descriptionIsRich() ) {
1030  str += toPlainText( event->description() );
1031  } else {
1032  str += event->description();
1033  }
1034  }
1035  QFont oldFont( p.font() );
1036  if ( eventBox.height() < 24 ) {
1037  if ( eventBox.height() < 12 ) {
1038  if ( eventBox.height() < 8 ) {
1039  p.setFont( QFont( QLatin1String("sans-serif"), 4 ) );
1040  } else {
1041  p.setFont( QFont( QLatin1String("sans-serif"), 5 ) );
1042  }
1043  } else {
1044  p.setFont( QFont( QLatin1String("sans-serif"), 6 ) );
1045  }
1046  } else {
1047  p.setFont( QFont( QLatin1String("sans-serif"), 8 ) );
1048  }
1049  showEventBox( p, EVENT_BORDER_WIDTH, eventBox, event, str );
1050  p.setFont( oldFont );
1051  }
1052 }
1053 
1054 void CalPrintPluginBase::drawDayBox( QPainter &p, const QDate &qd,
1055  const QTime &fromTime, const QTime &toTime,
1056  const QRect &box, bool fullDate,
1057  bool printRecurDaily, bool printRecurWeekly,
1058  bool singleLineLimit, bool showNoteLines,
1059  bool includeDescription,
1060  bool excludeConfidential,
1061  bool excludePrivate )
1062 {
1063  QString dayNumStr;
1064  const KLocale *local = KGlobal::locale();
1065 
1066  QTime myFromTime, myToTime;
1067  if ( fromTime.isValid() ) {
1068  myFromTime = fromTime;
1069  } else {
1070  myFromTime = QTime( 0, 0, 0 );
1071  }
1072  if ( toTime.isValid() ) {
1073  myToTime = toTime;
1074  } else {
1075  myToTime = QTime( 23, 59, 59 );
1076  }
1077 
1078  if ( fullDate && mCalSys ) {
1079  dayNumStr = i18nc( "weekday, shortmonthname daynumber",
1080  "%1, %2 <numid>%3</numid>",
1081  mCalSys->weekDayName( qd ),
1082  mCalSys->monthName( qd, KCalendarSystem::ShortName ),
1083  qd.day() );
1084  } else {
1085  dayNumStr = QString::number( qd.day() );
1086  }
1087 
1088  QRect subHeaderBox( box );
1089  subHeaderBox.setHeight( mSubHeaderHeight );
1090  drawShadedBox( p, BOX_BORDER_WIDTH, p.background(), box );
1091  drawShadedBox( p, 0, QColor( 232, 232, 232 ), subHeaderBox );
1092  drawBox( p, BOX_BORDER_WIDTH, box );
1093  QString hstring( holidayString( qd ) );
1094  const QFont oldFont( p.font() );
1095 
1096  QRect headerTextBox( subHeaderBox );
1097  headerTextBox.setLeft( subHeaderBox.left() + 5 );
1098  headerTextBox.setRight( subHeaderBox.right() - 5 );
1099  if ( !hstring.isEmpty() ) {
1100  p.setFont( QFont( QLatin1String("sans-serif"), 8, QFont::Bold, true ) );
1101  p.drawText( headerTextBox, Qt::AlignLeft | Qt::AlignVCenter, hstring );
1102  }
1103  p.setFont( QFont( QLatin1String("sans-serif"), 10, QFont::Bold ) );
1104  p.drawText( headerTextBox, Qt::AlignRight | Qt::AlignVCenter, dayNumStr );
1105 
1106  const KCalCore::Event::List eventList =
1107  mCalendar->events( qd, KSystemTimeZones::local(),
1108  KCalCore::EventSortStartDate,
1109  KCalCore::SortDirectionAscending );
1110 
1111  QString timeText;
1112  p.setFont( QFont( QLatin1String("sans-serif"), 7 ) );
1113 
1114  int textY = mSubHeaderHeight; // gives the relative y-coord of the next printed entry
1115  unsigned int visibleEventsCounter = 0;
1116  Q_FOREACH ( const Event::Ptr &currEvent, eventList ) {
1117  Q_ASSERT( currEvent );
1118  if ( !currEvent->allDay() ) {
1119  if ( currEvent->dtEnd().toLocalZone().time() <= myFromTime ||
1120  currEvent->dtStart().toLocalZone().time() > myToTime ) {
1121  continue;
1122  }
1123  }
1124  if ( ( !printRecurDaily && currEvent->recurrenceType() == Recurrence::rDaily ) ||
1125  ( !printRecurWeekly && currEvent->recurrenceType() == Recurrence::rWeekly ) ) {
1126  continue;
1127  }
1128  if ( ( excludeConfidential && currEvent->secrecy() == Incidence::SecrecyConfidential ) ||
1129  ( excludePrivate && currEvent->secrecy() == Incidence::SecrecyPrivate ) ) {
1130  continue;
1131  }
1132  if ( currEvent->allDay() || currEvent->isMultiDay() ) {
1133  timeText.clear();
1134  } else {
1135  timeText = local->formatTime( currEvent->dtStart().toLocalZone().time() ) + QLatin1Char(' ');
1136  }
1137  p.save();
1138  setCategoryColors( p, currEvent );
1139  QString summaryStr = currEvent->summary();
1140  if ( !currEvent->location().isEmpty() ) {
1141  summaryStr = i18nc( "summary, location",
1142  "%1, %2", summaryStr, currEvent->location() );
1143  }
1144  drawIncidence( p, box, timeText,
1145  summaryStr, currEvent->description(),
1146  textY, singleLineLimit, includeDescription,
1147  currEvent->descriptionIsRich() );
1148  p.restore();
1149  visibleEventsCounter++;
1150 
1151  if ( textY >= box.height() ) {
1152  const QChar downArrow( 0x21e3 );
1153 
1154  const unsigned int invisibleIncidences =
1155  ( eventList.count() - visibleEventsCounter ) + mCalendar->todos( qd ).count();
1156  if ( invisibleIncidences > 0 ) {
1157  const QString warningMsg = QString::fromLatin1( "%1 (%2)" ).arg( downArrow ).arg( invisibleIncidences );
1158 
1159  QFontMetrics fm( p.font() );
1160  QRect msgRect = fm.boundingRect( warningMsg );
1161  msgRect.setRect( box.right() - msgRect.width() - 2,
1162  box.bottom() - msgRect.height() - 2,
1163  msgRect.width(), msgRect.height() );
1164 
1165  p.save();
1166  p.setPen( Qt::red ); //krazy:exclude=qenums we don't allow custom print colors
1167  p.drawText( msgRect, Qt::AlignLeft, warningMsg );
1168  p.restore();
1169  }
1170  break;
1171  }
1172  }
1173 
1174  if ( textY < box.height() ) {
1175  Todo::List todos = mCalendar->todos( qd );
1176  foreach ( const Todo::Ptr &todo, todos ) {
1177  if ( !todo->allDay() ) {
1178  if ( ( todo->hasDueDate() && todo->dtDue().toLocalZone().time() <= myFromTime ) ||
1179  ( todo->hasStartDate() && todo->dtStart().toLocalZone().time() > myToTime ) ) {
1180  continue;
1181  }
1182  }
1183  if ( ( !printRecurDaily && todo->recurrenceType() == Recurrence::rDaily ) ||
1184  ( !printRecurWeekly && todo->recurrenceType() == Recurrence::rWeekly ) ) {
1185  continue;
1186  }
1187  if ( ( excludeConfidential && todo->secrecy() == Incidence::SecrecyConfidential ) ||
1188  ( excludePrivate && todo->secrecy() == Incidence::SecrecyPrivate ) ) {
1189  continue;
1190  }
1191  if ( todo->hasStartDate() && !todo->allDay() ) {
1192  timeText = KGlobal::locale()->formatTime( todo->dtStart().toLocalZone().time() ) + QLatin1Char(' ');
1193  } else {
1194  timeText.clear();
1195  }
1196  p.save();
1197  setCategoryColors( p, todo );
1198  QString summaryStr = todo->summary();
1199  if ( !todo->location().isEmpty() ) {
1200  summaryStr = i18nc( "summary, location",
1201  "%1, %2", summaryStr, todo->location() );
1202  }
1203 
1204  QString str;
1205  if ( todo->hasDueDate() ) {
1206  if ( !todo->allDay() ) {
1207  str = i18nc( "to-do summary (Due: datetime)", "%1 (Due: %2)",
1208  summaryStr,
1209  KGlobal::locale()->formatDateTime( todo->dtDue().toLocalZone() ) );
1210  } else {
1211  str = i18nc( "to-do summary (Due: date)", "%1 (Due: %2)",
1212  summaryStr,
1213  KGlobal::locale()->formatDate(
1214  todo->dtDue().toLocalZone().date(), KLocale::ShortDate ) );
1215  }
1216  } else {
1217  str = summaryStr;
1218  }
1219  drawIncidence( p, box, timeText,
1220  i18n( "To-do: %1", str ), todo->description(),
1221  textY, singleLineLimit, includeDescription,
1222  todo->descriptionIsRich() );
1223  p.restore();
1224  }
1225  }
1226  if ( showNoteLines ) {
1227  drawNoteLines( p, box, box.y() + textY );
1228  }
1229 
1230  p.setFont( oldFont );
1231 }
1232 
1233 void CalPrintPluginBase::drawIncidence( QPainter &p, const QRect &dayBox,
1234  const QString &time,
1235  const QString &summary,
1236  const QString &description,
1237  int &textY, bool singleLineLimit,
1238  bool includeDescription,
1239  bool richDescription )
1240 {
1241  kDebug() << "summary =" << summary << ", singleLineLimit=" << singleLineLimit;
1242 
1243  int flags = Qt::AlignLeft | Qt::OpaqueMode;
1244  QFontMetrics fm = p.fontMetrics();
1245  const int borderWidth = p.pen().width() + 1;
1246  QRect timeBound = p.boundingRect( dayBox.x() + borderWidth,
1247  dayBox.y() + textY,
1248  dayBox.width(), fm.lineSpacing(),
1249  flags, time );
1250 
1251  int summaryWidth = time.isEmpty() ? 0 : timeBound.width() + 3;
1252  QRect summaryBound = QRect( dayBox.x() + borderWidth + summaryWidth,
1253  dayBox.y() + textY + 1,
1254  dayBox.width() - summaryWidth - ( borderWidth * 2 ),
1255  dayBox.height() - textY );
1256 
1257  QString summaryText = summary;
1258  QString descText = toPlainText( description );
1259  bool boxOverflow = false;
1260 
1261  if ( singleLineLimit ) {
1262  if ( includeDescription && !descText.isEmpty() ) {
1263  summaryText += QLatin1String(", ") + descText;
1264  }
1265  int totalHeight = fm.lineSpacing() + borderWidth;
1266  int textBoxHeight = ( totalHeight > ( dayBox.height() - textY ) ) ?
1267  dayBox.height() - textY :
1268  totalHeight;
1269  summaryBound.setHeight( textBoxHeight );
1270  QRect lineRect( dayBox.x() + borderWidth, dayBox.y() + textY,
1271  dayBox.width() - ( borderWidth * 2 ), textBoxHeight );
1272  drawBox( p, 1, lineRect );
1273  if ( !time.isEmpty() ) {
1274  p.drawText( timeBound, flags, time );
1275  }
1276  p.drawText( summaryBound, flags, summaryText );
1277  } else {
1278  QTextDocument textDoc;
1279  QTextCursor textCursor( &textDoc );
1280  if ( richDescription ) {
1281  QTextCursor textCursor( &textDoc );
1282  textCursor.insertText( summaryText );
1283  if ( includeDescription && !description.isEmpty() ) {
1284  textCursor.insertText( QLatin1String("\n") );
1285  textCursor.insertHtml( description );
1286  }
1287  } else {
1288  textCursor.insertText( summaryText );
1289  if ( includeDescription && !descText.isEmpty() ) {
1290  textCursor.insertText( QLatin1String("\n") );
1291  textCursor.insertText( descText );
1292  }
1293  }
1294  textDoc.setPageSize( QSize( summaryBound.width(), summaryBound.height() ) );
1295  p.save();
1296  QRect clipBox( 0, 0, summaryBound.width(), summaryBound.height() );
1297  p.setFont( p.font() );
1298  p.translate( summaryBound.x(), summaryBound.y() );
1299  summaryBound.setHeight( textDoc.documentLayout()->documentSize().height() );
1300  if ( summaryBound.bottom() > dayBox.bottom() ) {
1301  summaryBound.setBottom( dayBox.bottom() );
1302  }
1303  clipBox.setHeight( summaryBound.height() );
1304  p.restore();
1305 
1306  p.save();
1307  QRect backBox( timeBound.x(), timeBound.y(),
1308  dayBox.width() - ( borderWidth * 2 ), clipBox.height() );
1309  drawBox( p, 1, backBox );
1310 
1311  if ( !time.isEmpty() ) {
1312  if ( timeBound.bottom() > dayBox.bottom() ) {
1313  timeBound.setBottom( dayBox.bottom() );
1314  }
1315  timeBound.moveTop ( timeBound.y() + ( summaryBound.height() - timeBound.height() ) / 2 );
1316  p.drawText( timeBound, flags, time );
1317  }
1318  p.translate( summaryBound.x(), summaryBound.y() );
1319  textDoc.drawContents( &p, clipBox );
1320  p.restore();
1321  boxOverflow = textDoc.pageCount() > 1;
1322  }
1323  if ( summaryBound.bottom() < dayBox.bottom() ) {
1324  QPen oldPen( p.pen() );
1325  p.setPen( QPen() );
1326  p.drawLine( dayBox.x(), summaryBound.bottom(),
1327  dayBox.x() + dayBox.width(), summaryBound.bottom() );
1328  p.setPen( oldPen );
1329  }
1330  textY += summaryBound.height();
1331 
1332  // show that we have overflowed the box
1333  if ( boxOverflow ) {
1334  QPolygon poly(3);
1335  int x = dayBox.x() + dayBox.width();
1336  int y = dayBox.y() + dayBox.height();
1337  poly.setPoint( 0, x - 10, y );
1338  poly.setPoint( 1, x, y - 10 );
1339  poly.setPoint( 2, x, y );
1340  QBrush oldBrush( p.brush() );
1341  p.setBrush( QBrush( Qt::black ) );
1342  p.drawPolygon(poly);
1343  p.setBrush( oldBrush );
1344  textY = dayBox.height();
1345  }
1346 }
1347 
1348 void CalPrintPluginBase::drawWeek( QPainter &p, const QDate &qd,
1349  const QTime &fromTime, const QTime &toTime,
1350  const QRect &box,
1351  bool singleLineLimit, bool showNoteLines,
1352  bool includeDescription,
1353  bool excludeConfidential,
1354  bool excludePrivate )
1355 {
1356  QDate weekDate = qd;
1357  const bool portrait = ( box.height() > box.width() );
1358  int cellWidth;
1359  int vcells;
1360  if ( portrait ) {
1361  cellWidth = box.width() / 2;
1362  vcells=3;
1363  } else {
1364  cellWidth = box.width() / 6;
1365  vcells=1;
1366  }
1367  const int cellHeight = box.height() / vcells;
1368 
1369  // correct begin of week
1370  int weekdayCol = weekdayColumn( qd.dayOfWeek() );
1371  weekDate = qd.addDays( -weekdayCol );
1372 
1373  for ( int i = 0; i < 7; ++i, weekDate = weekDate.addDays(1) ) {
1374  // Saturday and sunday share a cell, so we have to special-case sunday
1375  int hpos = ( ( i < 6 ) ? i : ( i - 1 ) ) / vcells;
1376  int vpos = ( ( i < 6 ) ? i : ( i - 1 ) ) % vcells;
1377  QRect dayBox(
1378  box.left() + cellWidth * hpos,
1379  box.top() + cellHeight * vpos + ( ( i == 6 ) ? ( cellHeight / 2 ) : 0 ),
1380  cellWidth, ( i < 5 ) ? ( cellHeight ) : ( cellHeight / 2 ) );
1381  drawDayBox( p, weekDate, fromTime, toTime, dayBox, true, true, true,
1382  singleLineLimit, showNoteLines, includeDescription,
1383  excludeConfidential, excludePrivate );
1384  } // for i through all weekdays
1385 }
1386 
1387 void CalPrintPluginBase::drawDays( QPainter &p,
1388  const QDate &start, const QDate &end,
1389  const QTime &fromTime, const QTime &toTime,
1390  const QRect &box,
1391  bool singleLineLimit, bool showNoteLines,
1392  bool includeDescription,
1393  bool excludeConfidential, bool excludePrivate )
1394 {
1395  const int numberOfDays = start.daysTo( end ) + 1;
1396  int vcells;
1397  const bool portrait = ( box.height() > box.width() );
1398  int cellWidth;
1399  if ( portrait ) {
1400  // 2 columns
1401  vcells = qCeil( static_cast<double>( numberOfDays ) / 2.0 );
1402  if ( numberOfDays > 1 ) {
1403  cellWidth = box.width() / 2;
1404  } else {
1405  cellWidth = box.width();
1406  }
1407  } else {
1408  // landscape: N columns
1409  vcells = 1;
1410  cellWidth = box.width() / numberOfDays;
1411  }
1412  const int cellHeight = box.height() / vcells;
1413  QDate weekDate = start;
1414  for ( int i = 0; i < numberOfDays; ++i, weekDate = weekDate.addDays(1) ) {
1415  const int hpos = i / vcells;
1416  const int vpos = i % vcells;
1417  const QRect dayBox(
1418  box.left() + cellWidth * hpos,
1419  box.top() + cellHeight * vpos,
1420  cellWidth, cellHeight );
1421  drawDayBox( p, weekDate, fromTime, toTime, dayBox,
1422  true, true, true, singleLineLimit,
1423  showNoteLines, includeDescription, excludeConfidential,
1424  excludePrivate );
1425  } // for i through all selected days
1426 }
1427 
1428 void CalPrintPluginBase::drawTimeTable( QPainter &p,
1429  const QDate &fromDate,
1430  const QDate &toDate,
1431  bool expandable,
1432  const QTime &fromTime,
1433  const QTime &toTime,
1434  const QRect &box,
1435  bool includeDescription,
1436  bool excludeTime,
1437  bool excludeConfidential,
1438  bool excludePrivate )
1439 {
1440  QTime myFromTime = fromTime;
1441  QTime myToTime = toTime;
1442  if ( expandable ) {
1443  QDate curDate( fromDate );
1444  KDateTime::Spec timeSpec = KSystemTimeZones::local();
1445  while ( curDate <= toDate ) {
1446  Event::List eventList = mCalendar->events( curDate, timeSpec );
1447  Q_FOREACH ( const Event::Ptr &event, eventList ) {
1448  Q_ASSERT( event );
1449  if ( event->allDay() ) {
1450  continue;
1451  }
1452  if ( event->dtStart().time() < myFromTime ) {
1453  myFromTime = event->dtStart().time();
1454  }
1455  if ( event->dtEnd().time() > myToTime ) {
1456  myToTime = event->dtEnd().time();
1457  }
1458  }
1459  curDate = curDate.addDays(1);
1460  }
1461  }
1462 
1463  // timeline is 1 hour:
1464  int alldayHeight = (int)( 3600. * box.height() / ( myFromTime.secsTo( myToTime ) + 3600. ) );
1465  int timelineWidth = TIMELINE_WIDTH;
1466 
1467  QRect dowBox( box );
1468  dowBox.setLeft( box.left() + timelineWidth );
1469  dowBox.setHeight( mSubHeaderHeight );
1470  drawDaysOfWeek( p, fromDate, toDate, dowBox );
1471 
1472  QRect tlBox( box );
1473  tlBox.setWidth( timelineWidth );
1474  tlBox.setTop( dowBox.bottom() + BOX_BORDER_WIDTH + alldayHeight );
1475  drawTimeLine( p, myFromTime, myToTime, tlBox );
1476 
1477  // draw each day
1478  QDate curDate( fromDate );
1479  KDateTime::Spec timeSpec = KSystemTimeZones::local();
1480  int i=0;
1481  double cellWidth = double( dowBox.width() ) / double( fromDate.daysTo( toDate ) + 1 );
1482  const QList<QDate> workDays = KOGlobals::self()->workDays( fromDate, toDate );
1483  while ( curDate <= toDate ) {
1484  QRect allDayBox( dowBox.left()+int( i * cellWidth ), dowBox.bottom() + BOX_BORDER_WIDTH,
1485  int( ( i + 1 ) * cellWidth ) - int( i * cellWidth ), alldayHeight );
1486  QRect dayBox( allDayBox );
1487  dayBox.setTop( tlBox.top() );
1488  dayBox.setBottom( box.bottom() );
1489  KCalCore::Event::List eventList = mCalendar->events( curDate, timeSpec,
1490  KCalCore::EventSortStartDate,
1491  KCalCore::SortDirectionAscending );
1492 
1493  alldayHeight = drawAllDayBox( p, eventList, curDate, false, allDayBox,
1494  excludeConfidential, excludePrivate );
1495  drawAgendaDayBox( p, eventList, curDate, false, myFromTime, myToTime,
1496  dayBox, includeDescription, excludeTime,
1497  excludeConfidential, excludePrivate, workDays );
1498 
1499  ++i;
1500  curDate = curDate.addDays(1);
1501  }
1502 }
1503 
1504 class MonthEventStruct
1505 {
1506  public:
1507  MonthEventStruct() : event(0) {}
1508  MonthEventStruct( const KDateTime &s, const KDateTime &e, const Event::Ptr &ev )
1509  {
1510  event = ev;
1511  start = s;
1512  end = e;
1513  if ( event->allDay() ) {
1514  start = KDateTime( start.date(), QTime( 0, 0, 0 ) );
1515  end = KDateTime( end.date().addDays(1), QTime( 0, 0, 0 ) ).addSecs(-1);
1516  }
1517  }
1518  bool operator < ( const MonthEventStruct &mes ) { return start < mes.start; }
1519  KDateTime start;
1520  KDateTime end;
1521  Event::Ptr event;
1522 };
1523 
1524 void CalPrintPluginBase::drawMonth( QPainter &p, const QDate &dt,
1525  const QRect &box, int maxdays,
1526  int subDailyFlags, int holidaysFlags )
1527 {
1528  const KCalendarSystem *calsys = calendarSystem();
1529  QRect subheaderBox( box );
1530  subheaderBox.setHeight( subHeaderHeight() );
1531  QRect borderBox( box );
1532  borderBox.setTop( subheaderBox.bottom() + 1 );
1533  drawSubHeaderBox( p, calsys->monthName( dt ), subheaderBox );
1534  // correct for half the border width
1535  int correction = ( BOX_BORDER_WIDTH/*-1*/ ) / 2;
1536  QRect daysBox( borderBox );
1537  daysBox.adjust( correction, correction, -correction, -correction );
1538 
1539  int daysinmonth = calsys->daysInMonth( dt );
1540  if ( maxdays <= 0 ) {
1541  maxdays = daysinmonth;
1542  }
1543 
1544  int d;
1545  float dayheight = float( daysBox.height() ) / float( maxdays );
1546 
1547  QColor holidayColor( 240, 240, 240 );
1548  QColor workdayColor( 255, 255, 255 );
1549  int dayNrWidth = p.fontMetrics().width( QLatin1String("99") );
1550 
1551  // Fill the remaining space (if a month has less days than others) with a crossed-out pattern
1552  if ( daysinmonth<maxdays ) {
1553  QRect dayBox( box.left(), daysBox.top() + qRound( dayheight * daysinmonth ), box.width(), 0 );
1554  dayBox.setBottom( daysBox.bottom() );
1555  p.fillRect( dayBox, Qt::DiagCrossPattern );
1556  }
1557  // Backgrounded boxes for each day, plus day numbers
1558  QBrush oldbrush( p.brush() );
1559 
1560  QList<QDate> workDays;
1561 
1562  {
1563  QDate startDate;
1564  QDate endDate;
1565  calsys->setDate( startDate, dt.year(), dt.month(), 1 );
1566  calsys->setDate( endDate, dt.year(), dt.month(), daysinmonth );
1567 
1568  workDays = KOGlobals::self()->workDays( startDate, endDate );
1569  }
1570 
1571  for ( d = 0; d < daysinmonth; ++d ) {
1572  QDate day;
1573  calsys->setDate( day, dt.year(), dt.month(), d+1 );
1574  QRect dayBox(
1575  daysBox.left()/*+rand()%50*/,
1576  daysBox.top() + qRound( dayheight * d ), daysBox.width()/*-rand()%50*/, 0 );
1577  // FIXME: When using a border width of 0 for event boxes,
1578  // don't let the rectangles overlap, i.e. subtract 1 from the top or bottom!
1579  dayBox.setBottom( daysBox.top() + qRound( dayheight * ( d + 1 ) ) - 1 );
1580 
1581  p.setBrush( workDays.contains( day ) ? workdayColor : holidayColor );
1582  p.drawRect( dayBox );
1583  QRect dateBox( dayBox );
1584  dateBox.setWidth( dayNrWidth + 3 );
1585  p.drawText( dateBox,
1586  Qt::AlignRight | Qt::AlignVCenter | Qt::TextSingleLine,
1587  QString::number( d + 1 ) );
1588  }
1589  p.setBrush( oldbrush );
1590  int xstartcont = box.left() + dayNrWidth + 5;
1591 
1592  QDate start, end;
1593  calsys->setDate( start, dt.year(), dt.month(), 1 );
1594  end = calsys->addMonths( start, 1 );
1595  end = calsys->addDays( end, -1 );
1596 
1597  const Event::List events = mCalendar->events( start, end );
1598  QMap<int, QStringList> textEvents;
1599  QList<EventViews::CellItem *> timeboxItems;
1600 
1601  // 1) For multi-day events, show boxes spanning several cells, use CellItem
1602  // print the summary vertically
1603  // 2) For sub-day events, print the concated summaries into the remaining
1604  // space of the box (optional, depending on the given flags)
1605  // 3) Draw some kind of timeline showing free and busy times
1606 
1607  // Holidays
1608  QList<Event::Ptr> holidays;
1609  for ( QDate d( start ); d <= end; d = d.addDays(1) ) {
1610  Event::Ptr e = holiday( d );
1611  if ( e ) {
1612  holidays.append( e );
1613  if ( holidaysFlags & TimeBoxes ) {
1614  timeboxItems.append( new PrintCellItem( e, KDateTime( d, QTime( 0, 0, 0 ) ),
1615  KDateTime( d.addDays(1), QTime( 0, 0, 0 ) ) ) );
1616  }
1617  if ( holidaysFlags & Text ) {
1618  textEvents[d.day()] << e->summary();
1619  }
1620  }
1621  }
1622 
1623  QList<MonthEventStruct> monthentries;
1624 
1625  KDateTime::Spec timeSpec = KSystemTimeZones::local();
1626  Q_FOREACH ( const Event::Ptr &e, events ) {
1627  if ( !e ) {
1628  continue;
1629  }
1630  if ( e->recurs() ) {
1631  if ( e->recursOn( start, timeSpec ) ) {
1632  // This occurrence has possibly started before the beginning of the
1633  // month, so obtain the start date before the beginning of the month
1634  QList<KDateTime> starttimes = e->startDateTimesForDate( start );
1635  QList<KDateTime>::ConstIterator it = starttimes.constBegin();
1636  for ( ; it != starttimes.constEnd(); ++it ) {
1637  monthentries.append( MonthEventStruct( *it, e->endDateForStart( *it ), e ) );
1638  }
1639  }
1640  // Loop through all remaining days of the month and check if the event
1641  // begins on that day (don't use Event::recursOn, as that will
1642  // also return events that have started earlier. These start dates
1643  // however, have already been treated!
1644  Recurrence *recur = e->recurrence();
1645  QDate d1( start.addDays(1) );
1646  while ( d1 <= end ) {
1647  if ( recur->recursOn( d1, timeSpec ) ) {
1648  TimeList times( recur->recurTimesOn( d1, timeSpec ) );
1649  for ( TimeList::ConstIterator it = times.constBegin();
1650  it != times.constEnd(); ++it ) {
1651  KDateTime d1start( d1, *it, timeSpec );
1652  monthentries.append( MonthEventStruct( d1start, e->endDateForStart( d1start ), e ) );
1653  }
1654  }
1655  d1 = d1.addDays(1);
1656  }
1657  } else {
1658  monthentries.append( MonthEventStruct( e->dtStart(), e->dtEnd(), e ) );
1659  }
1660  }
1661 
1662 // TODO: to port the month entries sorting
1663 
1664 // qSort( monthentries.begin(), monthentries.end() );
1665 
1666  QList<MonthEventStruct>::ConstIterator mit = monthentries.constBegin();
1667  KDateTime endofmonth( end, QTime( 0, 0, 0 ) );
1668  endofmonth = endofmonth.addDays(1);
1669  for ( ; mit != monthentries.constEnd(); ++mit ) {
1670  if ( (*mit).start.date() == (*mit).end.date() ) {
1671  // Show also single-day events as time line boxes
1672  if ( subDailyFlags & TimeBoxes ) {
1673  timeboxItems.append(
1674  new PrintCellItem( (*mit).event, (*mit).start, (*mit).end ) );
1675  }
1676  // Show as text in the box
1677  if ( subDailyFlags & Text ) {
1678  textEvents[(*mit).start.date().day()] << (*mit).event->summary();
1679  }
1680  } else {
1681  // Multi-day events are always shown as time line boxes
1682  KDateTime thisstart( (*mit).start );
1683  KDateTime thisend( (*mit).end );
1684  if ( thisstart.date() < start ) {
1685  thisstart.setDate( start );
1686  }
1687  if ( thisend > endofmonth ) {
1688  thisend = endofmonth;
1689  }
1690  timeboxItems.append(
1691  new PrintCellItem( (*mit).event, thisstart, thisend ) );
1692  }
1693  }
1694 
1695  // For Multi-day events, line them up nicely so that the boxes don't overlap
1696  QListIterator<EventViews::CellItem *> it1( timeboxItems );
1697  while ( it1.hasNext() ) {
1698  EventViews::CellItem *placeItem = it1.next();
1699  EventViews::CellItem::placeItem( timeboxItems, placeItem );
1700  }
1701  KDateTime starttime( start, QTime( 0, 0, 0 ) );
1702  int newxstartcont = xstartcont;
1703 
1704  QFont oldfont( p.font() );
1705  p.setFont( QFont( QLatin1String("sans-serif"), 7 ) );
1706  while ( it1.hasNext() ) {
1707  PrintCellItem *placeItem = static_cast<PrintCellItem *>( it1.next() );
1708  int minsToStart = starttime.secsTo( placeItem->start() ) / 60;
1709  int minsToEnd = starttime.secsTo( placeItem->end() ) / 60;
1710 
1711  QRect eventBox(
1712  xstartcont + placeItem->subCell() * 17,
1713  daysBox.top() + qRound(
1714  double( minsToStart * daysBox.height() ) / double( maxdays * 24 * 60 ) ), 14, 0 );
1715  eventBox.setBottom(
1716  daysBox.top() + qRound(
1717  double( minsToEnd * daysBox.height() ) / double( maxdays * 24 * 60 ) ) );
1718  drawVerticalBox( p, 0, eventBox, placeItem->event()->summary() );
1719  newxstartcont = qMax( newxstartcont, eventBox.right() );
1720  }
1721  xstartcont = newxstartcont;
1722 
1723  // For Single-day events, simply print their summaries into the remaining
1724  // space of the day's cell
1725  for ( int d=0; d<daysinmonth; ++d ) {
1726  QStringList dayEvents( textEvents[d+1] );
1727  QString txt = dayEvents.join( QLatin1String(", ") );
1728  QRect dayBox( xstartcont, daysBox.top() + qRound( dayheight * d ), 0, 0 );
1729  dayBox.setRight( box.right() );
1730  dayBox.setBottom( daysBox.top() + qRound( dayheight * ( d + 1 ) ) );
1731  printEventString( p, dayBox, txt, Qt::AlignTop | Qt::AlignLeft | Qt::TextWrapAnywhere );
1732  }
1733  p.setFont( oldfont );
1734  drawBox( p, BOX_BORDER_WIDTH, borderBox );
1735  p.restore();
1736 }
1737 
1738 void CalPrintPluginBase::drawMonthTable( QPainter &p, const QDate &qd,
1739  const QTime &fromTime, const QTime &toTime,
1740  bool weeknumbers, bool recurDaily,
1741  bool recurWeekly, bool singleLineLimit,
1742  bool showNoteLines,
1743  bool includeDescription,
1744  bool excludeConfidential,
1745  bool excludePrivate,
1746  const QRect &box )
1747 {
1748  int yoffset = mSubHeaderHeight;
1749  int xoffset = 0;
1750  QDate monthDate( QDate( qd.year(), qd.month(), 1 ) );
1751  QDate monthFirst( monthDate );
1752  QDate monthLast( monthDate.addMonths(1).addDays(-1) );
1753 
1754  int weekdayCol = weekdayColumn( monthDate.dayOfWeek() );
1755  monthDate = monthDate.addDays(-weekdayCol);
1756 
1757  if (weeknumbers) {
1758  xoffset += 14;
1759  }
1760 
1761  int rows = ( weekdayCol + qd.daysInMonth() - 1 ) / 7 + 1;
1762  double cellHeight = ( box.height() - yoffset ) / ( 1. * rows );
1763  double cellWidth = ( box.width() - xoffset ) / 7.;
1764 
1765  // Precalculate the grid...
1766  // rows is at most 6, so using 8 entries in the array is fine, too!
1767  int coledges[8], rowedges[8];
1768  for ( int i = 0; i <= 7; ++i ) {
1769  rowedges[i] = int( box.top() + yoffset + i * cellHeight );
1770  coledges[i] = int( box.left() + xoffset + i * cellWidth );
1771  }
1772 
1773  if ( weeknumbers ) {
1774  QFont oldFont( p.font() );
1775  QFont newFont( p.font() );
1776  newFont.setPointSize( 6 );
1777  p.setFont( newFont );
1778  QDate weekDate( monthDate );
1779  for ( int row = 0; row<rows; ++row ) {
1780  int calWeek = weekDate.weekNumber();
1781  QRect rc( box.left(), rowedges[row],
1782  coledges[0] - 3 - box.left(), rowedges[row + 1] - rowedges[row] );
1783  p.drawText( rc, Qt::AlignRight | Qt::AlignVCenter, QString::number( calWeek ) );
1784  weekDate = weekDate.addDays( 7 );
1785  }
1786  p.setFont( oldFont );
1787  }
1788 
1789  QRect daysOfWeekBox( box );
1790  daysOfWeekBox.setHeight( mSubHeaderHeight );
1791  daysOfWeekBox.setLeft( box.left() + xoffset );
1792  drawDaysOfWeek( p, monthDate, monthDate.addDays( 6 ), daysOfWeekBox );
1793 
1794  QColor back = p.background().color();
1795  bool darkbg = false;
1796  for ( int row = 0; row < rows; ++row ) {
1797  for ( int col = 0; col < 7; ++col ) {
1798  // show days from previous/next month with a grayed background
1799  if ( ( monthDate < monthFirst ) || ( monthDate > monthLast ) ) {
1800  p.setBackground( back.darker( 120 ) );
1801  darkbg = true;
1802  }
1803  QRect dayBox( coledges[col], rowedges[row],
1804  coledges[col + 1] - coledges[col], rowedges[row + 1] - rowedges[row] );
1805  drawDayBox( p, monthDate, fromTime, toTime, dayBox, false,
1806  recurDaily, recurWeekly, singleLineLimit, showNoteLines,
1807  includeDescription, excludeConfidential, excludePrivate );
1808  if ( darkbg ) {
1809  p.setBackground( back );
1810  darkbg = false;
1811  }
1812  monthDate = monthDate.addDays(1);
1813  }
1814  }
1815 }
1816 
1817 void CalPrintPluginBase::drawTodoLines( QPainter &p,
1818  const QString &entry,
1819  int x, int &y, int width,
1820  int pageHeight, bool richTextEntry,
1821  QList<TodoParentStart *> &startPoints,
1822  bool connectSubTodos )
1823 {
1824  QString plainEntry = ( richTextEntry ) ? toPlainText( entry ) : entry;
1825 
1826  QRect textrect( 0, 0, width, -1 );
1827  int flags = Qt::AlignLeft;
1828  QFontMetrics fm = p.fontMetrics();
1829 
1830  QStringList lines = plainEntry.split( QLatin1Char( '\n' ) );
1831  for ( int currentLine = 0; currentLine < lines.count(); currentLine++ ) {
1832  // split paragraphs into lines
1833  KWordWrap *ww = KWordWrap::formatText( fm, textrect, flags, lines[currentLine] );
1834  QStringList textLine = ww->wrappedString().split( QLatin1Char( '\n' ) );
1835  delete ww;
1836 
1837  // print each individual line
1838  for ( int lineCount = 0; lineCount < textLine.count(); lineCount++ ) {
1839  if ( y >= pageHeight ) {
1840  if ( connectSubTodos ) {
1841  for ( int i = 0; i < startPoints.size(); ++i ) {
1842  TodoParentStart *rct;
1843  rct = startPoints.at( i );
1844  int start = rct->mRect.bottom() + 1;
1845  int center = rct->mRect.left() + ( rct->mRect.width() / 2 );
1846  int to = y;
1847  if ( !rct->mSamePage ) {
1848  start = 0;
1849  }
1850  if ( rct->mHasLine ) {
1851  p.drawLine( center, start, center, to );
1852  }
1853  rct->mSamePage = false;
1854  }
1855  }
1856  y = 0;
1857  mPrinter->newPage();
1858  }
1859  y += fm.height();
1860  p.drawText( x, y, textLine[lineCount] );
1861  }
1862  }
1863 }
1864 
1865 void CalPrintPluginBase::drawTodo( int &count, const KCalCore::Todo::Ptr &todo, QPainter &p,
1866  KCalCore::TodoSortField sortField,
1867  KCalCore::SortDirection sortDir,
1868  bool connectSubTodos, bool strikeoutCompleted,
1869  bool desc, int posPriority, int posSummary,
1870  int posDueDt, int posPercentComplete,
1871  int level, int x, int &y, int width,
1872  int pageHeight, const KCalCore::Todo::List &todoList,
1873  TodoParentStart *r, bool excludeConfidential,
1874  bool excludePrivate )
1875 {
1876  QString outStr;
1877  const KLocale *local = KGlobal::locale();
1878  QRect rect;
1879  TodoParentStart startpt;
1880  // This list keeps all starting points of the parent to-dos so the connection
1881  // lines of the tree can easily be drawn (needed if a new page is started)
1882  static QList<TodoParentStart *> startPoints;
1883  if ( level < 1 ) {
1884  startPoints.clear();
1885  }
1886 
1887  y += 10;
1888 
1889  // Compute the right hand side of the to-do box
1890  int rhs = posPercentComplete;
1891  if ( rhs < 0 ) {
1892  rhs = posDueDt; //not printing percent completed
1893  }
1894  if ( rhs < 0 ) {
1895  rhs = x + width; //not printing due dates either
1896  }
1897 
1898  int left = posSummary + ( level * 10 );
1899 
1900  // If this is a sub-to-do, r will not be 0, and we want the LH side
1901  // of the priority line up to the RH side of the parent to-do's priority
1902  bool showPriority = posPriority >= 0;
1903  int lhs = posPriority;
1904  if ( r ) {
1905  lhs = r->mRect.right() + 1;
1906  }
1907 
1908  outStr.setNum( todo->priority() );
1909  rect = p.boundingRect( lhs, y + 10, 5, -1, Qt::AlignCenter, outStr );
1910  // Make it a more reasonable size
1911  rect.setWidth( 18 );
1912  rect.setHeight( 18 );
1913 
1914  // Draw a checkbox
1915  p.setBrush( QBrush( Qt::NoBrush ) );
1916  p.drawRect( rect );
1917  if ( todo->isCompleted() ) {
1918  // cross out the rectangle for completed to-dos
1919  p.drawLine( rect.topLeft(), rect.bottomRight() );
1920  p.drawLine( rect.topRight(), rect.bottomLeft() );
1921  }
1922  lhs = rect.right() + 3;
1923 
1924  // Priority
1925  if ( todo->priority() > 0 && showPriority ) {
1926  p.drawText( rect, Qt::AlignCenter, outStr );
1927  }
1928  startpt.mRect = rect; //save for later
1929 
1930  // Connect the dots
1931  if ( r && level > 0 && connectSubTodos ) {
1932  int bottom;
1933  int center( r->mRect.left() + ( r->mRect.width() / 2 ) );
1934  int to( rect.top() + ( rect.height() / 2 ) );
1935  int endx( rect.left() );
1936  p.drawLine( center, to, endx, to ); // side connector
1937  if ( r->mSamePage ) {
1938  bottom = r->mRect.bottom() + 1;
1939  } else {
1940  bottom = 0;
1941  }
1942  p.drawLine( center, bottom, center, to );
1943  }
1944 
1945  // summary
1946  outStr = todo->summary();
1947  rect = p.boundingRect( lhs, rect.top(), ( rhs - ( left + rect.width() + 5 ) ),
1948  -1, Qt::TextWordWrap, outStr );
1949 
1950  QRect newrect;
1951  QFont newFont( p.font() );
1952  QFont oldFont( p.font() );
1953  if ( todo->isCompleted() && strikeoutCompleted ) {
1954  newFont.setStrikeOut( true );
1955  p.setFont( newFont );
1956  }
1957  p.drawText( rect, Qt::TextWordWrap, outStr, &newrect );
1958  p.setFont( oldFont );
1959  // due date
1960  if ( todo->hasDueDate() && posDueDt >= 0 ) {
1961  outStr = local->formatDate( todo->dtDue().toLocalZone().date(), KLocale::ShortDate );
1962  rect = p.boundingRect( posDueDt, y, x + width, -1,
1963  Qt::AlignTop | Qt::AlignLeft, outStr );
1964  p.drawText( rect, Qt::AlignTop | Qt::AlignLeft, outStr );
1965  }
1966 
1967  // percentage completed
1968  bool showPercentComplete = posPercentComplete >= 0;
1969  if ( showPercentComplete ) {
1970  int lwidth = 24;
1971  int lheight = 12;
1972  //first, draw the progress bar
1973  int progress = (int)( ( lwidth * todo->percentComplete() ) / 100.0 + 0.5 );
1974 
1975  p.setBrush( QBrush( Qt::NoBrush ) );
1976  p.drawRect( posPercentComplete, y+3, lwidth, lheight );
1977  if ( progress > 0 ) {
1978  p.setBrush( QColor( 128, 128, 128 ) );
1979  p.drawRect( posPercentComplete, y+3, progress, lheight );
1980  }
1981 
1982  //now, write the percentage
1983  outStr = i18n( "%1%", todo->percentComplete() );
1984  rect = p.boundingRect( posPercentComplete+lwidth+3, y, x + width, -1,
1985  Qt::AlignTop | Qt::AlignLeft, outStr );
1986  p.drawText( rect, Qt::AlignTop | Qt::AlignLeft, outStr );
1987  }
1988 
1989  y += 10;
1990 
1991  // Make a list of all the sub-to-dos related to this to-do.
1992  Todo::List t;
1993  Incidence::List relations = mCalendar->childIncidences( todo->uid() );
1994 
1995  foreach ( const Incidence::Ptr &incidence, relations ) {
1996  // In the future, to-dos might also be related to events
1997  // Manually check if the sub-to-do is in the list of to-dos to print
1998  // The problem is that relations() does not apply filters, so
1999  // we need to compare manually with the complete filtered list!
2000  Todo::Ptr subtodo = incidence.dynamicCast<KCalCore::Todo>();
2001  if ( !subtodo ) continue;
2002 #ifdef AKONADI_PORT_DISABLED
2003  if ( subtodo && todoList.contains( subtodo ) ) {
2004 #else
2005  bool subtodoOk = false;
2006  if ( subtodo ) {
2007  foreach ( const KCalCore::Todo::Ptr &tt, todoList ) {
2008  if ( tt == subtodo ) {
2009  subtodoOk = true;
2010  break;
2011  }
2012  }
2013  }
2014  if ( subtodoOk ) {
2015 #endif
2016  if ( ( excludeConfidential &&
2017  subtodo->secrecy() == Incidence::SecrecyConfidential ) ||
2018  ( excludePrivate &&
2019  subtodo->secrecy() == Incidence::SecrecyPrivate ) ) {
2020  continue;
2021  }
2022  t.append( subtodo );
2023  }
2024  }
2025 
2026  // has sub-todos?
2027  startpt.mHasLine = ( relations.size() > 0 );
2028  startPoints.append( &startpt );
2029 
2030  // description
2031  if ( !todo->description().isEmpty() && desc ) {
2032  y = newrect.bottom() + 5;
2033  drawTodoLines( p, todo->description(), left, y,
2034  width - ( left + 10 - x ), pageHeight,
2035  todo->descriptionIsRich(),
2036  startPoints, connectSubTodos );
2037  } else {
2038  y += 10;
2039  }
2040 
2041  // Sort the sub-to-dos and print them
2042 #ifdef AKONADI_PORT_DISABLED
2043  KCalCore::Todo::List sl = mCalendar->sortTodos( &t, sortField, sortDir );
2044 #else
2045  KCalCore::Todo::List tl;
2046  foreach ( const Todo::Ptr &todo, t ) {
2047  tl.append( todo );
2048  }
2049  KCalCore::Todo::List sl = mCalendar->sortTodos( tl, sortField, sortDir );
2050 #endif
2051 
2052  int subcount = 0;
2053  foreach ( const Todo::Ptr &isl, sl ) {
2054  count++;
2055  if ( ++subcount == sl.size() ) {
2056  startpt.mHasLine = false;
2057  }
2058  drawTodo( count, isl, p, sortField, sortDir,
2059  connectSubTodos, strikeoutCompleted,
2060  desc, posPriority, posSummary, posDueDt, posPercentComplete,
2061  level+1, x, y, width, pageHeight, todoList, &startpt,
2062  excludeConfidential, excludePrivate );
2063  }
2064  startPoints.removeAll( &startpt );
2065 }
2066 
2067 int CalPrintPluginBase::weekdayColumn( int weekday )
2068 {
2069  int w = weekday + 7 - KGlobal::locale()->weekStartDay();
2070  return w % 7;
2071 }
2072 
2073 void CalPrintPluginBase::drawTextLines( QPainter &p, const QString &entry,
2074  int x, int &y, int width,
2075  int pageHeight, bool richTextEntry )
2076 {
2077  QString plainEntry = ( richTextEntry ) ? toPlainText( entry ) : entry;
2078 
2079  QRect textrect( 0, 0, width, -1 );
2080  int flags = Qt::AlignLeft;
2081  QFontMetrics fm = p.fontMetrics();
2082 
2083  QStringList lines = plainEntry.split( QLatin1Char( '\n' ) );
2084  for ( int currentLine = 0; currentLine < lines.count(); currentLine++ ) {
2085  // split paragraphs into lines
2086  KWordWrap *ww = KWordWrap::formatText( fm, textrect, flags, lines[currentLine] );
2087  QStringList textLine = ww->wrappedString().split( QLatin1Char( '\n' ) );
2088  delete ww;
2089  // print each individual line
2090  for ( int lineCount = 0; lineCount < textLine.count(); lineCount++ ) {
2091  if ( y >= pageHeight ) {
2092  y = 0;
2093  mPrinter->newPage();
2094  }
2095  y += fm.height();
2096  p.drawText( x, y, textLine[lineCount] );
2097  }
2098  }
2099 }
2100 
2101 void CalPrintPluginBase::drawJournal( const Journal::Ptr &journal, QPainter &p,
2102  int x, int &y, int width, int pageHeight )
2103 {
2104  QFont oldFont( p.font() );
2105  p.setFont( QFont( QLatin1String("sans-serif"), 15 ) );
2106  QString headerText;
2107  QString dateText( KGlobal::locale()->formatDate( journal->dtStart().toLocalZone().date(),
2108  KLocale::LongDate ) );
2109 
2110  if ( journal->summary().isEmpty() ) {
2111  headerText = dateText;
2112  } else {
2113  headerText = i18nc( "Description - date", "%1 - %2", journal->summary(), dateText );
2114  }
2115 
2116  QRect rect( p.boundingRect( x, y, width, -1, Qt::TextWordWrap, headerText ) );
2117  if ( rect.bottom() > pageHeight ) {
2118  // Start new page...
2119  y = 0;
2120  mPrinter->newPage();
2121  rect = p.boundingRect( x, y, width, -1, Qt::TextWordWrap, headerText );
2122  }
2123  QRect newrect;
2124  p.drawText( rect, Qt::TextWordWrap, headerText, &newrect );
2125  p.setFont( oldFont );
2126 
2127  y = newrect.bottom() + 4;
2128 
2129  p.drawLine( x + 3, y, x + width - 6, y );
2130  y += 5;
2131  if ( !( journal->organizer()->fullName().isEmpty() ) ) {
2132  drawTextLines( p, i18n( "Person: %1", journal->organizer()->fullName() ),
2133  x, y, width, pageHeight, false );
2134  y += 7;
2135  }
2136  if ( !( journal->description().isEmpty() ) ) {
2137  drawTextLines( p, journal->description(), x, y, width, pageHeight,
2138  journal->descriptionIsRich() );
2139  y += 7;
2140  }
2141  y += 10;
2142 }
2143 
2144 void CalPrintPluginBase::drawSplitHeaderRight( QPainter &p, const QDate &fd,
2145  const QDate &td, const QDate &,
2146  int width, int height )
2147 {
2148  QFont oldFont( p.font() );
2149 
2150  QPen oldPen( p.pen() );
2151  QPen pen( Qt::black, 4 );
2152 
2153  QString title;
2154  if ( mCalSys ) {
2155  if ( fd.month() == td.month() ) {
2156  title = i18nc( "Date range: Month dayStart - dayEnd", "%1 %2 - %3",
2157  mCalSys->monthName( fd.month(), KCalendarSystem::LongName ),
2158  mCalSys->formatDate( fd, KLocale::Day, KLocale::LongNumber ),
2159  mCalSys->formatDate( td, KLocale::Day, KLocale::LongNumber ) );
2160  } else {
2161  title = i18nc( "Date range: monthStart dayStart - monthEnd dayEnd", "%1 %2 - %3 %4",
2162  mCalSys->monthName( fd.month(), KCalendarSystem::LongName ),
2163  mCalSys->formatDate( fd, KLocale::Day, KLocale::LongNumber ),
2164  mCalSys->monthName( td.month(), KCalendarSystem::LongName ),
2165  mCalSys->formatDate( td, KLocale::Day, KLocale::LongNumber ) );
2166  }
2167  }
2168 
2169  if ( height < 60 ) {
2170  p.setFont( QFont( QLatin1String("Times"), 22 ) );
2171  } else {
2172  p.setFont( QFont( QLatin1String("Times"), 28 ) );
2173  }
2174 
2175  int lineSpacing = p.fontMetrics().lineSpacing();
2176  p.drawText( 0, 0, width, lineSpacing,
2177  Qt::AlignRight | Qt::AlignTop, title );
2178 
2179  title.truncate(0);
2180 
2181  p.setPen( pen );
2182  p.drawLine( 300, lineSpacing, width, lineSpacing );
2183  p.setPen( oldPen );
2184 
2185  if ( height < 60 ) {
2186  p.setFont( QFont( QLatin1String("Times"), 14, QFont::Bold, true ) );
2187  } else {
2188  p.setFont( QFont( QLatin1String("Times"), 18, QFont::Bold, true ) );
2189  }
2190 
2191  title += QString::number( fd.year() );
2192  p.drawText( 0, lineSpacing, width, lineSpacing,
2193  Qt::AlignRight | Qt::AlignTop, title );
2194 
2195  p.setFont( oldFont );
2196 }
2197 
2198 void CalPrintPluginBase::drawNoteLines( QPainter &p, const QRect &box, int startY )
2199 {
2200  int lineHeight = int( p.fontMetrics().lineSpacing() * 1.5 );
2201  int linePos = box.y();
2202  int startPos = startY;
2203  // adjust line to start at multiple from top of box for alignment
2204  while ( linePos < startPos ) {
2205  linePos += lineHeight;
2206  }
2207  QPen oldPen( p.pen() );
2208  p.setPen( Qt::DotLine );
2209  while ( linePos < box.bottom() ) {
2210  p.drawLine( box.left() + padding(), linePos,
2211  box.right() - padding(), linePos );
2212  linePos += lineHeight;
2213  }
2214  p.setPen( oldPen );
2215 }
2216 
2217 QString CalPrintPluginBase::toPlainText( const QString &htmlText )
2218 {
2219  // this converts possible rich text to plain text
2220  return QTextDocumentFragment::fromHtml( htmlText ).toPlainText();
2221 }
CalPrintPluginBase::dayStart
QTime dayStart()
Definition: calprintpluginbase.cpp:246
CalPrintPluginBase::doPrint
virtual void doPrint(QPrinter *printer)
Start printing.
Definition: calprintpluginbase.cpp:142
CalPrintPluginBase::drawDays
void drawDays(QPainter &p, const QDate &start, const QDate &end, const QTime &fromTime, const QTime &toTime, const QRect &box, bool singleLineLimit, bool showNoteLines, bool includeDescription, bool excludeConfidential, bool excludePrivate)
Draw the (filofax) table for a bunch of days, using drawDayBox.
Definition: calprintpluginbase.cpp:1387
CalPrintPluginBase::drawHeader
int drawHeader(QPainter &p, const QString &title, const QDate &month1, const QDate &month2, const QRect &box, bool expand=false, QColor backColor=QColor())
Draw the gray header bar of the printout to the QPainter.
Definition: calprintpluginbase.cpp:553
CalPrintPluginBase::holiday
Event::Ptr holiday(const QDate &dt)
Definition: calprintpluginbase.cpp:287
KOrg::PrintPlugin::mFromDate
QDate mFromDate
Definition: printplugin.h:172
CalPrintPluginBase::useColors
bool useColors() const
Definition: calprintpluginbase.cpp:221
koglobals.h
CalPrintPluginBase::mFooterHeight
int mFooterHeight
Definition: calprintpluginbase.h:654
CalPrintPluginBase::orientation
QPrinter::Orientation orientation() const
Definition: calprintpluginbase.cpp:241
CalPrintPluginBase::TimeBoxes
Definition: calprintpluginbase.h:69
CalPrintPluginBase::setPrintFooter
void setPrintFooter(bool printFooter)
Definition: calprintpluginbase.cpp:236
CalPrintPluginBase::padding
int padding() const
Definition: calprintpluginbase.cpp:371
KOrg::PrintPlugin::description
virtual QString description()=0
Returns short description of print format.
KOrg::PrintPlugin::mPrinter
QPrinter * mPrinter
The printer object.
Definition: printplugin.h:180
CalPrintPluginBase::setFooterHeight
void setFooterHeight(const int height)
Definition: calprintpluginbase.cpp:356
CalPrintPluginBase::drawJournal
void drawJournal(const Journal::Ptr &journal, QPainter &p, int x, int &y, int width, int pageHeight)
Draws single journal item.
Definition: calprintpluginbase.cpp:2101
CalPrintPluginBase::mPrintFooter
bool mPrintFooter
Definition: calprintpluginbase.h:648
MARGIN_SIZE
#define MARGIN_SIZE
Definition: calprintpluginbase.h:53
CalPrintPluginBase::drawDayBox
void drawDayBox(QPainter &p, const QDate &qd, const QTime &fromTime, const QTime &toTime, const QRect &box, bool fullDate=false, bool printRecurDaily=true, bool printRecurWeekly=true, bool singleLineLimit=true, bool showNoteLines=false, bool includeDescription=false, bool excludeDescription=true, bool excludePrivate=true)
Draw the box containing a list of all events of the given day (with their times, of course)...
Definition: calprintpluginbase.cpp:1054
QWidget
calprintpluginbase.h
CalPrintPluginBase::toPlainText
QString toPlainText(const QString &htmlText)
Definition: calprintpluginbase.cpp:2217
KOrg::PrintPlugin::mCoreHelper
KOrg::CoreHelper * mCoreHelper
Definition: printplugin.h:177
CalPrintPluginBase::showEventBox
void showEventBox(QPainter &p, int linewidth, const QRect &box, const Incidence::Ptr &incidence, const QString &str, int flags=-1)
Print the box for the given event with the given string.
Definition: calprintpluginbase.cpp:424
CalPrintPluginBase::categoryBgColor
QColor categoryBgColor(const Incidence::Ptr &incidence)
Helper functions to hide the KOrg::CoreHelper.
Definition: calprintpluginbase.cpp:267
CalPrintPluginBase::drawSubHeaderBox
void drawSubHeaderBox(QPainter &p, const QString &str, const QRect &box)
Draw a subheader box with a shaded background and the given string.
Definition: calprintpluginbase.cpp:445
CalPrintPluginBase::printFooter
bool printFooter() const
Definition: calprintpluginbase.cpp:231
EVENT_BORDER_WIDTH
#define EVENT_BORDER_WIDTH
Definition: calprintpluginbase.h:56
CalPrintPluginBase::weekdayColumn
static int weekdayColumn(int weekday)
Determines the column of the given weekday ( 1=Monday, 7=Sunday ), taking the start of the week setti...
Definition: calprintpluginbase.cpp:2067
KOrg::CoreHelper::holidayString
virtual QString holidayString(const QDate &dt)=0
CalPrintPluginBase::Text
Definition: calprintpluginbase.h:68
CalPrintPluginBase::mBorder
int mBorder
Definition: calprintpluginbase.h:657
CalPrintPluginBase::drawSplitHeaderRight
void drawSplitHeaderRight(QPainter &p, const QDate &fd, const QDate &td, const QDate &cd, int width, int height)
Definition: calprintpluginbase.cpp:2144
CalPrintPluginBase::~CalPrintPluginBase
virtual ~CalPrintPluginBase()
Definition: calprintpluginbase.cpp:118
LANDSCAPE_HEADER_HEIGHT
#define LANDSCAPE_HEADER_HEIGHT
Definition: calprintpluginbase.h:49
CalPrintPluginBase::drawDaysOfWeek
void drawDaysOfWeek(QPainter &p, const QDate &fromDate, const QDate &toDate, const QRect &box)
Draw a horizontal bar with the weekday names of the given date range in the given area of the painter...
Definition: calprintpluginbase.cpp:703
CalPrintPluginBase::setCategoryColors
void setCategoryColors(QPainter &p, const Incidence::Ptr &incidence)
Definition: calprintpluginbase.cpp:255
PORTRAIT_HEADER_HEIGHT
#define PORTRAIT_HEADER_HEIGHT
Definition: calprintpluginbase.h:48
CalPrintPluginBase::drawNoteLines
void drawNoteLines(QPainter &p, const QRect &box, int startY)
Draws dotted lines for notes in a box.
Definition: calprintpluginbase.cpp:2198
CalPrintPluginBase::mCalSys
const KCalendarSystem * mCalSys
Definition: calprintpluginbase.h:658
CalPrintPluginBase::mExcludeConfidential
bool mExcludeConfidential
Definition: calprintpluginbase.h:650
koprefs.h
CalPrintPluginBase::headerHeight
int headerHeight() const
Returns the height of the page header.
Definition: calprintpluginbase.cpp:315
CalPrintPluginBase::setPadding
void setPadding(const int margin)
Definition: calprintpluginbase.cpp:376
CalPrintPluginBase::drawBox
static void drawBox(QPainter &p, int linewidth, const QRect &rect)
Draw a box with given width at the given coordinates.
Definition: calprintpluginbase.cpp:391
CalPrintPluginBase::mMargin
int mMargin
Definition: calprintpluginbase.h:655
CalPrintPluginBase::drawAgendaItem
void drawAgendaItem(PrintCellItem *item, QPainter &p, const KDateTime &startPrintDate, const KDateTime &endPrintDate, float minlen, const QRect &box, bool includeDescription, bool excludeTime)
Definition: calprintpluginbase.cpp:975
CalPrintPluginBase::drawIncidence
void drawIncidence(QPainter &p, const QRect &dayBox, const QString &time, const QString &summary, const QString &description, int &textY, bool singleLineLimit, bool includeDescription, bool richDescription)
Definition: calprintpluginbase.cpp:1233
SUBHEADER_HEIGHT
#define SUBHEADER_HEIGHT
Definition: calprintpluginbase.h:50
CalPrintPluginBase::drawTodoLines
void drawTodoLines(QPainter &p, const QString &entry, int x, int &y, int width, int pageHeight, bool richTextEntry, QList< TodoParentStart * > &startPoints, bool connectSubTodos)
Definition: calprintpluginbase.cpp:1817
cleanStr
static QString cleanStr(const QString &instr)
Definition: calprintpluginbase.cpp:55
CalPrintPluginBase::drawShadedBox
static void drawShadedBox(QPainter &p, int linewidth, const QBrush &brush, const QRect &rect)
Draw a shaded box with given width at the given coordinates.
Definition: calprintpluginbase.cpp:406
CalPrintPluginBase::drawDaysOfWeekBox
void drawDaysOfWeekBox(QPainter &p, const QDate &qd, const QRect &box)
Draw a single weekday name in a box inside the given area of the painter.
Definition: calprintpluginbase.cpp:721
CalPrintPluginBase::drawTimeTable
void drawTimeTable(QPainter &p, const QDate &fromDate, const QDate &toDate, bool expandable, const QTime &fromTime, const QTime &toTime, const QRect &box, bool includeDescription, bool excludeTime, bool excludeConfidential, bool excludePrivate)
Draw the timetable view of the given time range from fromDate to toDate.
Definition: calprintpluginbase.cpp:1428
CalPrintPluginBase::mExcludePrivate
bool mExcludePrivate
Definition: calprintpluginbase.h:651
KOrg::CoreHelper::categoryColor
virtual QColor categoryColor(const QStringList &cats)=0
CalPrintPluginBase::setHeaderHeight
void setHeaderHeight(const int height)
Definition: calprintpluginbase.cpp:326
CalPrintPluginBase::drawBoxWithCaption
int drawBoxWithCaption(QPainter &p, const QRect &box, const QString &caption, const QString &contents, bool sameLine, bool expand, const QFont &captionFont, const QFont &textFont, bool richContents=false)
Draw a component box with a heading (printed in bold).
Definition: calprintpluginbase.cpp:470
CalPrintPluginBase::drawSmallMonth
void drawSmallMonth(QPainter &p, const QDate &qd, const QRect &box)
Draw a small calendar with the days of a month into the given area.
Definition: calprintpluginbase.cpp:642
CalPrintPluginBase::mSubHeaderHeight
int mSubHeaderHeight
Definition: calprintpluginbase.h:653
CalPrintPluginBase::doLoadConfig
void doLoadConfig()
Load complete config.
Definition: calprintpluginbase.cpp:175
PADDING_SIZE
#define PADDING_SIZE
Definition: calprintpluginbase.h:54
CalPrintPluginBase::setSubHeaderHeight
void setSubHeaderHeight(const int height)
Definition: calprintpluginbase.cpp:336
KOHelper::getTextColor
KORGANIZERPRIVATE_EXPORT QColor getTextColor(const QColor &c)
Returns a nice QColor for text, give the input color &c.
Definition: kohelper.cpp:32
CalPrintPluginBase::subHeaderHeight
int subHeaderHeight() const
Definition: calprintpluginbase.cpp:331
KOrg::CoreHelper::dayStart
virtual QTime dayStart()=0
KOGlobals::self
static KOGlobals * self()
Definition: koglobals.cpp:43
CalPrintPluginBase::doSaveConfig
void doSaveConfig()
Save complete config.
Definition: calprintpluginbase.cpp:193
CalPrintPluginBase::holidayString
QString holidayString(const QDate &dt)
Definition: calprintpluginbase.cpp:282
CalPrintPluginBase::drawMonthTable
void drawMonthTable(QPainter &p, const QDate &qd, const QTime &fromTime, const QTime &toTime, bool weeknumbers, bool recurDaily, bool recurWeekly, bool singleLineLimit, bool showNoteLines, bool includeDescription, bool excludeConfidential, bool excludePrivate, const QRect &box)
Draw the month table of the month containing the date qd.
Definition: calprintpluginbase.cpp:1738
KOGlobals::workDays
QList< QDate > workDays(const QDate &start, const QDate &end) const
Returns a list containing work days between start and .
Definition: koglobals.cpp:96
KOrg::PrintPlugin::mToDate
QDate mToDate
Definition: printplugin.h:173
CalPrintPluginBase::calendarSystem
const KCalendarSystem * calendarSystem() const
Definition: calprintpluginbase.cpp:305
KOrg::CoreHelper
Definition: corehelper.h:30
CalPrintPluginBase::mUseColors
bool mUseColors
Definition: calprintpluginbase.h:647
CalPrintPluginBase::drawTextLines
void drawTextLines(QPainter &p, const QString &entry, int x, int &y, int width, int pageHeight, bool richTextEntry)
Draws text lines splitting on page boundaries.
Definition: calprintpluginbase.cpp:2073
CalPrintPluginBase::loadConfig
virtual void loadConfig()=0
Load print format configuration from config file.
CalPrintPluginBase::setCalendarSystem
void setCalendarSystem(const KCalendarSystem *calsys)
Definition: calprintpluginbase.cpp:310
CalPrintPluginBase::print
virtual void print(QPainter &p, int width, int height)=0
Actually do the printing.
kohelper.h
CalPrintPluginBase::drawTodo
void drawTodo(int &count, const KCalCore::Todo::Ptr &todo, QPainter &p, KCalCore::TodoSortField sortField, KCalCore::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 KCalCore::Todo::List &todoList, TodoParentStart *r, bool excludeConfidential, bool excludePrivate)
Draws single to-do and its (intented) sub-to-dos, optionally connects them by a tree-like line...
Definition: calprintpluginbase.cpp:1865
CalPrintPluginBase::setBorderWidth
void setBorderWidth(const int border)
Definition: calprintpluginbase.cpp:386
BOX_BORDER_WIDTH
#define BOX_BORDER_WIDTH
Definition: calprintpluginbase.h:55
CalPrintPluginBase::mHeaderHeight
int mHeaderHeight
Definition: calprintpluginbase.h:652
CalPrintPluginBase::drawFooter
int drawFooter(QPainter &p, const QRect &box)
Draw a page footer containing the printing date and possibly other things, like a page number...
Definition: calprintpluginbase.cpp:628
CalPrintPluginBase::footerHeight
int footerHeight() const
Returns the height of the page footer.
Definition: calprintpluginbase.cpp:341
KOrg::PrintPlugin::mConfig
KConfig * mConfig
Definition: printplugin.h:183
CalPrintPluginBase::createConfigWidget
virtual QWidget * createConfigWidget(QWidget *)
Returns widget for configuring the print format.
Definition: calprintpluginbase.cpp:122
CalPrintPluginBase::borderWidth
int borderWidth() const
Definition: calprintpluginbase.cpp:381
CalPrintPluginBase::mPadding
int mPadding
Definition: calprintpluginbase.h:656
CalPrintPluginBase::setMargin
void setMargin(const int margin)
Definition: calprintpluginbase.cpp:366
KOrg::PrintPlugin::info
virtual QString info() const =0
Returns long description of print format.
LANDSCAPE_FOOTER_HEIGHT
#define LANDSCAPE_FOOTER_HEIGHT
Definition: calprintpluginbase.h:52
CalPrintPluginBase::margin
int margin() const
Definition: calprintpluginbase.cpp:361
KOPrefsBase::todoOverdueColor
QColor todoOverdueColor() const
Get To-do overdue color.
Definition: koprefs_base.h:1177
CalPrintPluginBase::printEventString
void printEventString(QPainter &p, const QRect &box, const QString &str, int flags=-1)
Print the given string (event summary) in the given rectangle.
Definition: calprintpluginbase.cpp:415
KOPrefs::instance
static KOPrefs * instance()
Get instance of KOPrefs.
Definition: koprefs.cpp:68
TIMELINE_WIDTH
#define TIMELINE_WIDTH
Definition: calprintpluginbase.h:58
CalPrintPluginBase::drawWeek
void drawWeek(QPainter &p, const QDate &qd, const QTime &fromTime, const QTime &toTime, const QRect &box, bool singleLineLimit, bool showNoteLines, bool includeDescription, bool excludeConfidential, bool excludePrivate)
Draw the week (filofax) table of the week containing the date qd.
Definition: calprintpluginbase.cpp:1348
CalPrintPluginBase::drawAgendaDayBox
void drawAgendaDayBox(QPainter &p, const KCalCore::Event::List &eventList, const QDate &qd, bool expandable, const QTime &fromTime, const QTime &toTime, const QRect &box, bool includeDescription, bool excludeTime, bool mExcludeConfidential, bool mExcludePrivate, const QList< QDate > &workDays)
Draw the agenda box for the day print style (the box showing all events of that day).
Definition: calprintpluginbase.cpp:858
CalPrintPluginBase::drawAllDayBox
int drawAllDayBox(QPainter &p, const KCalCore::Event::List &eventList, const QDate &qd, bool expandable, const QRect &box, bool mExcludeConfidential, bool mExcludePrivate)
Draw the all-day box for the agenda print view (the box on top which doesn't have a time on the time ...
Definition: calprintpluginbase.cpp:799
CalPrintPluginBase::drawMonth
void drawMonth(QPainter &p, const QDate &dt, const QRect &box, int maxdays=-1, int subDailyFlags=TimeBoxes, int holidaysFlags=Text)
Draw a vertical representation of the month containing the date dt.
Definition: calprintpluginbase.cpp:1524
CalPrintPluginBase::drawTimeLine
void drawTimeLine(QPainter &p, const QTime &fromTime, const QTime &toTime, const QRect &box)
Draw a (vertical) time scale from time fromTime to toTime inside the given area of the painter...
Definition: calprintpluginbase.cpp:726
CalPrintPluginBase::setUseColors
void setUseColors(bool useColors)
Definition: calprintpluginbase.cpp:226
QFrame
KOrg::PrintPlugin::mCalendar
Akonadi::ETMCalendar::Ptr mCalendar
Definition: printplugin.h:181
CalPrintPluginBase::drawVerticalBox
void drawVerticalBox(QPainter &p, int linewidth, const QRect &box, const QString &str, int flags=-1)
Draw an event box with vertical text.
Definition: calprintpluginbase.cpp:454
CalPrintPluginBase::saveConfig
virtual void saveConfig()=0
Write print format configuration to config file.
CalPrintPluginBase::CalPrintPluginBase
CalPrintPluginBase()
Constructor.
Definition: calprintpluginbase.cpp:111
KOrg::PrintPlugin::groupName
virtual QString groupName()=0
Returns KConfig group name where store settings.
PORTRAIT_FOOTER_HEIGHT
#define PORTRAIT_FOOTER_HEIGHT
Definition: calprintpluginbase.h:51
CalPrintPluginBase::setKOrgCoreHelper
void setKOrgCoreHelper(KOrg::CoreHelper *helper)
HELPER FUNCTIONS.
Definition: calprintpluginbase.cpp:213
KOrg::CoreHelper::calendarSystem
virtual const KCalendarSystem * calendarSystem()=0
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:56:19 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

korganizer

Skip menu "korganizer"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal