33 #include <Akonadi/Calendar/ETMCalendar>
34 #include <calendarsupport/utils.h>
35 #include <calendarviews/agenda/cellitem.h>
37 #include <KCalendarSystem>
38 #include <KConfigGroup>
40 #include <KSystemTimeZones>
43 #include <QAbstractTextDocumentLayout>
48 #include <QTextCursor>
49 #include <QTextDocument>
50 #include <QTextDocumentFragment>
53 using namespace KCalCore;
55 static QString
cleanStr(
const QString &instr )
58 return ret.replace( QLatin1Char(
'\n'), QLatin1Char(
' ') );
64 class CalPrintPluginBase::TodoParentStart
67 TodoParentStart(
const QRect &pt = QRect(),
bool hasLine =
false,
bool page =
true )
68 : mRect( pt ), mHasLine( hasLine ), mSamePage( page ) {}
79 class PrintCellItem :
public EventViews::CellItem
82 PrintCellItem(
const Event::Ptr &event,
const KDateTime &start,
const KDateTime &end )
83 : mEvent( event ), mStart( start ), mEnd( end )
87 Event::Ptr event()
const {
return mEvent; }
89 QString label()
const {
return mEvent->summary(); }
91 KDateTime start()
const {
return mStart; }
92 KDateTime end()
const {
return mEnd; }
96 bool overlaps( EventViews::CellItem *o )
const
98 PrintCellItem *other =
static_cast<PrintCellItem *
>( o );
99 return !( other->start() >= end() || other->end() <= start() );
104 KDateTime mStart, mEnd;
112 : PrintPlugin(), mUseColors( true ), mPrintFooter( true ),
113 mHeaderHeight( -1 ), mSubHeaderHeight(
SUBHEADER_HEIGHT ), mFooterHeight( -1 ),
125 QVBoxLayout *layout =
new QVBoxLayout( wdg );
128 QFont titleFont( title->font() );
129 titleFont.setPointSize( 20 );
130 titleFont.setBold(
true );
131 title->setFont( titleFont );
133 layout->addWidget( title );
134 layout->addWidget(
new QLabel(
info(), wdg ) );
135 layout->addSpacing( 20 );
137 new QLabel( i18n(
"This printing style does not have any configuration options." ), wdg ) );
138 layout->addStretch();
157 p.setViewport( margins, margins,
158 p.viewport().width() - 2 * margins,
159 p.viewport().height() - 2 * margins );
164 int pageWidth = p.window().width();
165 int pageHeight = p.window().height();
169 print( p, pageWidth, pageHeight );
180 QDateTime dt = QDateTime::currentDateTime();
181 mFromDate = group.readEntry(
"FromDate", dt ).date();
182 mToDate = group.readEntry(
"ToDate", dt ).date();
183 mUseColors = group.readEntry(
"UseColors",
true );
189 kDebug() <<
"No config available in loadConfig!!!!";
198 QDateTime dt = QDateTime::currentDateTime();
200 group.writeEntry(
"FromDate", dt );
202 group.writeEntry(
"ToDate", dt );
209 kDebug() <<
"No config available in saveConfig!!!!";
215 PrintPlugin::setKOrgCoreHelper( helper );
248 QTime start( 8, 0, 0 );
258 if ( bgColor.isValid() ) {
259 p.setBrush( bgColor );
262 if ( tColor.isValid() ) {
271 if ( incidence->type() == Incidence::TypeTodo ) {
272 if ( ( incidence.staticCast<Todo>() )->isOverdue() ) {
290 if ( !hstring.isEmpty() ) {
292 KDateTime::Spec timeSpec = KSystemTimeZones::local();
293 KDateTime kdt( dt, QTime(), timeSpec );
294 Event::Ptr
holiday(
new Event );
295 holiday->setSummary( hstring );
296 holiday->setDtStart( kdt );
297 holiday->setDtEnd( kdt );
298 holiday->setAllDay(
true );
299 holiday->setCategories( i18n(
"Holiday" ) );
319 }
else if (
orientation() == QPrinter::Portrait ) {
349 }
else if (
orientation() == QPrinter::Portrait ) {
396 if ( linewidth >= 0 ) {
397 pen.setWidth( linewidth );
400 p.setPen( Qt::NoPen );
407 const QBrush &brush,
const QRect &rect )
409 QBrush oldbrush( p.brush() );
412 p.setBrush( oldbrush );
416 const QString &str,
int flags )
419 newbox.adjust( 3, 1, -1, -1 );
420 p.drawText( newbox, ( flags == -1 ) ?
421 ( Qt::AlignTop | Qt::AlignLeft | Qt::TextWordWrap ) : flags, str );
425 const Incidence::Ptr &incidence,
const QString &str,
428 QPen oldpen( p.pen() );
429 QBrush oldbrush( p.brush() );
432 p.setBrush( bgColor );
434 p.setBrush( QColor( 232, 232, 232 ) );
442 p.setBrush( oldbrush );
448 QFont oldfont( p.font() );
449 p.setFont( QFont( QLatin1String(
"sans-serif"), 10, QFont::Bold ) );
450 p.drawText( box, Qt::AlignCenter | Qt::AlignVCenter, str );
451 p.setFont( oldfont );
455 const QString &str,
int flags )
459 QRect rotatedBox( -box.top() - box.height(), box.left(), box.height(), box.width() );
460 showEventBox( p, linewidth, rotatedBox, Incidence::Ptr(), str,
461 ( flags == -1 ) ? Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine : flags );
471 const QString &caption,
472 const QString &contents,
473 bool sameLine,
bool expand,
474 const QFont &captionFont,
475 const QFont &textFont,
478 QFont oldFont( p.font() );
487 QRect captionBox( box.left() +
padding(), box.top() +
padding(), 0, 0 );
488 p.setFont( captionFont );
489 captionBox = p.boundingRect( captionBox,
490 Qt::AlignLeft | Qt::AlignTop | Qt::TextSingleLine,
492 p.setFont( oldFont );
493 if ( captionBox.right() > box.right() ) {
494 captionBox.setRight( box.right() );
496 if ( expand && captionBox.bottom() +
padding() > box.bottom() ) {
497 box.setBottom( captionBox.bottom() +
padding() );
501 QRect textBox( captionBox );
502 if ( !contents.isEmpty() ) {
504 textBox.setLeft( captionBox.right() +
padding() );
506 textBox.setTop( captionBox.bottom() +
padding() );
508 textBox.setRight( box.right() );
511 p.setFont( captionFont );
512 p.drawText( captionBox, Qt::AlignLeft | Qt::AlignTop | Qt::TextSingleLine,
515 if ( !contents.isEmpty() ) {
518 p.setFont( textFont );
519 p.drawText( textBox, Qt::AlignLeft | Qt::AlignTop | Qt::TextSingleLine,
524 if ( richContents ) {
525 rtb.setHtml( contents );
527 rtb.setPlainText( contents );
529 int boxHeight = allbox.height();
531 boxHeight -= captionBox.height();
533 rtb.setPageSize( QSize( textBox.width(), boxHeight ) );
534 rtb.setDefaultFont( textFont );
536 p.translate( textBox.x() -
borderWidth, textBox.y() );
537 QRect clipBox( 0, 0, box.width(), boxHeight );
538 rtb.drawContents( &p, clipBox );
540 textBox.setBottom( textBox.y() +
541 rtb.documentLayout()->documentSize().height() );
544 p.setFont( oldFont );
549 return textBox.bottom();
554 const QDate &month1,
const QDate &month2,
const QRect &allbox,
555 bool expand, QColor backColor )
558 int smallMonthWidth = ( allbox.width() / 4 ) - 10;
559 if ( smallMonthWidth > 100 ) {
560 smallMonthWidth = 100;
564 QRect textRect( allbox );
566 QFont oldFont( p.font() );
567 QFont newFont( QLatin1String(
"sans-serif"), ( textRect.height() < 60 ) ? 16 : 18, QFont::Bold );
569 p.setFont( newFont );
571 p.boundingRect( textRect, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextWordWrap, title );
572 p.setFont( oldFont );
573 int h = boundingR.height();
574 if ( h > allbox.height() ) {
576 textRect.setHeight( h );
580 if ( !backColor.isValid() ) {
581 backColor = QColor( 232, 232, 232 );
588 QRect monthbox2( box.right()-10-smallMonthWidth, box.top(),
589 smallMonthWidth, box.height() );
590 if ( month2.isValid() ) {
591 drawSmallMonth( p, QDate( month2.year(), month2.month(), 1 ), monthbox2 );
592 textRect.setRight( monthbox2.left() );
594 QRect monthbox1( monthbox2.left()-10-smallMonthWidth, box.top(),
595 smallMonthWidth, box.height() );
596 if ( month1.isValid() ) {
597 drawSmallMonth( p, QDate( month1.year(), month1.month(), 1 ), monthbox1 );
598 textRect.setRight( monthbox1.left() );
602 p.setFont( newFont );
603 textRect.adjust( 5, 0, 0, 0 );
604 p.drawText( textRect, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextWordWrap, title );
605 p.setFont( oldFont );
608 QRect monthbox2( box.right()-10-smallMonthWidth, box.top(),
609 smallMonthWidth, box.height() );
610 if ( month2.isValid() ) {
611 drawSmallMonth( p, QDate( month2.year(), month2.month(), 1 ), monthbox2 );
612 textRect.setRight( monthbox2.left() );
614 QRect monthbox1( box.left()+10, box.top(), smallMonthWidth, box.height() );
615 if ( month1.isValid() ) {
616 drawSmallMonth( p, QDate( month1.year(), month1.month(), 1 ), monthbox1 );
617 textRect.setLeft( monthbox1.right() );
621 p.setFont( newFont );
622 p.drawText( textRect, Qt::AlignCenter | Qt::AlignVCenter | Qt::TextWordWrap, title );
623 p.setFont( oldFont );
625 return textRect.bottom();
630 QFont oldfont( p.font() );
631 p.setFont( QFont( QLatin1String(
"sans-serif"), 6 ) );
632 QFontMetrics fm( p.font() );
634 KGlobal::locale()->formatDateTime( QDateTime::currentDateTime(), KLocale::LongDate );
635 p.drawText( footbox, Qt::AlignCenter | Qt::AlignVCenter | Qt::TextSingleLine,
636 i18nc(
"print date: formatted-datetime",
"printed: %1", dateStr ) );
637 p.setFont( oldfont );
639 return footbox.bottom();
645 int month = qd.month();
646 QDate monthDate( QDate( qd.year(), qd.month(), 1 ) );
648 QDate monthDate2( monthDate.addDays( -weekdayCol ) );
650 double cellWidth = double( box.width() ) /
double( 7 );
651 int rownr = 3 + ( qd.daysInMonth() + weekdayCol - 1 ) / 7;
653 double cellHeight = ( box.height() - 5 ) / rownr;
654 QFont oldFont( p.font() );
655 p.setFont( QFont( QLatin1String(
"sans-serif"),
int(cellHeight-2), QFont::Normal ) );
659 QRect titleBox( box );
660 titleBox.setHeight(
int( cellHeight + 1 ) );
661 p.drawText( titleBox, Qt::AlignTop | Qt::AlignHCenter,
mCalSys->monthName( qd ) );
665 QRect wdayBox( box );
666 wdayBox.setTop(
int( box.top() + 3 + cellHeight ) );
667 wdayBox.setHeight(
int( 2 * cellHeight ) -
int( cellHeight ) );
670 for (
int col = 0; col < 7; ++col ) {
671 QString tmpStr =
mCalSys->weekDayName( monthDate2 )[0].toUpper();
672 wdayBox.setLeft(
int( box.left() + col * cellWidth ) );
673 wdayBox.setRight(
int( box.left() + ( col + 1 ) * cellWidth ) );
674 p.drawText( wdayBox, Qt::AlignCenter, tmpStr );
675 monthDate2 = monthDate2.addDays( 1 );
680 int calStartY = wdayBox.bottom() + 2;
681 p.drawLine( box.left(), calStartY, box.right(), calStartY );
682 monthDate = monthDate.addDays( -weekdayCol );
684 for (
int row = 0; row < (rownr-2); row++ ) {
685 for (
int col = 0; col < 7; col++ ) {
686 if ( monthDate.month() == month ) {
687 QRect dayRect(
int( box.left() + col * cellWidth ),
688 int( calStartY + row * cellHeight ), 0, 0 );
689 dayRect.setRight(
int( box.left() + ( col + 1 ) * cellWidth ) );
690 dayRect.setBottom(
int( calStartY + ( row + 1 ) * cellHeight ) );
691 p.drawText( dayRect, Qt::AlignCenter, QString::number( monthDate.day() ) );
693 monthDate = monthDate.addDays(1);
696 p.setFont( oldFont );
704 const QDate &fromDate,
705 const QDate &toDate,
const QRect &box )
707 double cellWidth = double( box.width() ) /
double( fromDate.daysTo( toDate ) + 1 );
708 QDate cellDate( fromDate );
709 QRect dateBox( box );
712 while ( cellDate <= toDate ) {
713 dateBox.setLeft( box.left() + int( i * cellWidth ) );
714 dateBox.setRight( box.left() + int( ( i + 1 ) * cellWidth ) );
716 cellDate = cellDate.addDays( 1 );
727 const QTime &toTime,
const QRect &box )
731 int totalsecs = fromTime.secsTo( toTime );
732 float minlen = (float)box.height() * 60. / (float)totalsecs;
733 float cellHeight = ( 60. * (float)minlen );
734 float currY = box.top();
736 int xcenter = box.left() + box.width() / 2;
738 QTime curTime( fromTime );
739 QTime endTime( toTime );
740 if ( fromTime.minute() > 30 ) {
741 curTime = QTime( fromTime.hour()+1, 0, 0 );
742 }
else if ( fromTime.minute() > 0 ) {
743 curTime = QTime( fromTime.hour(), 30, 0 );
744 float yy = currY + minlen * (float)fromTime.secsTo( curTime ) / 60.;
745 p.drawLine( xcenter, (
int)yy, box.right(), (int)yy );
746 curTime = QTime( fromTime.hour() + 1, 0, 0 );
748 currY += ( float( fromTime.secsTo( curTime ) * minlen ) / 60. );
750 while ( curTime < endTime ) {
751 p.drawLine( box.left(), (int)currY, box.right(), (int)currY );
752 int newY = (int)( currY + cellHeight / 2. );
754 if ( newY < box.bottom() ) {
755 QFont oldFont( p.font() );
757 if ( !KGlobal::locale()->use12Clock() ) {
758 p.drawLine( xcenter, (
int)newY, box.right(), (int)newY );
759 numStr.setNum( curTime.hour() );
760 if ( cellHeight > 30 ) {
761 p.setFont( QFont( QLatin1String(
"sans-serif"), 14, QFont::Bold ) );
763 p.setFont( QFont( QLatin1String(
"sans-serif"), 12, QFont::Bold ) );
765 p.drawText( box.left() + 4, (int)currY + 2, box.width() / 2 - 2, (int)cellHeight,
766 Qt::AlignTop | Qt::AlignRight, numStr );
767 p.setFont( QFont( QLatin1String(
"helvetica"), 10, QFont::Normal ) );
768 p.drawText( xcenter + 4, (
int)currY+2, box.width() / 2 + 2, (int)( cellHeight / 2 ) - 3,
769 Qt::AlignTop | Qt::AlignLeft, QLatin1String(
"00") );
771 p.drawLine( box.left(), (int)newY, box.right(), (int)newY );
772 QTime time( curTime.hour(), 0 );
773 numStr = KGlobal::locale()->formatTime( time );
774 if ( box.width() < 60 ) {
775 p.setFont( QFont( QLatin1String(
"sans-serif"), 7, QFont::Bold ) );
777 p.setFont( QFont( QLatin1String(
"sans-serif"), 12, QFont::Bold ) );
779 p.drawText( box.left() + 2, (int)currY + 2, box.width() - 4, (int)cellHeight / 2 - 3,
780 Qt::AlignTop|Qt::AlignLeft, numStr );
783 p.setFont( oldFont );
785 if ( curTime.secsTo( endTime ) > 3600 ) {
786 curTime = curTime.addSecs( 3600 );
800 const QDate &qd,
bool expandable,
802 bool excludeConfidential,
803 bool excludePrivate )
805 Event::List::Iterator it;
806 int offset = box.top();
809 Event::List eventList = eventList_;
812 eventList.prepend( hd );
815 it = eventList.begin();
816 while ( it != eventList.end() ) {
817 Event::Ptr currEvent = *it;
818 if ( ( excludeConfidential && currEvent->secrecy() == Incidence::SecrecyConfidential ) ||
819 ( excludePrivate && currEvent->secrecy() == Incidence::SecrecyPrivate ) ) {
822 if ( currEvent && currEvent->allDay() ) {
825 QRect eventBox( box );
826 eventBox.setTop( offset );
828 offset += box.height();
830 if ( !multiDayStr.isEmpty() ) {
831 multiDayStr += QLatin1String(
", ");
833 multiDayStr += currEvent->summary();
835 it = eventList.erase( it );
841 int ret = box.height();
842 QRect eventBox( box );
844 if ( !multiDayStr.isEmpty() ) {
851 ret = offset - box.top();
852 eventBox.setBottom( ret );
859 const QDate &qd,
bool expandable,
860 const QTime &fromTime,
863 bool includeDescription,
865 bool excludeConfidential,
867 const QList<QDate> &workDays )
869 QTime myFromTime, myToTime;
870 if ( fromTime.isValid() ) {
871 myFromTime = fromTime;
873 myFromTime = QTime( 0, 0, 0 );
875 if ( toTime.isValid() ) {
878 myToTime = QTime( 23, 59, 59 );
881 if ( !workDays.contains( qd ) ) {
892 Q_FOREACH (
const KCalCore::Event::Ptr &event, events ) {
894 if ( ( excludeConfidential && event->secrecy() == Incidence::SecrecyConfidential ) ||
895 ( excludePrivate && event->secrecy() == Incidence::SecrecyPrivate ) ) {
899 if ( event->allDay() ) {
902 if ( event->dtStart().time() < myFromTime ) {
903 myFromTime =
event->dtStart().time();
905 if ( event->dtEnd().time() > myToTime ) {
906 myToTime =
event->dtEnd().time();
912 int totalsecs = myFromTime.secsTo( myToTime );
913 float minlen = box.height() * 60. / totalsecs;
914 float cellHeight = 60. * minlen;
915 float currY = box.top();
918 QTime curTime( QTime( myFromTime.hour(), 0, 0 ) );
919 currY += myFromTime.secsTo( curTime ) * minlen / 60;
921 while ( curTime < myToTime && curTime.isValid() ) {
922 if ( currY > box.top() ) {
923 p.drawLine( box.left(), int( currY ), box.right(), int( currY ) );
925 currY += cellHeight / 2;
926 if ( ( currY > box.top() ) && ( currY < box.bottom() ) ) {
928 QPen oldPen( p.pen() );
929 p.setPen( QColor( 192, 192, 192 ) );
930 p.drawLine( box.left(), int( currY ), box.right(), int( currY ) );
933 if ( curTime.secsTo( myToTime ) > 3600 ) {
934 curTime = curTime.addSecs( 3600 );
938 currY += cellHeight / 2;
941 KDateTime startPrintDate = KDateTime( qd, myFromTime );
942 KDateTime endPrintDate = KDateTime( qd, myToTime );
947 QList<EventViews::CellItem *> cells;
949 Akonadi::Item::List::ConstIterator itEvents;
950 foreach (
const Event::Ptr &event, events ) {
951 if ( event->allDay() ) {
954 QList<KDateTime> times =
event->startDateTimesForDate( qd );
955 for ( QList<KDateTime>::ConstIterator it = times.constBegin();
956 it != times.constEnd(); ++it ) {
957 cells.append(
new PrintCellItem( event, (*it), event->endDateForStart( *it ) ) );
961 QListIterator<EventViews::CellItem *> it1( cells );
962 while ( it1.hasNext() ) {
963 EventViews::CellItem *placeItem = it1.next();
964 EventViews::CellItem::placeItem( cells, placeItem );
967 QListIterator<EventViews::CellItem *> it2( cells );
968 while ( it2.hasNext() ) {
969 PrintCellItem *placeItem =
static_cast<PrintCellItem *
>( it2.next() );
970 drawAgendaItem( placeItem, p, startPrintDate, endPrintDate, minlen, box,
971 includeDescription, excludeTime );
976 const KDateTime &startPrintDate,
977 const KDateTime &endPrintDate,
978 float minlen,
const QRect &box,
979 bool includeDescription,
982 Event::Ptr
event = item->event();
985 KDateTime startTime = item->start();
986 KDateTime endTime = item->end();
987 if ( ( startTime < endPrintDate && endTime > startPrintDate ) ||
988 ( endTime > startPrintDate && startTime < endPrintDate ) ) {
989 if ( startTime < startPrintDate ) {
990 startTime = startPrintDate;
992 if ( endTime > endPrintDate ) {
993 endTime = endPrintDate;
995 int currentWidth = box.width() / item->subCells();
996 int currentX = box.left() + item->subCell() * currentWidth;
998 int( box.top() + startPrintDate.secsTo( startTime ) * minlen / 60. );
1000 int( box.top() + startPrintDate.secsTo( endTime ) * minlen / 60. ) - currentYPos;
1002 QRect eventBox( currentX, currentYPos, currentWidth, currentHeight );
1004 if ( excludeTime ) {
1005 if ( event->location().isEmpty() ) {
1006 str =
cleanStr( event->summary() );
1008 str = i18nc(
"summary, location",
"%1, %2",
1012 if ( event->location().isEmpty() ) {
1013 str = i18nc(
"starttime - endtime summary",
1015 KGlobal::locale()->formatTime( item->start().toLocalZone().time() ),
1016 KGlobal::locale()->formatTime( item->end().toLocalZone().time() ),
1019 str = i18nc(
"starttime - endtime summary, location",
1021 KGlobal::locale()->formatTime( item->start().toLocalZone().time() ),
1022 KGlobal::locale()->formatTime( item->end().toLocalZone().time() ),
1027 if ( includeDescription && !event->description().isEmpty() ) {
1028 str += QLatin1Char(
'\n');
1029 if ( event->descriptionIsRich() ) {
1032 str +=
event->description();
1035 QFont oldFont( p.font() );
1036 if ( eventBox.height() < 24 ) {
1037 if ( eventBox.height() < 12 ) {
1038 if ( eventBox.height() < 8 ) {
1039 p.setFont( QFont( QLatin1String(
"sans-serif"), 4 ) );
1041 p.setFont( QFont( QLatin1String(
"sans-serif"), 5 ) );
1044 p.setFont( QFont( QLatin1String(
"sans-serif"), 6 ) );
1047 p.setFont( QFont( QLatin1String(
"sans-serif"), 8 ) );
1050 p.setFont( oldFont );
1055 const QTime &fromTime,
const QTime &toTime,
1056 const QRect &box,
bool fullDate,
1057 bool printRecurDaily,
bool printRecurWeekly,
1058 bool singleLineLimit,
bool showNoteLines,
1059 bool includeDescription,
1060 bool excludeConfidential,
1061 bool excludePrivate )
1064 const KLocale *local = KGlobal::locale();
1066 QTime myFromTime, myToTime;
1067 if ( fromTime.isValid() ) {
1068 myFromTime = fromTime;
1070 myFromTime = QTime( 0, 0, 0 );
1072 if ( toTime.isValid() ) {
1075 myToTime = QTime( 23, 59, 59 );
1079 dayNumStr = i18nc(
"weekday, shortmonthname daynumber",
1080 "%1, %2 <numid>%3</numid>",
1082 mCalSys->monthName( qd, KCalendarSystem::ShortName ),
1085 dayNumStr = QString::number( qd.day() );
1088 QRect subHeaderBox( box );
1091 drawShadedBox( p, 0, QColor( 232, 232, 232 ), subHeaderBox );
1094 const QFont oldFont( p.font() );
1096 QRect headerTextBox( subHeaderBox );
1097 headerTextBox.setLeft( subHeaderBox.left() + 5 );
1098 headerTextBox.setRight( subHeaderBox.right() - 5 );
1099 if ( !hstring.isEmpty() ) {
1100 p.setFont( QFont( QLatin1String(
"sans-serif"), 8, QFont::Bold,
true ) );
1101 p.drawText( headerTextBox, Qt::AlignLeft | Qt::AlignVCenter, hstring );
1103 p.setFont( QFont( QLatin1String(
"sans-serif"), 10, QFont::Bold ) );
1104 p.drawText( headerTextBox, Qt::AlignRight | Qt::AlignVCenter, dayNumStr );
1106 const KCalCore::Event::List eventList =
1107 mCalendar->events( qd, KSystemTimeZones::local(),
1108 KCalCore::EventSortStartDate,
1109 KCalCore::SortDirectionAscending );
1112 p.setFont( QFont( QLatin1String(
"sans-serif"), 7 ) );
1115 unsigned int visibleEventsCounter = 0;
1116 Q_FOREACH (
const Event::Ptr &currEvent, eventList ) {
1117 Q_ASSERT( currEvent );
1118 if ( !currEvent->allDay() ) {
1119 if ( currEvent->dtEnd().toLocalZone().time() <= myFromTime ||
1120 currEvent->dtStart().toLocalZone().time() > myToTime ) {
1124 if ( ( !printRecurDaily && currEvent->recurrenceType() == Recurrence::rDaily ) ||
1125 ( !printRecurWeekly && currEvent->recurrenceType() == Recurrence::rWeekly ) ) {
1128 if ( ( excludeConfidential && currEvent->secrecy() == Incidence::SecrecyConfidential ) ||
1129 ( excludePrivate && currEvent->secrecy() == Incidence::SecrecyPrivate ) ) {
1132 if ( currEvent->allDay() || currEvent->isMultiDay() ) {
1135 timeText = local->formatTime( currEvent->dtStart().toLocalZone().time() ) + QLatin1Char(
' ');
1139 QString summaryStr = currEvent->summary();
1140 if ( !currEvent->location().isEmpty() ) {
1141 summaryStr = i18nc(
"summary, location",
1142 "%1, %2", summaryStr, currEvent->location() );
1145 summaryStr, currEvent->description(),
1146 textY, singleLineLimit, includeDescription,
1147 currEvent->descriptionIsRich() );
1149 visibleEventsCounter++;
1151 if ( textY >= box.height() ) {
1152 const QChar downArrow( 0x21e3 );
1154 const unsigned int invisibleIncidences =
1155 ( eventList.count() - visibleEventsCounter ) +
mCalendar->todos( qd ).count();
1156 if ( invisibleIncidences > 0 ) {
1157 const QString warningMsg = QString::fromLatin1(
"%1 (%2)" ).arg( downArrow ).arg( invisibleIncidences );
1159 QFontMetrics fm( p.font() );
1160 QRect msgRect = fm.boundingRect( warningMsg );
1161 msgRect.setRect( box.right() - msgRect.width() - 2,
1162 box.bottom() - msgRect.height() - 2,
1163 msgRect.width(), msgRect.height() );
1166 p.setPen( Qt::red );
1167 p.drawText( msgRect, Qt::AlignLeft, warningMsg );
1174 if ( textY < box.height() ) {
1175 Todo::List todos =
mCalendar->todos( qd );
1176 foreach (
const Todo::Ptr &todo, todos ) {
1177 if ( !todo->allDay() ) {
1178 if ( ( todo->hasDueDate() && todo->dtDue().toLocalZone().time() <= myFromTime ) ||
1179 ( todo->hasStartDate() && todo->dtStart().toLocalZone().time() > myToTime ) ) {
1183 if ( ( !printRecurDaily && todo->recurrenceType() == Recurrence::rDaily ) ||
1184 ( !printRecurWeekly && todo->recurrenceType() == Recurrence::rWeekly ) ) {
1187 if ( ( excludeConfidential && todo->secrecy() == Incidence::SecrecyConfidential ) ||
1188 ( excludePrivate && todo->secrecy() == Incidence::SecrecyPrivate ) ) {
1191 if ( todo->hasStartDate() && !todo->allDay() ) {
1192 timeText = KGlobal::locale()->formatTime( todo->dtStart().toLocalZone().time() ) + QLatin1Char(
' ');
1198 QString summaryStr = todo->summary();
1199 if ( !todo->location().isEmpty() ) {
1200 summaryStr = i18nc(
"summary, location",
1201 "%1, %2", summaryStr, todo->location() );
1205 if ( todo->hasDueDate() ) {
1206 if ( !todo->allDay() ) {
1207 str = i18nc(
"to-do summary (Due: datetime)",
"%1 (Due: %2)",
1209 KGlobal::locale()->formatDateTime( todo->dtDue().toLocalZone() ) );
1211 str = i18nc(
"to-do summary (Due: date)",
"%1 (Due: %2)",
1213 KGlobal::locale()->formatDate(
1214 todo->dtDue().toLocalZone().date(), KLocale::ShortDate ) );
1220 i18n(
"To-do: %1", str ), todo->description(),
1221 textY, singleLineLimit, includeDescription,
1222 todo->descriptionIsRich() );
1226 if ( showNoteLines ) {
1230 p.setFont( oldFont );
1234 const QString &time,
1235 const QString &summary,
1236 const QString &description,
1237 int &textY,
bool singleLineLimit,
1238 bool includeDescription,
1239 bool richDescription )
1241 kDebug() <<
"summary =" << summary <<
", singleLineLimit=" << singleLineLimit;
1243 int flags = Qt::AlignLeft | Qt::OpaqueMode;
1244 QFontMetrics fm = p.fontMetrics();
1246 QRect timeBound = p.boundingRect( dayBox.x() +
borderWidth,
1248 dayBox.width(), fm.lineSpacing(),
1251 int summaryWidth = time.isEmpty() ? 0 : timeBound.width() + 3;
1252 QRect summaryBound = QRect( dayBox.x() + borderWidth + summaryWidth,
1253 dayBox.y() + textY + 1,
1254 dayBox.width() - summaryWidth - ( borderWidth * 2 ),
1255 dayBox.height() - textY );
1257 QString summaryText = summary;
1259 bool boxOverflow =
false;
1261 if ( singleLineLimit ) {
1262 if ( includeDescription && !descText.isEmpty() ) {
1263 summaryText += QLatin1String(
", ") + descText;
1266 int textBoxHeight = ( totalHeight > ( dayBox.height() - textY ) ) ?
1267 dayBox.height() - textY :
1269 summaryBound.setHeight( textBoxHeight );
1270 QRect lineRect( dayBox.x() +
borderWidth, dayBox.y() + textY,
1271 dayBox.width() - ( borderWidth * 2 ), textBoxHeight );
1273 if ( !time.isEmpty() ) {
1274 p.drawText( timeBound, flags, time );
1276 p.drawText( summaryBound, flags, summaryText );
1278 QTextDocument textDoc;
1279 QTextCursor textCursor( &textDoc );
1280 if ( richDescription ) {
1281 QTextCursor textCursor( &textDoc );
1282 textCursor.insertText( summaryText );
1283 if ( includeDescription && !description.isEmpty() ) {
1284 textCursor.insertText( QLatin1String(
"\n") );
1285 textCursor.insertHtml( description );
1288 textCursor.insertText( summaryText );
1289 if ( includeDescription && !descText.isEmpty() ) {
1290 textCursor.insertText( QLatin1String(
"\n") );
1291 textCursor.insertText( descText );
1294 textDoc.setPageSize( QSize( summaryBound.width(), summaryBound.height() ) );
1296 QRect clipBox( 0, 0, summaryBound.width(), summaryBound.height() );
1297 p.setFont( p.font() );
1298 p.translate( summaryBound.x(), summaryBound.y() );
1299 summaryBound.setHeight( textDoc.documentLayout()->documentSize().height() );
1300 if ( summaryBound.bottom() > dayBox.bottom() ) {
1301 summaryBound.setBottom( dayBox.bottom() );
1303 clipBox.setHeight( summaryBound.height() );
1307 QRect backBox( timeBound.x(), timeBound.y(),
1308 dayBox.width() - ( borderWidth * 2 ), clipBox.height() );
1311 if ( !time.isEmpty() ) {
1312 if ( timeBound.bottom() > dayBox.bottom() ) {
1313 timeBound.setBottom( dayBox.bottom() );
1315 timeBound.moveTop ( timeBound.y() + ( summaryBound.height() - timeBound.height() ) / 2 );
1316 p.drawText( timeBound, flags, time );
1318 p.translate( summaryBound.x(), summaryBound.y() );
1319 textDoc.drawContents( &p, clipBox );
1321 boxOverflow = textDoc.pageCount() > 1;
1323 if ( summaryBound.bottom() < dayBox.bottom() ) {
1324 QPen oldPen( p.pen() );
1326 p.drawLine( dayBox.x(), summaryBound.bottom(),
1327 dayBox.x() + dayBox.width(), summaryBound.bottom() );
1330 textY += summaryBound.height();
1333 if ( boxOverflow ) {
1335 int x = dayBox.x() + dayBox.width();
1336 int y = dayBox.y() + dayBox.height();
1337 poly.setPoint( 0, x - 10, y );
1338 poly.setPoint( 1, x, y - 10 );
1339 poly.setPoint( 2, x, y );
1340 QBrush oldBrush( p.brush() );
1341 p.setBrush( QBrush( Qt::black ) );
1342 p.drawPolygon(poly);
1343 p.setBrush( oldBrush );
1344 textY = dayBox.height();
1349 const QTime &fromTime,
const QTime &toTime,
1351 bool singleLineLimit,
bool showNoteLines,
1352 bool includeDescription,
1353 bool excludeConfidential,
1354 bool excludePrivate )
1356 QDate weekDate = qd;
1357 const bool portrait = ( box.height() > box.width() );
1361 cellWidth = box.width() / 2;
1364 cellWidth = box.width() / 6;
1367 const int cellHeight = box.height() / vcells;
1371 weekDate = qd.addDays( -weekdayCol );
1373 for (
int i = 0; i < 7; ++i, weekDate = weekDate.addDays(1) ) {
1375 int hpos = ( ( i < 6 ) ? i : ( i - 1 ) ) / vcells;
1376 int vpos = ( ( i < 6 ) ? i : ( i - 1 ) ) % vcells;
1378 box.left() + cellWidth * hpos,
1379 box.top() + cellHeight * vpos + ( ( i == 6 ) ? ( cellHeight / 2 ) : 0 ),
1380 cellWidth, ( i < 5 ) ? ( cellHeight ) : ( cellHeight / 2 ) );
1381 drawDayBox( p, weekDate, fromTime, toTime, dayBox,
true,
true,
true,
1382 singleLineLimit, showNoteLines, includeDescription,
1383 excludeConfidential, excludePrivate );
1388 const QDate &start,
const QDate &end,
1389 const QTime &fromTime,
const QTime &toTime,
1391 bool singleLineLimit,
bool showNoteLines,
1392 bool includeDescription,
1393 bool excludeConfidential,
bool excludePrivate )
1395 const int numberOfDays = start.daysTo( end ) + 1;
1397 const bool portrait = ( box.height() > box.width() );
1401 vcells = qCeil( static_cast<double>( numberOfDays ) / 2.0 );
1402 if ( numberOfDays > 1 ) {
1403 cellWidth = box.width() / 2;
1405 cellWidth = box.width();
1410 cellWidth = box.width() / numberOfDays;
1412 const int cellHeight = box.height() / vcells;
1413 QDate weekDate = start;
1414 for (
int i = 0; i < numberOfDays; ++i, weekDate = weekDate.addDays(1) ) {
1415 const int hpos = i / vcells;
1416 const int vpos = i % vcells;
1418 box.left() + cellWidth * hpos,
1419 box.top() + cellHeight * vpos,
1420 cellWidth, cellHeight );
1421 drawDayBox( p, weekDate, fromTime, toTime, dayBox,
1422 true,
true,
true, singleLineLimit,
1423 showNoteLines, includeDescription, excludeConfidential,
1429 const QDate &fromDate,
1430 const QDate &toDate,
1432 const QTime &fromTime,
1433 const QTime &toTime,
1435 bool includeDescription,
1437 bool excludeConfidential,
1438 bool excludePrivate )
1440 QTime myFromTime = fromTime;
1441 QTime myToTime = toTime;
1443 QDate curDate( fromDate );
1444 KDateTime::Spec timeSpec = KSystemTimeZones::local();
1445 while ( curDate <= toDate ) {
1446 Event::List eventList =
mCalendar->events( curDate, timeSpec );
1447 Q_FOREACH (
const Event::Ptr &event, eventList ) {
1449 if ( event->allDay() ) {
1452 if ( event->dtStart().time() < myFromTime ) {
1453 myFromTime =
event->dtStart().time();
1455 if ( event->dtEnd().time() > myToTime ) {
1456 myToTime =
event->dtEnd().time();
1459 curDate = curDate.addDays(1);
1464 int alldayHeight = (int)( 3600. * box.height() / ( myFromTime.secsTo( myToTime ) + 3600. ) );
1467 QRect dowBox( box );
1468 dowBox.setLeft( box.left() + timelineWidth );
1473 tlBox.setWidth( timelineWidth );
1478 QDate curDate( fromDate );
1479 KDateTime::Spec timeSpec = KSystemTimeZones::local();
1481 double cellWidth = double( dowBox.width() ) /
double( fromDate.daysTo( toDate ) + 1 );
1483 while ( curDate <= toDate ) {
1484 QRect allDayBox( dowBox.left()+int( i * cellWidth ), dowBox.bottom() +
BOX_BORDER_WIDTH,
1485 int( ( i + 1 ) * cellWidth ) - int( i * cellWidth ), alldayHeight );
1486 QRect dayBox( allDayBox );
1487 dayBox.setTop( tlBox.top() );
1488 dayBox.setBottom( box.bottom() );
1489 KCalCore::Event::List eventList =
mCalendar->events( curDate, timeSpec,
1490 KCalCore::EventSortStartDate,
1491 KCalCore::SortDirectionAscending );
1493 alldayHeight =
drawAllDayBox( p, eventList, curDate,
false, allDayBox,
1494 excludeConfidential, excludePrivate );
1496 dayBox, includeDescription, excludeTime,
1497 excludeConfidential, excludePrivate, workDays );
1500 curDate = curDate.addDays(1);
1504 class MonthEventStruct
1507 MonthEventStruct() : event(0) {}
1508 MonthEventStruct(
const KDateTime &s,
const KDateTime &e,
const Event::Ptr &ev )
1513 if ( event->allDay() ) {
1514 start = KDateTime( start.date(), QTime( 0, 0, 0 ) );
1515 end = KDateTime( end.date().addDays(1), QTime( 0, 0, 0 ) ).addSecs(-1);
1518 bool operator < (
const MonthEventStruct &mes ) {
return start < mes.start; }
1525 const QRect &box,
int maxdays,
1526 int subDailyFlags,
int holidaysFlags )
1529 QRect subheaderBox( box );
1531 QRect borderBox( box );
1532 borderBox.setTop( subheaderBox.bottom() + 1 );
1536 QRect daysBox( borderBox );
1537 daysBox.adjust( correction, correction, -correction, -correction );
1539 int daysinmonth = calsys->daysInMonth( dt );
1540 if ( maxdays <= 0 ) {
1541 maxdays = daysinmonth;
1545 float dayheight = float( daysBox.height() ) /
float( maxdays );
1547 QColor holidayColor( 240, 240, 240 );
1548 QColor workdayColor( 255, 255, 255 );
1549 int dayNrWidth = p.fontMetrics().width( QLatin1String(
"99") );
1552 if ( daysinmonth<maxdays ) {
1553 QRect dayBox( box.left(), daysBox.top() + qRound( dayheight * daysinmonth ), box.width(), 0 );
1554 dayBox.setBottom( daysBox.bottom() );
1555 p.fillRect( dayBox, Qt::DiagCrossPattern );
1558 QBrush oldbrush( p.brush() );
1560 QList<QDate> workDays;
1565 calsys->setDate( startDate, dt.year(), dt.month(), 1 );
1566 calsys->setDate( endDate, dt.year(), dt.month(), daysinmonth );
1571 for ( d = 0; d < daysinmonth; ++d ) {
1573 calsys->setDate( day, dt.year(), dt.month(), d+1 );
1576 daysBox.top() + qRound( dayheight * d ), daysBox.width(), 0 );
1579 dayBox.setBottom( daysBox.top() + qRound( dayheight * ( d + 1 ) ) - 1 );
1581 p.setBrush( workDays.contains( day ) ? workdayColor : holidayColor );
1582 p.drawRect( dayBox );
1583 QRect dateBox( dayBox );
1584 dateBox.setWidth( dayNrWidth + 3 );
1585 p.drawText( dateBox,
1586 Qt::AlignRight | Qt::AlignVCenter | Qt::TextSingleLine,
1587 QString::number( d + 1 ) );
1589 p.setBrush( oldbrush );
1590 int xstartcont = box.left() + dayNrWidth + 5;
1593 calsys->setDate( start, dt.year(), dt.month(), 1 );
1594 end = calsys->addMonths( start, 1 );
1595 end = calsys->addDays( end, -1 );
1597 const Event::List events =
mCalendar->events( start, end );
1598 QMap<int, QStringList> textEvents;
1599 QList<EventViews::CellItem *> timeboxItems;
1608 QList<Event::Ptr> holidays;
1609 for ( QDate d( start ); d <= end; d = d.addDays(1) ) {
1612 holidays.append( e );
1614 timeboxItems.append(
new PrintCellItem( e, KDateTime( d, QTime( 0, 0, 0 ) ),
1615 KDateTime( d.addDays(1), QTime( 0, 0, 0 ) ) ) );
1617 if ( holidaysFlags &
Text ) {
1618 textEvents[d.day()] << e->summary();
1623 QList<MonthEventStruct> monthentries;
1625 KDateTime::Spec timeSpec = KSystemTimeZones::local();
1626 Q_FOREACH (
const Event::Ptr &e, events ) {
1630 if ( e->recurs() ) {
1631 if ( e->recursOn( start, timeSpec ) ) {
1634 QList<KDateTime> starttimes = e->startDateTimesForDate( start );
1635 QList<KDateTime>::ConstIterator it = starttimes.constBegin();
1636 for ( ; it != starttimes.constEnd(); ++it ) {
1637 monthentries.append( MonthEventStruct( *it, e->endDateForStart( *it ), e ) );
1644 Recurrence *recur = e->recurrence();
1645 QDate d1( start.addDays(1) );
1646 while ( d1 <= end ) {
1647 if ( recur->recursOn( d1, timeSpec ) ) {
1648 TimeList times( recur->recurTimesOn( d1, timeSpec ) );
1649 for ( TimeList::ConstIterator it = times.constBegin();
1650 it != times.constEnd(); ++it ) {
1651 KDateTime d1start( d1, *it, timeSpec );
1652 monthentries.append( MonthEventStruct( d1start, e->endDateForStart( d1start ), e ) );
1658 monthentries.append( MonthEventStruct( e->dtStart(), e->dtEnd(), e ) );
1666 QList<MonthEventStruct>::ConstIterator mit = monthentries.constBegin();
1667 KDateTime endofmonth( end, QTime( 0, 0, 0 ) );
1668 endofmonth = endofmonth.addDays(1);
1669 for ( ; mit != monthentries.constEnd(); ++mit ) {
1670 if ( (*mit).start.date() == (*mit).end.date() ) {
1673 timeboxItems.append(
1674 new PrintCellItem( (*mit).event, (*mit).start, (*mit).end ) );
1677 if ( subDailyFlags &
Text ) {
1678 textEvents[(*mit).start.date().day()] << (*mit).event->summary();
1682 KDateTime thisstart( (*mit).start );
1683 KDateTime thisend( (*mit).end );
1684 if ( thisstart.date() < start ) {
1685 thisstart.setDate( start );
1687 if ( thisend > endofmonth ) {
1688 thisend = endofmonth;
1690 timeboxItems.append(
1691 new PrintCellItem( (*mit).event, thisstart, thisend ) );
1696 QListIterator<EventViews::CellItem *> it1( timeboxItems );
1697 while ( it1.hasNext() ) {
1698 EventViews::CellItem *placeItem = it1.next();
1699 EventViews::CellItem::placeItem( timeboxItems, placeItem );
1701 KDateTime starttime( start, QTime( 0, 0, 0 ) );
1702 int newxstartcont = xstartcont;
1704 QFont oldfont( p.font() );
1705 p.setFont( QFont( QLatin1String(
"sans-serif"), 7 ) );
1706 while ( it1.hasNext() ) {
1707 PrintCellItem *placeItem =
static_cast<PrintCellItem *
>( it1.next() );
1708 int minsToStart = starttime.secsTo( placeItem->start() ) / 60;
1709 int minsToEnd = starttime.secsTo( placeItem->end() ) / 60;
1712 xstartcont + placeItem->subCell() * 17,
1713 daysBox.top() + qRound(
1714 double( minsToStart * daysBox.height() ) /
double( maxdays * 24 * 60 ) ), 14, 0 );
1716 daysBox.top() + qRound(
1717 double( minsToEnd * daysBox.height() ) /
double( maxdays * 24 * 60 ) ) );
1719 newxstartcont = qMax( newxstartcont, eventBox.right() );
1721 xstartcont = newxstartcont;
1725 for (
int d=0; d<daysinmonth; ++d ) {
1726 QStringList dayEvents( textEvents[d+1] );
1727 QString txt = dayEvents.join( QLatin1String(
", ") );
1728 QRect dayBox( xstartcont, daysBox.top() + qRound( dayheight * d ), 0, 0 );
1729 dayBox.setRight( box.right() );
1730 dayBox.setBottom( daysBox.top() + qRound( dayheight * ( d + 1 ) ) );
1731 printEventString( p, dayBox, txt, Qt::AlignTop | Qt::AlignLeft | Qt::TextWrapAnywhere );
1733 p.setFont( oldfont );
1739 const QTime &fromTime,
const QTime &toTime,
1740 bool weeknumbers,
bool recurDaily,
1741 bool recurWeekly,
bool singleLineLimit,
1743 bool includeDescription,
1744 bool excludeConfidential,
1745 bool excludePrivate,
1750 QDate monthDate( QDate( qd.year(), qd.month(), 1 ) );
1751 QDate monthFirst( monthDate );
1752 QDate monthLast( monthDate.addMonths(1).addDays(-1) );
1755 monthDate = monthDate.addDays(-weekdayCol);
1761 int rows = ( weekdayCol + qd.daysInMonth() - 1 ) / 7 + 1;
1762 double cellHeight = ( box.height() - yoffset ) / ( 1. * rows );
1763 double cellWidth = ( box.width() - xoffset ) / 7.;
1767 int coledges[8], rowedges[8];
1768 for (
int i = 0; i <= 7; ++i ) {
1769 rowedges[i] = int( box.top() + yoffset + i * cellHeight );
1770 coledges[i] = int( box.left() + xoffset + i * cellWidth );
1773 if ( weeknumbers ) {
1774 QFont oldFont( p.font() );
1775 QFont newFont( p.font() );
1776 newFont.setPointSize( 6 );
1777 p.setFont( newFont );
1778 QDate weekDate( monthDate );
1779 for (
int row = 0; row<rows; ++row ) {
1780 int calWeek = weekDate.weekNumber();
1781 QRect rc( box.left(), rowedges[row],
1782 coledges[0] - 3 - box.left(), rowedges[row + 1] - rowedges[row] );
1783 p.drawText( rc, Qt::AlignRight | Qt::AlignVCenter, QString::number( calWeek ) );
1784 weekDate = weekDate.addDays( 7 );
1786 p.setFont( oldFont );
1789 QRect daysOfWeekBox( box );
1791 daysOfWeekBox.setLeft( box.left() + xoffset );
1792 drawDaysOfWeek( p, monthDate, monthDate.addDays( 6 ), daysOfWeekBox );
1794 QColor back = p.background().color();
1795 bool darkbg =
false;
1796 for (
int row = 0; row < rows; ++row ) {
1797 for (
int col = 0; col < 7; ++col ) {
1799 if ( ( monthDate < monthFirst ) || ( monthDate > monthLast ) ) {
1800 p.setBackground( back.darker( 120 ) );
1803 QRect dayBox( coledges[col], rowedges[row],
1804 coledges[col + 1] - coledges[col], rowedges[row + 1] - rowedges[row] );
1805 drawDayBox( p, monthDate, fromTime, toTime, dayBox,
false,
1806 recurDaily, recurWeekly, singleLineLimit, showNoteLines,
1807 includeDescription, excludeConfidential, excludePrivate );
1809 p.setBackground( back );
1812 monthDate = monthDate.addDays(1);
1818 const QString &entry,
1819 int x,
int &y,
int width,
1820 int pageHeight,
bool richTextEntry,
1821 QList<TodoParentStart *> &startPoints,
1822 bool connectSubTodos )
1824 QString plainEntry = ( richTextEntry ) ?
toPlainText( entry ) : entry;
1826 QRect textrect( 0, 0, width, -1 );
1827 int flags = Qt::AlignLeft;
1828 QFontMetrics fm = p.fontMetrics();
1830 QStringList lines = plainEntry.split( QLatin1Char(
'\n' ) );
1831 for (
int currentLine = 0; currentLine < lines.count(); currentLine++ ) {
1833 KWordWrap *ww = KWordWrap::formatText( fm, textrect, flags, lines[currentLine] );
1834 QStringList textLine = ww->wrappedString().split( QLatin1Char(
'\n' ) );
1838 for (
int lineCount = 0; lineCount < textLine.count(); lineCount++ ) {
1839 if ( y >= pageHeight ) {
1840 if ( connectSubTodos ) {
1841 for (
int i = 0; i < startPoints.size(); ++i ) {
1842 TodoParentStart *rct;
1843 rct = startPoints.at( i );
1844 int start = rct->mRect.bottom() + 1;
1845 int center = rct->mRect.left() + ( rct->mRect.width() / 2 );
1847 if ( !rct->mSamePage ) {
1850 if ( rct->mHasLine ) {
1851 p.drawLine( center, start, center, to );
1853 rct->mSamePage =
false;
1860 p.drawText( x, y, textLine[lineCount] );
1866 KCalCore::TodoSortField sortField,
1867 KCalCore::SortDirection sortDir,
1868 bool connectSubTodos,
bool strikeoutCompleted,
1869 bool desc,
int posPriority,
int posSummary,
1870 int posDueDt,
int posPercentComplete,
1871 int level,
int x,
int &y,
int width,
1872 int pageHeight,
const KCalCore::Todo::List &todoList,
1873 TodoParentStart *r,
bool excludeConfidential,
1874 bool excludePrivate )
1877 const KLocale *local = KGlobal::locale();
1879 TodoParentStart startpt;
1882 static QList<TodoParentStart *> startPoints;
1884 startPoints.clear();
1890 int rhs = posPercentComplete;
1898 int left = posSummary + ( level * 10 );
1902 bool showPriority = posPriority >= 0;
1903 int lhs = posPriority;
1905 lhs = r->mRect.right() + 1;
1908 outStr.setNum( todo->priority() );
1909 rect = p.boundingRect( lhs, y + 10, 5, -1, Qt::AlignCenter, outStr );
1911 rect.setWidth( 18 );
1912 rect.setHeight( 18 );
1915 p.setBrush( QBrush( Qt::NoBrush ) );
1917 if ( todo->isCompleted() ) {
1919 p.drawLine( rect.topLeft(), rect.bottomRight() );
1920 p.drawLine( rect.topRight(), rect.bottomLeft() );
1922 lhs = rect.right() + 3;
1925 if ( todo->priority() > 0 && showPriority ) {
1926 p.drawText( rect, Qt::AlignCenter, outStr );
1928 startpt.mRect = rect;
1931 if ( r && level > 0 && connectSubTodos ) {
1933 int center( r->mRect.left() + ( r->mRect.width() / 2 ) );
1934 int to( rect.top() + ( rect.height() / 2 ) );
1935 int endx( rect.left() );
1936 p.drawLine( center, to, endx, to );
1937 if ( r->mSamePage ) {
1938 bottom = r->mRect.bottom() + 1;
1942 p.drawLine( center, bottom, center, to );
1946 outStr = todo->summary();
1947 rect = p.boundingRect( lhs, rect.top(), ( rhs - ( left + rect.width() + 5 ) ),
1948 -1, Qt::TextWordWrap, outStr );
1951 QFont newFont( p.font() );
1952 QFont oldFont( p.font() );
1953 if ( todo->isCompleted() && strikeoutCompleted ) {
1954 newFont.setStrikeOut(
true );
1955 p.setFont( newFont );
1957 p.drawText( rect, Qt::TextWordWrap, outStr, &newrect );
1958 p.setFont( oldFont );
1960 if ( todo->hasDueDate() && posDueDt >= 0 ) {
1961 outStr = local->formatDate( todo->dtDue().toLocalZone().date(), KLocale::ShortDate );
1962 rect = p.boundingRect( posDueDt, y, x + width, -1,
1963 Qt::AlignTop | Qt::AlignLeft, outStr );
1964 p.drawText( rect, Qt::AlignTop | Qt::AlignLeft, outStr );
1968 bool showPercentComplete = posPercentComplete >= 0;
1969 if ( showPercentComplete ) {
1973 int progress = (int)( ( lwidth * todo->percentComplete() ) / 100.0 + 0.5 );
1975 p.setBrush( QBrush( Qt::NoBrush ) );
1976 p.drawRect( posPercentComplete, y+3, lwidth, lheight );
1977 if ( progress > 0 ) {
1978 p.setBrush( QColor( 128, 128, 128 ) );
1979 p.drawRect( posPercentComplete, y+3, progress, lheight );
1983 outStr = i18n(
"%1%", todo->percentComplete() );
1984 rect = p.boundingRect( posPercentComplete+lwidth+3, y, x + width, -1,
1985 Qt::AlignTop | Qt::AlignLeft, outStr );
1986 p.drawText( rect, Qt::AlignTop | Qt::AlignLeft, outStr );
1993 Incidence::List relations =
mCalendar->childIncidences( todo->uid() );
1995 foreach (
const Incidence::Ptr &incidence, relations ) {
2000 Todo::Ptr subtodo = incidence.dynamicCast<KCalCore::Todo>();
2001 if ( !subtodo )
continue;
2002 #ifdef AKONADI_PORT_DISABLED
2003 if ( subtodo && todoList.contains( subtodo ) ) {
2005 bool subtodoOk =
false;
2007 foreach (
const KCalCore::Todo::Ptr &tt, todoList ) {
2008 if ( tt == subtodo ) {
2016 if ( ( excludeConfidential &&
2017 subtodo->secrecy() == Incidence::SecrecyConfidential ) ||
2019 subtodo->secrecy() == Incidence::SecrecyPrivate ) ) {
2022 t.append( subtodo );
2027 startpt.mHasLine = ( relations.size() > 0 );
2028 startPoints.append( &startpt );
2031 if ( !todo->description().isEmpty() && desc ) {
2032 y = newrect.bottom() + 5;
2034 width - ( left + 10 - x ), pageHeight,
2035 todo->descriptionIsRich(),
2036 startPoints, connectSubTodos );
2042 #ifdef AKONADI_PORT_DISABLED
2043 KCalCore::Todo::List sl =
mCalendar->sortTodos( &t, sortField, sortDir );
2045 KCalCore::Todo::List tl;
2046 foreach (
const Todo::Ptr &todo, t ) {
2049 KCalCore::Todo::List sl =
mCalendar->sortTodos( tl, sortField, sortDir );
2053 foreach (
const Todo::Ptr &isl, sl ) {
2055 if ( ++subcount == sl.size() ) {
2056 startpt.mHasLine =
false;
2058 drawTodo( count, isl, p, sortField, sortDir,
2059 connectSubTodos, strikeoutCompleted,
2060 desc, posPriority, posSummary, posDueDt, posPercentComplete,
2061 level+1, x, y, width, pageHeight, todoList, &startpt,
2062 excludeConfidential, excludePrivate );
2064 startPoints.removeAll( &startpt );
2069 int w = weekday + 7 - KGlobal::locale()->weekStartDay();
2074 int x,
int &y,
int width,
2075 int pageHeight,
bool richTextEntry )
2077 QString plainEntry = ( richTextEntry ) ?
toPlainText( entry ) : entry;
2079 QRect textrect( 0, 0, width, -1 );
2080 int flags = Qt::AlignLeft;
2081 QFontMetrics fm = p.fontMetrics();
2083 QStringList lines = plainEntry.split( QLatin1Char(
'\n' ) );
2084 for (
int currentLine = 0; currentLine < lines.count(); currentLine++ ) {
2086 KWordWrap *ww = KWordWrap::formatText( fm, textrect, flags, lines[currentLine] );
2087 QStringList textLine = ww->wrappedString().split( QLatin1Char(
'\n' ) );
2090 for (
int lineCount = 0; lineCount < textLine.count(); lineCount++ ) {
2091 if ( y >= pageHeight ) {
2096 p.drawText( x, y, textLine[lineCount] );
2102 int x,
int &y,
int width,
int pageHeight )
2104 QFont oldFont( p.font() );
2105 p.setFont( QFont( QLatin1String(
"sans-serif"), 15 ) );
2107 QString dateText( KGlobal::locale()->formatDate( journal->dtStart().toLocalZone().date(),
2108 KLocale::LongDate ) );
2110 if ( journal->summary().isEmpty() ) {
2111 headerText = dateText;
2113 headerText = i18nc(
"Description - date",
"%1 - %2", journal->summary(), dateText );
2116 QRect rect( p.boundingRect( x, y, width, -1, Qt::TextWordWrap, headerText ) );
2117 if ( rect.bottom() > pageHeight ) {
2121 rect = p.boundingRect( x, y, width, -1, Qt::TextWordWrap, headerText );
2124 p.drawText( rect, Qt::TextWordWrap, headerText, &newrect );
2125 p.setFont( oldFont );
2127 y = newrect.bottom() + 4;
2129 p.drawLine( x + 3, y, x + width - 6, y );
2131 if ( !( journal->organizer()->fullName().isEmpty() ) ) {
2132 drawTextLines( p, i18n(
"Person: %1", journal->organizer()->fullName() ),
2133 x, y, width, pageHeight,
false );
2136 if ( !( journal->description().isEmpty() ) ) {
2137 drawTextLines( p, journal->description(), x, y, width, pageHeight,
2138 journal->descriptionIsRich() );
2145 const QDate &td,
const QDate &,
2146 int width,
int height )
2148 QFont oldFont( p.font() );
2150 QPen oldPen( p.pen() );
2151 QPen pen( Qt::black, 4 );
2155 if ( fd.month() == td.month() ) {
2156 title = i18nc(
"Date range: Month dayStart - dayEnd",
"%1 %2 - %3",
2157 mCalSys->monthName( fd.month(), KCalendarSystem::LongName ),
2158 mCalSys->formatDate( fd, KLocale::Day, KLocale::LongNumber ),
2159 mCalSys->formatDate( td, KLocale::Day, KLocale::LongNumber ) );
2161 title = i18nc(
"Date range: monthStart dayStart - monthEnd dayEnd",
"%1 %2 - %3 %4",
2162 mCalSys->monthName( fd.month(), KCalendarSystem::LongName ),
2163 mCalSys->formatDate( fd, KLocale::Day, KLocale::LongNumber ),
2164 mCalSys->monthName( td.month(), KCalendarSystem::LongName ),
2165 mCalSys->formatDate( td, KLocale::Day, KLocale::LongNumber ) );
2169 if ( height < 60 ) {
2170 p.setFont( QFont( QLatin1String(
"Times"), 22 ) );
2172 p.setFont( QFont( QLatin1String(
"Times"), 28 ) );
2175 int lineSpacing = p.fontMetrics().lineSpacing();
2176 p.drawText( 0, 0, width, lineSpacing,
2177 Qt::AlignRight | Qt::AlignTop, title );
2182 p.drawLine( 300, lineSpacing, width, lineSpacing );
2185 if ( height < 60 ) {
2186 p.setFont( QFont( QLatin1String(
"Times"), 14, QFont::Bold,
true ) );
2188 p.setFont( QFont( QLatin1String(
"Times"), 18, QFont::Bold,
true ) );
2191 title += QString::number( fd.year() );
2192 p.drawText( 0, lineSpacing, width, lineSpacing,
2193 Qt::AlignRight | Qt::AlignTop, title );
2195 p.setFont( oldFont );
2200 int lineHeight = int( p.fontMetrics().lineSpacing() * 1.5 );
2201 int linePos = box.y();
2202 int startPos = startY;
2204 while ( linePos < startPos ) {
2205 linePos += lineHeight;
2207 QPen oldPen( p.pen() );
2208 p.setPen( Qt::DotLine );
2209 while ( linePos < box.bottom() ) {
2210 p.drawLine( box.left() +
padding(), linePos,
2211 box.right() -
padding(), linePos );
2212 linePos += lineHeight;
2220 return QTextDocumentFragment::fromHtml( htmlText ).toPlainText();
virtual void doPrint(QPrinter *printer)
Start printing.
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.
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.
Event::Ptr holiday(const QDate &dt)
QPrinter::Orientation orientation() const
void setPrintFooter(bool printFooter)
virtual QString description()=0
Returns short description of print format.
QPrinter * mPrinter
The printer object.
void setFooterHeight(const int height)
void drawJournal(const Journal::Ptr &journal, QPainter &p, int x, int &y, int width, int pageHeight)
Draws single journal item.
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)...
QString toPlainText(const QString &htmlText)
KOrg::CoreHelper * mCoreHelper
void showEventBox(QPainter &p, int linewidth, const QRect &box, const Incidence::Ptr &incidence, const QString &str, int flags=-1)
Print the box for the given event with the given string.
QColor categoryBgColor(const Incidence::Ptr &incidence)
Helper functions to hide the KOrg::CoreHelper.
void drawSubHeaderBox(QPainter &p, const QString &str, const QRect &box)
Draw a subheader box with a shaded background and the given string.
#define EVENT_BORDER_WIDTH
static int weekdayColumn(int weekday)
Determines the column of the given weekday ( 1=Monday, 7=Sunday ), taking the start of the week setti...
virtual QString holidayString(const QDate &dt)=0
void drawSplitHeaderRight(QPainter &p, const QDate &fd, const QDate &td, const QDate &cd, int width, int height)
virtual ~CalPrintPluginBase()
#define LANDSCAPE_HEADER_HEIGHT
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...
void setCategoryColors(QPainter &p, const Incidence::Ptr &incidence)
#define PORTRAIT_HEADER_HEIGHT
void drawNoteLines(QPainter &p, const QRect &box, int startY)
Draws dotted lines for notes in a box.
const KCalendarSystem * mCalSys
bool mExcludeConfidential
int headerHeight() const
Returns the height of the page header.
void setPadding(const int margin)
static void drawBox(QPainter &p, int linewidth, const QRect &rect)
Draw a box with given width at the given coordinates.
void drawAgendaItem(PrintCellItem *item, QPainter &p, const KDateTime &startPrintDate, const KDateTime &endPrintDate, float minlen, const QRect &box, bool includeDescription, bool excludeTime)
void drawIncidence(QPainter &p, const QRect &dayBox, const QString &time, const QString &summary, const QString &description, int &textY, bool singleLineLimit, bool includeDescription, bool richDescription)
void drawTodoLines(QPainter &p, const QString &entry, int x, int &y, int width, int pageHeight, bool richTextEntry, QList< TodoParentStart * > &startPoints, bool connectSubTodos)
static QString cleanStr(const QString &instr)
static void drawShadedBox(QPainter &p, int linewidth, const QBrush &brush, const QRect &rect)
Draw a shaded box with given width at the given coordinates.
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.
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.
virtual QColor categoryColor(const QStringList &cats)=0
void setHeaderHeight(const int height)
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).
void drawSmallMonth(QPainter &p, const QDate &qd, const QRect &box)
Draw a small calendar with the days of a month into the given area.
void doLoadConfig()
Load complete config.
void setSubHeaderHeight(const int height)
KORGANIZERPRIVATE_EXPORT QColor getTextColor(const QColor &c)
Returns a nice QColor for text, give the input color &c.
int subHeaderHeight() const
virtual QTime dayStart()=0
static KOGlobals * self()
void doSaveConfig()
Save complete config.
QString holidayString(const QDate &dt)
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.
QList< QDate > workDays(const QDate &start, const QDate &end) const
Returns a list containing work days between start and .
const KCalendarSystem * calendarSystem() const
void drawTextLines(QPainter &p, const QString &entry, int x, int &y, int width, int pageHeight, bool richTextEntry)
Draws text lines splitting on page boundaries.
virtual void loadConfig()=0
Load print format configuration from config file.
void setCalendarSystem(const KCalendarSystem *calsys)
virtual void print(QPainter &p, int width, int height)=0
Actually do the printing.
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...
void setBorderWidth(const int border)
int drawFooter(QPainter &p, const QRect &box)
Draw a page footer containing the printing date and possibly other things, like a page number...
int footerHeight() const
Returns the height of the page footer.
virtual QWidget * createConfigWidget(QWidget *)
Returns widget for configuring the print format.
void setMargin(const int margin)
virtual QString info() const =0
Returns long description of print format.
#define LANDSCAPE_FOOTER_HEIGHT
QColor todoOverdueColor() const
Get To-do overdue color.
void printEventString(QPainter &p, const QRect &box, const QString &str, int flags=-1)
Print the given string (event summary) in the given rectangle.
static KOPrefs * instance()
Get instance of KOPrefs.
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.
void drawAgendaDayBox(QPainter &p, const KCalCore::Event::List &eventList, const QDate &qd, bool expandable, const QTime &fromTime, const QTime &toTime, const QRect &box, bool includeDescription, bool excludeTime, bool mExcludeConfidential, bool mExcludePrivate, const QList< QDate > &workDays)
Draw the agenda box for the day print style (the box showing all events of that day).
int drawAllDayBox(QPainter &p, const KCalCore::Event::List &eventList, const QDate &qd, bool expandable, const QRect &box, bool mExcludeConfidential, bool mExcludePrivate)
Draw the all-day box for the agenda print view (the box on top which doesn't have a time on the time ...
void drawMonth(QPainter &p, const QDate &dt, const QRect &box, int maxdays=-1, int subDailyFlags=TimeBoxes, int holidaysFlags=Text)
Draw a vertical representation of the month containing the date dt.
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...
void setUseColors(bool useColors)
Akonadi::ETMCalendar::Ptr mCalendar
void drawVerticalBox(QPainter &p, int linewidth, const QRect &box, const QString &str, int flags=-1)
Draw an event box with vertical text.
virtual void saveConfig()=0
Write print format configuration to config file.
CalPrintPluginBase()
Constructor.
virtual QString groupName()=0
Returns KConfig group name where store settings.
#define PORTRAIT_FOOTER_HEIGHT
void setKOrgCoreHelper(KOrg::CoreHelper *helper)
HELPER FUNCTIONS.
virtual const KCalendarSystem * calendarSystem()=0