File indexing completed on 2024-04-28 05:11:31
0001 /* 0002 SPDX-FileCopyrightText: 2000, 2001, 2004 Cornelius Schumacher <schumacher@kde.org> 0003 SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com> 0004 SPDX-FileCopyrightText: 2010 Andras Mantia <andras@kdab.com> 0005 SPDX-FileCopyrightText: 2010 Casey Link <casey@kdab.com> 0006 0007 SPDX-License-Identifier: LGPL-2.0-or-later 0008 */ 0009 0010 #pragma once 0011 0012 #include "incidenceeditor_export.h" 0013 #include <CalendarSupport/FreeBusyItem> 0014 0015 #include <QBitArray> 0016 #include <QSet> 0017 #include <QTimer> 0018 0019 namespace CalendarSupport 0020 { 0021 class FreeBusyItemModel; 0022 } 0023 0024 namespace IncidenceEditorNG 0025 { 0026 /** 0027 * Takes a list of attendees and event info (e.g., min time start, max time end) 0028 * fetches their freebusy information, then identifies conflicts and periods of non-conflict. 0029 * 0030 * It exposes these periods so another class can display them to the user and allow 0031 * them to choose a correct time. 0032 * @author Casey Link 0033 */ 0034 class INCIDENCEEDITOR_EXPORT ConflictResolver : public QObject 0035 { 0036 Q_OBJECT 0037 public: 0038 /** 0039 * @param parentWidget is passed to Akonadi when fetching free/busy data. 0040 */ 0041 explicit ConflictResolver(QWidget *parentWidget, QObject *parent = nullptr); 0042 0043 /** 0044 * Add an attendee 0045 * The attendees free busy info will be fetched 0046 * and integrated into the resolver. 0047 */ 0048 void insertAttendee(const KCalendarCore::Attendee &attendee); 0049 0050 void insertAttendee(const CalendarSupport::FreeBusyItem::Ptr &freebusy); 0051 /** 0052 * Removes an attendee 0053 * The attendee will no longer be considered when 0054 * resolving conflicts 0055 */ 0056 0057 void removeAttendee(const KCalendarCore::Attendee &attendee); 0058 0059 /** 0060 * Clear all attendees 0061 */ 0062 void clearAttendees(); 0063 0064 /** 0065 * Returns whether the resolver contains the attendee 0066 */ 0067 [[nodiscard]] bool containsAttendee(const KCalendarCore::Attendee &attendee); 0068 0069 /** 0070 * Constrain the free time slot search to the weekdays 0071 * identified by their KCalendarSystem integer representation 0072 * Default is Monday - Friday 0073 * @param weekdays a 7 bit array indicating the allowed days (bit 0=Monday, value 1=allowed). 0074 * @see KCalendarSystem 0075 */ 0076 void setAllowedWeekdays(const QBitArray &weekdays); 0077 0078 /** 0079 * Constrain the free time slot search to the set participant roles. 0080 * Mandatory roles are considered the minimum required to attend 0081 * the meeting, so only those attendees with the mandatory roles will 0082 * be considered in the search. 0083 * Default is all roles are mandatory. 0084 * @param roles the set of mandatory participant roles 0085 */ 0086 void setMandatoryRoles(const QSet<KCalendarCore::Attendee::Role> &roles); 0087 0088 /** 0089 * Returns a list of date time ranges that conform to the 0090 * search constraints. 0091 * @see setMandatoryRoles 0092 * @see setAllowedWeekdays 0093 */ 0094 [[nodiscard]] KCalendarCore::Period::List availableSlots() const; 0095 0096 /** 0097 Finds a free slot in the future which has at least the same size as 0098 the initial slot. 0099 */ 0100 [[nodiscard]] bool findFreeSlot(const KCalendarCore::Period &dateTimeRange); 0101 0102 CalendarSupport::FreeBusyItemModel *model() const; 0103 0104 Q_SIGNALS: 0105 /** 0106 * Emitted when the user changes the start and end dateTimes 0107 * for the incidence. 0108 */ 0109 void dateTimesChanged(const QDateTime &newStart, const QDateTime &newEnd); 0110 0111 /** 0112 * Emitted when there are conflicts 0113 * @param number the number of conflicts 0114 */ 0115 void conflictsDetected(int number); 0116 0117 /** 0118 * Emitted when the resolver locates new free slots. 0119 */ 0120 void freeSlotsAvailable(const KCalendarCore::Period::List &); 0121 0122 public Q_SLOTS: 0123 /** 0124 * Set the timeframe constraints 0125 * 0126 * These control the timeframe for which conflicts are to be resolved. 0127 */ 0128 void setEarliestDate(QDate newDate); 0129 void setEarliestTime(QTime newTime); 0130 void setLatestDate(QDate newDate); 0131 void setLatestTime(QTime newTime); 0132 0133 void setEarliestDateTime(const QDateTime &newDateTime); 0134 void setLatestDateTime(const QDateTime &newDateTime); 0135 0136 void freebusyDataChanged(); 0137 0138 void findAllFreeSlots(); 0139 0140 void setResolution(int seconds); 0141 0142 private: 0143 /** 0144 Checks whether the slot specified by (tryFrom, tryTo) matches the 0145 search constraints. If yes, return true. The return value is the 0146 number of conflicts that were detected, and (tryFrom, tryTo) contain the next free slot for 0147 that participant. In other words, the returned slot does not have to 0148 be free for everybody else. 0149 */ 0150 INCIDENCEEDITOR_NO_EXPORT int tryDate(QDateTime &tryFrom, QDateTime &tryTo); 0151 0152 /** 0153 Checks whether the slot specified by (tryFrom, tryTo) is available 0154 for the participant with specified fb. If yes, return true. If 0155 not, return false and change (tryFrom, tryTo) to contain the next 0156 possible slot for this participant (not necessarily a slot that is 0157 available for all participants). 0158 */ 0159 INCIDENCEEDITOR_NO_EXPORT bool tryDate(const KCalendarCore::FreeBusy::Ptr &fb, QDateTime &tryFrom, QDateTime &tryTo); 0160 0161 /** 0162 * Checks whether the supplied attendee passes the 0163 * current mandatory role constraint. 0164 * @return true if the attendee is of one of the mandatory roles, false if not 0165 */ 0166 INCIDENCEEDITOR_NO_EXPORT bool matchesRoleConstraint(const KCalendarCore::Attendee &attendee); 0167 0168 INCIDENCEEDITOR_NO_EXPORT void calculateConflicts(); 0169 0170 KCalendarCore::Period mTimeframeConstraint; //!< the datetime range for outside of which 0171 // free slots won't be searched. 0172 KCalendarCore::Period::List mAvailableSlots; 0173 0174 QTimer mCalculateTimer; //!< A timer is used control the calculation of conflicts 0175 // to prevent the process from being repeated many times 0176 // after a series of quick parameter changes. 0177 0178 CalendarSupport::FreeBusyItemModel *const mFBModel; 0179 QWidget *mParentWidget = nullptr; 0180 0181 QSet<KCalendarCore::Attendee::Role> mMandatoryRoles; 0182 QBitArray mWeekdays; //!< a 7 bit array indicating the allowed days 0183 //(bit 0 = Monday, value 1 = allowed). 0184 0185 int mSlotResolutionSeconds; 0186 }; 0187 }