12#include "calprintdefaultplugins.h"
18#include <Akonadi/CalendarUtils>
19#include <Akonadi/Item>
21#include <KCalendarCore/Visitor>
23#include <KCalUtils/IncidenceFormatter>
24#include <KCalUtils/Stringify>
26#include <KConfigGroup>
30using namespace CalendarSupport;
36CalPrintIncidence::CalPrintIncidence()
41CalPrintIncidence::~CalPrintIncidence() =
default;
45 return new CalPrintIncidenceConfig(w);
48void CalPrintIncidence::readSettingsWidget()
50 auto cfg =
dynamic_cast<CalPrintIncidenceConfig *
>((
QWidget *)mConfigWidget);
54 mShowOptions = cfg->mShowDetails->isChecked();
55 mShowSubitemsNotes = cfg->mShowSubitemsNotes->isChecked();
56 mShowAttendees = cfg->mShowAttendees->isChecked();
57 mShowAttachments = cfg->mShowAttachments->isChecked();
62void CalPrintIncidence::setSettingsWidget()
64 auto cfg =
dynamic_cast<CalPrintIncidenceConfig *
>((
QWidget *)mConfigWidget);
68 cfg->mShowDetails->setChecked(mShowOptions);
69 cfg->mShowSubitemsNotes->setChecked(mShowSubitemsNotes);
70 cfg->mShowAttendees->setChecked(mShowAttendees);
71 cfg->mShowAttachments->setChecked(mShowAttachments);
76void CalPrintIncidence::doLoadConfig()
81 mShowOptions = grp.readEntry(
"Show Options",
false);
82 mShowSubitemsNotes = grp.readEntry(
"Show Subitems and Notes",
false);
83 mShowAttendees = grp.readEntry(
"Use Attendees",
false);
84 mShowAttachments = grp.readEntry(
"Use Attachments",
false);
89void CalPrintIncidence::doSaveConfig()
94 grp.writeEntry(
"Show Options", mShowOptions);
95 grp.writeEntry(
"Show Subitems and Notes", mShowSubitemsNotes);
96 grp.writeEntry(
"Use Attendees", mShowAttendees);
97 grp.writeEntry(
"Use Attachments", mShowAttachments);
105 TimePrintStringsVisitor() =
default;
109 return incidence->accept(*
this, incidence);
112 QString mStartCaption, mStartString;
113 QString mEndCaption, mEndString;
114 QString mDurationCaption, mDurationString;
119 if (
event->dtStart().isValid()) {
120 mStartCaption =
i18n(
"Start date: ");
123 mStartCaption =
i18n(
"No start date");
124 mStartString.
clear();
127 if (
event->hasEndDate()) {
128 mEndCaption =
i18n(
"End date: ");
130 }
else if (
event->hasDuration()) {
131 mEndCaption =
i18n(
"Duration: ");
132 int mins =
event->duration().asSeconds() / 60;
134 mEndString +=
i18np(
"1 hour ",
"%1 hours ", mins / 60);
137 mEndString +=
i18np(
"1 minute ",
"%1 minutes ", mins % 60);
140 mEndCaption =
i18n(
"No end date");
148 if (
todo->hasStartDate()) {
149 mStartCaption =
i18n(
"Start date: ");
152 mStartCaption =
i18n(
"No start date");
153 mStartString.
clear();
156 if (
todo->hasDueDate()) {
157 mEndCaption =
i18n(
"Due date: ");
160 mEndCaption =
i18n(
"No due date");
168 mStartCaption =
i18n(
"Start date: ");
185 int textWd = captionFM.horizontalAdvance(caption);
193 textRect.setLeft(textRect.left() + textWd);
198 return textRect.bottom();
201void CalPrintIncidence::print(
QPainter &p,
int width,
int height)
212 for (it = mSelectedIncidences.
constBegin(); it != mSelectedIncidences.
constEnd(); ++it) {
253 QRect box(0, 0, width, height);
258 int titleBottom =
drawHeader(p, (*it)->summary(),
QDate(),
QDate(), titleBox,
true, headerColor);
259 titleBox.setBottom(titleBottom);
261 QRect timesBox(titleBox);
262 timesBox.setTop(titleBox.bottom() + padding());
263 timesBox.setHeight(height / 8);
265 TimePrintStringsVisitor stringVis;
266 int h = timesBox.top();
267 if (stringVis.act(*it)) {
268 QRect textRect(timesBox.left() + padding(), timesBox.top() + padding(), 0, lineHeight);
269 textRect.setRight(timesBox.center().x());
270 h = printCaptionAndText(p, textRect, stringVis.mStartCaption, stringVis.mStartString, captionFont, textFont);
272 textRect.setLeft(textRect.right());
273 textRect.setRight(timesBox.right() - padding());
274 h = qMax(printCaptionAndText(p, textRect, stringVis.mEndCaption, stringVis.mEndString, captionFont, textFont), h);
278 if ((*it)->recurs()) {
279 QRect recurBox(timesBox.left() + padding(), h + padding(), timesBox.right() - padding(), lineHeight);
284 if (!recurs->exDates().isEmpty()) {
285 exceptString =
i18nc(
"except for listed dates",
" except");
286 for (
int i = 0; i < recurs->exDates().size(); ++i) {
291 displayString.
append(exceptString);
292 h = qMax(printCaptionAndText(p, recurBox,
i18n(
"Repeats: "), displayString, captionFont, textFont), h);
297 QRect alarmBox(timesBox.left() + padding(), h + padding(), timesBox.right() - padding(), lineHeight);
300 cap =
i18n(
"No reminders");
303 cap =
i18np(
"Reminder: ",
"%1 reminders: ", alarms.
count());
314 if (alarm->hasStartOffset()) {
315 offset = alarm->startOffset().asSeconds();
317 offsetstr =
ki18nc(
"N days/hours/minutes before/after the start/end",
"%1 before the start");
320 offsetstr =
ki18nc(
"N days/hours/minutes before/after the start/end",
"%1 after the start");
322 }
else if (alarm->hasEndOffset()) {
323 offset = alarm->endOffset().asSeconds();
325 offsetstr =
ki18nc(
"N days/hours/minutes before/after the start/end",
"%1 before the end");
328 offsetstr =
ki18nc(
"N days/hours/minutes before/after the start/end",
"%1 after the end");
332 offset = offset / 60;
335 if (offset % (24 * 60) == 0 && offset > 0) {
336 useoffset = offset / (24 * 60);
337 offsetstr = offsetstr.
subs(
i18np(
"1 day",
"%1 days", useoffset));
338 }
else if (offset % 60 == 0 && offset > 0) {
339 useoffset = offset / 60;
340 offsetstr = offsetstr.
subs(
i18np(
"1 hour",
"%1 hours", useoffset));
343 offsetstr = offsetstr.
subs(
i18np(
"1 minute",
"%1 minutes", useoffset));
345 alarmStrings << offsetstr.
toString();
347 txt = alarmStrings.
join(
i18nc(
"Spacer for the joined list of categories/tags",
", "));
349 h = qMax(printCaptionAndText(p, alarmBox, cap, txt, captionFont, textFont), h);
351 QRect organizerBox(timesBox.left() + padding(), h + padding(), timesBox.right() - padding(), lineHeight);
352 h = qMax(printCaptionAndText(p, organizerBox,
i18n(
"Organizer: "), (*it)->organizer().fullName(), captionFont, textFont), h);
355 timesBox.setBottom(qMax(timesBox.bottom(), h + padding()));
356 drawBox(p, BOX_BORDER_WIDTH, timesBox);
358 QRect locationBox(timesBox);
359 locationBox.setTop(timesBox.bottom() + padding());
360 locationBox.setHeight(0);
361 int locationBottom = 0;
372 locationBox.setBottom(locationBottom);
375 QRect footerBox(locationBox);
376 footerBox.setBottom(box.
bottom());
377 footerBox.setTop(footerBox.bottom() - lineHeight - 2 * padding());
379 QRect categoriesBox(footerBox);
380 categoriesBox.setBottom(footerBox.top());
381 categoriesBox.setTop(categoriesBox.bottom() - lineHeight - 2 * padding());
383 QRect attachmentsBox(box.
left(), attendeesBox.top() - padding() - box.
height() / 9, box.
width() * 3 / 4 - padding(), box.
height() / 9);
384 QRect optionsBox(isJournal ? box.
left() : attachmentsBox.right() + padding(), attachmentsBox.top(), 0, 0);
385 optionsBox.setRight(box.
right());
386 optionsBox.setBottom(attachmentsBox.bottom());
387 QRect notesBox(optionsBox.left(), isJournal ? (timesBox.bottom() + padding()) : (locationBox.bottom() + padding()), optionsBox.width(), 0);
388 notesBox.setBottom(optionsBox.top() - padding());
389 QRect descriptionBox(notesBox);
390 descriptionBox.setLeft(box.
left());
391 descriptionBox.setRight(attachmentsBox.right());
394 if (!mShowSubitemsNotes || isJournal) {
395 descriptionBox.setRight(box.
right());
397 if (!mShowAttachments || !mShowAttendees) {
398 descriptionBox.setBottom(attachmentsBox.bottom());
399 optionsBox.setTop(attendeesBox.top());
400 optionsBox.setBottom(attendeesBox.bottom());
401 notesBox.setBottom(attachmentsBox.bottom());
403 attendeesBox.setRight(attachmentsBox.right());
405 if (!mShowAttachments && !mShowAttendees) {
406 if (mShowSubitemsNotes) {
407 descriptionBox.setBottom(attendeesBox.bottom());
410 descriptionBox.setBottom(attendeesBox.bottom());
411 notesBox.setBottom(attendeesBox.bottom());
415 if (mShowAttachments && !isJournal) {
417 attachmentsBox.setRight(box.
right());
418 attachmentsBox.setRight(box.
right());
420 if (!mShowAttendees) {
421 attachmentsBox.setTop(attendeesBox.top());
422 attachmentsBox.setBottom(attendeesBox.bottom());
427 i18n(
"Description:"),
428 (*it)->description(),
433 (*it)->descriptionIsRich());
438 if (mShowSubitemsNotes && !isJournal) {
440 for (
const auto &incidence : mCalendar->incidences()) {
445 if (
todo->relatedTo() != (*it)->uid()) {
466 subitemCaption =
i18n(
"No Subitems");
469 subitemCaption =
i18np(
"1 Subitem:",
"%1 Subitems:", relations.
count());
476 for (
const auto &todo : std::as_const(relations)) {
482 statusString = KCalUtils::Stringify::incidenceStatus(
todo->status());
485 statusString =
i18nc(
"no status",
"none");
487 statusString =
i18nc(
"unknown status",
"unknown");
492 if (
todo->dtStart().isValid()) {
495 if (!
todo->allDay()) {
502 i18nc(
"subitem due date",
506 if (!
todo->allDay()) {
508 i18nc(
"subitem due time",
513 subitemString +=
i18nc(
"subitem counter",
"%1: ", count);
514 subitemString +=
todo->summary();
517 subitemString += datesString;
520 subitemString +=
i18nc(
"subitem Status: statusString",
"Status: %1\n", statusString);
537 if (mShowAttachments && !isJournal) {
541 attachmentCaption =
i18n(
"No Attachments");
544 attachmentCaption =
i18np(
"1 Attachment:",
"%1 Attachments:", attachments.
count());
548 for (; ait != attachments.
constEnd(); ++ait) {
549 if (!attachmentString.
isEmpty()) {
550 attachmentString +=
i18nc(
"Spacer for list of attachments",
" ");
552 attachmentString.
append((*ait).label());
563 if (mShowAttendees) {
567 attendeeCaption =
i18n(
"No Attendees");
569 attendeeCaption =
i18np(
"1 Attendee:",
"%1 Attendees:", attendees.
count());
573 for (; ait != attendees.
constEnd(); ++ait) {
574 if (!attendeeString.
isEmpty()) {
577 attendeeString +=
i18nc(
578 "Formatting of an attendee: "
579 "'Name (Role): Status', e.g. 'Reinhold Kainhofer "
580 "<reinhold@kainhofer.com> (Participant): Awaiting Response'",
583 KCalUtils::Stringify::attendeeRole((*ait).role()),
584 KCalUtils::Stringify::attendeeStatus((*ait).status()));
598 if (!KCalUtils::Stringify::incidenceStatus((*it)->status()).isEmpty()) {
599 optionsString +=
i18n(
"Status: %1", KCalUtils::Stringify::incidenceStatus((*it)->status()));
609 optionsString +=
i18n(
"Show as: Busy");
611 optionsString +=
i18n(
"Show as: Free");
616 if (t->isOverdue()) {
617 optionsString +=
i18n(
"This task is overdue!");
623 drawBoxWithCaption(p, optionsBox,
i18n(
"Settings: "), optionsString,
false,
false, captionFont, textFont);
629 (*it)->categories().join(
i18nc(
"Spacer for the joined list of categories/tags",
", ")),
646CalPrintTimetable::CalPrintTimetable()
651CalPrintTimetable::~CalPrintTimetable() =
default;
653void CalPrintTimetable::doLoadConfig()
659 QTime tm1(dayStart());
661 QDateTime endTm(dt, tm1.addSecs(12 * 60 * 60));
662 mStartTime = grp.readEntry(
"Start time", startTm).time();
663 mEndTime = grp.readEntry(
"End time", endTm).time();
664 mIncludeDescription = grp.readEntry(
"Include description",
false);
665 mIncludeCategories = grp.readEntry(
"Include categories",
false);
666 mIncludeTodos = grp.readEntry(
"Include todos",
false);
667 mIncludeAllEvents = grp.readEntry(
"Include all events",
false);
668 mSingleLineLimit = grp.readEntry(
"Single line limit",
false);
669 mExcludeTime = grp.readEntry(
"Exclude time",
false);
673void CalPrintTimetable::doSaveConfig()
679 grp.writeEntry(
"Start time", dt);
681 grp.writeEntry(
"End time", dt);
682 grp.writeEntry(
"Include description", mIncludeDescription);
683 grp.writeEntry(
"Include categories", mIncludeCategories);
684 grp.writeEntry(
"Include todos", mIncludeTodos);
685 grp.writeEntry(
"Include all events", mIncludeAllEvents);
686 grp.writeEntry(
"Single line limit", mSingleLineLimit);
687 grp.writeEntry(
"Exclude time", mExcludeTime);
702 if (!workDays.contains(qd)) {
705 drawBox(p, BOX_BORDER_WIDTH, box);
709 eventBox.setTop(box.
top() + padding());
710 eventBox.setBottom(eventBox.top() + lineSpacing);
718 if (currEvent->location().isEmpty()) {
719 str = cleanString(currEvent->summary());
721 str =
i18nc(
"summary, location",
"%1, %2", cleanString(currEvent->summary()), cleanString(currEvent->location()));
723 if (mIncludeCategories && !currEvent->categoriesStr().isEmpty()) {
724 str =
i18nc(
"summary, categories",
"%1, %2", str, currEvent->categoriesStr());
727 eventBox.setTop(eventBox.bottom());
728 eventBox.setBottom(eventBox.top() + lineSpacing);
734 QTime myFromTime = mStartTime;
735 QTime myToTime = mEndTime;
736 int maxAllDayEvents = 0;
737 QDate curDate(fromDate);
738 while (curDate <= toDate) {
740 int allDayEvents = holiday(curDate).
isEmpty() ? 0 : 1;
747 if (
event->allDay()) {
749 }
else if (mIncludeAllEvents) {
750 if (
event->dtStart().time() < myFromTime) {
751 myFromTime =
event->dtStart().time();
753 if (
event->dtEnd().time() > myToTime) {
754 myToTime =
event->dtEnd().time();
758 if (allDayEvents > maxAllDayEvents) {
759 maxAllDayEvents = allDayEvents;
761 curDate = curDate.addDays(1);
767 int timelineWidth = TIMELINE_WIDTH + padding();
770 dowBox.setLeft(box.
left() + timelineWidth);
771 dowBox.setHeight(mSubHeaderHeight);
774 int tlTop = dowBox.bottom();
776 int alldayHeight = 0;
777 if (maxAllDayEvents > 0) {
779 const auto alldayLabel =
i18nc(
"label for timetable all-day boxes",
"All day");
783 alldayHeight = std::max(maxAllDayEvents * lineSpacing + 2 * padding(), labelHeight);
786 QRect(0, tlTop, TIMELINE_WIDTH, alldayHeight),
790 tlTop += alldayHeight + padding();
794 tlBox.setWidth(TIMELINE_WIDTH);
801 double cellWidth = double(dowBox.width() - 1) / double(fromDate.
daysTo(toDate) + 1);
802 QRect allDayBox(dowBox.left(), dowBox.bottom(), cellWidth, alldayHeight);
803 const QList<QDate> workDays = CalendarSupport::workDays(fromDate, toDate);
804 while (curDate <= toDate) {
808 allDayBox.setLeft(dowBox.left() +
int(i * cellWidth));
809 allDayBox.setRight(dowBox.left() +
int((i + 1) * cellWidth));
810 if (maxAllDayEvents > 0) {
811 if (
const auto h = holidayEvent(curDate)) {
814 drawAllDayBox(p, eventList, curDate, allDayBox, workDays);
817 QRect dayBox(allDayBox);
818 dayBox.setTop(tlTop);
819 dayBox.setBottom(box.
bottom());
820 drawAgendaDayBox(p, eventList, curDate,
false, myFromTime, myToTime, dayBox, mIncludeDescription, mIncludeCategories, mExcludeTime, workDays);
823 curDate = curDate.addDays(1);
831CalPrintDay::CalPrintDay()
832 : CalPrintTimetable()
836CalPrintDay::~CalPrintDay() =
default;
840 return new CalPrintDayConfig(w);
843void CalPrintDay::readSettingsWidget()
845 auto cfg =
dynamic_cast<CalPrintDayConfig *
>((
QWidget *)mConfigWidget);
847 mFromDate = cfg->mFromDate->date();
848 mToDate = cfg->mToDate->date();
850 if (cfg->mPrintTypeFilofax->isChecked()) {
851 mDayPrintType = Filofax;
852 }
else if (cfg->mPrintTypeTimetable->isChecked()) {
853 mDayPrintType = Timetable;
855 mDayPrintType = SingleTimetable;
858 mStartTime = cfg->mFromTime->time();
859 mEndTime = cfg->mToTime->time();
860 mIncludeAllEvents = cfg->mIncludeAllEvents->isChecked();
862 mIncludeDescription = cfg->mIncludeDescription->isChecked();
863 mIncludeCategories = cfg->mIncludeCategories->isChecked();
864 mSingleLineLimit = cfg->mSingleLineLimit->isChecked();
865 mIncludeTodos = cfg->mIncludeTodos->isChecked();
869 mExcludeTime = cfg->mExcludeTime->isChecked();
875void CalPrintDay::setSettingsWidget()
877 auto cfg =
dynamic_cast<CalPrintDayConfig *
>((
QWidget *)mConfigWidget);
879 cfg->mFromDate->setDate(mFromDate);
880 cfg->mToDate->setDate(mToDate);
882 cfg->mPrintTypeFilofax->setChecked(mDayPrintType == Filofax);
883 cfg->mPrintTypeTimetable->setChecked(mDayPrintType == Timetable);
884 cfg->mPrintTypeSingleTimetable->setChecked(mDayPrintType == SingleTimetable);
886 cfg->mFromTime->setTime(mStartTime);
887 cfg->mToTime->setTime(mEndTime);
888 cfg->mIncludeAllEvents->setChecked(mIncludeAllEvents);
890 cfg->mIncludeDescription->setChecked(mIncludeDescription);
891 cfg->mIncludeCategories->setChecked(mIncludeCategories);
892 cfg->mSingleLineLimit->setChecked(mSingleLineLimit);
893 cfg->mIncludeTodos->setChecked(mIncludeTodos);
897 cfg->mExcludeTime->setChecked(mExcludeTime);
903void CalPrintDay::doLoadConfig()
905 CalPrintTimetable::doLoadConfig();
908 mDayPrintType =
static_cast<eDayPrintType
>(grp.readEntry(
"Print type",
static_cast<int>(Timetable)));
913void CalPrintDay::doSaveConfig()
915 readSettingsWidget();
918 grp.writeEntry(
"Print type",
int(mDayPrintType));
920 CalPrintTimetable::doSaveConfig();
923void CalPrintDay::setDateRange(
const QDate &from,
const QDate &to)
926 auto cfg =
dynamic_cast<CalPrintDayConfig *
>((
QWidget *)mConfigWidget);
928 cfg->mFromDate->setDate(from);
929 cfg->mToDate->setDate(to);
935 const int numberOfDays = mFromDate.
daysTo(mToDate) + 1;
937 const bool portrait = (box.
height() > box.
width());
941 vcells = std::ceil(
static_cast<double>(numberOfDays) / 2.0);
942 if (numberOfDays > 1) {
943 cellWidth = box.
width() / 2;
945 cellWidth = box.
width();
950 cellWidth = box.
width() / numberOfDays;
952 const int cellHeight = box.
height() / vcells;
953 QDate weekDate = mFromDate;
954 for (
int i = 0; i < numberOfDays; ++i, weekDate = weekDate.
addDays(1)) {
955 const int hpos = i / vcells;
956 const int vpos = i % vcells;
957 const QRect dayBox(box.
left() + cellWidth * hpos, box.
top() + cellHeight * vpos, cellWidth, cellHeight);
958 drawDayBox(p, weekDate, mStartTime, mEndTime, dayBox,
true,
true,
true, mSingleLineLimit, mIncludeDescription, mIncludeCategories);
962void CalPrintDay::print(
QPainter &p,
int width,
int height)
964 QDate curDay(mFromDate);
969 QRect daysBox(headerBox);
970 daysBox.setTop(headerBox.bottom() + padding());
971 daysBox.setBottom(height);
975 switch (mDayPrintType) {
977 case SingleTimetable: {
981 if (mFromDate == mToDate) {
984 title =
i18nc(
"date from-to",
"%1\u2013%2", line1, line2);
987 if (mDayPrintType == Filofax) {
988 drawDays(p, daysBox);
989 }
else if (mDayPrintType == SingleTimetable) {
990 drawTimeTable(p, mFromDate, mToDate, daysBox);
1001 QTime curStartTime(mStartTime);
1002 QTime curEndTime(mEndTime);
1006 if (curEndTime <= curStartTime) {
1007 curStartTime =
QTime(curStartTime.hour(), 0, 0);
1008 curEndTime = curStartTime.addSecs(3600);
1012 drawTimeTable(p, curDay, curDay, daysBox);
1017 curDay = curDay.addDays(1);
1018 if (curDay <= mToDate) {
1021 }
while (curDay <= mToDate);
1029CalPrintWeek::CalPrintWeek()
1030 : CalPrintTimetable()
1034CalPrintWeek::~CalPrintWeek() =
default;
1038 return new CalPrintWeekConfig(w);
1041void CalPrintWeek::readSettingsWidget()
1043 auto cfg =
dynamic_cast<CalPrintWeekConfig *
>((
QWidget *)mConfigWidget);
1045 mFromDate = cfg->mFromDate->date();
1046 mToDate = cfg->mToDate->date();
1048 if (cfg->mPrintTypeFilofax->isChecked()) {
1049 mWeekPrintType = Filofax;
1050 }
else if (cfg->mPrintTypeTimetable->isChecked()) {
1051 mWeekPrintType = Timetable;
1052 }
else if (cfg->mPrintTypeSplitWeek->isChecked()) {
1053 mWeekPrintType = SplitWeek;
1055 mWeekPrintType = Timetable;
1058 mStartTime = cfg->mFromTime->time();
1059 mEndTime = cfg->mToTime->time();
1060 mIncludeAllEvents = cfg->mIncludeAllEvents->isChecked();
1063 mSingleLineLimit = cfg->mSingleLineLimit->isChecked();
1064 mIncludeTodos = cfg->mIncludeTodos->isChecked();
1067 mIncludeDescription = cfg->mIncludeDescription->isChecked();
1068 mIncludeCategories = cfg->mIncludeCategories->isChecked();
1069 mExcludeTime = cfg->mExcludeTime->isChecked();
1075void CalPrintWeek::setSettingsWidget()
1077 auto cfg =
dynamic_cast<CalPrintWeekConfig *
>((
QWidget *)mConfigWidget);
1079 cfg->mFromDate->setDate(mFromDate);
1080 cfg->mToDate->setDate(mToDate);
1082 cfg->mPrintTypeFilofax->setChecked(mWeekPrintType == Filofax);
1083 cfg->mPrintTypeTimetable->setChecked(mWeekPrintType == Timetable);
1084 cfg->mPrintTypeSplitWeek->setChecked(mWeekPrintType == SplitWeek);
1086 cfg->mFromTime->setTime(mStartTime);
1087 cfg->mToTime->setTime(mEndTime);
1088 cfg->mIncludeAllEvents->setChecked(mIncludeAllEvents);
1091 cfg->mSingleLineLimit->setChecked(mSingleLineLimit);
1092 cfg->mIncludeTodos->setChecked(mIncludeTodos);
1095 cfg->mIncludeDescription->setChecked(mIncludeDescription);
1096 cfg->mIncludeCategories->setChecked(mIncludeCategories);
1097 cfg->mExcludeTime->setChecked(mExcludeTime);
1104void CalPrintWeek::doLoadConfig()
1106 CalPrintTimetable::doLoadConfig();
1109 mWeekPrintType = (eWeekPrintType)(grp.readEntry(
"Print type", (
int)Filofax));
1111 setSettingsWidget();
1114void CalPrintWeek::doSaveConfig()
1116 readSettingsWidget();
1119 grp.writeEntry(
"Print type",
int(mWeekPrintType));
1121 CalPrintTimetable::doSaveConfig();
1126 if (mWeekPrintType == Filofax) {
1128 }
else if (mWeekPrintType == SplitWeek) {
1135void CalPrintWeek::setDateRange(
const QDate &from,
const QDate &to)
1138 auto cfg =
dynamic_cast<CalPrintWeekConfig *
>((
QWidget *)mConfigWidget);
1140 cfg->mFromDate->setDate(from);
1141 cfg->mToDate->setDate(to);
1147 QDate weekDate = qd;
1148 const bool portrait = (box.
height() > box.
width());
1152 cellWidth = box.
width() / 2;
1155 cellWidth = box.
width() / 6;
1158 const int cellHeight = box.
height() / vcells;
1162 weekDate = qd.
addDays(-weekdayCol);
1164 for (
int i = 0; i < 7; ++i, weekDate = weekDate.
addDays(1)) {
1166 int hpos = ((i < 6) ? i : (i - 1)) / vcells;
1167 int vpos = ((i < 6) ? i : (i - 1)) % vcells;
1168 QRect dayBox(box.
left() + cellWidth * hpos,
1169 box.
top() + cellHeight * vpos + ((i == 6) ? (cellHeight / 2) : 0),
1171 (i < 5) ? (cellHeight) : (cellHeight / 2));
1172 drawDayBox(p, weekDate, mStartTime, mEndTime, dayBox,
true,
true,
true, mSingleLineLimit, mIncludeDescription, mIncludeCategories);
1176void CalPrintWeek::print(
QPainter &p,
int width,
int height)
1184 fromWeek = mFromDate.
addDays(-weekdayCol);
1186 toWeek = mToDate.
addDays(6 - weekdayCol);
1188 curWeek = fromWeek.
addDays(6);
1198 QRect weekBox(headerBox);
1199 weekBox.setTop(headerBox.bottom() + padding());
1200 weekBox.setBottom(height);
1202 switch (mWeekPrintType) {
1207 title =
i18nc(
"date from-to",
"%1\u2013%2", line1, line2);
1210 drawWeek(p, curWeek, weekBox);
1217 if (curWeek <= toWeek) {
1220 }
while (curWeek <= toWeek);
1229 title =
i18nc(
"date from - to (week number)",
"%1\u2013%2 (Week %3)", line1, line2, curWeek.
weekNumber());
1231 title =
i18nc(
"date from - to\\n(week number)",
"%1\u2013%2\n(Week %3)", line1, line2, curWeek.
weekNumber());
1235 drawTimeTable(p, fromWeek, curWeek, weekBox);
1241 fromWeek = fromWeek.
addDays(7);
1242 curWeek = fromWeek.
addDays(6);
1243 if (curWeek <= toWeek) {
1246 }
while (curWeek <= toWeek);
1250 QRect weekBox1(weekBox);
1254 weekBox1.setRight(
int((width - TIMELINE_WIDTH) * 3. / 4. + TIMELINE_WIDTH));
1259 drawSplitHeaderRight(p, fromWeek, curWeek,
QDate(), width, hh);
1260 drawTimeTable(p, fromWeek, endLeft, weekBox);
1265 drawSplitHeaderRight(p, fromWeek, curWeek,
QDate(), width, hh);
1266 drawTimeTable(p, endLeft.addDays(1), curWeek, weekBox1);
1272 fromWeek = fromWeek.
addDays(7);
1273 curWeek = fromWeek.
addDays(6);
1274 if (curWeek <= toWeek) {
1277 }
while (curWeek <= toWeek);
1287CalPrintMonth::CalPrintMonth()
1292CalPrintMonth::~CalPrintMonth() =
default;
1296 return new CalPrintMonthConfig(w);
1299void CalPrintMonth::readSettingsWidget()
1301 auto cfg =
dynamic_cast<CalPrintMonthConfig *
>((
QWidget *)mConfigWidget);
1304 mFromDate =
QDate(cfg->mFromYear->value(), cfg->mFromMonth->currentIndex() + 1, 1);
1305 mToDate =
QDate(cfg->mToYear->value(), cfg->mToMonth->currentIndex() + 1, 1);
1307 mWeekNumbers = cfg->mWeekNumbers->isChecked();
1308 mRecurDaily = cfg->mRecurDaily->isChecked();
1309 mRecurWeekly = cfg->mRecurWeekly->isChecked();
1310 mIncludeTodos = cfg->mIncludeTodos->isChecked();
1312 mSingleLineLimit = cfg->mSingleLineLimit->isChecked();
1315 mIncludeDescription = cfg->mIncludeDescription->isChecked();
1316 mIncludeCategories = cfg->mIncludeCategories->isChecked();
1322void CalPrintMonth::setSettingsWidget()
1324 auto cfg =
dynamic_cast<CalPrintMonthConfig *
>((
QWidget *)mConfigWidget);
1327 setDateRange(mFromDate, mToDate);
1329 cfg->mWeekNumbers->setChecked(mWeekNumbers);
1330 cfg->mRecurDaily->setChecked(mRecurDaily);
1331 cfg->mRecurWeekly->setChecked(mRecurWeekly);
1332 cfg->mIncludeTodos->setChecked(mIncludeTodos);
1334 cfg->mSingleLineLimit->setChecked(mSingleLineLimit);
1337 cfg->mIncludeDescription->setChecked(mIncludeDescription);
1338 cfg->mIncludeCategories->setChecked(mIncludeCategories);
1344void CalPrintMonth::doLoadConfig()
1349 mWeekNumbers = grp.readEntry(
"Print week numbers",
true);
1350 mRecurDaily = grp.readEntry(
"Print daily incidences",
true);
1351 mRecurWeekly = grp.readEntry(
"Print weekly incidences",
true);
1352 mIncludeTodos = grp.readEntry(
"Include todos",
false);
1353 mSingleLineLimit = grp.readEntry(
"Single line limit",
false);
1354 mIncludeDescription = grp.readEntry(
"Include description",
false);
1355 mIncludeCategories = grp.readEntry(
"Include categories",
false);
1357 setSettingsWidget();
1360void CalPrintMonth::doSaveConfig()
1362 readSettingsWidget();
1365 grp.writeEntry(
"Print week numbers", mWeekNumbers);
1366 grp.writeEntry(
"Print daily incidences", mRecurDaily);
1367 grp.writeEntry(
"Print weekly incidences", mRecurWeekly);
1368 grp.writeEntry(
"Include todos", mIncludeTodos);
1369 grp.writeEntry(
"Single line limit", mSingleLineLimit);
1370 grp.writeEntry(
"Include description", mIncludeDescription);
1371 grp.writeEntry(
"Include categories", mIncludeCategories);
1376void CalPrintMonth::setDateRange(
const QDate &from,
const QDate &to)
1379 auto cfg =
dynamic_cast<CalPrintMonthConfig *
>((
QWidget *)mConfigWidget);
1382 cfg->mFromMonth->clear();
1383 cfg->mToMonth->clear();
1384 for (
int i = 1; i < 13; ++i) {
1386 cfg->mFromMonth->addItem(monthName);
1387 cfg->mToMonth->addItem(monthName);
1389 cfg->mFromMonth->setCurrentIndex(from.
month() - 1);
1390 cfg->mFromYear->setValue(to.
year());
1391 cfg->mToMonth->setCurrentIndex(mToDate.
month() - 1);
1392 cfg->mToYear->setValue(mToDate.
year());
1396void CalPrintMonth::print(
QPainter &p,
int width,
int height)
1402 fromMonth = mFromDate.
addDays(-(mFromDate.
day() - 1));
1405 curMonth = fromMonth;
1411 QRect monthBox(0, 0, width, height);
1412 monthBox.setTop(headerBox.bottom() + padding());
1417 QDate tmp(fromMonth);
1419 tmp = tmp.addDays(-weekdayCol);
1430 mIncludeDescription,
1439 if (curMonth <= toMonth) {
1442 }
while (curMonth <= toMonth);
1449CalPrintTodos::CalPrintTodos()
1452 mTodoSortField = TodoFieldUnset;
1453 mTodoSortDirection = TodoDirectionUnset;
1456CalPrintTodos::~CalPrintTodos() =
default;
1460 return new CalPrintTodoConfig(w);
1463void CalPrintTodos::readSettingsWidget()
1465 auto cfg =
dynamic_cast<CalPrintTodoConfig *
>((
QWidget *)mConfigWidget);
1468 mPageTitle = cfg->mTitle->text();
1470 if (cfg->mPrintAll->isChecked()) {
1471 mTodoPrintType = TodosAll;
1472 }
else if (cfg->mPrintUnfinished->isChecked()) {
1473 mTodoPrintType = TodosUnfinished;
1474 }
else if (cfg->mPrintDueRange->isChecked()) {
1475 mTodoPrintType = TodosDueRange;
1477 mTodoPrintType = TodosAll;
1480 mFromDate = cfg->mFromDate->date();
1481 mToDate = cfg->mToDate->date();
1483 mIncludeDescription = cfg->mDescription->isChecked();
1484 mIncludePriority = cfg->mPriority->isChecked();
1485 mIncludeCategories = cfg->mCategories->isChecked();
1486 mIncludeStartDate = cfg->mStartDate->isChecked();
1487 mIncludeDueDate = cfg->mDueDate->isChecked();
1488 mIncludePercentComplete = cfg->mPercentComplete->isChecked();
1489 mConnectSubTodos = cfg->mConnectSubTodos->isChecked();
1490 mStrikeOutCompleted = cfg->mStrikeOutCompleted->isChecked();
1494 mTodoSortField = (eTodoSortField)cfg->mSortField->currentIndex();
1495 mTodoSortDirection = (eTodoSortDirection)cfg->mSortDirection->currentIndex();
1501void CalPrintTodos::setSettingsWidget()
1503 auto cfg =
dynamic_cast<CalPrintTodoConfig *
>((
QWidget *)mConfigWidget);
1505 cfg->mTitle->setText(mPageTitle);
1507 cfg->mPrintAll->setChecked(mTodoPrintType == TodosAll);
1508 cfg->mPrintUnfinished->setChecked(mTodoPrintType == TodosUnfinished);
1509 cfg->mPrintDueRange->setChecked(mTodoPrintType == TodosDueRange);
1511 cfg->mFromDate->setDate(mFromDate);
1512 cfg->mToDate->setDate(mToDate);
1514 cfg->mDescription->setChecked(mIncludeDescription);
1515 cfg->mPriority->setChecked(mIncludePriority);
1516 cfg->mCategories->setChecked(mIncludeCategories);
1517 cfg->mStartDate->setChecked(mIncludeStartDate);
1518 cfg->mDueDate->setChecked(mIncludeDueDate);
1519 cfg->mPercentComplete->setChecked(mIncludePercentComplete);
1520 cfg->mConnectSubTodos->setChecked(mConnectSubTodos);
1521 cfg->mStrikeOutCompleted->setChecked(mStrikeOutCompleted);
1525 if (mTodoSortField != TodoFieldUnset) {
1527 cfg->mSortField->addItem(
i18nc(
"@option sort by summary",
"Summary"));
1528 cfg->mSortField->addItem(
i18nc(
"@option sort by start date/time",
"Start Date"));
1529 cfg->mSortField->addItem(
i18nc(
"@option sort by due date/time",
"Due Date"));
1530 cfg->mSortField->addItem(
i18nc(
"@option sort by priority",
"Priority"));
1531 cfg->mSortField->addItem(
i18nc(
"@option sort by percent completed",
"Percent Complete"));
1532 cfg->mSortField->addItem(
i18nc(
"@option sort by tags",
"Tags"));
1533 cfg->mSortField->setCurrentIndex(mTodoSortField);
1536 if (mTodoSortDirection != TodoDirectionUnset) {
1538 cfg->mSortDirection->addItem(
i18nc(
"@option sort in increasing order",
"Ascending"));
1539 cfg->mSortDirection->addItem(
i18nc(
"@option sort in descreasing order",
"Descending"));
1540 cfg->mSortDirection->setCurrentIndex(mTodoSortDirection);
1547void CalPrintTodos::doLoadConfig()
1552 mPageTitle = grp.readEntry(
"Page title",
i18n(
"To-do list"));
1553 mTodoPrintType = (eTodoPrintType)grp.readEntry(
"Print type",
static_cast<int>(TodosAll));
1554 mIncludeDescription = grp.readEntry(
"Include description",
true);
1555 mIncludePriority = grp.readEntry(
"Include priority",
true);
1556 mIncludeCategories = grp.readEntry(
"Include categories",
true);
1557 mIncludeStartDate = grp.readEntry(
"Include start date",
true);
1558 mIncludeDueDate = grp.readEntry(
"Include due date",
true);
1559 mIncludePercentComplete = grp.readEntry(
"Include percentage completed",
true);
1560 mConnectSubTodos = grp.readEntry(
"Connect subtodos",
true);
1561 mStrikeOutCompleted = grp.readEntry(
"Strike out completed summaries",
true);
1562 mTodoSortField = (eTodoSortField)grp.readEntry(
"Sort field",
static_cast<int>(TodoFieldSummary));
1563 mTodoSortDirection = (eTodoSortDirection)grp.readEntry(
"Sort direction",
static_cast<int>(TodoDirectionAscending));
1565 setSettingsWidget();
1568void CalPrintTodos::doSaveConfig()
1570 readSettingsWidget();
1573 grp.writeEntry(
"Page title", mPageTitle);
1574 grp.writeEntry(
"Print type",
int(mTodoPrintType));
1575 grp.writeEntry(
"Include description", mIncludeDescription);
1576 grp.writeEntry(
"Include priority", mIncludePriority);
1577 grp.writeEntry(
"Include categories", mIncludeCategories);
1578 grp.writeEntry(
"Include start date", mIncludeStartDate);
1579 grp.writeEntry(
"Include due date", mIncludeDueDate);
1580 grp.writeEntry(
"Include percentage completed", mIncludePercentComplete);
1581 grp.writeEntry(
"Connect subtodos", mConnectSubTodos);
1582 grp.writeEntry(
"Strike out completed summaries", mStrikeOutCompleted);
1583 grp.writeEntry(
"Sort field",
static_cast<int>(mTodoSortField));
1584 grp.writeEntry(
"Sort direction",
static_cast<int>(mTodoSortDirection));
1589void CalPrintTodos::print(
QPainter &p,
int width,
int height)
1591 int possummary = 100;
1612 mCurrentLinePos += lineSpacing;
1613 int pospriority = -1;
1614 if (mIncludePriority) {
1615 outStr +=
i18n(
"Priority");
1617 p.
drawText(pospriority, mCurrentLinePos - 2, outStr);
1620 int posSoFar = width;
1623 if (mIncludeDueDate) {
1625 outStr +=
i18nc(
"@label to-do due date",
"Due");
1627 posdue = posSoFar - widDue;
1628 p.
drawText(posdue, mCurrentLinePos - 2, outStr);
1633 if (mIncludeStartDate) {
1635 outStr +=
i18nc(
"@label to-do start date",
"Start");
1637 posStart = posSoFar - widStart - 5;
1638 p.
drawText(posStart, mCurrentLinePos - 2, outStr);
1639 posSoFar = posStart;
1642 int poscomplete = -1;
1643 if (mIncludePercentComplete) {
1645 outStr +=
i18nc(
"@label to-do percentage complete",
"Complete");
1647 poscomplete = posSoFar - widComplete - 5;
1648 p.
drawText(poscomplete, mCurrentLinePos - 2, outStr);
1649 posSoFar = poscomplete;
1652 int posCategories = -1;
1653 if (mIncludeCategories) {
1655 outStr +=
i18nc(
"@label to-do categories",
"Tags");
1657 posCategories = posSoFar - widCats - 5;
1658 p.
drawText(posCategories, mCurrentLinePos - 2, outStr);
1667 switch (mTodoSortDirection) {
1668 case TodoDirectionAscending:
1671 case TodoDirectionDescending:
1674 case TodoDirectionUnset:
1679 switch (mTodoSortField) {
1680 case TodoFieldSummary:
1683 case TodoFieldStartDate:
1686 case TodoFieldDueDate:
1689 case TodoFieldPriority:
1692 case TodoFieldPercentComplete:
1695 case TodoFieldCategories:
1698 case TodoFieldUnset:
1703 todoList = mCalendar->todos(sortField, sortDirection);
1704 switch (mTodoPrintType) {
1707 case TodosUnfinished:
1710 if (!
todo->isCompleted()) {
1714 todoList = tempList;
1719 if (
todo->hasDueDate()) {
1720 if (
todo->dtDue().date() >= mFromDate &&
todo->dtDue().date() <= mToDate) {
1727 todoList = tempList;
1735 if (
todo->relatedTo().isEmpty()) {
1743 mStrikeOutCompleted,
1744 mIncludeDescription,
1767#include "moc_calprintdefaultplugins.cpp"
Base class for Calendar printing classes.
int drawHeader(QPainter &p, const QString &title, QDate month1, QDate month2, QRect box, bool expand=false, QColor backColor=QColor())
Draw the gray header bar of the printout to the QPainter.
int drawBoxWithCaption(QPainter &p, 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).
int footerHeight() const
Returns the height of the page footer.
static void drawShadedBox(QPainter &p, int linewidth, const QBrush &brush, QRect rect)
Draw a shaded box with given width at the given coordinates.
bool mExcludePrivate
Whether or not to print incidences with secrecy "private".
void drawAgendaDayBox(QPainter &p, const KCalendarCore::Event::List &eventList, QDate qd, bool expandable, QTime fromTime, QTime toTime, QRect box, bool includeDescription, bool includeCategories, bool excludeTime, const QList< QDate > &workDays)
Draw the agenda box for the day print style (the box showing all events of that day).
void drawTodo(int &count, const KCalendarCore::Todo::Ptr &todo, QPainter &p, KCalendarCore::TodoSortField sortField, KCalendarCore::SortDirection sortDir, bool connectSubTodos, bool strikeoutCompleted, bool desc, int posPriority, int posSummary, int posCategories, int posStartDt, int posDueDt, int posPercentComplete, int level, int x, int &y, int width, int pageHeight, const KCalendarCore::Todo::List &todoList, TodoParentStart *r)
Draws single to-do and its (indented) sub-to-dos, optionally connects them by a tree-like line,...
bool mShowNoteLines
Whether or not to print horizontal lines in note areas.
void drawVerticalBox(QPainter &p, int linewidth, QRect box, const QString &str, int flags=-1)
Draw an event box with vertical text.
static void drawBox(QPainter &p, int linewidth, QRect rect)
Draw a box with given width at the given coordinates.
int headerHeight() const
Returns the height of the page header.
void printEventString(QPainter &p, QRect box, const QString &str, int flags=-1)
Print the given string (event summary) in the given rectangle.
int drawFooter(QPainter &p, QRect box)
Draw a page footer containing the printing date and possibly other things, like a page number.
bool mExcludeConfidential
Whether or not to print incidences with secrecy "confidential".
void doSaveConfig() override
Save complete configuration.
void doLoadConfig() override
Load complete configuration.
void drawDayBox(QPainter &p, QDate qd, QTime fromTime, QTime toTime, QRect box, bool fullDate=false, bool printRecurDaily=true, bool printRecurWeekly=true, bool singleLineLimit=true, bool includeDescription=false, bool includeCategories=false)
Draw the box containing a list of all events of the given day (with their times, of course).
void drawMonthTable(QPainter &p, QDate qd, QTime fromTime, QTime toTime, bool weeknumbers, bool recurDaily, bool recurWeekly, bool singleLineLimit, bool includeDescription, bool includeCategories, QRect box)
Draw the month table of the month containing the date qd.
void drawDaysOfWeek(QPainter &p, QDate fromDate, QDate toDate, QRect box)
Draw a horizontal bar with the weekday names of the given date range in the given area of the painter...
static int weekdayColumn(int weekday)
Determines the column of the given weekday ( 1=Monday, 7=Sunday ), taking the start of the week setti...
bool mPrintFooter
Whether or not to print a footer at the bottoms of pages.
void drawNoteLines(QPainter &p, QRect box, int startY)
Draws dotted lines for notes in a box.
void drawTimeLine(QPainter &p, QTime fromTime, QTime toTime, QRect box)
Draw a (vertical) time scale from time fromTime to toTime inside the given area of the painter.
bool mUseColors
Whether or not to use event category colors to draw the events.
virtual void setSettingsWidget()
Set configuration widget to reflect settings of current object.
virtual void setDateRange(const QDate &from, const QDate &to)
Set date range which should be printed.
virtual QString groupName() const =0
Returns KConfig group name where store settings.
QPrinter * mPrinter
The printer object.
KLocalizedString subs(const KLocalizedString &a, int fieldWidth=0, QChar fillChar=QLatin1Char(' ')) const
QString i18np(const char *singular, const char *plural, const TYPE &arg...)
QString i18nc(const char *context, const char *text, const TYPE &arg...)
KLocalizedString KI18N_EXPORT ki18nc(const char *context, const char *text)
QString i18n(const char *text, const TYPE &arg...)
AKONADI_CALENDAR_EXPORT KCalendarCore::Incidence::Ptr incidence(const Akonadi::Item &item)
AKONADI_CALENDAR_EXPORT KCalendarCore::Journal::Ptr journal(const Akonadi::Item &item)
AKONADI_CALENDAR_EXPORT KCalendarCore::Todo::Ptr todo(const Akonadi::Item &item)
AKONADI_CALENDAR_EXPORT KCalendarCore::Event::Ptr event(const Akonadi::Item &item)
char * toString(const EngineQuery &query)
KCALUTILS_EXPORT QString incidenceSecrecy(KCalendarCore::Incidence::Secrecy secrecy)
QDate addDays(qint64 ndays) const const
QDate addMonths(int nmonths) const const
int dayOfWeek() const const
int daysInMonth() const const
qint64 daysTo(QDate d) const const
int weekNumber(int *yearNumber) const const
QDateTime currentDateTime()
QRect boundingRect(QChar ch) const const
int horizontalAdvance(QChar ch) const const
int lineSpacing() const const
void append(QList< T > &&value)
const_iterator constBegin() const const
const_iterator constEnd() const const
qsizetype count() const const
bool isEmpty() const const
void prepend(parameter_type value)
void push_back(parameter_type value)
void reserve(qsizetype size)
QString standaloneMonthName(int month, FormatType type) const const
void drawText(const QPoint &position, const QString &text)
const QFont & font() const const
QFontMetrics fontMetrics() const const
void setFont(const QFont &font)
virtual bool newPage() override
QSharedPointer< X > dynamicCast() const const
QSharedPointer< X > staticCast() const const
QString & append(QChar ch)
bool isEmpty() const const
QString number(double n, char format, int precision)
QString & replace(QChar before, QChar after, Qt::CaseSensitivity cs)
void truncate(qsizetype position)
QString join(QChar separator) const const
QTimeZone systemTimeZone()