File indexing completed on 2024-05-12 05:13:27
0001 /* 0002 SPDX-FileCopyrightText: 1999 Preston Brown <pbrown@kde.org> 0003 SPDX-FileCopyrightText: 2000, 2001 Cornelius Schumacher <schumacher@kde.org> 0004 SPDX-FileCopyrightText: 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com> 0005 SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.net> 0006 SPDX-FileContributor: Kevin Krammer <krake@kdab.com> 0007 0008 SPDX-License-Identifier: GPL-2.0-or-later WITH Qt-Commercial-exception-1.0 0009 */ 0010 #pragma once 0011 0012 #include "eventviews_export.h" 0013 0014 #include <Akonadi/Collection> 0015 #include <Akonadi/CollectionCalendar> 0016 #include <Akonadi/Item> 0017 0018 #include <KCalendarCore/Incidence> 0019 #include <KCalendarCore/Todo> 0020 0021 #include <QByteArray> 0022 #include <QDate> 0023 #include <QSet> 0024 #include <QWidget> 0025 0026 #include <memory> 0027 0028 class QAbstractItemModel; 0029 0030 namespace CalendarSupport 0031 { 0032 class CollectionSelection; 0033 class KCalPrefs; 0034 } 0035 0036 namespace Akonadi 0037 { 0038 class IncidenceChanger; 0039 } 0040 0041 class KCheckableProxyModel; 0042 class KConfigGroup; 0043 0044 namespace EventViews 0045 { 0046 enum { BUSY_BACKGROUND_ALPHA = 70 }; 0047 0048 class EventViewPrivate; 0049 class Prefs; 0050 using PrefsPtr = QSharedPointer<Prefs>; 0051 using KCalPrefsPtr = QSharedPointer<CalendarSupport::KCalPrefs>; 0052 0053 /** 0054 EventView is the abstract base class from which all other calendar views 0055 for event data are derived. It provides methods for displaying 0056 appointments and events on one or more days. The actual number of 0057 days that a view actually supports is not defined by this abstract class; 0058 that is up to the classes that inherit from it. It also provides 0059 methods for updating the display, retrieving the currently selected 0060 event (or events), and the like. 0061 0062 @short Abstract class from which all event views are derived. 0063 @author Preston Brown <pbrown@kde.org> 0064 @see KOListView, AgendaView, KOMonthView 0065 */ 0066 class EVENTVIEWS_EXPORT EventView : public QWidget 0067 { 0068 Q_OBJECT 0069 public: 0070 enum { 0071 // This value is passed to QColor's lighter(int factor) for selected events 0072 BRIGHTNESS_FACTOR = 110 0073 }; 0074 0075 enum ItemIcon { 0076 CalendarCustomIcon = 0, 0077 TaskIcon, 0078 JournalIcon, 0079 RecurringIcon, 0080 ReminderIcon, 0081 ReadOnlyIcon, 0082 ReplyIcon, 0083 AttendingIcon, 0084 TentativeIcon, 0085 OrganizerIcon, 0086 IconCount = 10 // Always keep at the end 0087 }; 0088 0089 enum Change { 0090 NothingChanged = 0, 0091 IncidencesAdded = 1, 0092 IncidencesEdited = 2, 0093 IncidencesDeleted = 4, 0094 DatesChanged = 8, 0095 FilterChanged = 16, 0096 ResourcesChanged = 32, 0097 ZoomChanged = 64, 0098 ConfigChanged = 128 0099 }; 0100 Q_DECLARE_FLAGS(Changes, Change) 0101 0102 /** 0103 * Constructs a view. 0104 * @param cal is a pointer to the calendar object from which events 0105 * will be retrieved for display. 0106 * @param parent is the parent QWidget. 0107 */ 0108 explicit EventView(QWidget *parent = nullptr); 0109 0110 /** 0111 * Destructor. Views will do view-specific cleanups here. 0112 */ 0113 ~EventView() override; 0114 0115 virtual void addCalendar(const Akonadi::CollectionCalendar::Ptr &calendar); 0116 virtual void removeCalendar(const Akonadi::CollectionCalendar::Ptr &calendar); 0117 0118 virtual void setModel(QAbstractItemModel *model); 0119 QAbstractItemModel *model() const; 0120 Akonadi::EntityTreeModel *entityTreeModel() const; 0121 0122 /* 0123 update config is called after prefs are set. 0124 */ 0125 virtual void setPreferences(const PrefsPtr &preferences); 0126 [[nodiscard]] PrefsPtr preferences() const; 0127 0128 virtual void setKCalPreferences(const KCalPrefsPtr &preferences); 0129 [[nodiscard]] KCalPrefsPtr kcalPreferences() const; 0130 0131 /** 0132 @return a list of selected events. Most views can probably only 0133 select a single event at a time, but some may be able to select 0134 more than one. 0135 */ 0136 virtual Akonadi::Item::List selectedIncidences() const = 0; 0137 0138 /** 0139 Returns a list of the dates of selected events. Most views can 0140 probably only select a single event at a time, but some may be able 0141 to select more than one. 0142 */ 0143 virtual KCalendarCore::DateList selectedIncidenceDates() const = 0; 0144 0145 /** 0146 Returns the start of the selection, or an invalid QDateTime if there is no selection 0147 or the view doesn't support selecting cells. 0148 */ 0149 virtual QDateTime selectionStart() const; 0150 0151 /** 0152 Returns the end of the selection, or an invalid QDateTime if there is no selection 0153 or the view doesn't support selecting cells. 0154 */ 0155 virtual QDateTime selectionEnd() const; 0156 0157 /** 0158 Sets the default start/end date/time for new events. 0159 Return true if anything was changed 0160 */ 0161 virtual bool eventDurationHint(QDateTime &startDt, QDateTime &endDt, bool &allDay) const; 0162 0163 /** 0164 Returns whether or not date range selection is enabled. This setting only 0165 applies to views that actually supports selecting cells. 0166 @see selectionStart() 0167 @see selectionEnd() 0168 */ 0169 [[nodiscard]] bool dateRangeSelectionEnabled() const; 0170 0171 /** 0172 Enable or disable date range selection. 0173 @see dateRangeSelectionEnabled() 0174 */ 0175 void setDateRangeSelectionEnabled(bool enable); 0176 0177 /** 0178 Returns the number of currently shown dates. 0179 A return value of 0 means no idea. 0180 */ 0181 virtual int currentDateCount() const = 0; 0182 0183 /** 0184 * returns whether this view supports zoom. 0185 * Base implementation returns false. 0186 */ 0187 virtual bool supportsZoom() const; 0188 0189 virtual bool hasConfigurationDialog() const; 0190 0191 virtual void showConfigurationDialog(QWidget *parent); 0192 0193 [[nodiscard]] QByteArray identifier() const; 0194 void setIdentifier(const QByteArray &identifier); 0195 0196 /** 0197 * reads the view configuration. View-specific configuration can be 0198 * restored via doRestoreConfig() 0199 * 0200 * @param configGroup the group to read settings from 0201 * @see doRestoreConfig() 0202 */ 0203 void restoreConfig(const KConfigGroup &configGroup); 0204 0205 /** 0206 * writes out the view configuration. View-specific configuration can be 0207 * saved via doSaveConfig() 0208 * 0209 * @param configGroup the group to store settings in 0210 * @see doSaveConfig() 0211 */ 0212 void saveConfig(KConfigGroup &configGroup); 0213 0214 //---------------------------------------------------------------------------- 0215 KCheckableProxyModel *takeCustomCollectionSelectionProxyModel(); 0216 KCheckableProxyModel *customCollectionSelectionProxyModel() const; 0217 void setCustomCollectionSelectionProxyModel(KCheckableProxyModel *model); 0218 0219 CalendarSupport::CollectionSelection *customCollectionSelection() const; 0220 0221 static CalendarSupport::CollectionSelection *globalCollectionSelection(); 0222 static void setGlobalCollectionSelection(CalendarSupport::CollectionSelection *selection); 0223 //---------------------------------------------------------------------------- 0224 0225 /** 0226 * returns the view at the given widget coordinate. This is usually the view 0227 * itself, except for composite views, where a subview will be returned. 0228 * The default implementation returns @p this . 0229 */ 0230 virtual EventView *viewAt(const QPoint &p); 0231 0232 /** 0233 * @param preferredMonth Used by month orientated views. Contains the 0234 * month to show when the week crosses months. It's a QDate instead 0235 * of uint so it can be easily fed to KCalendarSystem's functions. 0236 */ 0237 virtual void setDateRange(const QDateTime &start, const QDateTime &end, const QDate &preferredMonth = QDate()); 0238 0239 [[nodiscard]] QDateTime startDateTime() const; 0240 [[nodiscard]] QDateTime endDateTime() const; 0241 0242 [[nodiscard]] QDateTime actualStartDateTime() const; 0243 [[nodiscard]] QDateTime actualEndDateTime() const; 0244 0245 [[nodiscard]] int showMoveRecurDialog(const KCalendarCore::Incidence::Ptr &incidence, QDate date); 0246 0247 /** 0248 Handles key events, opens the new event dialog when enter is pressed, activates type ahead. 0249 */ 0250 [[nodiscard]] bool processKeyEvent(QKeyEvent *); 0251 0252 /* 0253 * Sets the QObject that will receive key events that were made 0254 * while the new event dialog was still being created. 0255 */ 0256 void setTypeAheadReceiver(QObject *o); 0257 0258 /** 0259 Returns the selection of collection to be used by this view 0260 (custom if set, or global otherwise). 0261 */ 0262 CalendarSupport::CollectionSelection *collectionSelection() const; 0263 0264 /** 0265 Notifies the view that there are pending changes so a redraw is needed. 0266 @param needed if the update is needed or not. 0267 */ 0268 virtual void setChanges(Changes changes); 0269 0270 /** 0271 Returns if there are pending changes and a redraw is needed. 0272 */ 0273 [[nodiscard]] Changes changes() const; 0274 0275 /** 0276 * Returns a variation of @p color that will be used for the border 0277 * of an agenda or month item. 0278 */ 0279 [[nodiscard]] static QColor itemFrameColor(const QColor &color, bool selected); 0280 0281 [[nodiscard]] QString iconForItem(const Akonadi::Item &); 0282 0283 [[nodiscard]] Akonadi::CollectionCalendar::Ptr calendarForCollection(const Akonadi::Collection &collection) const; 0284 [[nodiscard]] Akonadi::CollectionCalendar::Ptr calendarForCollection(Akonadi::Collection::Id collectionId) const; 0285 0286 public Q_SLOTS: 0287 /** 0288 Shows given incidences. Depending on the actual view it might not 0289 be possible to show all given events. 0290 0291 @param incidenceList a list of incidences to show. 0292 @param date is the QDate on which the incidences are being shown. 0293 */ 0294 virtual void showIncidences(const Akonadi::Item::List &incidenceList, const QDate &date) = 0; 0295 0296 /** 0297 Updates the current display to reflect changes that may have happened 0298 in the calendar since the last display refresh. 0299 */ 0300 virtual void updateView() = 0; 0301 virtual void dayPassed(const QDate &); 0302 0303 /** 0304 Assign a new incidence change helper object. 0305 */ 0306 virtual void setIncidenceChanger(Akonadi::IncidenceChanger *changer); 0307 0308 /** 0309 Write all unsaved data back to calendar store. 0310 */ 0311 virtual void flushView(); 0312 0313 /** 0314 Re-reads the configuration and picks up relevant 0315 changes which are applicable to the view. 0316 */ 0317 virtual void updateConfig(); 0318 0319 /** 0320 Clear selection. The incidenceSelected signal is not emitted. 0321 */ 0322 virtual void clearSelection(); 0323 0324 void focusChanged(QWidget *, QWidget *); 0325 0326 /** 0327 Perform the default action for an incidence, e.g. open the event editor, 0328 when double-clicking an event in the agenda view. 0329 */ 0330 void defaultAction(const Akonadi::Item &incidence); 0331 0332 /** 0333 Set which holiday regions the user wants to use. 0334 @param regions a list of Holiday Regions strings. 0335 */ 0336 void setHolidayRegions(const QStringList ®ions); 0337 0338 Q_SIGNALS: 0339 /** 0340 * when the view changes the dates that are selected in one way or 0341 * another, this signal is emitted. It should be connected back to 0342 * the KDateNavigator object so that it changes appropriately, 0343 * and any other objects that need to be aware that the list of 0344 * selected dates has changed. 0345 * @param datelist the new list of selected dates 0346 */ 0347 void datesSelected(const KCalendarCore::DateList &datelist); 0348 0349 /** 0350 * Emitted when an event is moved using the mouse in an agenda 0351 * view (week / month). 0352 */ 0353 void shiftedEvent(const QDate &olddate, const QDate &newdate); 0354 0355 void incidenceSelected(const Akonadi::Item &, const QDate); 0356 0357 /** 0358 * instructs the receiver to show the incidence in read-only mode. 0359 */ 0360 void showIncidenceSignal(const Akonadi::Item &); 0361 0362 /** 0363 * instructs the receiver to begin editing the incidence specified in 0364 * some manner. Doesn't make sense to connect to more than one 0365 * receiver. 0366 */ 0367 void editIncidenceSignal(const Akonadi::Item &); 0368 0369 /** 0370 * instructs the receiver to delete the Incidence in some manner; some 0371 * possibilities include automatically, with a confirmation dialog 0372 * box, etc. Doesn't make sense to connect to more than one receiver. 0373 */ 0374 void deleteIncidenceSignal(const Akonadi::Item &); 0375 0376 /** 0377 * instructs the receiver to cut the Incidence 0378 */ 0379 void cutIncidenceSignal(const Akonadi::Item &); 0380 0381 /** 0382 * instructs the receiver to copy the incidence 0383 */ 0384 void copyIncidenceSignal(const Akonadi::Item &); 0385 0386 /** 0387 * instructs the receiver to paste the incidence 0388 */ 0389 void pasteIncidenceSignal(); 0390 0391 /** 0392 * instructs the receiver to toggle the alarms of the Incidence. 0393 */ 0394 void toggleAlarmSignal(const Akonadi::Item &); 0395 0396 /** 0397 * instructs the receiver to toggle the completion state of the Incidence 0398 * (which must be a Todo type). 0399 */ 0400 void toggleTodoCompletedSignal(const Akonadi::Item &); 0401 0402 /** 0403 * Copy the incidence to the specified resource. 0404 */ 0405 void copyIncidenceToResourceSignal(const Akonadi::Item &, const Akonadi::Collection &); 0406 0407 /** 0408 * Move the incidence to the specified resource. 0409 */ 0410 void moveIncidenceToResourceSignal(const Akonadi::Item &, const Akonadi::Collection &); 0411 0412 /** Dissociate from a recurring incidence the occurrence on the given 0413 * date to a new incidence or dissociate all occurrences from the 0414 * given date onwards. 0415 */ 0416 void dissociateOccurrencesSignal(const Akonadi::Item &, const QDate &); 0417 0418 /** 0419 * instructs the receiver to create a new event in given collection. Doesn't make 0420 * sense to connect to more than one receiver. 0421 */ 0422 void newEventSignal(); 0423 /** 0424 * instructs the receiver to create a new event with the specified beginning 0425 * time. Doesn't make sense to connect to more than one receiver. 0426 */ 0427 void newEventSignal(const QDate &); 0428 /** 0429 * instructs the receiver to create a new event with the specified beginning 0430 * time. Doesn't make sense to connect to more than one receiver. 0431 */ 0432 void newEventSignal(const QDateTime &); 0433 /** 0434 * instructs the receiver to create a new event, with the specified 0435 * beginning end ending times. Doesn't make sense to connect to more 0436 * than one receiver. 0437 */ 0438 void newEventSignal(const QDateTime &, const QDateTime &); 0439 0440 void newTodoSignal(const QDate &); 0441 void newSubTodoSignal(const Akonadi::Item &); 0442 0443 void newJournalSignal(const QDate &); 0444 0445 protected Q_SLOTS: 0446 virtual void calendarReset(); 0447 0448 private: 0449 EVENTVIEWS_NO_EXPORT void onCollectionChanged(const Akonadi::Collection &, const QSet<QByteArray> &); 0450 0451 protected: 0452 QList<Akonadi::CollectionCalendar::Ptr> calendars() const; 0453 Akonadi::CollectionCalendar::Ptr calendar3(const Akonadi::Item &item) const; 0454 Akonadi::CollectionCalendar::Ptr calendar3(const KCalendarCore::Incidence::Ptr &incidence) const; 0455 0456 bool makesWholeDayBusy(const KCalendarCore::Incidence::Ptr &incidence) const; 0457 Akonadi::IncidenceChanger *changer() const; 0458 0459 /** 0460 * reimplement to read view-specific settings. 0461 */ 0462 virtual void doRestoreConfig(const KConfigGroup &configGroup); 0463 0464 /** 0465 * reimplement to write view-specific settings. 0466 */ 0467 virtual void doSaveConfig(KConfigGroup &configGroup); 0468 0469 /** 0470 @deprecated 0471 */ 0472 virtual void showDates(const QDate &start, const QDate &end, const QDate &preferredMonth = QDate()) = 0; 0473 0474 /** 0475 * from the requested date range (passed via setDateRange()), calculates the 0476 * adjusted date range actually displayed by the view, depending on the 0477 * view's supported range (e.g., a month view always displays one month) 0478 * The default implementation returns the range unmodified 0479 * 0480 * @param preferredMonth Used by month orientated views. Contains the 0481 * month to show when the week crosses months. It's a QDate instead of 0482 * uint so it can be easily fed to KCalendarSystem's functions. 0483 */ 0484 virtual QPair<QDateTime, QDateTime> actualDateRange(const QDateTime &start, const QDateTime &end, const QDate &preferredMonth = QDate()) const; 0485 /* 0486 virtual void incidencesAdded( const Akonadi::Item::List &incidences ); 0487 virtual void incidencesAboutToBeRemoved( const Akonadi::Item::List &incidences ); 0488 virtual void incidencesChanged( const Akonadi::Item::List &incidences ); 0489 */ 0490 virtual void handleBackendError(const QString &error); 0491 0492 private: 0493 std::unique_ptr<EventViewPrivate> const d_ptr; 0494 Q_DECLARE_PRIVATE(EventView) 0495 }; 0496 }