Commit ce69d6e7 authored by David Jarvie's avatar David Jarvie
Browse files

Formatting

parent ca679b08
/*
* akonadidatamodel.h - KAlarm calendar file access using Akonadi
* Program: kalarm
* Copyright © 2010-2019 David Jarvie <djarvie@kde.org>
* Copyright © 2010-2020 David Jarvie <djarvie@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -45,143 +45,143 @@ using namespace KAlarmCal;
class AkonadiDataModel : public Akonadi::EntityTreeModel, public ResourceDataModelBase
{
Q_OBJECT
public:
enum Change { Enabled, ReadOnly, AlarmTypes };
static AkonadiDataModel* instance();
~AkonadiDataModel() override;
static Akonadi::ChangeRecorder* monitor();
/** Refresh the specified collection instance with up to date data. */
bool refresh(Akonadi::Collection&) const;
/** Refresh the specified item instance with up to date data. */
bool refresh(Akonadi::Item&) const;
Resource resource(Akonadi::Collection::Id) const;
Resource resource(const QModelIndex&) const;
QModelIndex resourceIndex(const Resource&) const;
QModelIndex resourceIndex(Akonadi::Collection::Id) const;
Akonadi::Collection* collection(Akonadi::Collection::Id id) const;
Akonadi::Collection* collection(const Resource&) const;
/** Reload a collection's data from Akonadi storage (not from the backend). */
bool reload(const Resource&);
/** Reload all collections' data from Akonadi storage (not from the backend). */
void reload();
KAEvent event(const QString& eventId) const;
KAEvent event(const QModelIndex&) const;
using QObject::event; // prevent warning about hidden virtual method
/** Return an event's model index, based on its ID. */
QModelIndex eventIndex(const KAEvent&) const;
QModelIndex eventIndex(const QString& eventId) const;
/** Return the up-to-date Item, given its ID.
* If not found, an invalid Item is returned.
*/
Akonadi::Item itemById(Akonadi::Item::Id) const;
/** Return the Item for a given event. */
Akonadi::Item itemForEvent(const QString& eventId) const;
QVariant data(const QModelIndex&, int role = Qt::DisplayRole) const override;
int headerDataEventRoleOffset() const override;
private Q_SLOTS:
/** Called when a resource notifies a message to display to the user. */
void slotResourceMessage(Resource&, ResourceType::MessageType, const QString& message, const QString& details);
Q_SIGNALS:
/** Signal emitted when the Akonadi server has stopped. */
void serverStopped();
protected:
QVariant entityHeaderData(int section, Qt::Orientation, int role, HeaderGroup) const override;
int entityColumnCount(HeaderGroup) const override;
private Q_SLOTS:
void checkResources(Akonadi::ServerManager::State);
void slotMigrationCompleted();
void collectionFetchResult(KJob*);
void slotCollectionChanged(const Akonadi::Collection& c, const QSet<QByteArray>& attrNames);
void slotCollectionRemoved(const Akonadi::Collection&);
void slotCollectionBeingCreated(const QString& path, Akonadi::Collection::Id, bool finished);
void slotCollectionTreeFetched();
void slotCollectionPopulated(Akonadi::Collection::Id);
void slotUpdateTimeTo();
void slotUpdateArchivedColour(const QColor&);
void slotUpdateDisabledColour(const QColor&);
void slotUpdateHolidays();
void slotUpdateWorkingHours();
void slotRowsInserted(const QModelIndex& parent, int start, int end);
void slotRowsAboutToBeRemoved(const QModelIndex& parent, int start, int end);
void slotMonitoredItemChanged(const Akonadi::Item&, const QSet<QByteArray>&);
void slotEmitEventUpdated();
private:
struct CalData // data per collection
{
CalData() : enabled(false) { }
CalData(bool e, const QColor& c) : colour(c), enabled(e) { }
QColor colour; // user selected color for the calendar
bool enabled; // whether the collection is enabled
};
struct CollJobData // collection data for jobs in progress
{
CollJobData() : id(-1) {}
CollJobData(Akonadi::Collection::Id i, const QString& d) : id(i), displayName(d) {}
Akonadi::Collection::Id id;
QString displayName;
};
struct CollTypeData // data for configuration dialog for collection creation job
{
CollTypeData() : parent(nullptr), alarmType(CalEvent::EMPTY) {}
CollTypeData(CalEvent::Type t, QWidget* p) : parent(p), alarmType(t) {}
QWidget* parent;
CalEvent::Type alarmType;
};
AkonadiDataModel(Akonadi::ChangeRecorder*, QObject* parent);
void initResourceMigrator();
Resource& updateResource(const Akonadi::Collection&) const;
/** Return the alarm for the specified Akonadi Item.
* The item's parentCollection() is set.
* @param res Set the resource for the item's parent collection.
* @return the event, or invalid event if no such event exists.
*/
KAEvent event(Akonadi::Item&, const QModelIndex&, Resource& res) const;
QModelIndex itemIndex(const Akonadi::Item&) const;
void signalDataChanged(bool (*checkFunc)(const Akonadi::Item&), int startColumn, int endColumn, const QModelIndex& parent);
void setCollectionChanged(Resource&, const Akonadi::Collection&, bool checkCompat);
QList<KAEvent> events(ResourceId) const;
void getChildEvents(const QModelIndex& parent, QList<KAEvent>&) const;
static AkonadiDataModel* mInstance;
static int mTimeHourPos; // position of hour within time string, or -1 if leading zeroes included
Akonadi::ChangeRecorder* mMonitor;
QHash<KJob*, CollJobData> mPendingCollectionJobs; // pending collection creation/deletion jobs, with collection ID & name
QHash<KJob*, CollTypeData> mPendingColCreateJobs; // default alarm type for pending collection creation jobs
QList<QString> mCollectionsBeingCreated; // path names of new collections being created by migrator
QList<Akonadi::Collection::Id> mCollectionIdsBeingCreated; // ids of new collections being created by migrator
struct EventIds
{
Akonadi::Collection::Id collectionId{-1};
Akonadi::Item::Id itemId{-1};
explicit EventIds(Akonadi::Collection::Id c = -1, Akonadi::Item::Id i = -1) : collectionId(c), itemId(i) {}
};
QHash<QString, EventIds> mEventIds; // collection and item ID for each event ID
mutable QHash<Akonadi::Collection::Id, Resource> mResources;
QQueue<KAEvent> mPendingEventChanges; // changed events with changedEvent() signal pending
Q_OBJECT
public:
enum Change { Enabled, ReadOnly, AlarmTypes };
static AkonadiDataModel* instance();
~AkonadiDataModel() override;
static Akonadi::ChangeRecorder* monitor();
/** Refresh the specified collection instance with up to date data. */
bool refresh(Akonadi::Collection&) const;
/** Refresh the specified item instance with up to date data. */
bool refresh(Akonadi::Item&) const;
Resource resource(Akonadi::Collection::Id) const;
Resource resource(const QModelIndex&) const;
QModelIndex resourceIndex(const Resource&) const;
QModelIndex resourceIndex(Akonadi::Collection::Id) const;
Akonadi::Collection* collection(Akonadi::Collection::Id id) const;
Akonadi::Collection* collection(const Resource&) const;
/** Reload a collection's data from Akonadi storage (not from the backend). */
bool reload(const Resource&);
/** Reload all collections' data from Akonadi storage (not from the backend). */
void reload();
KAEvent event(const QString& eventId) const;
KAEvent event(const QModelIndex&) const;
using QObject::event; // prevent warning about hidden virtual method
/** Return an event's model index, based on its ID. */
QModelIndex eventIndex(const KAEvent&) const;
QModelIndex eventIndex(const QString& eventId) const;
/** Return the up-to-date Item, given its ID.
* If not found, an invalid Item is returned.
*/
Akonadi::Item itemById(Akonadi::Item::Id) const;
/** Return the Item for a given event. */
Akonadi::Item itemForEvent(const QString& eventId) const;
QVariant data(const QModelIndex&, int role = Qt::DisplayRole) const override;
int headerDataEventRoleOffset() const override;
private Q_SLOTS:
/** Called when a resource notifies a message to display to the user. */
void slotResourceMessage(Resource&, ResourceType::MessageType, const QString& message, const QString& details);
Q_SIGNALS:
/** Signal emitted when the Akonadi server has stopped. */
void serverStopped();
protected:
QVariant entityHeaderData(int section, Qt::Orientation, int role, HeaderGroup) const override;
int entityColumnCount(HeaderGroup) const override;
private Q_SLOTS:
void checkResources(Akonadi::ServerManager::State);
void slotMigrationCompleted();
void collectionFetchResult(KJob*);
void slotCollectionChanged(const Akonadi::Collection& c, const QSet<QByteArray>& attrNames);
void slotCollectionRemoved(const Akonadi::Collection&);
void slotCollectionBeingCreated(const QString& path, Akonadi::Collection::Id, bool finished);
void slotCollectionTreeFetched();
void slotCollectionPopulated(Akonadi::Collection::Id);
void slotUpdateTimeTo();
void slotUpdateArchivedColour(const QColor&);
void slotUpdateDisabledColour(const QColor&);
void slotUpdateHolidays();
void slotUpdateWorkingHours();
void slotRowsInserted(const QModelIndex& parent, int start, int end);
void slotRowsAboutToBeRemoved(const QModelIndex& parent, int start, int end);
void slotMonitoredItemChanged(const Akonadi::Item&, const QSet<QByteArray>&);
void slotEmitEventUpdated();
private:
struct CalData // data per collection
{
CalData() : enabled(false) { }
CalData(bool e, const QColor& c) : colour(c), enabled(e) { }
QColor colour; // user selected color for the calendar
bool enabled; // whether the collection is enabled
};
struct CollJobData // collection data for jobs in progress
{
CollJobData() : id(-1) {}
CollJobData(Akonadi::Collection::Id i, const QString& d) : id(i), displayName(d) {}
Akonadi::Collection::Id id;
QString displayName;
};
struct CollTypeData // data for configuration dialog for collection creation job
{
CollTypeData() : parent(nullptr), alarmType(CalEvent::EMPTY) {}
CollTypeData(CalEvent::Type t, QWidget* p) : parent(p), alarmType(t) {}
QWidget* parent;
CalEvent::Type alarmType;
};
AkonadiDataModel(Akonadi::ChangeRecorder*, QObject* parent);
void initResourceMigrator();
Resource& updateResource(const Akonadi::Collection&) const;
/** Return the alarm for the specified Akonadi Item.
* The item's parentCollection() is set.
* @param res Set the resource for the item's parent collection.
* @return the event, or invalid event if no such event exists.
*/
KAEvent event(Akonadi::Item&, const QModelIndex&, Resource& res) const;
QModelIndex itemIndex(const Akonadi::Item&) const;
void signalDataChanged(bool (*checkFunc)(const Akonadi::Item&), int startColumn, int endColumn, const QModelIndex& parent);
void setCollectionChanged(Resource&, const Akonadi::Collection&, bool checkCompat);
QList<KAEvent> events(ResourceId) const;
void getChildEvents(const QModelIndex& parent, QList<KAEvent>&) const;
static AkonadiDataModel* mInstance;
static int mTimeHourPos; // position of hour within time string, or -1 if leading zeroes included
Akonadi::ChangeRecorder* mMonitor;
QHash<KJob*, CollJobData> mPendingCollectionJobs; // pending collection creation/deletion jobs, with collection ID & name
QHash<KJob*, CollTypeData> mPendingColCreateJobs; // default alarm type for pending collection creation jobs
QList<QString> mCollectionsBeingCreated; // path names of new collections being created by migrator
QList<Akonadi::Collection::Id> mCollectionIdsBeingCreated; // ids of new collections being created by migrator
struct EventIds
{
Akonadi::Collection::Id collectionId{-1};
Akonadi::Item::Id itemId{-1};
explicit EventIds(Akonadi::Collection::Id c = -1, Akonadi::Item::Id i = -1) : collectionId(c), itemId(i) {}
};
QHash<QString, EventIds> mEventIds; // collection and item ID for each event ID
mutable QHash<Akonadi::Collection::Id, Resource> mResources;
QQueue<KAEvent> mPendingEventChanges; // changed events with changedEvent() signal pending
};
#endif // AKONADIDATAMODEL_H
......
......@@ -56,57 +56,57 @@ using namespace KAlarmCal;
// Creates, or migrates from KResources, a single alarm calendar
class CalendarCreator : public QObject
{
Q_OBJECT
public:
// Constructor to migrate a calendar from KResources.
CalendarCreator(const QString& resourceType, const KConfigGroup&);
// Constructor to create a default Akonadi calendar.
CalendarCreator(CalEvent::Type, const QString& file, const QString& name);
bool isValid() const { return mAlarmType != CalEvent::EMPTY; }
CalEvent::Type alarmType() const { return mAlarmType; }
bool newCalendar() const { return mNew; }
QString resourceName() const { return mName; }
Collection::Id collectionId() const { return mCollectionId; }
QString path() const { return mUrlString; }
QString errorMessage() const { return mErrorMessage; }
void createAgent(const QString& agentType, QObject* parent);
public Q_SLOTS:
void agentCreated(KJob*);
Q_SIGNALS:
void creating(const QString& path);
void finished(CalendarCreator*);
private Q_SLOTS:
void fetchCollection();
void collectionFetchResult(KJob*);
void resourceSynchronised(KJob*);
void modifyCollectionJobDone(KJob*);
private:
void finish(bool cleanup);
bool writeLocalFileConfig();
bool writeLocalDirectoryConfig();
bool writeRemoteFileConfig();
template <class Interface> Interface* writeBasicConfig();
enum ResourceType { LocalFile, LocalDir, RemoteFile };
AgentInstance mAgent;
CalEvent::Type mAlarmType;
ResourceType mResourceType;
QString mUrlString;
QString mName;
QColor mColour;
QString mErrorMessage;
Collection::Id mCollectionId;
int mCollectionFetchRetryCount;
bool mReadOnly;
bool mEnabled;
bool mStandard;
const bool mNew; // true if creating default, false if converting
bool mFinished{false};
Q_OBJECT
public:
// Constructor to migrate a calendar from KResources.
CalendarCreator(const QString& resourceType, const KConfigGroup&);
// Constructor to create a default Akonadi calendar.
CalendarCreator(CalEvent::Type, const QString& file, const QString& name);
bool isValid() const { return mAlarmType != CalEvent::EMPTY; }
CalEvent::Type alarmType() const { return mAlarmType; }
bool newCalendar() const { return mNew; }
QString resourceName() const { return mName; }
Collection::Id collectionId() const { return mCollectionId; }
QString path() const { return mUrlString; }
QString errorMessage() const { return mErrorMessage; }
void createAgent(const QString& agentType, QObject* parent);
public Q_SLOTS:
void agentCreated(KJob*);
Q_SIGNALS:
void creating(const QString& path);
void finished(CalendarCreator*);
private Q_SLOTS:
void fetchCollection();
void collectionFetchResult(KJob*);
void resourceSynchronised(KJob*);
void modifyCollectionJobDone(KJob*);
private:
void finish(bool cleanup);
bool writeLocalFileConfig();
bool writeLocalDirectoryConfig();
bool writeRemoteFileConfig();
template <class Interface> Interface* writeBasicConfig();
enum ResourceType { LocalFile, LocalDir, RemoteFile };
AgentInstance mAgent;
CalEvent::Type mAlarmType;
ResourceType mResourceType;
QString mUrlString;
QString mName;
QColor mColour;
QString mErrorMessage;
Collection::Id mCollectionId;
int mCollectionFetchRetryCount;
bool mReadOnly;
bool mEnabled;
bool mStandard;
const bool mNew; // true if creating default, false if converting
bool mFinished{false};
};
......
......@@ -43,41 +43,41 @@ using namespace KAlarmCal;
*/
class AkonadiResourceMigrator : public QObject
{
Q_OBJECT
public:
~AkonadiResourceMigrator();
static AkonadiResourceMigrator* instance();
static void reset();
static void execute();
static void updateToCurrentFormat(const Resource&, bool ignoreKeepFormat, QObject* parent);
static bool completed() { return mCompleted; }
Q_OBJECT
public:
~AkonadiResourceMigrator();
static AkonadiResourceMigrator* instance();
static void reset();
static void execute();
static void updateToCurrentFormat(const Resource&, bool ignoreKeepFormat, QObject* parent);
static bool completed() { return mCompleted; }
Q_SIGNALS:
/** Signal emitted when a resource is about to be created, and when creation has
* completed (successfully or not).
* @param path path of the resource
* @param id collection ID if @p finished is @c true, else invalid
* @param finished @c true if finished, @c false otherwise
*/
void creating(const QString& path, Akonadi::Collection::Id id, bool finished);
Q_SIGNALS:
/** Signal emitted when a resource is about to be created, and when creation has
* completed (successfully or not).
* @param path path of the resource
* @param id collection ID if @p finished is @c true, else invalid
* @param finished @c true if finished, @c false otherwise
*/
void creating(const QString& path, Akonadi::Collection::Id id, bool finished);
private Q_SLOTS:
void collectionFetchResult(KJob*);
void creatingCalendar(const QString& path);
void calendarCreated(CalendarCreator*);
private Q_SLOTS:
void collectionFetchResult(KJob*);
void creatingCalendar(const QString& path);
void calendarCreated(CalendarCreator*);
private:
AkonadiResourceMigrator(QObject* parent = nullptr);
void migrateOrCreate();
void createDefaultResources();
private:
AkonadiResourceMigrator(QObject* parent = nullptr);
void migrateOrCreate();
void createDefaultResources();
static AkonadiResourceMigrator* mInstance;
QList<CalendarCreator*> mCalendarsPending; // pending calendar migration or creation jobs
QList<Akonadi::CollectionFetchJob*> mFetchesPending; // pending collection fetch jobs for existing resources
CalEvent::Types mExistingAlarmTypes; // alarm types provided by existing Akonadi resources
static bool mCompleted; // execute() has completed
static AkonadiResourceMigrator* mInstance;
QList<CalendarCreator*> mCalendarsPending; // pending calendar migration or creation jobs
QList<Akonadi::CollectionFetchJob*> mFetchesPending; // pending collection fetch jobs for existing resources
CalEvent::Types mExistingAlarmTypes; // alarm types provided by existing Akonadi resources
static bool mCompleted; // execute() has completed
friend class AkonadiCalendarUpdater;
friend class AkonadiCalendarUpdater;
};
#endif // AKONADIRESOURCEMIGRATOR_H
......
......@@ -42,106 +42,106 @@ using namespace KAlarmCal;
=============================================================================*/
class ResourceDataModelBase
{
public:
/** Data column numbers. */
enum
{
// Item columns
TimeColumn = 0, TimeToColumn, RepeatColumn, ColourColumn, TypeColumn, TextColumn,
TemplateNameColumn,
ColumnCount
};
/** Additional model data roles. */
enum
{
UserRole = Qt::UserRole + 500, // copied from Akonadi::EntityTreeModel
ItemTypeRole = UserRole, // item's type: calendar or event
// Calendar roles
ResourceIdRole, // the resource ID
BaseColourRole, // background colour ignoring collection colour
// Event roles
EventIdRole, // the event ID
ParentResourceIdRole, // the parent resource ID of the event
EnabledRole, // true for enabled alarm, false for disabled
StatusRole, // KAEvent::ACTIVE/ARCHIVED/TEMPLATE
AlarmActionsRole, // KAEvent::Actions
AlarmSubActionRole, // KAEvent::Action
ValueRole, // numeric value
SortRole, // the value to use for sorting
TimeDisplayRole, // time column value with '~' representing omitted leading zeroes
ColumnTitleRole, // column titles (whether displayed or not)
CommandErrorRole // last command execution error for alarm (per user)
};
/** The type of a model row. */
enum class Type { Error = 0, Event, Resource };
virtual ~ResourceDataModelBase();
public:
static QSize iconSize() { return mIconSize; }
/** Return a bulleted list of alarm types for inclusion in an i18n message. */
static QString typeListForDisplay(CalEvent::Types);
/** Get the tooltip for a resource. The resource's enabled status is
* evaluated for specified alarm types. */
QString tooltip(const Resource&, CalEvent::Types) const;
/** Return the read-only status tooltip for a resource.
* A null string is returned if the resource is fully writable. */
static QString readOnlyTooltip(const Resource&);
/** Return offset to add to headerData() role, for item models. */
virtual int headerDataEventRoleOffset() const { return 0; }
/** Return whether calendar migration/creation at initialisation has completed. */
bool isMigrationComplete() const;
protected:
ResourceDataModelBase();
static QVariant headerData(int section, Qt::Orientation, int role, bool eventHeaders, bool& handled);
/** Return whether resourceData() and/or eventData() handle a role. */
bool roleHandled(int role) const;
/** Return the model data for a resource.
* @param role may be updated for calling the base model.
* @param handled updated to true if the reply is valid, else set to false.
*/
QVariant resourceData(int& role, const Resource&, bool& handled) const;
/** Return the model data for an event.
* @param handled updated to true if the reply is valid, else set to false.
*/
QVariant eventData(int role, int column, const KAEvent& event, const Resource&, bool& handled) const;
/** Called when a resource notifies a message to display to the user. */
void handleResourceMessage(ResourceType::MessageType, const QString& message, const QString& details);
/** Return whether calendar migration is currently in progress. */
bool isMigrating() const;
/** To be called when calendar migration has been initiated (or reset). */
void setMigrationInitiated(bool started = true);
/** To be called when calendar migration has been initiated (or reset). */
void setMigrationComplete();
static QString repeatText(const KAEvent&);
static QString repeatOrder(const KAEvent&);
static QString whatsThisText(int column);
static QPixmap* eventIcon(const KAEvent&);
private:
static QPixmap* mTextIcon;
static QPixmap* mFileIcon;
static QPixmap* mCommandIcon;
static QPixmap* mEmailIcon;
static QPixmap* mAudioIcon;
static QSize mIconSize; // maximum size of any icon
int mMigrationStatus{-1}; // migration status, -1 = no, 0 = initiated, 1 = complete
public:
/** Data column numbers. */
enum
{
// Item columns
TimeColumn = 0, TimeToColumn, RepeatColumn, ColourColumn, TypeColumn, TextColumn,
TemplateNameColumn,
ColumnCount
};
/** Additional model data roles. */
enum
{
UserRole = Qt::UserRole + 500, // copied from Akonadi::EntityTreeModel
ItemTypeRole = UserRole, // item's type: calendar or event
// Calendar roles
ResourceIdRole, // the resource ID