File indexing completed on 2024-06-02 05:19:20

0001 /*
0002  *  fileresource.cpp  -  base class for calendar resource accessed via file system
0003  *  Program:  kalarm
0004  *  SPDX-FileCopyrightText: 2006-2023 David Jarvie <djarvie@kde.org>
0005  *
0006  *  SPDX-License-Identifier: GPL-2.0-or-later
0007  */
0008 
0009 #include "fileresource.h"
0010 
0011 #include "fileresourcesettings.h"
0012 #include "fileresourceconfigmanager.h"
0013 #include "singlefileresourceconfigdialog.h"
0014 #include "resources.h"
0015 #include "lib/autoqpointer.h"
0016 #include "kalarmcalendar/version.h"
0017 #include "kalarm_debug.h"
0018 
0019 #include <KLocalizedString>
0020 
0021 
0022 FileResource::FileResource(FileResourceSettings::Ptr settings)
0023     : ResourceType(settings->id())
0024     , mSettings(settings)
0025 {
0026     if (!mSettings  ||  !mSettings->isValid()
0027     ||  id() < 0  ||  mSettings->id() != id())
0028         mStatus = Status::NotConfigured;
0029 }
0030 
0031 FileResource::~FileResource()
0032 {
0033 }
0034 
0035 bool FileResource::isValid() const
0036 {
0037 #ifdef DEBUG_DETAIL
0038     if (!mSettings  ||  !mSettings->isValid())
0039         qDebug() << "FileResource::isValid:" << displayId() << "NO (mSettings)";
0040     if (mStatus == Status::NotConfigured  ||  mStatus == Status::Unusable)
0041         qDebug() << "FileResource::isValid:" << displayId() << "NO (Not configured)";
0042     if (mStatus == Status::Closed)
0043         qDebug() << "FileResource::isValid:" << displayId() << "NO (Closed)";
0044     if (id() < 0)
0045         qDebug() << "FileResource::isValid:" << displayId() << "NO (ID < 0)";
0046     if (mSettings  &&  mSettings->id() != id())
0047         qDebug() << "FileResource::isValid:" << displayId() << "NO (ID:" << id() << mSettings->id() << ")";
0048 #endif
0049     // The settings ID must not have changed since construction.
0050     return mSettings  &&  mSettings->isValid()
0051        &&  mStatus < Status::Unusable
0052        &&  id() >= 0  &&  mSettings->id() == id();
0053 }
0054 
0055 ResourceId FileResource::displayId() const
0056 {
0057     return id() & ~IdFlag;
0058 }
0059 
0060 QString FileResource::storageTypeString(bool description) const
0061 {
0062     if (!mSettings)
0063         return {};
0064     bool file;
0065     switch (mSettings->storageType())
0066     {
0067         case FileResourceSettings::File:
0068             file = true;
0069             break;
0070         case FileResourceSettings::Directory:
0071             file = false;
0072             break;
0073         default:
0074             return {};
0075     }
0076     return storageTypeStr(description, file, mSettings->url().isLocalFile());
0077 }
0078 
0079 QUrl FileResource::location() const
0080 {
0081     return mSettings ? mSettings->url() : QUrl();
0082 }
0083 
0084 QString FileResource::displayLocation() const
0085 {
0086     return mSettings ? mSettings->displayLocation() : QString();
0087 }
0088 
0089 QString FileResource::displayName() const
0090 {
0091     return mSettings ? mSettings->displayName() : QString();
0092 }
0093 
0094 QString FileResource::configName() const
0095 {
0096     return mSettings ? mSettings->configName() : QString();
0097 }
0098 
0099 CalEvent::Types FileResource::alarmTypes() const
0100 {
0101     return mSettings ? mSettings->alarmTypes() : CalEvent::EMPTY;
0102 }
0103 
0104 CalEvent::Types FileResource::enabledTypes() const
0105 {
0106     return mSettings && mSettings->isValid() ? mSettings->enabledTypes() : CalEvent::EMPTY;
0107 }
0108 
0109 void FileResource::setEnabled(CalEvent::Type type, bool enabled)
0110 {
0111     if (mSettings)
0112     {
0113         const CalEvent::Types oldEnabled = mSettings->enabledTypes();
0114         const Changes changes = mSettings->setEnabled(type, enabled);
0115         handleEnabledChange(changes, oldEnabled);
0116     }
0117 }
0118 
0119 void FileResource::setEnabled(CalEvent::Types types)
0120 {
0121     if (mSettings)
0122     {
0123         const CalEvent::Types oldEnabled = mSettings->enabledTypes();
0124         const Changes changes = mSettings->setEnabled(types);
0125         handleEnabledChange(changes, oldEnabled);
0126     }
0127 }
0128 
0129 bool FileResource::readOnly() const
0130 {
0131     return mSettings ? mSettings->readOnly() : true;
0132 }
0133 
0134 void FileResource::setReadOnly(bool ronly)
0135 {
0136     if (mSettings)
0137     {
0138         const CalEvent::Types oldEnabled = mSettings->enabledTypes();
0139         Changes changes = mSettings->setReadOnly(ronly);
0140         if (changes)
0141         {
0142             handleSettingsChange(changes);
0143             Resources::notifySettingsChanged(this, changes, oldEnabled);
0144         }
0145     }
0146 }
0147 
0148 int FileResource::writableStatus(CalEvent::Type type) const
0149 {
0150     if (!mSettings  ||  !mSettings->isValid()  ||  mSettings->readOnly())
0151         return -1;
0152     if ((type == CalEvent::EMPTY  && !mSettings->enabledTypes())
0153     ||  (type != CalEvent::EMPTY  && !mSettings->isEnabled(type)))
0154         return -1;
0155     switch (mCompatibility)
0156     {
0157         case KACalendar::Current:
0158             return 1;
0159         case KACalendar::Converted:
0160         case KACalendar::Convertible:
0161             return 0;
0162         default:
0163             return -1;
0164     }
0165 }
0166 
0167 bool FileResource::isWritable(const KAEvent& event) const
0168 {
0169     return isWritable(event.category());
0170 }
0171 
0172 bool FileResource::keepFormat() const
0173 {
0174     return mSettings ? mSettings->keepFormat() : true;
0175 }
0176 
0177 void FileResource::setKeepFormat(bool keep)
0178 {
0179     if (mSettings)
0180     {
0181         const CalEvent::Types oldEnabled = mSettings->enabledTypes();
0182         Changes changes = mSettings->setKeepFormat(keep);
0183         if (changes)
0184         {
0185             handleSettingsChange(changes);
0186             Resources::notifySettingsChanged(this, changes, oldEnabled);
0187         }
0188     }
0189 }
0190 
0191 QColor FileResource::backgroundColour() const
0192 {
0193     return mSettings ? mSettings->backgroundColour() : QColor();
0194 }
0195 
0196 void FileResource::setBackgroundColour(const QColor& colour)
0197 {
0198     if (mSettings)
0199     {
0200         const CalEvent::Types oldEnabled = mSettings->enabledTypes();
0201         Changes changes = mSettings->setBackgroundColour(colour);
0202         if (changes)
0203         {
0204             handleSettingsChange(changes);
0205             Resources::notifySettingsChanged(this, changes, oldEnabled);
0206         }
0207     }
0208 }
0209 
0210 bool FileResource::configIsStandard(CalEvent::Type type) const
0211 {
0212     return mSettings ? mSettings->isStandard(type) : false;
0213 }
0214 
0215 CalEvent::Types FileResource::configStandardTypes() const
0216 {
0217     return mSettings ? mSettings->standardTypes() : CalEvent::EMPTY;
0218 }
0219 
0220 void FileResource::configSetStandard(CalEvent::Type type, bool standard)
0221 {
0222     if (mSettings)
0223     {
0224         const CalEvent::Types oldEnabled = mSettings->enabledTypes();
0225         Changes changes = mSettings->setStandard(type, standard);
0226         if (changes)
0227         {
0228             handleSettingsChange(changes);
0229             Resources::notifySettingsChanged(this, changes, oldEnabled);
0230         }
0231     }
0232 }
0233 
0234 void FileResource::configSetStandard(CalEvent::Types types)
0235 {
0236     if (mSettings)
0237     {
0238         const CalEvent::Types oldEnabled = mSettings->enabledTypes();
0239         Changes changes = mSettings->setStandard(types);
0240         if (changes)
0241         {
0242             handleSettingsChange(changes);
0243             Resources::notifySettingsChanged(this, changes, oldEnabled);
0244         }
0245     }
0246 }
0247 
0248 KACalendar::Compat FileResource::compatibilityVersion(QString& versionString) const
0249 {
0250     versionString = KAlarmCal::getVersionString(mVersion);
0251     return mCompatibility;
0252 }
0253 
0254 /******************************************************************************
0255 * Edit the resource's configuration.
0256 */
0257 void FileResource::editResource(QWidget* dialogParent)
0258 {
0259     switch (storageType())
0260     {
0261         case Storage::File:
0262         {
0263             // Use AutoQPointer to guard against crash on application exit while
0264             // the dialogue is still open. It prevents double deletion (both on
0265             // deletion of parent, and on return from this function).
0266             AutoQPointer<SingleFileResourceConfigDialog> dlg = new SingleFileResourceConfigDialog(false, dialogParent);
0267             const CalEvent::Types enabled = enabledTypes();
0268             CalEvent::Types types = alarmTypes();
0269             if (((types & CalEvent::ACTIVE)  &&  (types & (CalEvent::ARCHIVED | CalEvent::TEMPLATE)))
0270             ||  ((types & CalEvent::ARCHIVED)  &&  (types & CalEvent::TEMPLATE)))
0271                 types &= enabled;
0272             const CalEvent::Type alarmType = (types & CalEvent::ACTIVE)   ? CalEvent::ACTIVE
0273                                            : (types & CalEvent::ARCHIVED) ? CalEvent::ARCHIVED
0274                                            : (types & CalEvent::TEMPLATE) ? CalEvent::TEMPLATE
0275                                            : CalEvent::ACTIVE;
0276             dlg->setAlarmType(alarmType);    // set default alarm type
0277             dlg->setUrl(location(), true);   // show location but disallow edits
0278             dlg->setDisplayName(displayName());
0279             dlg->setReadOnly(readOnly());
0280             if (dlg->exec() == QDialog::Accepted)
0281             {
0282                 // Make any changes requested by the user.
0283                 // Note that the location and alarm type cannot be changed.
0284                 qCDebug(KALARM_LOG) << "FileResource::editResource: Edited" << dlg->displayName();
0285                 setReadOnly(dlg->readOnly());
0286                 Changes changes = mSettings ? mSettings->setDisplayName(dlg->displayName()) : NoChange;
0287                 if (changes != NoChange)
0288                     Resources::notifySettingsChanged(this, changes, enabled);
0289             }
0290             break;
0291         }
0292         case Storage::Directory:
0293             // Not currently intended to be implemented.
0294             break;
0295 
0296         default:
0297             break;
0298     }
0299 }
0300 
0301 /******************************************************************************
0302 * Remove the resource and its settings. The calendar file is not removed.
0303 * The instance will be invalid once it has been removed.
0304 */
0305 bool FileResource::removeResource()
0306 {
0307     qCDebug(KALARM_LOG) << "FileResource::removeResource:" << displayId();
0308     Resources::notifyResourceToBeRemoved(this);
0309     Resource res = Resources::resource(id());
0310     bool ok = FileResourceConfigManager::removeResource(res);
0311     ResourceType::removeResource(id());
0312     return ok;
0313 }
0314 
0315 /******************************************************************************
0316 * Load the resource.
0317 */
0318 bool FileResource::load(bool readThroughCache)
0319 {
0320     qCDebug(KALARM_LOG) << "FileResource::load:" << displayName();
0321     QString errorMessage;
0322     if (!mSettings  ||  !mSettings->isValid())
0323     {
0324         qCWarning(KALARM_LOG) << "FileResource::load: Resource not configured!" << displayName();
0325         errorMessage = i18nc("@info", "Calendar is not configured.");
0326     }
0327     else if (mStatus == Status::Closed)
0328         qCWarning(KALARM_LOG) << "FileResource::load: Resource closed!" << displayName();
0329     else
0330     {
0331         if (!isEnabled(CalEvent::EMPTY))
0332         {
0333             // Don't load a disabled resource, but mark it as usable (but not loaded).
0334             qCDebug(KALARM_LOG) << "FileResource::load: Resource disabled" << displayName();
0335             setStatus(Status::Ready);
0336             return false;
0337         }
0338 
0339         // Do the actual loading.
0340         QHash<QString, KAEvent> newEvents;
0341         switch (doLoad(newEvents, readThroughCache, errorMessage))
0342         {
0343             case 1:   // success
0344                 loaded(true, newEvents, QString());
0345                 return true;
0346             case 0:   // loading initiated
0347                 return true;
0348             default:  // failure
0349                 break;
0350         }
0351     }
0352 
0353     if (!errorMessage.isEmpty())
0354         Resources::notifyResourceMessage(this, MessageType::Error, xi18nc("@info", "Error loading calendar <resource>%1</resource>.", displayName()), errorMessage);
0355     setNewlyEnabled(false);
0356     return false;
0357 }
0358 
0359 /******************************************************************************
0360 * Called when the resource has loaded, to finish setting it up.
0361 */
0362 void FileResource::loaded(bool success, QHash<QString, KAEvent>& newEvents, const QString& errorMessage)
0363 {
0364     if (!mSettings)
0365         return;
0366     if (!success)
0367     {
0368         // This is only done when a delayed load fails.
0369         // If the resource previously loaded successfully, leave its events (in
0370         // mEvents) unchanged.
0371         if (!errorMessage.isEmpty())
0372             Resources::notifyResourceMessage(this, MessageType::Error, xi18nc("@info", "Error loading calendar <resource>%1</resource>.", displayName()), errorMessage);
0373         return;
0374     }
0375 
0376     if (isEnabled(CalEvent::ACTIVE))
0377     {
0378         // Set any command execution error flags for the events.
0379         // These are stored in the KAlarm config file, not the alarm
0380         // calendar, since they are specific to the user's local system.
0381         bool changed = false;
0382         QHash<QString, KAEvent::CmdErr> cmdErrors = mSettings->commandErrors();
0383         for (auto errit = cmdErrors.begin();  errit != cmdErrors.end();  )
0384         {
0385             auto evit = newEvents.find(errit.key());
0386             if (evit != newEvents.end())
0387             {
0388                 KAEvent& event = evit.value();
0389                 if (event.category() == CalEvent::ACTIVE)
0390                 {
0391                     event.setCommandError(errit.value());
0392                     ++errit;
0393                     continue;
0394                 }
0395             }
0396             // The event for this command error doesn't exist, or is not active,
0397             // so remove this command error from the settings.
0398             errit = cmdErrors.erase(errit);
0399             changed = true;
0400         }
0401 
0402         if (changed)
0403             mSettings->setCommandErrors(cmdErrors);
0404     }
0405 
0406     // Update the list of loaded events for the resource.
0407     setLoadedEvents(newEvents);
0408 }
0409 
0410 /******************************************************************************
0411 * Save the resource.
0412 */
0413 bool FileResource::save(QString* errorMessage, bool writeThroughCache, bool force)
0414 {
0415     qCDebug(KALARM_LOG) << "FileResource::save:" << displayName();
0416     if (!checkSave())
0417         return false;
0418 
0419     QString errMessage;
0420     switch (doSave(writeThroughCache, force, errMessage))
0421     {
0422         case 1:   // success
0423             saved(true, QString());
0424             return true;
0425 
0426         case 0:   // saving initiated
0427             return true;
0428 
0429         default:  // failure
0430             if (!errMessage.isEmpty())
0431             {
0432                 const QString msg = xi18nc("@info", "Error saving calendar <resource>%1</resource>.", displayName());
0433                 if (errorMessage)
0434                 {
0435                     *errorMessage = msg + errMessage;
0436                     static const QRegularExpression re(QStringLiteral("</html><html>"));
0437                     errorMessage->replace(re, QStringLiteral("<br><br>"));
0438                 }
0439                 else
0440                     Resources::notifyResourceMessage(this, MessageType::Error, msg, errMessage);
0441             }
0442             return false;
0443     }
0444 }
0445 
0446 /******************************************************************************
0447 * Check whether the resource can be saved.
0448 */
0449 bool FileResource::checkSave()
0450 {
0451     QString errorMessage;
0452     if (!mSettings  ||  !mSettings->isValid())
0453     {
0454         qCWarning(KALARM_LOG) << "FileResource::checkSave: FileResource not configured!" << displayName();
0455         errorMessage = i18nc("@info", "Calendar is not configured.");
0456     }
0457     else if (!isValid()  ||  !mSettings->enabledTypes())
0458         return false;
0459     else if (readOnly())
0460     {
0461         qCWarning(KALARM_LOG) << "FileResource::checkSave: Read-only resource!" << displayName();
0462         errorMessage = i18nc("@info", "Calendar is read-only.");
0463     }
0464     else if (mCompatibility != KACalendar::Current)
0465     {
0466         qCWarning(KALARM_LOG) << "FileResource::checkSave: Calendar is in wrong format" << displayLocation();
0467         errorMessage = xi18nc("@info", "Calendar file is in wrong format: <filename>%1</filename>.", displayLocation());
0468     }
0469     else
0470         return true;
0471 
0472     Resources::notifyResourceMessage(this, MessageType::Error, xi18nc("@info", "Error saving calendar <resource>%1</resource>.", displayName()), errorMessage);
0473     return false;
0474 }
0475 
0476 /******************************************************************************
0477 * Called when the resource has saved, to finish the process.
0478 */
0479 void FileResource::saved(bool success, const QString& errorMessage)
0480 {
0481     if (!success  &&  !errorMessage.isEmpty())
0482         Resources::notifyResourceMessage(this, MessageType::Error, xi18nc("@info", "Error saving calendar <resource>%1</resource>.", displayName()), errorMessage);
0483 }
0484 
0485 /******************************************************************************
0486 * Add an event to the resource.
0487 */
0488 bool FileResource::addEvent(const KAEvent& event)
0489 {
0490     qCDebug(KALARM_LOG) << "FileResource::addEvent:" << event.id();
0491     if (!isValid())
0492         qCWarning(KALARM_LOG) << "FileResource::addEvent: Resource invalid!" << displayName();
0493     else if (!isEnabled(CalEvent::EMPTY))
0494         qCDebug(KALARM_LOG) << "FileResource::addEvent: Resource disabled!" << displayName();
0495     else if (!isWritable(event.category()))
0496         qCWarning(KALARM_LOG) << "FileResource::addEvent: Calendar not writable" << displayName();
0497 
0498     else if (doAddEvent(event))
0499     {
0500         setUpdatedEvents({event}, false);
0501 
0502         if (mSettings  &&  mSettings->isEnabled(CalEvent::ACTIVE))
0503         {
0504             // Add this event's command error to the settings.
0505             if (event.category() == CalEvent::ACTIVE
0506             &&  event.commandError() != KAEvent::CmdErr::None)
0507             {
0508                 QHash<QString, KAEvent::CmdErr> cmdErrors = mSettings->commandErrors();
0509                 cmdErrors[event.id()] = event.commandError();
0510                 mSettings->setCommandErrors(cmdErrors);
0511             }
0512         }
0513 
0514         scheduleSave();
0515         notifyUpdatedEvents();
0516         return true;
0517     }
0518     return false;
0519 }
0520 
0521 /******************************************************************************
0522 * Update an event in the resource. Its UID must be unchanged.
0523 */
0524 bool FileResource::updateEvent(const KAEvent& event, bool saveIfReadOnly)
0525 {
0526     qCDebug(KALARM_LOG) << "FileResource::updateEvent:" << event.id();
0527     if (!isValid())
0528         qCWarning(KALARM_LOG) << "FileResource::updateEvent: Resource invalid!" << displayName();
0529     else if (!isEnabled(CalEvent::EMPTY))
0530         qCDebug(KALARM_LOG) << "FileResource::updateEvent: Resource disabled!" << displayName();
0531     else
0532     {
0533         const bool wantSave = saveIfReadOnly || !readOnly();
0534         if (!isWritable(event.category()))
0535         {
0536             if (wantSave)
0537             {
0538                 qCWarning(KALARM_LOG) << "FileResource::updateEvent: Calendar not writable" << displayName();
0539                 return false;
0540             }
0541             qCDebug(KALARM_LOG) << "FileResource::updateEvent: Not saving read-only calendar" << displayName();
0542         }
0543 
0544         if (doUpdateEvent(event))
0545         {
0546             setUpdatedEvents({event}, false);
0547 
0548             // Update command errors held in the settings, if appropriate.
0549             if (mSettings  &&  mSettings->isEnabled(CalEvent::ACTIVE))
0550                 handleCommandErrorChange(event);
0551 
0552             if (wantSave)
0553                 scheduleSave();
0554             notifyUpdatedEvents();
0555             return true;
0556         }
0557     }
0558     return false;
0559 }
0560 
0561 /******************************************************************************
0562 * Delete an event from the resource.
0563 */
0564 bool FileResource::deleteEvent(const KAEvent& event)
0565 {
0566     qCDebug(KALARM_LOG) << "FileResource::deleteEvent:" << event.id();
0567     if (!isValid())
0568         qCWarning(KALARM_LOG) << "FileResource::deleteEvent: Resource invalid!" << displayName();
0569     else if (!isEnabled(CalEvent::EMPTY))
0570         qCDebug(KALARM_LOG) << "FileResource::deleteEvent: Resource disabled!" << displayName();
0571     else if (!isWritable(event.category()))
0572         qCWarning(KALARM_LOG) << "FileResource::deleteEvent: Calendar not writable" << displayName();
0573 
0574     else if (doDeleteEvent(event))
0575     {
0576         setDeletedEvents({event});
0577 
0578         if (mSettings  &&  mSettings->isEnabled(CalEvent::ACTIVE))
0579         {
0580             QHash<QString, KAEvent::CmdErr> cmdErrors = mSettings->commandErrors();
0581             if (cmdErrors.remove(event.id()))
0582                 mSettings->setCommandErrors(cmdErrors);
0583         }
0584 
0585         scheduleSave();
0586         return true;
0587     }
0588     return false;
0589 }
0590 
0591 /******************************************************************************
0592 * Save a command error change to the settings.
0593 */
0594 void FileResource::handleCommandErrorChange(const KAEvent& event)
0595 {
0596     if (!mSettings)
0597         return;
0598     // Update command errors held in the settings, if appropriate.
0599     bool changed = false;
0600     QHash<QString, KAEvent::CmdErr> cmdErrors = mSettings->commandErrors();
0601     if (event.category() != CalEvent::ACTIVE
0602     ||  event.commandError() == KAEvent::CmdErr::None)
0603     {
0604         if (cmdErrors.remove(event.id()))
0605             changed = true;
0606     }
0607     else if (event.category() == CalEvent::ACTIVE)
0608     {
0609         auto it = cmdErrors.find(event.id());
0610         if (it == cmdErrors.end())
0611         {
0612             cmdErrors[event.id()] = event.commandError();
0613             changed = true;
0614         }
0615         else if (event.commandError() != it.value())
0616         {
0617             it.value() = event.commandError();
0618             changed = true;
0619         }
0620     }
0621     if (changed)
0622     {
0623         mSettings->setCommandErrors(cmdErrors);
0624         Resources::notifyEventUpdated(this, event);
0625     }
0626 }
0627 
0628 /******************************************************************************
0629 * Update a resource to the current KAlarm storage format.
0630 */
0631 bool FileResource::updateStorageFormat(Resource& res)
0632 {
0633     if (!res.is<FileResource>())
0634     {
0635         qCCritical(KALARM_LOG) << "FileResource::updateStorageFormat: Error: Not a FileResource:" << res.displayName();
0636         return false;
0637     }
0638     return resource<FileResource>(res)->updateStorageFmt();
0639 }
0640 
0641 /******************************************************************************
0642 * Return the resource's unique identifier for use in cache file names etc.
0643 */
0644 QString FileResource::identifier() const
0645 {
0646     if (!mSettings)
0647         return {};
0648     return QStringLiteral("FileResource%1").arg(mSettings->id() & ~IdFlag);
0649 }
0650 
0651 /******************************************************************************
0652 * Find the compatibility of an existing calendar file.
0653 */
0654 KACalendar::Compat FileResource::getCompatibility(const KCalendarCore::FileStorage::Ptr& fileStorage, int& version)
0655 {
0656     QString versionString;
0657     version = KACalendar::updateVersion(fileStorage, versionString);
0658     switch (version)
0659     {
0660         case KACalendar::IncompatibleFormat:
0661             return KACalendar::Incompatible;  // calendar is not in KAlarm format, or is in a future format
0662         case KACalendar::CurrentFormat:
0663             return KACalendar::Current;       // calendar is in the current format
0664         default:
0665             return KACalendar::Convertible;   // calendar is in an out of date format
0666     }
0667 }
0668 
0669 /******************************************************************************
0670 * Called when the resource settings have changed.
0671 */
0672 void FileResource::handleSettingsChange(Changes& changes)
0673 {
0674     qCDebug(KALARM_LOG) << "FileResource::handleSettingsChange:" << displayId();
0675     if (changes & AlarmTypes)
0676     {
0677         qCDebug(KALARM_LOG) << "FileResource::handleSettingsChange:" << displayId() << "Update alarm types";
0678         load();
0679     }
0680     if (changes & Enabled)
0681     {
0682         qCDebug(KALARM_LOG) << "FileResource::handleSettingsChange:" << displayId() << "Update enabled status";
0683         if (mSettings  &&  mSettings->enabledTypes())
0684         {
0685             // Alarms are now enabled. Reload the calendar file because,
0686             // although ResourceType retains its record of alarms of disabled
0687             // types, changes are not processed when disabled calendar files
0688             // are updated. Also, when the calendar is loaded, disabled alarm
0689             // types are not fully processed by loaded().
0690             setNewlyEnabled();   // ensure all events are notified
0691             load();
0692             changes |= Loaded;
0693         }
0694     }
0695 }
0696 
0697 /******************************************************************************
0698 * Called when the resource settings have changed.
0699 */
0700 void FileResource::handleEnabledChange(Changes changes, CalEvent::Types oldEnabled)
0701 {
0702     if (changes)
0703     {
0704         handleSettingsChange(changes);
0705         Resources::notifySettingsChanged(this, changes, oldEnabled);
0706     }
0707 }
0708 
0709 /******************************************************************************
0710 * Set the new status of the resource.
0711 * If the resource status is already Unusable, it cannot be set usable again.
0712 */
0713 void FileResource::setStatus(Status newStatus)
0714 {
0715     if (newStatus != mStatus
0716     &&  (mStatus < Status::Unusable  ||  mStatus == Status::Unusable  ||  newStatus > mStatus))
0717     {
0718         mStatus = newStatus;
0719         if (mStatus > Status::Unusable)
0720             setFailed();
0721         setError(mStatus == Status::Broken);
0722     }
0723 }
0724 
0725 #include "moc_fileresource.cpp"
0726 
0727 // vim: et sw=4: