File indexing completed on 2024-05-12 16:59:38

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 subLabels(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     std::string utf8Str;
0053     dateString.toUTF8String<std::string>(utf8Str);
0054 
0055     return QString::fromStdString(utf8Str);
0056 }
0057 
0058 QString HebrewCalendarProviderPrivate::formattedDateStringInNativeLanguage(const icu::UnicodeString &str) const
0059 {
0060     UErrorCode errorCode = U_ZERO_ERROR;
0061     icu::UnicodeString dateString;
0062     icu::SimpleDateFormat formatter(str, m_nativeLocale, errorCode);
0063     formatter.setCalendar(*m_calendar);
0064     formatter.format(m_calendar->getTime(errorCode), dateString);
0065 
0066     std::string utf8Str;
0067     dateString.toUTF8String<std::string>(utf8Str);
0068 
0069     return QString::fromStdString(utf8Str);
0070 }
0071 
0072 QCalendar::YearMonthDay HebrewCalendarProviderPrivate::fromGregorian(const QDate &_date)
0073 {
0074     if (U_FAILURE(m_errorCode) || !_date.isValid() || !setDate(_date)) {
0075         return {};
0076     }
0077 
0078     return date();
0079 }
0080 
0081 CalendarEvents::CalendarEventsPlugin::SubLabel HebrewCalendarProviderPrivate::subLabels(const QDate &date)
0082 {
0083     auto sublabel = CalendarEvents::CalendarEventsPlugin::SubLabel{};
0084 
0085     if (U_FAILURE(m_errorCode) || !date.isValid() || !setDate(date)) {
0086         return sublabel;
0087     }
0088 
0089     const bool isLocaleHebrew = QLocale::system().language() == QLocale::Hebrew;
0090 
0091     sublabel.dayLabel = isLocaleHebrew ? formattedDateString("d") : QString::number(day());
0092     const QString hebrewDateString = formattedDateString("d בMMMM y"); // See https://unicode-org.github.io/cldr/ldml/tr35-dates.html
0093     // Translated month names are available in https://github.com/unicode-org/icu/tree/main/icu4c/source/data/locales
0094     sublabel.label = isLocaleHebrew ? hebrewDateString
0095                                     : i18ndc("plasma_calendar_alternatecalendar",
0096                                              "%1 Day number %2 Translated month name in Hebrew/Jewish calendar %3 Year number %4 Full date in Hebrew",
0097                                              "%1 %2, %3 (%4)",
0098                                              QString::number(day()),
0099                                              formattedDateStringInNativeLanguage("MMMM"),
0100                                              QString::number(year()),
0101                                              hebrewDateString);
0102     sublabel.priority = CalendarEvents::CalendarEventsPlugin::SubLabelPriority::Low;
0103 
0104     return sublabel;
0105 }
0106 
0107 HebrewCalendarProvider::HebrewCalendarProvider(QObject *parent, CalendarSystem::System calendarSystem)
0108     : AbstractCalendarProvider(parent, calendarSystem)
0109     , d(std::make_unique<HebrewCalendarProviderPrivate>())
0110 {
0111     Q_ASSERT(m_calendarSystem == CalendarSystem::Hebrew);
0112 }
0113 
0114 HebrewCalendarProvider::~HebrewCalendarProvider()
0115 {
0116 }
0117 
0118 QCalendar::YearMonthDay HebrewCalendarProvider::fromGregorian(const QDate &date) const
0119 {
0120     return d->fromGregorian(date);
0121 }
0122 
0123 CalendarEvents::CalendarEventsPlugin::SubLabel HebrewCalendarProvider::subLabels(const QDate &date) const
0124 {
0125     return d->subLabels(date);
0126 }