File indexing completed on 2024-06-02 05:19:23
0001 /* 0002 * resources.h - container for all ResourceType instances 0003 * Program: kalarm 0004 * SPDX-FileCopyrightText: 2019-2021 David Jarvie <djarvie@kde.org> 0005 * 0006 * SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #pragma once 0010 0011 #include "datamodel.h" 0012 #include "resource.h" 0013 #include "resourcemodel.h" 0014 0015 #include <QObject> 0016 0017 using namespace KAlarmCal; 0018 0019 /** Class to contain all ResourceType instances. 0020 * It provides connection to signals from all ResourceType instances. 0021 */ 0022 class Resources : public QObject 0023 { 0024 Q_OBJECT 0025 public: 0026 /** Creates the unique Resources instance. 0027 * Note that this merely creates a container for individual resources, 0028 * and doesn't create or initialise any ResourceType instances. 0029 */ 0030 static Resources* instance(); 0031 0032 ~Resources() override; 0033 Resources(const Resources&) = delete; 0034 Resources& operator=(const Resources&) const = delete; 0035 0036 /** Return a copy of the resource with a given ID. 0037 * @return The resource, or invalid if the ID doesn't already exist or is invalid. 0038 */ 0039 static Resource resource(ResourceId); 0040 0041 /** Return a copy of the resource with a given display ID. 0042 * @return The resource, or invalid if the ID doesn't already exist or is invalid 0043 * or if more than one resource has the same display ID. 0044 */ 0045 static Resource resourceFromDisplayId(ResourceId); 0046 0047 /** Remove a resource. The calendar file is not removed. 0048 * @return true if the resource has been removed or a removal job has been scheduled. 0049 */ 0050 static bool removeResource(Resource&); 0051 0052 /** Sorting criteria for allResources(Type, Sorting). May be OR'ed together. */ 0053 enum Sorts 0054 { 0055 NoSort = 0, 0056 DisplayName = 0x01, // sort by display name 0057 DefaultFirst = 0x02 // default resource is first in list. Requires a CalEvent::Type to be specified. 0058 }; 0059 Q_DECLARE_FLAGS(Sorting, Sorts) 0060 /** Return all resources of a kind which contain a specified alarm type. 0061 * @tparam RType Resource type to fetch, default = all types. 0062 * @param alarmType Alarm type to check for, or CalEvent::EMPTY for any type. 0063 * @param sorting Sorting criteria to use. 0064 */ 0065 template <class RType = ResourceType> 0066 static QList<Resource> allResources(CalEvent::Type alarmType = CalEvent::EMPTY, Sorting sorting = NoSort); 0067 0068 /** Return the enabled resources which contain a specified alarm type. 0069 * @param type Alarm type to check for, or CalEvent::EMPTY for any type. 0070 * @param writable If true, only writable resources are included. 0071 */ 0072 static QList<Resource> enabledResources(CalEvent::Type type = CalEvent::EMPTY, bool writable = false); 0073 0074 /** Return the standard resource for an alarm type. This is the resource 0075 * which can be set as the default to add new alarms to. 0076 * Only enabled and writable resources can be standard. 0077 * In the case of archived alarm resources, if no resource is specified 0078 * as standard and there is exactly one writable archived alarm resource, 0079 * that resource will be automatically set as standard. 0080 * 0081 * @param type Alarm type. 0082 * @param useOnlyResource If there is only one resource for the alarm type, 0083 * set it as standard. 0084 * @return standard resource, or null if none. 0085 */ 0086 static Resource getStandard(CalEvent::Type type, bool useOnlyResource = false); 0087 0088 /** Return whether a resource is the standard resource for a specified alarm 0089 * type. Only enabled and writable resources can be standard. 0090 * In the case of archived alarms, if no resource is specified as standard 0091 * and the resource is the only writable archived alarm resource, it will 0092 * be automatically set as standard. 0093 */ 0094 static bool isStandard(const Resource& resource, CalEvent::Type); 0095 0096 /** Return the alarm type(s) for which a resource is the standard resource. 0097 * Only enabled and writable resources can be standard. 0098 * @param useDefault false to return the defined standard types, if any; 0099 * true to return the types for which it is the standard 0100 * or only resource. 0101 */ 0102 static CalEvent::Types standardTypes(const Resource& resource, bool useDefault = false); 0103 0104 /** Set or clear a resource as the standard resource for a specified alarm 0105 * type. This does not affect its status for other alarm types. 0106 * The resource must be writable and enabled for the type, to set 0107 * standard = true. 0108 * If the resource is being set as standard, the standard status for the 0109 * alarm type is cleared for any other resources. 0110 */ 0111 static void setStandard(Resource& resource, CalEvent::Type, bool standard); 0112 0113 /** Set which alarm types a resource is the standard resource for. 0114 * Its standard status is cleared for other alarm types. 0115 * The resource must be writable and enabled for the type, to set 0116 * standard = true. 0117 * If the resource is being set as standard for any alarm types, the 0118 * standard status is cleared for those alarm types for any other resources. 0119 */ 0120 static void setStandard(Resource& resource, CalEvent::Types); 0121 0122 /** Options for destination(). May be OR'ed together. */ 0123 enum DestOption 0124 { 0125 NoDestOption = 0, 0126 NoResourcePrompt = 0x01, //!< Don't prompt the user even if the standard resource is not valid. 0127 UseOnlyResource = 0x02 //!< If there is only one enabled resource, set it as standard. 0128 }; 0129 Q_DECLARE_FLAGS(DestOptions, DestOption) 0130 0131 /** Find the resource to be used to store an event of a given type. 0132 * This will be the standard resource for the type, but if this is not valid, 0133 * the user will be prompted to select a resource. 0134 * @param type The event type 0135 * @param promptParent The parent widget for the prompt 0136 * @param options Options to use 0137 * @param cancelled If non-null: set to true if the user cancelled the 0138 * prompt dialogue; set to false if any other error 0139 */ 0140 static Resource destination(CalEvent::Type type, QWidget* promptParent = nullptr, DestOptions options = NoDestOption, bool* cancelled = nullptr); 0141 0142 /** Return whether all configured and migrated resources have been created. */ 0143 static bool allCreated(); 0144 0145 /** Return whether all configured and migrated resources have been loaded 0146 * at least once. */ 0147 static bool allPopulated(); 0148 0149 /** Return the resource which an event belongs to, provided that the event's 0150 * alarm type is enabled. */ 0151 static Resource resourceForEvent(const QString& eventId); 0152 0153 /** Return the resource which an event belongs to, and the event, provided 0154 * that the event's alarm type is enabled. */ 0155 static Resource resourceForEvent(const QString& eventId, KAEvent& event); 0156 0157 /** Return the resource which has a given configuration identifier. */ 0158 static Resource resourceForConfigName(const QString& configName); 0159 0160 /** To be called when the start-of-day time has changed, to adjust the start 0161 * times of all date-only alarms' recurrences, in all resources. 0162 */ 0163 static void adjustStartOfDay(); 0164 0165 /** Called to notify that a new resource has completed its initialisation, 0166 * in order to emit the resourceAdded() signal. */ 0167 static void notifyNewResourceInitialised(Resource&); 0168 0169 /** Called to notify that all configured and migrated resources have now 0170 * been created. */ 0171 static void notifyResourcesCreated(); 0172 0173 /** Called by a resource to notify that loading of events has successfully completed, 0174 * or that loading has failed. */ 0175 static void notifyResourcePopulated(const ResourceType*); 0176 0177 /** Called to notify that a resource is about to be removed. */ 0178 static void notifyResourceToBeRemoved(ResourceType*); 0179 0180 /** Called by a resource to notify that its settings have changed. 0181 * This will cause the settingsChanged() signal to be emitted. 0182 */ 0183 static void notifySettingsChanged(ResourceType*, ResourceType::Changes, CalEvent::Types oldEnabled); 0184 0185 /** Called by a resource when a user message should be displayed. 0186 * This will cause the resourceMessage() signal to be emitted. 0187 * @param message Must include the resource's display name in order to 0188 * identify the resource to the user. 0189 */ 0190 static void notifyResourceMessage(ResourceType*, ResourceType::MessageType, const QString& message, const QString& details); 0191 0192 /** Called when a user message should be displayed for a resource. 0193 * This will cause the resourceMessage() signal to be emitted. 0194 * @param message Must include the resource's display name in order to 0195 * identify the resource to the user. 0196 */ 0197 static void notifyResourceMessage(ResourceId, ResourceType::MessageType, const QString& message, const QString& details); 0198 0199 /** Called by a resource to notify that it has added events. */ 0200 static void notifyEventsAdded(ResourceType*, const QList<KAEvent>&); 0201 0202 /** Called by a resource to notify that it has changed an event. 0203 * The event's UID must be unchanged. 0204 */ 0205 static void notifyEventUpdated(ResourceType*, const KAEvent& event); 0206 0207 /** Called by a resource to notify that it is about to delete events. */ 0208 static void notifyEventsToBeRemoved(ResourceType*, const QList<KAEvent>&); 0209 0210 /** Called by a resource to notify that it has deleted events. */ 0211 static void notifyEventsRemoved(ResourceType*, const QList<KAEvent>&); 0212 0213 /** Called by a resource settings instance to notify that it is about to be destructed. */ 0214 static void notifySettingsDestroyed(ResourceId); 0215 0216 Q_SIGNALS: 0217 /** Emitted when a resource's settings have changed. */ 0218 void settingsChanged(Resource&, ResourceType::Changes); 0219 0220 /** Emitted when all configured resource have been created (but not 0221 * necessarily populated), and any necessary resource migration and 0222 * the creation of default resources has been performed. 0223 */ 0224 void resourcesCreated(); 0225 0226 /** Emitted when all configured and migrated resources have been loaded for 0227 * the first time, or cannot currently be loaded. 0228 * This is always emitted after resourcesCreated(). 0229 */ 0230 void resourcesPopulated(); 0231 0232 /** Emitted when a new resource has been created. 0233 * The resource may or may not have loaded its events before the signal is 0234 * emitted. 0235 */ 0236 void resourceAdded(Resource&); 0237 0238 /** Emitted when a resource's events have been successfully loaded. 0239 * 0240 * This signal is not emitted if the resource's events have already been 0241 * loaded before its resourceAdded() signal is emitted. 0242 * 0243 * @see Resource::isPopulated() can be called at any time to check whether 0244 * the resource's events have been loaded. 0245 */ 0246 void resourcePopulated(Resource&); 0247 0248 /** Emitted when a resource's config and settings are about to be removed. */ 0249 void resourceToBeRemoved(Resource&); 0250 0251 /** Emitted when a resource's config and settings have been removed. */ 0252 void resourceRemoved(KAlarmCal::ResourceId); 0253 0254 /** Emitted when a resource message should be displayed to the user. 0255 * @note Connections to this signal should use Qt::QueuedConnection type 0256 * to allow processing to continue while the user message is displayed. 0257 */ 0258 void resourceMessage(ResourceType::MessageType, const QString& message, const QString& details); 0259 0260 /** Emitted when events have been added to a resource. 0261 * Events are only notified whose alarm type is enabled. 0262 * 0263 * This signal is not emitted when events are added to the resource before 0264 * its resourceAdded() signal is emitted. 0265 */ 0266 void eventsAdded(Resource&, const QList<KAEvent>&); 0267 0268 /** Emitted when an event has been updated in a resource. 0269 * Events are only notified whose alarm type is enabled. 0270 * The event's UID is unchanged. 0271 */ 0272 void eventUpdated(Resource&, const KAEvent&); 0273 0274 /** Emitted when events are about to be deleted from a resource. 0275 * Events are only notified whose alarm type is enabled. 0276 */ 0277 void eventsToBeRemoved(Resource&, const QList<KAEvent>&); 0278 0279 /** Emitted when events have been deleted from a resource. 0280 * Events are only notified whose alarm type is enabled. 0281 */ 0282 void eventsRemoved(Resource&, const QList<KAEvent>&); 0283 0284 private: 0285 Resources(); 0286 0287 /** Add a new ResourceType instance, with a Resource owner. 0288 * Once the resource has completed its initialisation, call 0289 * notifyNewResourceInitialised() to emit the resourceAdded() signal. 0290 * is require 0291 * @param type Newly constructed ResourceType instance, which will belong to 0292 * 'resource' if successful. On error, it will be deleted. 0293 * @param resource If type is invalid, updated to an invalid resource; 0294 * If type ID already exists, updated to the existing resource with that ID; 0295 * If type ID doesn't exist, updated to the new resource containing res. 0296 * @return true if a new resource has been created, false if invalid or already exists. 0297 */ 0298 static bool addResource(ResourceType* type, Resource& resource); 0299 0300 /** Remove the resource with a given ID. 0301 * @note The ResourceType instance will only be deleted once all Resource 0302 * instances which refer to this ID go out of scope. 0303 */ 0304 static void removeResource(ResourceId); 0305 0306 static void checkResourcesPopulated(); 0307 0308 static Resources* mInstance; // the unique instance 0309 static QHash<ResourceId, Resource> mResources; // contains all ResourceType instances with an ID 0310 static bool mCreated; // all resources have been created 0311 static bool mPopulated; // all resources have been loaded once 0312 0313 friend class ResourceType; 0314 }; 0315 0316 Q_DECLARE_OPERATORS_FOR_FLAGS(Resources::Sorting) 0317 Q_DECLARE_OPERATORS_FOR_FLAGS(Resources::DestOptions) 0318 0319 0320 /*============================================================================= 0321 * Template definitions. 0322 *============================================================================*/ 0323 0324 template <class RType> 0325 QList<Resource> Resources::allResources(CalEvent::Type type, Sorting sorting) 0326 { 0327 const CalEvent::Types types = (type == CalEvent::EMPTY) 0328 ? CalEvent::ACTIVE | CalEvent::ARCHIVED | CalEvent::TEMPLATE 0329 : type; 0330 0331 QList<Resource> result; 0332 Resource std; 0333 if ((sorting & DefaultFirst) && type != CalEvent::EMPTY) 0334 { 0335 std = getStandard(type, (type == CalEvent::ARCHIVED)); 0336 if (std.isValid() && std.is<RType>()) 0337 result += std; 0338 } 0339 const int start = result.size(); 0340 0341 for (auto it = mResources.constBegin(); it != mResources.constEnd(); ++it) 0342 { 0343 const Resource& res = it.value(); 0344 if (res != std && res.is<RType>() && (res.alarmTypes() & types)) 0345 result += res; 0346 } 0347 0348 if (sorting & DisplayName) 0349 std::sort(result.begin() + start, result.end(), [](const Resource& a, const Resource& b) { return a.displayName().compare(b.displayName(), Qt::CaseInsensitive) < 0; }); 0350 0351 return result; 0352 } 0353 0354 // vim: et sw=4: