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

calendarsupport

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

KDE's Doxygen guidelines are available online.

calendarsupport

Skip menu "calendarsupport"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

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
  • pimprint

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