File indexing completed on 2024-05-12 05:29:42

0001 /*
0002     SPDX-FileCopyrightText: 2022 Fushan Wen <qydwhotmail@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "config-ICU.h"
0008 
0009 #include "alternatecalendarplugin.h"
0010 
0011 #include <QThreadPool>
0012 
0013 #include <KSharedConfig>
0014 
0015 #include "provider/qtcalendar.h"
0016 #if HAVE_ICU
0017 #include "provider/chinesecalendar.h"
0018 #include "provider/hebrewcalendar.h"
0019 #include "provider/indiancalendar.h"
0020 #include "provider/islamiccalendar.h"
0021 #endif
0022 
0023 using namespace Qt::StringLiterals;
0024 using SubLabel = CalendarEvents::CalendarEventsPlugin::SubLabel;
0025 
0026 AlternateCalendarPlugin::AlternateCalendarPlugin(QObject *parent)
0027     : CalendarEvents::CalendarEventsPlugin(parent)
0028 {
0029     auto config = KSharedConfig::openConfig("plasma_calendar_alternatecalendar"_L1, KConfig::NoGlobals);
0030     m_generalConfigGroup = config->group("General");
0031     m_configWatcher = KConfigWatcher::create(config);
0032     connect(m_configWatcher.get(), &KConfigWatcher::configChanged, this, &AlternateCalendarPlugin::updateSettings);
0033 
0034     init();
0035 }
0036 
0037 AlternateCalendarPlugin::~AlternateCalendarPlugin()
0038 {
0039 }
0040 
0041 void AlternateCalendarPlugin::loadEventsForDateRange(const QDate &startDate, const QDate &endDate)
0042 {
0043     if (!endDate.isValid() || m_calendarSystem == CalendarSystem::Gregorian) {
0044         return;
0045     }
0046 
0047     if (m_lastStartDate == startDate && m_lastEndDate == endDate) {
0048         emitDataChangedSignal();
0049         return;
0050     }
0051 
0052     switch (m_calendarSystem) {
0053 #if HAVE_ICU
0054     case CalendarSystem::Chinese:
0055         m_provider = new ChineseCalendarProvider(this, m_calendarSystem, startDate, endDate);
0056         break;
0057     case CalendarSystem::Indian:
0058         m_provider = new IndianCalendarProvider(this, m_calendarSystem, startDate, endDate);
0059         break;
0060     case CalendarSystem::Hebrew:
0061         m_provider = new HebrewCalendarProvider(this, m_calendarSystem, startDate, endDate);
0062         break;
0063     case CalendarSystem::Jalali:
0064     case CalendarSystem::Islamic:
0065     case CalendarSystem::IslamicCivil:
0066     case CalendarSystem::IslamicUmalqura:
0067         m_provider = new IslamicCalendarProvider(this, m_calendarSystem, startDate, endDate, m_dateOffset);
0068         break;
0069 #else
0070     // Fall back to QtCalendar
0071     case CalendarSystem::Jalali:
0072     case CalendarSystem::IslamicCivil:
0073 #endif
0074     case CalendarSystem::Julian:
0075     case CalendarSystem::Milankovic:
0076         m_provider = new QtCalendarProvider(this, m_calendarSystem, startDate, endDate, m_dateOffset);
0077         break;
0078     default:
0079         m_provider = new AbstractCalendarProvider(this, m_calendarSystem, startDate, endDate, m_dateOffset);
0080     }
0081     connect(m_provider,
0082             &AbstractCalendarProvider::dataReady,
0083             this,
0084             [this, startDate, endDate](const QHash<QDate, QCalendar::YearMonthDay> &alternateDatesData,
0085                                        const QHash<QDate, CalendarEvents::CalendarEventsPlugin::SubLabel> &sublabelData) {
0086                 // Check if the sender is the latest
0087                 if (m_provider == sender()) {
0088                     m_alternateDateCache = alternateDatesData;
0089                     m_sublabelCache = sublabelData;
0090                     m_lastStartDate = startDate;
0091                     m_lastEndDate = endDate;
0092                     emitDataChangedSignal();
0093                     m_provider = nullptr;
0094                 }
0095                 delete sender();
0096             });
0097 
0098     m_provider->setAutoDelete(false);
0099     QThreadPool::globalInstance()->start(m_provider);
0100 }
0101 
0102 void AlternateCalendarPlugin::updateSettings(const KConfigGroup &configGroup)
0103 {
0104     if (configGroup.config()->name() != "plasma_calendar_alternatecalendar"_L1) {
0105         return;
0106     }
0107     init();
0108     loadEventsForDateRange(m_lastStartDate, m_lastEndDate);
0109 }
0110 
0111 void AlternateCalendarPlugin::init()
0112 {
0113     m_dateOffset = m_generalConfigGroup.readEntry("dateOffset", 0);
0114 
0115     // Find the matched calendar system
0116     const QString system = m_generalConfigGroup.readEntry("calendarSystem", "Julian");
0117     const auto systemIt = s_calendarMap.find(system);
0118 
0119     if (systemIt == s_calendarMap.end()) {
0120         // Invalid config, fall back to Gregorian
0121         m_calendarSystem = CalendarSystem::Gregorian;
0122     } else {
0123         m_calendarSystem = systemIt->second.system;
0124     }
0125 
0126     // Clear the old cache when config is reloaded
0127     m_lastStartDate = {};
0128     m_lastEndDate = {};
0129     m_alternateDateCache.clear();
0130     m_sublabelCache.clear();
0131 }
0132 
0133 void AlternateCalendarPlugin::emitDataChangedSignal()
0134 {
0135     if (!m_alternateDateCache.empty()) {
0136         Q_EMIT alternateCalendarDateReady(m_alternateDateCache);
0137     }
0138     Q_EMIT subLabelReady(m_sublabelCache);
0139 }
0140 
0141 #include "moc_alternatecalendarplugin.cpp"