File indexing completed on 2024-06-16 05:03:55

0001 /*
0002     SPDX-FileCopyrightText: 2023 Fushan Wen <qydwhotmail@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "hebrewcalendar.h"
0008 
0009 #include "icucalendar_p.h"
0010 
0011 class HebrewCalendarProviderPrivate : public ICUCalendarPrivate
0012 {
0013 public:
0014     explicit HebrewCalendarProviderPrivate();
0015 
0016     /**
0017      * For formatting, see the documentation of SimpleDateFormat:
0018      * https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classicu_1_1SimpleDateFormat.html#details
0019      */
0020     QString formattedDateString(const icu::UnicodeString &str) const;
0021     QString formattedDateStringInNativeLanguage(const icu::UnicodeString &str) const;
0022 
0023     QCalendar::YearMonthDay fromGregorian(const QDate &_date);
0024     CalendarEvents::CalendarEventsPlugin::SubLabel subLabel(const QDate &date);
0025 
0026 private:
0027     // See https://unicode-org.github.io/icu/userguide/locale/#keywords for available keywords
0028     icu::Locale m_hebrewLocale;
0029     icu::Locale m_nativeLocale;
0030 };
0031 
0032 HebrewCalendarProviderPrivate::HebrewCalendarProviderPrivate()
0033     : ICUCalendarPrivate()
0034     , m_hebrewLocale(icu::Locale("he_IL", 0, 0, "calendar=hebrew;numbers=hebr"))
0035     , m_nativeLocale(icu::Locale(QLocale::system().name().toLatin1(), 0, 0, "calendar=hebrew;numbers=hebr"))
0036 {
0037     if (U_FAILURE(m_errorCode)) {
0038         return; // Failed to create m_GregorianCalendar
0039     }
0040 
0041     m_calendar.reset(icu::Calendar::createInstance(icu::Locale("he_IL@calendar=hebrew"), m_errorCode));
0042 }
0043 
0044 QString HebrewCalendarProviderPrivate::formattedDateString(const icu::UnicodeString &str) const
0045 {
0046     UErrorCode errorCode = U_ZERO_ERROR;
0047     icu::UnicodeString dateString;
0048     icu::SimpleDateFormat formatter(str, m_hebrewLocale, errorCode);
0049     formatter.setCalendar(*m_calendar);
0050     formatter.format(m_calendar->getTime(errorCode), dateString);
0051 
0052     return QString::fromUtf16(dateString.getBuffer(), dateString.length());
0053 }
0054 
0055 QString HebrewCalendarProviderPrivate::formattedDateStringInNativeLanguage(const icu::UnicodeString &str) const
0056 {
0057     UErrorCode errorCode = U_ZERO_ERROR;
0058     icu::UnicodeString dateString;
0059     icu::SimpleDateFormat formatter(str, m_nativeLocale, errorCode);
0060     formatter.setCalendar(*m_calendar);
0061     formatter.format(m_calendar->getTime(errorCode), dateString);
0062 
0063     return QString::fromUtf16(dateString.getBuffer(), dateString.length());
0064 }
0065 
0066 QCalendar::YearMonthDay HebrewCalendarProviderPrivate::fromGregorian(const QDate &_date)
0067 {
0068     if (U_FAILURE(m_errorCode) || !_date.isValid() || !setDate(_date)) {
0069         return {};
0070     }
0071 
0072     return date();
0073 }
0074 
0075 CalendarEvents::CalendarEventsPlugin::SubLabel HebrewCalendarProviderPrivate::subLabel(const QDate &date)
0076 {
0077     auto sublabel = CalendarEvents::CalendarEventsPlugin::SubLabel{};
0078 
0079     if (U_FAILURE(m_errorCode) || !date.isValid() || !setDate(date)) {
0080         return sublabel;
0081     }
0082 
0083     const bool isLocaleHebrew = QLocale::system().language() == QLocale::Hebrew;
0084 
0085     sublabel.dayLabel = isLocaleHebrew ? formattedDateString("d") : QString::number(day());
0086     const QString hebrewDateString = formattedDateString("d בMMMM y"); // See https://unicode-org.github.io/cldr/ldml/tr35-dates.html
0087     // Translated month names are available in https://github.com/unicode-org/icu/tree/main/icu4c/source/data/locales
0088     sublabel.label = isLocaleHebrew ? hebrewDateString
0089                                     : i18ndc("plasma_calendar_alternatecalendar",
0090                                              "%1 Day number %2 Translated month name in Hebrew/Jewish calendar %3 Year number %4 Full date in Hebrew",
0091                                              "%1 %2, %3 (%4)",
0092                                              QString::number(day()),
0093                                              formattedDateStringInNativeLanguage("MMMM"),
0094                                              QString::number(year()),
0095                                              hebrewDateString);
0096     sublabel.priority = CalendarEvents::CalendarEventsPlugin::SubLabelPriority::Low;
0097 
0098     return sublabel;
0099 }
0100 
0101 HebrewCalendarProvider::HebrewCalendarProvider(QObject *parent, CalendarSystem::System calendarSystem, const QDate &startDate, const QDate &endDate)
0102     : AbstractCalendarProvider(parent, calendarSystem, startDate, endDate)
0103     , d(std::make_unique<HebrewCalendarProviderPrivate>())
0104 {
0105     Q_ASSERT(m_calendarSystem == CalendarSystem::Hebrew);
0106 }
0107 
0108 HebrewCalendarProvider::~HebrewCalendarProvider()
0109 {
0110 }
0111 
0112 QCalendar::YearMonthDay HebrewCalendarProvider::fromGregorian(const QDate &date) const
0113 {
0114     return d->fromGregorian(date);
0115 }
0116 
0117 CalendarEvents::CalendarEventsPlugin::SubLabel HebrewCalendarProvider::subLabel(const QDate &date) const
0118 {
0119     return d->subLabel(date);
0120 }