File indexing completed on 2024-11-24 04:42:28
0001 /* 0002 * calendarfunctions.cpp - miscellaneous calendar access functions 0003 * Program: kalarm 0004 * SPDX-FileCopyrightText: 2020 David Jarvie <djarvie@kde.org> 0005 * 0006 * SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #include "calendarfunctions.h" 0010 0011 #include "preferences.h" 0012 #include "lib/messagebox.h" 0013 #include "kalarm_debug.h" 0014 0015 #include <KCalendarCore/CalFormat> 0016 #include <KCalendarCore/Event> 0017 #include <KCalendarCore/MemoryCalendar> 0018 using namespace KCalendarCore; 0019 0020 #include <KLocalizedString> 0021 #include <KJobWidgets> 0022 #include <KIO/StoredTransferJob> 0023 0024 #include <QTemporaryFile> 0025 0026 0027 namespace KAlarm 0028 { 0029 0030 /****************************************************************************** 0031 * Import alarms from a calendar file. The alarms are converted to the current 0032 * KAlarm format and are given new unique event IDs. 0033 * Parameters: parent: parent widget for error message boxes 0034 * alarmList: imported alarms are appended to this list 0035 */ 0036 bool importCalendarFile(const QUrl& url, CalEvent::Types alarmTypes, bool newId, QWidget* parent, QHash<CalEvent::Type, QList<KAEvent>>& alarmList) 0037 { 0038 if (!url.isValid()) 0039 { 0040 qCDebug(KALARM_LOG) << "KAlarm::importCalendarFile: Invalid URL"; 0041 return false; 0042 } 0043 0044 // If the URL is remote, download it into a temporary local file. 0045 QString filename; 0046 bool local = url.isLocalFile(); 0047 if (local) 0048 { 0049 filename = url.toLocalFile(); 0050 if (!QFile::exists(filename)) 0051 { 0052 qCDebug(KALARM_LOG) << "KAlarm::importCalendarFile:" << url.toDisplayString() << "not found"; 0053 KAMessageBox::error(parent, xi18nc("@info", "Could not load calendar <filename>%1</filename>.", url.toDisplayString())); 0054 return false; 0055 } 0056 } 0057 else 0058 { 0059 auto getJob = KIO::storedGet(url); 0060 KJobWidgets::setWindow(getJob, parent); 0061 if (!getJob->exec()) 0062 { 0063 qCCritical(KALARM_LOG) << "KAlarm::importCalendarFile: Download failure"; 0064 KAMessageBox::error(parent, xi18nc("@info", "Cannot download calendar: <filename>%1</filename>", url.toDisplayString())); 0065 return false; 0066 } 0067 QTemporaryFile tmpFile; 0068 tmpFile.setAutoRemove(false); 0069 tmpFile.write(getJob->data()); 0070 tmpFile.seek(0); 0071 filename = tmpFile.fileName(); 0072 qCDebug(KALARM_LOG) << "KAlarm::importCalendarFile: --- Downloaded to" << filename; 0073 } 0074 0075 // Read the calendar and add its alarms to the current calendars 0076 MemoryCalendar::Ptr cal(new MemoryCalendar(Preferences::timeSpecAsZone())); 0077 FileStorage::Ptr calStorage(new FileStorage(cal, filename)); 0078 bool success = calStorage->load(); 0079 if (!local) 0080 QFile::remove(filename); 0081 if (!success) 0082 { 0083 qCDebug(KALARM_LOG) << "KAlarm::importCalendarFile: Error loading calendar '" << filename <<"'"; 0084 KAMessageBox::error(parent, xi18nc("@info", "Could not load calendar <filename>%1</filename>.", url.toDisplayString())); 0085 return false; 0086 } 0087 0088 QString versionString; 0089 const bool currentFormat = (KACalendar::updateVersion(calStorage, versionString) != KACalendar::IncompatibleFormat); 0090 const Event::List events = cal->rawEvents(); 0091 for (const Event::Ptr& event : events) 0092 { 0093 if (event->alarms().isEmpty() || !KAEvent(event).isValid()) 0094 continue; // ignore events without alarms, or usable alarms 0095 CalEvent::Type type = CalEvent::status(event); 0096 if (type == CalEvent::TEMPLATE) 0097 { 0098 // If we know the event was not created by KAlarm, don't treat it as a template 0099 if (!currentFormat) 0100 type = CalEvent::ACTIVE; 0101 } 0102 if (!(type & alarmTypes)) 0103 continue; 0104 0105 Event::Ptr newev(new Event(*event)); 0106 0107 // If there is a display alarm without display text, use the event 0108 // summary text instead. 0109 if (type == CalEvent::ACTIVE && !newev->summary().isEmpty()) 0110 { 0111 const Alarm::List& alarms = newev->alarms(); 0112 for (Alarm::Ptr alarm : alarms) 0113 { 0114 if (alarm->type() == Alarm::Display && alarm->text().isEmpty()) 0115 alarm->setText(newev->summary()); 0116 } 0117 newev->setSummary(QString()); // KAlarm only uses summary for template names 0118 } 0119 0120 // Give the event a new ID, or ensure that it is in the correct format. 0121 const QString id = newId ? CalFormat::createUniqueId() : newev->uid(); 0122 newev->setUid(CalEvent::uid(id, type)); 0123 0124 alarmList[type] += KAEvent(newev); 0125 } 0126 return true; 0127 } 0128 0129 } 0130 0131 // vim: et sw=4: