Commit aabf184f authored by Glen Ditchfield's avatar Glen Ditchfield 🐛
Browse files

Display multi-day holidays as one wide block in the Month View

Display multi-day holidays, such as Lunar New Year in the Hong Kong
holiday list, just like a multi-day event:  a block that spans days,
instead of separate blocks on each day.

As a side-effect, Valentine's Day does not appear in the Month View
when it happens to fall on a non-workday.  The Month View will only
show true non-workday holidays.

Users of multiple regional calendars may see multiple holidays on a
day, instead of one block with multiple holiday names in it.

BUG: 187116
parent a0a30549
Pipeline #79890 failed with stage
in 2 minutes and 14 seconds
......@@ -33,16 +33,21 @@ void MonthItemOrderTest::longerInstancesFirst()
{
QDate startDate(2000, 01, 01);
IncidenceMonthItem *longEvent = eventItem(startDate, startDate.addDays(1));
HolidayMonthItem *longHoliday = new HolidayMonthItem(nullptr, startDate, startDate.addDays(1), QStringLiteral(""));
for (int offset = -1; offset < 3; offset++) {
QDate d = startDate.addDays(offset);
IncidenceMonthItem *shortEvent = eventItem(d, d);
QVERIFY( MonthItem::greaterThan(longEvent, shortEvent));
QVERIFY( ! MonthItem::greaterThan(shortEvent, longEvent));
QVERIFY( MonthItem::greaterThan(longHoliday, shortEvent));
QVERIFY( ! MonthItem::greaterThan(shortEvent, longHoliday));
HolidayMonthItem *shortHoliday = new HolidayMonthItem(nullptr, d, QStringLiteral(""));
QVERIFY( MonthItem::greaterThan(longEvent, shortHoliday));
QVERIFY( ! MonthItem::greaterThan(shortHoliday, longEvent));
QVERIFY( MonthItem::greaterThan(longHoliday, shortHoliday));
QVERIFY( ! MonthItem::greaterThan(shortHoliday, longHoliday));
}
}
......
......@@ -667,8 +667,14 @@ void IncidenceMonthItem::setNewDates(const KCalendarCore::Incidence::Ptr &incide
//-----------------------------------------------------------------
// HOLIDAYMONTHITEM
HolidayMonthItem::HolidayMonthItem(MonthScene *monthScene, QDate date, const QString &name)
: HolidayMonthItem(monthScene, date, date, name)
{
}
HolidayMonthItem::HolidayMonthItem(MonthScene *monthScene, QDate startDate, QDate endDate, const QString &name)
: MonthItem(monthScene)
, mDate(date)
, mStartDate(startDate)
, mEndDate(endDate)
, mName(name)
{
}
......
......@@ -336,18 +336,19 @@ class EVENTVIEWS_EXPORT HolidayMonthItem : public MonthItem
public:
HolidayMonthItem(MonthScene *monthScene, QDate date, const QString &name);
HolidayMonthItem(MonthScene *monthScene, QDate startDate, QDate endDate, const QString &name);
~HolidayMonthItem() override;
bool greaterThanFallback(const MonthItem *other) const override;
QDate realStartDate() const override
{
return mDate;
return mStartDate;
}
QDate realEndDate() const override
{
return mDate;
return mEndDate;
}
bool allDay() const override
......@@ -386,7 +387,8 @@ protected:
void finalizeResize(const QDate &newStartDate, const QDate &newEndDate) override;
private:
QDate mDate;
QDate mStartDate;
QDate mEndDate;
QString mName;
};
}
......
......@@ -20,6 +20,7 @@
#include "calendarview_debug.h"
#include <KCalendarCore/OccurrenceIterator>
#include <KCheckableProxyModel>
#include <KHolidays/HolidayRegion>
#include <KLocalizedString>
#include <QIcon>
......@@ -435,6 +436,19 @@ Akonadi::Item::List MonthView::selectedIncidences() const
return selected;
}
KHolidays::Holiday::List MonthView::holidays(QDate startDate, QDate endDate)
{
KHolidays::Holiday::List holidays;
auto const regions = CalendarSupport::KCalPrefs::instance()->mHolidays;
for (auto const r : regions) {
KHolidays::HolidayRegion region(r);
if (region.isValid()) {
holidays += region.holidays(startDate, endDate);
}
}
return holidays;
}
void MonthView::reloadIncidences()
{
if (changes() == NothingChanged) {
......@@ -502,16 +516,10 @@ void MonthView::reloadIncidences()
}
// add holidays
const QList<QDate> workDays = CalendarSupport::workDays(actualStartDateTime().date(), actualEndDateTime().date());
for (QDate date = actualStartDateTime().date(); date <= actualEndDateTime().date(); date = date.addDays(1)) {
// Only call CalendarSupport::holiday() if it's not a workDay, saves come cpu cicles.
if (!workDays.contains(date)) {
QStringList holidays(CalendarSupport::holiday(date));
if (!holidays.isEmpty()) {
MonthItem *holidayItem = new HolidayMonthItem(d->scene, date, holidays.join(i18nc("@item:intext delimiter for joining holiday names", ",")));
d->scene->mManagerList << holidayItem;
}
for (auto const h : holidays(actualStartDateTime().date(), actualEndDateTime().date())) {
if (h.dayType() == KHolidays::Holiday::NonWorkday) {
MonthItem *holidayItem = new HolidayMonthItem(d->scene, h.observedStartDate(), h.observedEndDate(), h.name());
d->scene->mManagerList << holidayItem;
}
}
......
......@@ -10,6 +10,8 @@
#include "eventview.h"
#include <KHolidays/HolidayRegion>
class QModelIndex;
namespace EventViews
......@@ -94,6 +96,8 @@ protected:
QPair<QDateTime, QDateTime> actualDateRange(const QDateTime &start, const QDateTime &end, const QDate &preferredMonth = QDate()) const override;
KHolidays::Holiday::List holidays(QDate startDate, QDate endDate);
// Compute and update the whole view
void reloadIncidences();
......
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