Verified Commit 47bcfc37 authored by Fushan Wen's avatar Fushan Wen 💬
Browse files

alternatecalendar: Add Chinese lunar calendar system support

The traditional Chinese calendar (also known as the Agricultural
Calendar is a lunisolar calendar which identifies years, months,
and days according to astronomical phenomena. In China, it is defined
by the Chinese national standard GB/T 33661–2017, "Calculation and
Promulgation of the Chinese Calendar", issued by the Standardization
Administration of China on May 12, 2017.

The plugin is adapted from https://github.com/BLumia/pineapple-calendar



Co-authored-by: Gary Wang's avatarGary Wang <wzc782970009@gmail.com>

FEATURE: 429892
FIXED-IN: 5.26
parent 73f19554
......@@ -24,6 +24,7 @@ if(ICU_FOUND)
set(alternatecalendar_LIB_SRCS
${alternatecalendar_LIB_SRCS}
provider/icucalendar_p.cpp
provider/chinesecalendar.cpp
)
set(alternatecalendar_LINK_LIBRARIES
${alternatecalendar_LINK_LIBRARIES}
......
......@@ -4,6 +4,8 @@
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "config-ICU.h"
#include "alternatecalendarplugin.h"
#include <KConfigGroup>
......@@ -11,6 +13,9 @@
#include <KSharedConfig>
#include "provider/qtcalendar.h"
#ifdef HAVE_ICU
#include "provider/chinesecalendar.h"
#endif
class AlternateCalendarPluginPrivate
{
......@@ -55,6 +60,11 @@ void AlternateCalendarPluginPrivate::init()
// Load/Reload the calendar provider
switch (m_calendarSystem) {
#ifdef HAVE_ICU
case CalendarSystem::Chinese:
m_calendarProvider.reset(new ChineseCalendarProvider(q, m_calendarSystem));
break;
#endif
#ifndef QT_BOOTSTRAPPED
case CalendarSystem::Julian:
case CalendarSystem::Milankovic:
......
......@@ -29,6 +29,7 @@ public:
#if QT_CONFIG(islamiccivilcalendar)
IslamicCivil = static_cast<int>(QCalendar::System::IslamicCivil),
#endif
Chinese = static_cast<int>(QCalendar::System::Last) + 1, // QTBUG-89824: QCalendar doesn't support Chinese calendar system
};
Q_ENUM(System)
};
......
......@@ -5,7 +5,7 @@
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "config-ICU.h"
#include "../../config-ICU.h"
#include "configstorage.h"
#include <QMetaEnum>
......@@ -26,6 +26,9 @@ CalendarSystemModel::CalendarSystemModel(QObject *parent)
#endif
#if QT_CONFIG(islamiccivilcalendar)
{CalendarSystem::IslamicCivil, i18ndc("plasma_calendar_alternatecalendar", "@item:inlist", "The Islamic Civil Calendar")},
#endif
#ifdef HAVE_ICU
{CalendarSystem::Chinese, i18ndc("plasma_calendar_alternatecalendar", "@item:inlist", "Chinese Lunar Calendar")},
#endif
};
const QMetaEnum e = QMetaEnum::fromType<CalendarSystem::System>();
......
/*
SPDX-FileCopyrightText: 2021 Gary Wang <wzc782970009@gmail.com>
SPDX-FileCopyrightText: 2022 Fushan Wen <qydwhotmail@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "chinesecalendar.h"
class ChineseCalendarProviderPrivate : public ICUCalendarPrivate
{
public:
explicit ChineseCalendarProviderPrivate();
CalendarEvents::CalendarEventsPlugin::SubLabel subLabels(const QDate &date);
private:
/**
* For formatting, see the documentation of SimpleDateFormat:
* https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classicu_1_1SimpleDateFormat.html#details
*/
QString formattedDateString(const icu::UnicodeString &str, bool hanidays = false) const;
QString yearDisplayName() const;
QString monthDisplayName() const;
QString dayDisplayName() const;
};
ChineseCalendarProviderPrivate::ChineseCalendarProviderPrivate()
: ICUCalendarPrivate()
{
if (U_FAILURE(m_errorCode)) {
return; // Failed to create m_GregorianCalendar
}
m_calendar.reset(icu::Calendar::createInstance("en_US@calendar=chinese", m_errorCode));
}
CalendarEvents::CalendarEventsPlugin::SubLabel ChineseCalendarProviderPrivate::subLabels(const QDate &date)
{
auto sublabel = CalendarEvents::CalendarEventsPlugin::SubLabel{};
if (U_FAILURE(m_errorCode) || !date.isValid() || !setDate(date)) {
return sublabel;
}
sublabel.yearLabel = yearDisplayName();
sublabel.monthLabel = monthDisplayName();
sublabel.dayLabel = day() == 1 ? monthDisplayName() : dayDisplayName();
sublabel.label = QStringLiteral("%1%2%3").arg(sublabel.yearLabel, sublabel.monthLabel, sublabel.dayLabel);
sublabel.priority = CalendarEvents::CalendarEventsPlugin::SubLabelPriority::Low;
return sublabel;
}
QString ChineseCalendarProviderPrivate::formattedDateString(const icu::UnicodeString &str, bool hanidays) const
{
const icu::Locale locale("zh", 0, 0, hanidays ? "calendar=chinese;numbers=hanidays" : "calendar=chinese");
UErrorCode errorCode = U_ZERO_ERROR;
icu::UnicodeString dateString;
icu::SimpleDateFormat formatter(str, locale, errorCode);
formatter.setCalendar(*m_calendar);
formatter.format(m_calendar->getTime(errorCode), dateString);
std::string utf8Str;
dateString.toUTF8String<std::string>(utf8Str);
return QString::fromUtf8(utf8Str.c_str());
}
QString ChineseCalendarProviderPrivate::yearDisplayName() const
{
return formattedDateString("U");
}
QString ChineseCalendarProviderPrivate::monthDisplayName() const
{
return formattedDateString("MMM");
}
QString ChineseCalendarProviderPrivate::dayDisplayName() const
{
return formattedDateString("d", true);
}
ChineseCalendarProvider::ChineseCalendarProvider(QObject *parent, CalendarSystem::System calendarSystem)
: AbstractCalendarProvider(parent, calendarSystem)
, d(std::make_unique<ChineseCalendarProviderPrivate>())
{
Q_ASSERT(m_calendarSystem == CalendarSystem::Chinese);
}
ChineseCalendarProvider::~ChineseCalendarProvider()
{
}
CalendarEvents::CalendarEventsPlugin::SubLabel ChineseCalendarProvider::subLabels(const QDate &date) const
{
return d->subLabels(date);
}
/*
SPDX-FileCopyrightText: 2021 Gary Wang <wzc782970009@gmail.com>
SPDX-FileCopyrightText: 2022 Fushan Wen <qydwhotmail@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include "abstractcalendarprovider.h"
#include "icucalendar_p.h"
/**
* @short An alternate calendar provider for Chinese calendar system.
*
* This class presents an alternate calendar provider for Chinese calendar system.
*/
class ChineseCalendarProvider : public AbstractCalendarProvider
{
Q_OBJECT
public:
explicit ChineseCalendarProvider(QObject *parent, CalendarSystem::System calendarSystem);
~ChineseCalendarProvider() override;
CalendarEvents::CalendarEventsPlugin::SubLabel subLabels(const QDate &date) const override;
private:
const std::unique_ptr<class ChineseCalendarProviderPrivate> d;
};
Supports Markdown
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