Commit 971009b7 authored by Glen Ditchfield's avatar Glen Ditchfield 🐛 Committed by Glen Ditchfield
Browse files

Combine the printed timetable implementations

The "all days on a single page" timetable view duplicated much of the
code of the other timetables, but added some enhancements.  This patch
combines them.
parent 61c430b8
Pipeline #67635 passed with stage
in 5 minutes and 11 seconds
......@@ -27,12 +27,6 @@
using namespace CalendarSupport;
static QString cleanString(const QString &instr)
{
QString ret = instr;
return ret.replace(QLatin1Char('\n'), QLatin1Char(' '));
}
/**************************************************************
* Print Incidence
**************************************************************/
......@@ -780,15 +774,15 @@ void CalPrintDay::print(QPainter &p, int width, int height)
QRect headerBox(0, 0, width, headerHeight());
QRect footerBox(0, height - footerHeight(), width, footerHeight());
height -= footerHeight();
QRect daysBox(headerBox);
daysBox.setTop(headerBox.bottom() + padding());
daysBox.setBottom(height);
auto local = QLocale::system();
switch (mDayPrintType) {
case Filofax:
case SingleTimetable: {
QRect daysBox(headerBox);
daysBox.setTop(headerBox.bottom() + padding());
daysBox.setBottom(height);
QString line1 = local.toString(mFromDate, QLocale::ShortFormat);
QString line2 = local.toString(mToDate, QLocale::ShortFormat);
QString title;
......@@ -846,97 +840,18 @@ void CalPrintDay::print(QPainter &p, int width, int height)
}
drawHeader(p, local.toString(curDay, QLocale::ShortFormat), curDay, QDate(), headerBox);
KCalendarCore::Event::List eventList =
mCalendar->events(curDay, QTimeZone::systemTimeZone(), KCalendarCore::EventSortStartDate, KCalendarCore::SortDirectionAscending);
// split out the all day events as they will be printed in a separate box
KCalendarCore::Event::List alldayEvents, timedEvents;
for (const KCalendarCore::Event::Ptr &event : qAsConst(eventList)) {
if (!event
|| (mExcludeConfidential && event->secrecy() == KCalendarCore::Incidence::SecrecyConfidential)
|| (mExcludePrivate && event->secrecy() == KCalendarCore::Incidence::SecrecyPrivate)) {
continue;
}
if (event->allDay()) {
alldayEvents.append(event);
} else {
timedEvents.append(event);
}
}
int fontSize = 11;
QFont textFont(QStringLiteral("sans-serif"), fontSize, QFont::Normal);
p.setFont(textFont);
int lineSpacing = p.fontMetrics().lineSpacing();
int maxAllDayEvents = 8; // the max we allow to be printed, sorry.
int allDayHeight = qMin(alldayEvents.count(), maxAllDayEvents) * lineSpacing;
allDayHeight = qMax(allDayHeight, (5 * lineSpacing)) + (2 * padding());
QRect allDayBox(TIMELINE_WIDTH + padding(), headerBox.bottom() + padding(), width - TIMELINE_WIDTH - padding(), allDayHeight);
if (!alldayEvents.isEmpty()) {
// draw the side bar for all-day events
QFont oldFont(p.font());
p.setFont(QFont(QStringLiteral("sans-serif"), 9, QFont::Normal));
drawVerticalBox(p,
BOX_BORDER_WIDTH,
QRect(0, headerBox.bottom() + padding(), TIMELINE_WIDTH, allDayHeight),
i18n("Today's Events"),
Qt::AlignHCenter | Qt::AlignVCenter | Qt::TextWordWrap);
p.setFont(oldFont);
// now draw at most maxAllDayEvents in the all-day box
drawBox(p, BOX_BORDER_WIDTH, allDayBox);
QRect eventBox(allDayBox);
eventBox.setLeft(TIMELINE_WIDTH + (2 * padding()));
eventBox.setTop(eventBox.top() + padding());
eventBox.setBottom(eventBox.top() + lineSpacing);
int count = 0;
for (const KCalendarCore::Event::Ptr &event : qAsConst(alldayEvents)) {
if (count == maxAllDayEvents) {
break;
}
count++;
QString str;
if (event->location().isEmpty()) {
str = cleanString(event->summary());
} else {
str = i18nc("summary, location", "%1, %2", cleanString(event->summary()), cleanString(event->location()));
}
if (mIncludeCategories && !event->categoriesStr().isEmpty()) {
str = i18nc("summary, categories", "%1, %2", str, cleanString(event->categoriesStr()));
}
printEventString(p, eventBox, str);
eventBox.setTop(eventBox.bottom());
eventBox.setBottom(eventBox.top() + lineSpacing);
}
} else {
allDayBox.setBottom(headerBox.bottom());
}
QRect dayBox(allDayBox);
dayBox.setTop(allDayBox.bottom() + padding());
dayBox.setBottom(height);
QList<QDate> workDays = CalendarSupport::workDays(curDay, curDay);
drawAgendaDayBox(p,
timedEvents,
curDay,
mIncludeAllEvents,
curStartTime,
curEndTime,
dayBox,
mIncludeDescription,
mIncludeCategories,
mExcludeTime,
mExcludeConfidential,
mExcludePrivate,
workDays);
QRect tlBox(dayBox);
tlBox.setLeft(0);
tlBox.setWidth(TIMELINE_WIDTH);
drawTimeLine(p, curStartTime, curEndTime, tlBox);
drawTimeTable(p,
curDay,
curDay,
mIncludeAllEvents,
mStartTime,
mEndTime,
daysBox,
mIncludeDescription,
mIncludeCategories,
mExcludeTime,
mExcludeConfidential,
mExcludePrivate);
if (mPrintFooter) {
drawFooter(p, footerBox);
}
......
......@@ -675,7 +675,7 @@ void CalPrintPluginBase::drawSmallMonth(QPainter &p, QDate qd, QRect box)
*/
void CalPrintPluginBase::drawDaysOfWeek(QPainter &p, const QDate &fromDate, QDate toDate, QRect box)
{
double cellWidth = double(box.width()) / double(fromDate.daysTo(toDate) + 1);
double cellWidth = double(box.width() - 1) / double(fromDate.daysTo(toDate) + 1);
QDate cellDate(fromDate);
QRect dateBox(box);
int i = 0;
......@@ -757,65 +757,53 @@ void CalPrintPluginBase::drawTimeLine(QPainter &p, QTime fromTime, QTime toTime,
}
}
/**
prints the all-day box for the agenda print view. if expandable is set,
height is the cell height of a single cell, and the returned height will
be the total height used for the all-day events. If !expandable, only one
cell will be used, and multiple events are concatenated using ", ".
*/
int CalPrintPluginBase::drawAllDayBox(QPainter &p,
const KCalendarCore::Event::List &eventList_,
static QString cleanString(const QString &instr)
{
QString ret = instr;
return ret.replace(QLatin1Char('\n'), QLatin1Char(' '));
}
void CalPrintPluginBase::drawAllDayBox(QPainter &p,
const KCalendarCore::Event::List &eventList,
QDate qd,
bool expandable,
QRect box,
bool includeCategories,
bool excludeConfidential,
bool excludePrivate)
bool excludePrivate,
const QList<QDate> &workDays)
{
int offset = box.top();
QString multiDayStr;
int lineSpacing = p.fontMetrics().lineSpacing();
KCalendarCore::Event::List eventList = eventList_;
KCalendarCore::Event::Ptr hd = holidayEvent(qd);
if (hd) {
eventList.prepend(hd);
if (!workDays.contains(qd)) {
drawShadedBox(p, BOX_BORDER_WIDTH, QColor(232, 232, 232), box);
} else {
drawBox(p, BOX_BORDER_WIDTH, box);
}
QRect eventBox(box);
eventBox.setTop(box.top() + padding());
eventBox.setBottom(eventBox.top() + lineSpacing);
for (const KCalendarCore::Event::Ptr &currEvent : qAsConst(eventList)) {
if (!currEvent
|| !currEvent->allDay()
|| (excludeConfidential && currEvent->secrecy() == KCalendarCore::Incidence::SecrecyConfidential)
|| (excludePrivate && currEvent->secrecy() == KCalendarCore::Incidence::SecrecyPrivate)) {
continue;
}
if (currEvent->allDay()) {
if (expandable) {
QRect eventBox(box);
eventBox.setTop(offset);
showEventBox(p, EVENT_BORDER_WIDTH, eventBox, currEvent, currEvent->summary());
offset += box.height();
} else {
if (!multiDayStr.isEmpty()) {
multiDayStr += QStringLiteral(", ");
}
multiDayStr += currEvent->summary();
}
}
}
int ret = box.height();
QRect eventBox(box);
if (!expandable) {
if (!multiDayStr.isEmpty()) {
drawShadedBox(p, BOX_BORDER_WIDTH, QColor(180, 180, 180), eventBox);
printEventString(p, eventBox, multiDayStr);
QString str;
if (currEvent->location().isEmpty()) {
str = cleanString(currEvent->summary());
} else {
drawBox(p, BOX_BORDER_WIDTH, eventBox);
str = i18nc("summary, location", "%1, %2", cleanString(currEvent->summary()), cleanString(currEvent->location()));
}
} else {
ret = offset - box.top();
eventBox.setBottom(ret);
drawBox(p, BOX_BORDER_WIDTH, eventBox);
if (includeCategories && !currEvent->categoriesStr().isEmpty()) {
str = i18nc("summary, categories", "%1, %2", str, currEvent->categoriesStr());
}
printEventString(p, eventBox, str);
eventBox.setTop(eventBox.bottom());
eventBox.setBottom(eventBox.top() + lineSpacing);
}
return ret;
}
void CalPrintPluginBase::drawAgendaDayBox(QPainter &p,
......@@ -1434,15 +1422,22 @@ void CalPrintPluginBase::drawTimeTable(QPainter &p,
{
QTime myFromTime = fromTime;
QTime myToTime = toTime;
if (expandable) {
QDate curDate(fromDate);
while (curDate <= toDate) {
KCalendarCore::Event::List eventList = mCalendar->events(curDate, QTimeZone::systemTimeZone());
for (const KCalendarCore::Event::Ptr &event : qAsConst(eventList)) {
Q_ASSERT(event);
if (event->allDay()) {
continue;
}
int maxAllDayEvents = 0;
QDate curDate(fromDate);
while (curDate <= toDate) {
KCalendarCore::Event::List eventList = mCalendar->events(curDate, QTimeZone::systemTimeZone());
const auto holidays = holiday(curDate);
int allDayEvents = holiday(curDate).isEmpty() ? 0 : 1;
for (const KCalendarCore::Event::Ptr &event : qAsConst(eventList)) {
Q_ASSERT(event);
if (!event
|| (excludeConfidential && event->secrecy() == KCalendarCore::Incidence::SecrecyConfidential)
|| (excludePrivate && event->secrecy() == KCalendarCore::Incidence::SecrecyPrivate)) {
continue;
}
if (event->allDay()) {
allDayEvents += 1;
} else if (expandable) {
if (event->dtStart().time() < myFromTime) {
myFromTime = event->dtStart().time();
}
......@@ -1450,38 +1445,70 @@ void CalPrintPluginBase::drawTimeTable(QPainter &p,
myToTime = event->dtEnd().time();
}
}
curDate = curDate.addDays(1);
}
if (allDayEvents > maxAllDayEvents) {
maxAllDayEvents = allDayEvents;
}
curDate = curDate.addDays(1);
}
// timeline is 1 hour:
int alldayHeight = (int)(3600. * box.height() / (myFromTime.secsTo(myToTime) + 3600.));
int timelineWidth = TIMELINE_WIDTH;
QFont oldFont(p.font());
p.setFont(QFont(QStringLiteral("sans-serif"), 11, QFont::Normal));
const int lineSpacing = p.fontMetrics().lineSpacing();
int timelineWidth = TIMELINE_WIDTH + padding();
QRect dowBox(box);
dowBox.setLeft(box.left() + timelineWidth);
dowBox.setHeight(mSubHeaderHeight);
drawDaysOfWeek(p, fromDate, toDate, dowBox);
int tlTop = dowBox.bottom();
int alldayHeight = 0;
if (maxAllDayEvents > 0) {
// Draw the side bar for all-day events.
const auto alldayLabel = i18nc("label for timetable all-day boxes", "All day");
QFont oldFont(p.font());
p.setFont(QFont(QStringLiteral("sans-serif"), 9, QFont::Normal));
const auto labelHeight = p.fontMetrics().horizontalAdvance(alldayLabel) + 2*padding();
alldayHeight = std::max(maxAllDayEvents*lineSpacing + 2*padding(), labelHeight);
drawVerticalBox(p,
BOX_BORDER_WIDTH,
QRect(0, tlTop, TIMELINE_WIDTH, alldayHeight),
alldayLabel,
Qt::AlignHCenter | Qt::AlignVCenter | Qt::TextWordWrap);
p.setFont(oldFont);
tlTop += alldayHeight +padding();
}
QRect tlBox(box);
tlBox.setWidth(timelineWidth);
tlBox.setTop(dowBox.bottom() + BOX_BORDER_WIDTH + alldayHeight);
tlBox.setWidth(TIMELINE_WIDTH);
tlBox.setTop(tlTop);
drawTimeLine(p, myFromTime, myToTime, tlBox);
// draw each day
QDate curDate(fromDate);
curDate = fromDate;
int i = 0;
double cellWidth = double(dowBox.width()) / double(fromDate.daysTo(toDate) + 1);
double cellWidth = double(dowBox.width() - 1) / double(fromDate.daysTo(toDate) + 1);
QRect allDayBox(dowBox.left(), dowBox.bottom(), cellWidth, alldayHeight);
const QList<QDate> workDays = CalendarSupport::workDays(fromDate, toDate);
while (curDate <= toDate) {
QRect allDayBox(dowBox.left() + int(i * cellWidth), dowBox.bottom() + BOX_BORDER_WIDTH, int((i + 1) * cellWidth) - int(i * cellWidth), alldayHeight);
QRect dayBox(allDayBox);
dayBox.setTop(tlBox.top());
dayBox.setBottom(box.bottom());
KCalendarCore::Event::List eventList =
mCalendar->events(curDate, QTimeZone::systemTimeZone(), KCalendarCore::EventSortStartDate, KCalendarCore::SortDirectionAscending);
alldayHeight = drawAllDayBox(p, eventList, curDate, false, allDayBox, excludeConfidential, excludePrivate);
allDayBox.setLeft(dowBox.left() + int(i * cellWidth));
allDayBox.setRight(dowBox.left() + int((i + 1) * cellWidth));
if (maxAllDayEvents > 0) {
if (const auto h = holidayEvent(curDate)) {
eventList.prepend(h);
}
drawAllDayBox(p, eventList, curDate, allDayBox, includeCategories, excludeConfidential, excludePrivate, workDays);
}
QRect dayBox(allDayBox);
dayBox.setTop(tlTop);
dayBox.setBottom(box.bottom());
drawAgendaDayBox(p,
eventList,
curDate,
......
......@@ -306,31 +306,25 @@ public:
/**
Draw the all-day box for the agenda print view (the box on top which
doesn't have a time on the time scale associated). If expandable is set,
height is the cell height of a single cell, and the returned height will
be the total height used for the all-day events. If !expandable, only one
cell will be used, and multiple events are concatenated using ", ".
doesn't have a time on the time scale associated).
@param p QPainter of the printout
@param eventList The list of all-day events that are supposed to be printed
inside this box
@param qd The date of the currently printed day
@param expandable If true, height is the height of one single cell, the printout
will use as many cells as events in the list and return the total height
needed for all of them. If false, height specifies the total height
allowed for all events, and the events are displayed in one cell,
with their summaries concatenated by ", ".
@param box coordinates of the all day box.
@param includeCategories Whether to print the event categories (tags) as well.
@param excludeConfidential Whether to exclude Incidence marked confidential.
@param excludePrivate Whether to exclude Incidence marked private.
@return The height used for the all-day box.
@param workDays List of workDays
*/
int drawAllDayBox(QPainter &p,
void drawAllDayBox(QPainter &p,
const KCalendarCore::Event::List &eventList,
QDate qd,
bool expandable,
QRect box,
bool includeCategories,
bool excludeConfidential,
bool excludePrivate);
bool excludePrivate,
const QList<QDate> &workDays);
/**
Draw the agenda box for the day print style (the box showing all events of that day).
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment