File indexing completed on 2025-01-05 03:52:00

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2003-11-03
0007  * Description : calendar parameters.
0008  *
0009  * SPDX-FileCopyrightText: 2003-2005 by Renchi Raju <renchi dot raju at gmail dot com>
0010  * SPDX-FileCopyrightText: 2007-2008 by Orgad Shaneh <orgads at gmail dot com>
0011  * SPDX-FileCopyrightText: 2011      by Andi Clemens <andi dot clemens at googlemail dot com>
0012  * SPDX-FileCopyrightText: 2012      by Angelo Naselli <anaselli at linux dot it>
0013  * SPDX-FileCopyrightText: 2012-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0014  *
0015  * SPDX-License-Identifier: GPL-2.0-or-later
0016  *
0017  * ============================================================ */
0018 
0019 #include "calsettings.h"
0020 
0021 // Local includes
0022 
0023 #include "digikam_debug.h"
0024 #include "digikam_globals.h"
0025 #include "calsystem.h"
0026 
0027 
0028 #ifdef HAVE_KCALENDAR
0029 
0030     // KCalCore includes
0031 
0032 #   if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
0033 
0034 #       include <kcalendarcore/icalformat.h>
0035 #       include <kcalendarcore/filestorage.h>
0036 #       include <kcalendarcore/memorycalendar.h>
0037 
0038 using namespace KCalendarCore;
0039 
0040 #   else
0041 
0042 #       include <kcalcore/icalformat.h>
0043 #       include <kcalcore/filestorage.h>
0044 #       include <kcalcore/memorycalendar.h>
0045 
0046 using namespace KCalCore;
0047 
0048 #   endif
0049 
0050     // Qt includes
0051 
0052 #   include <QTimeZone>
0053 
0054 #endif // HAVE_KCALENDAR
0055 
0056 namespace DigikamGenericCalendarPlugin
0057 {
0058 
0059 class Q_DECL_HIDDEN CalSettings::Private
0060 {
0061 public:
0062 
0063     explicit Private()
0064     {
0065     }
0066 
0067     QMap<int, QUrl>  monthMap;
0068     QMap<QDate, Day> special;
0069 };
0070 
0071 QPointer<CalSettings> CalSettings::s_instance;
0072 
0073 CalSettings::CalSettings(QObject* const parent)
0074     : QObject(parent),
0075       d      (new Private)
0076 {
0077     params.drawLines = false;
0078     params.year      = CalSystem().earliestValidDate().year() + 1;
0079     setPaperSize(QLatin1String("A4"));
0080     setResolution(QLatin1String("High"));
0081     setImagePos(0);
0082 }
0083 
0084 CalSettings::~CalSettings()
0085 {
0086     delete d;
0087 }
0088 
0089 CalSettings* CalSettings::instance(QObject* const parent)
0090 {
0091     if (s_instance.isNull())
0092     {
0093         s_instance = new CalSettings(parent);
0094     }
0095 
0096     return s_instance;
0097 }
0098 
0099 void CalSettings::setYear(int year)
0100 {
0101     params.year = year;
0102 
0103     Q_EMIT settingsChanged();
0104 }
0105 
0106 int CalSettings::year() const
0107 {
0108     return params.year;
0109 }
0110 
0111 void CalSettings::setImage(int month, const QUrl& path)
0112 {
0113     d->monthMap.insert(month, path);
0114 }
0115 
0116 QUrl CalSettings::image(int month) const
0117 {
0118     return (d->monthMap.contains(month) ? d->monthMap[month] : QUrl());
0119 }
0120 
0121 void CalSettings::setPaperSize(const QString& paperSize)
0122 {
0123     if      (paperSize == QLatin1String("A4"))
0124     {
0125         params.paperWidth  = 210;
0126         params.paperHeight = 297;
0127         params.pageSize    = QPageSize::A4;
0128     }
0129     else if (paperSize == QLatin1String("US Letter"))
0130     {
0131         params.paperWidth  = 216;
0132         params.paperHeight = 279;
0133         params.pageSize    = QPageSize::Letter;
0134     }
0135 
0136     Q_EMIT settingsChanged();
0137 }
0138 
0139 void CalSettings::setResolution(const QString& resolution)
0140 {
0141     if      (resolution == QLatin1String("High"))
0142     {
0143         params.printResolution = QPrinter::HighResolution;
0144     }
0145     else if (resolution == QLatin1String("Low"))
0146     {
0147         params.printResolution = QPrinter::ScreenResolution;
0148     }
0149 
0150     Q_EMIT settingsChanged();
0151 }
0152 
0153 void CalSettings::setImagePos(int pos)
0154 {
0155     const int previewSize = 300;
0156 
0157     switch (pos)
0158     {
0159         case CalParams::Top:
0160         {
0161             float zoom    = qMin((float)previewSize / params.paperWidth,
0162                                  (float)previewSize / params.paperHeight);
0163             params.width  = (int)(params.paperWidth  * zoom);
0164             params.height = (int)(params.paperHeight * zoom);
0165 
0166             params.imgPos = CalParams::Top;
0167             break;
0168         }
0169 
0170         case CalParams::Left:
0171         {
0172             float zoom    = qMin((float)previewSize / params.paperWidth,
0173                                  (float)previewSize / params.paperHeight);
0174             params.width  = (int)(params.paperHeight  * zoom);
0175             params.height = (int)(params.paperWidth   * zoom);
0176 
0177             params.imgPos = CalParams::Left;
0178             break;
0179         }
0180 
0181         default:
0182         {
0183             float zoom    = qMin((float)previewSize / params.paperWidth,
0184                                  (float)previewSize / params.paperHeight);
0185             params.width  = (int)(params.paperHeight  * zoom);
0186             params.height = (int)(params.paperWidth   * zoom);
0187 
0188             params.imgPos = CalParams::Right;
0189             break;
0190         }
0191     }
0192 
0193     Q_EMIT settingsChanged();
0194 }
0195 
0196 void CalSettings::setDrawLines(bool draw)
0197 {
0198     if (params.drawLines != draw)
0199     {
0200         params.drawLines = draw;
0201         Q_EMIT settingsChanged();
0202     }
0203 }
0204 
0205 void CalSettings::setRatio(int ratio)
0206 {
0207     if (params.ratio != ratio)
0208     {
0209         params.ratio = ratio;
0210         Q_EMIT settingsChanged();
0211     }
0212 }
0213 
0214 void CalSettings::setFont(const QString& font)
0215 {
0216     if (params.baseFont.family() != font)
0217     {
0218         params.baseFont = QFont(font);
0219         Q_EMIT settingsChanged();
0220     }
0221 }
0222 
0223 void CalSettings::clearSpecial()
0224 {
0225     d->special.clear();
0226 }
0227 
0228 void CalSettings::addSpecial(const QDate& date, const Day& info)
0229 {
0230     if (d->special.contains(date))
0231     {
0232         d->special[date].second.append(QLatin1String("; ")).append(info.second);
0233     }
0234     else
0235     {
0236         d->special[date] = info;
0237     }
0238 }
0239 
0240 bool CalSettings::isPrayDay(const QDate& date) const
0241 {
0242     return (date.dayOfWeek() == Qt::Sunday);
0243 }
0244 
0245 /*!
0246  * \returns true if d->special formatting is to be applied to the particular day
0247  */
0248 bool CalSettings::isSpecial(int month, int day) const
0249 {
0250     QDate dt = CalSystem().date(params.year, month, day);
0251 
0252     return (isPrayDay(dt) || d->special.contains(dt));
0253 }
0254 
0255 /*!
0256  * \returns the color to be used for painting of the day info
0257  */
0258 QColor CalSettings::getDayColor(int month, int day) const
0259 {
0260     QDate dt = CalSystem().date(params.year, month, day);
0261 
0262     if (isPrayDay(dt))
0263     {
0264         return Qt::red;
0265     }
0266 
0267     if (d->special.contains(dt))
0268     {
0269         return d->special[dt].first;
0270     }
0271 
0272     // default
0273 
0274     return Qt::black;
0275 }
0276 
0277 /*!
0278  * \returns the description of the day to be painted on the calendar.
0279  */
0280 QString CalSettings::getDayDescr(int month, int day) const
0281 {
0282     QDate dt = CalSystem().date(params.year, month, day);
0283 
0284     QString ret;
0285 
0286     if (d->special.contains(dt))
0287     {
0288         ret = d->special[dt].second;
0289     }
0290 
0291     return ret;
0292 }
0293 
0294 QPrinter::PrinterMode CalSettings::resolution() const
0295 {
0296     return params.printResolution;
0297 }
0298 
0299 #ifdef HAVE_KCALENDAR
0300 
0301 void CalSettings::loadSpecial(const QUrl& url, const QColor& color)
0302 {
0303     if (url.isEmpty())
0304     {
0305         qCDebug(DIGIKAM_DPLUGIN_GENERIC_LOG) << "Loading calendar from file failed: No valid url provided!";
0306         return;
0307     }
0308 
0309 #   ifdef HAVE_KCALENDAR_QDATETIME
0310 
0311     MemoryCalendar::Ptr memCal(new MemoryCalendar(QTimeZone::utc()));
0312     using DateTime = QDateTime;
0313 
0314 #   else
0315 
0316     MemoryCalendar::Ptr memCal(new MemoryCalendar(QLatin1String("UTC")));
0317     using DateTime = KDateTime;
0318 
0319 #   endif
0320 
0321     FileStorage::Ptr fileStorage(new FileStorage(memCal, url.toLocalFile(), new ICalFormat));
0322 
0323     qCDebug(DIGIKAM_DPLUGIN_GENERIC_LOG) << "Loading calendar from file " << url.toLocalFile();
0324 
0325     if (!fileStorage->load())
0326     {
0327         qCWarning(DIGIKAM_DPLUGIN_GENERIC_LOG) << "Failed to load calendar file!";
0328     }
0329     else
0330     {
0331         CalSystem calSys;
0332         QDate     qFirst, qLast;
0333 
0334         qFirst = calSys.date(params.year, 1, 1);
0335         qLast  = calSys.date(params.year + 1, 1, 1);
0336         qLast  = qLast.addDays(-1);
0337 
0338         DateTime dtFirst(qFirst, QTime(0, 0));
0339         DateTime dtLast(qLast, QTime(0, 0));
0340         DateTime dtCurrent;
0341 
0342         int counter                = 0;
0343         Event::List list = memCal->rawEvents(qFirst, qLast);
0344 
0345         Q_FOREACH (const Event::Ptr event, list)
0346         {
0347             qCDebug(DIGIKAM_DPLUGIN_GENERIC_LOG) << event->summary() << QT_ENDL << "--------";
0348             counter++;
0349 
0350             if (event->recurs())
0351             {
0352                 Recurrence* const recur = event->recurrence();
0353 
0354                 for (dtCurrent = recur->getNextDateTime(dtFirst.addDays(-1));
0355                      (dtCurrent <= dtLast) && dtCurrent.isValid();
0356                      dtCurrent = recur->getNextDateTime(dtCurrent))
0357                 {
0358                     addSpecial(dtCurrent.date(), Day(color, event->summary()));
0359                 }
0360             }
0361             else
0362             {
0363                 addSpecial(event->dtStart().date(), Day(color, event->summary()));
0364             }
0365         }
0366 
0367         qCDebug(DIGIKAM_DPLUGIN_GENERIC_LOG) << "Loaded " << counter << " events";
0368 
0369 #   if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
0370 
0371         memCal->close();
0372 
0373 #   endif
0374 
0375         if (fileStorage->close())
0376         {
0377             qCWarning(DIGIKAM_DPLUGIN_GENERIC_LOG) << "Failed to close calendar file!";
0378         }
0379     }
0380 }
0381 
0382 #endif // HAVE_KCALENDAR
0383 
0384 } // namespace Digikam
0385 
0386 #include "moc_calsettings.cpp"