File indexing completed on 2024-11-17 04:42:35
0001 /* 0002 SPDX-FileCopyrightText: 2000, 2001, 2003 Cornelius Schumacher <schumacher@kde.org> 0003 SPDX-FileCopyrightText: 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later WITH Qt-Commercial-exception-1.0 0006 */ 0007 #pragma once 0008 0009 #include "viewcalendar.h" 0010 0011 #include <CalendarSupport/CellItem> 0012 0013 #include <Akonadi/Item> 0014 0015 #include <QDateTime> 0016 #include <QPointer> 0017 #include <QWidget> 0018 0019 namespace EventViews 0020 { 0021 class AgendaItem; 0022 class EventView; 0023 0024 struct MultiItemInfo { 0025 int mStartCellXLeft, mStartCellXRight; 0026 int mStartCellYTop, mStartCellYBottom; 0027 QPointer<AgendaItem> mFirstMultiItem; 0028 QPointer<AgendaItem> mPrevMultiItem; 0029 QPointer<AgendaItem> mNextMultiItem; 0030 QPointer<AgendaItem> mLastMultiItem; 0031 }; 0032 0033 /** 0034 @class AgendaItem 0035 0036 @brief This class describes the widgets that represent the various calendar 0037 items in the agenda view 0038 0039 The AgendaItem has to make sure that it receives all mouse events, which 0040 are to be used for dragging and resizing. That means it has to be installed 0041 as event filter for its children, if it has children, and it has to pass 0042 mouse events from the children to itself. See eventFilter(). 0043 0044 Some comments on the movement of multi-day items: 0045 Basically, the agenda items are arranged in two implicit double-linked lists. 0046 The mMultiItemInfo works like before to describe the currently viewed 0047 multi-item. 0048 When moving, new events might need to be added to the beginning or the end of 0049 the multi-item sequence, or events might need to be hidden. I cannot just 0050 delete this items, since I have to restore/show them if the move is reset 0051 (i.e. if a drag started). So internally, I keep another doubly-linked list 0052 which is longer than the one defined by mMultiItemInfo, but includes the 0053 multi-item sequence, too. 0054 0055 The mStartMoveInfo stores the first and last item of the multi-item sequence 0056 when the move started. The prev and next members of mStartMoveInfo are used 0057 for that longer sequence including all (shown and hidden) items. 0058 */ 0059 0060 class AgendaItem : public QWidget, public CalendarSupport::CellItem 0061 { 0062 Q_OBJECT 0063 public: 0064 using QPtr = QPointer<AgendaItem>; 0065 using List = QList<QPtr>; 0066 0067 AgendaItem(EventView *eventView, 0068 const MultiViewCalendar::Ptr &calendar, 0069 const KCalendarCore::Incidence::Ptr &incidence, 0070 int itemPos, 0071 int itemCount, 0072 const QDateTime &qd, 0073 bool isSelected, 0074 QWidget *parent); 0075 ~AgendaItem() override; 0076 0077 [[nodiscard]] int cellXLeft() const 0078 { 0079 return mCellXLeft; 0080 } 0081 0082 [[nodiscard]] int cellXRight() const 0083 { 0084 return mCellXRight; 0085 } 0086 0087 [[nodiscard]] int cellYTop() const 0088 { 0089 return mCellYTop; 0090 } 0091 0092 [[nodiscard]] int cellYBottom() const 0093 { 0094 return mCellYBottom; 0095 } 0096 0097 [[nodiscard]] int cellHeight() const; 0098 [[nodiscard]] int cellWidth() const; 0099 0100 [[nodiscard]] int itemPos() const 0101 { 0102 return mItemPos; 0103 } 0104 0105 [[nodiscard]] int itemCount() const 0106 { 0107 return mItemCount; 0108 } 0109 0110 void setCellXY(int X, int YTop, int YBottom); 0111 void setCellY(int YTop, int YBottom); 0112 void setCellX(int XLeft, int XRight); 0113 void setCellXRight(int XRight); 0114 0115 /** Start movement */ 0116 void startMove(); 0117 0118 /** Reset to original values */ 0119 void resetMove(); 0120 0121 /** End the movement (i.e. clean up) */ 0122 void endMove(); 0123 0124 void moveRelative(int dx, int dy); 0125 0126 /** 0127 * Expands the item's top. 0128 * 0129 * @param dy delta y, number of units to be added to mCellYTop 0130 * @param allowOverLimit If false, the new mCellYTop can't be bigger than 0131 * mCellYBottom, instead, it gets mCellYBottom's value. 0132 * If true, @p dy is always added, regardless if mCellYTop 0133 * becomes bigger than mCellYBottom, this is useful when 0134 * moving items because it guarantees expandTop and the 0135 * following expandBottom call add the same value. 0136 */ 0137 void expandTop(int dy, const bool allowOverLimit = false); 0138 void expandBottom(int dy); 0139 void expandLeft(int dx); 0140 void expandRight(int dx); 0141 0142 [[nodiscard]] bool isMultiItem() const; 0143 0144 AgendaItem::QPtr prevMoveItem() const 0145 { 0146 return (mStartMoveInfo) ? (mStartMoveInfo->mPrevMultiItem) : nullptr; 0147 } 0148 0149 AgendaItem::QPtr nextMoveItem() const 0150 { 0151 return (mStartMoveInfo) ? (mStartMoveInfo->mNextMultiItem) : nullptr; 0152 } 0153 0154 MultiItemInfo *moveInfo() const 0155 { 0156 return mStartMoveInfo; 0157 } 0158 0159 void setMultiItem(const AgendaItem::QPtr &first, const AgendaItem::QPtr &prev, const AgendaItem::QPtr &next, const AgendaItem::QPtr &last); 0160 0161 AgendaItem::QPtr prependMoveItem(const AgendaItem::QPtr &); 0162 0163 AgendaItem::QPtr appendMoveItem(const AgendaItem::QPtr &); 0164 0165 AgendaItem::QPtr removeMoveItem(const AgendaItem::QPtr &); 0166 0167 AgendaItem::QPtr firstMultiItem() const 0168 { 0169 return (mMultiItemInfo) ? (mMultiItemInfo->mFirstMultiItem) : nullptr; 0170 } 0171 0172 AgendaItem::QPtr prevMultiItem() const 0173 { 0174 return (mMultiItemInfo) ? (mMultiItemInfo->mPrevMultiItem) : nullptr; 0175 } 0176 0177 AgendaItem::QPtr nextMultiItem() const 0178 { 0179 return (mMultiItemInfo) ? (mMultiItemInfo->mNextMultiItem) : nullptr; 0180 } 0181 0182 AgendaItem::QPtr lastMultiItem() const 0183 { 0184 return (mMultiItemInfo) ? (mMultiItemInfo->mLastMultiItem) : nullptr; 0185 } 0186 0187 [[nodiscard]] bool dissociateFromMultiItem(); 0188 0189 void setIncidence(const KCalendarCore::Incidence::Ptr &incidence); 0190 0191 const KCalendarCore::Incidence::Ptr &incidence() const 0192 { 0193 return mIncidence; 0194 } 0195 0196 [[nodiscard]] QDateTime occurrenceDateTime() const 0197 { 0198 return mOccurrenceDateTime; 0199 } 0200 0201 [[nodiscard]] QDate occurrenceDate() const; 0202 0203 // /** Update the date of this item's occurrence (not in the event) */ 0204 void setOccurrenceDateTime(const QDateTime &qd); 0205 0206 void setText(const QString &text) 0207 { 0208 mLabelText = text; 0209 } 0210 0211 [[nodiscard]] QString text() const 0212 { 0213 return mLabelText; 0214 } 0215 0216 QList<AgendaItem::QPtr> &conflictItems(); 0217 void setConflictItems(const QList<AgendaItem::QPtr> &); 0218 void addConflictItem(const AgendaItem::QPtr &ci); 0219 0220 QString label() const override; 0221 0222 /** Tells whether this item overlaps item @p o */ 0223 bool overlaps(CellItem *o) const override; 0224 0225 void setResourceColor(const QColor &color) 0226 { 0227 mResourceColor = color; 0228 } 0229 0230 [[nodiscard]] QColor resourceColor() const 0231 { 0232 return mResourceColor; 0233 } 0234 0235 Q_SIGNALS: 0236 void removeAgendaItem(const AgendaItem::QPtr &); 0237 void showAgendaItem(const AgendaItem::QPtr &); 0238 0239 public Q_SLOTS: 0240 void updateIcons(); 0241 void select(bool selected = true); 0242 void addAttendee(const QString &); 0243 0244 protected: 0245 bool eventFilter(QObject *obj, QEvent *event) override; 0246 bool event(QEvent *event) override; 0247 void dragEnterEvent(QDragEnterEvent *e) override; 0248 void dropEvent(QDropEvent *e) override; 0249 void paintEvent(QPaintEvent *e) override; 0250 0251 /** private movement functions. startMove needs to be called of only one of 0252 * the multitems. it will then loop through the whole series using 0253 * startMovePrivate. Same for resetMove and endMove */ 0254 void startMovePrivate(); 0255 void resetMovePrivate(); 0256 void endMovePrivate(); 0257 0258 // Variables to remember start position 0259 MultiItemInfo *mStartMoveInfo = nullptr; 0260 // Color of the resource 0261 QColor mResourceColor; 0262 0263 private: 0264 void paintIcon(QPainter *p, int &x, int y, int ft); 0265 0266 // paint all visible icons 0267 void paintIcons(QPainter *p, int &x, int y, int ft); 0268 0269 void drawRoundedRect(QPainter *p, 0270 QRect rect, 0271 bool selected, 0272 const QColor &bgColor, 0273 const QColor &frameColor, 0274 bool frame, 0275 int ft, 0276 bool roundTop, 0277 bool roundBottom); 0278 0279 [[nodiscard]] QColor getCategoryColor() const; 0280 [[nodiscard]] QColor getFrameColor(const QColor &resourceColor, const QColor &categoryColor) const; 0281 [[nodiscard]] QColor getBackgroundColor(const QColor &resourceColor, const QColor &categoryColor) const; 0282 0283 int mCellXLeft, mCellXRight; 0284 int mCellYTop, mCellYBottom; 0285 0286 EventView *const mEventView; 0287 MultiViewCalendar::Ptr mCalendar; 0288 KCalendarCore::Incidence::Ptr mIncidence; 0289 QDateTime mOccurrenceDateTime; 0290 bool mValid = true; 0291 bool mCloned = false; 0292 QString mLabelText; 0293 bool mSelected; 0294 bool mIconAlarm; 0295 bool mIconRecur; 0296 bool mIconReadonly; 0297 bool mIconReply; 0298 bool mIconGroup; 0299 bool mIconGroupTent; 0300 bool mIconOrganizer; 0301 bool mSpecialEvent; 0302 0303 // For incidences that expand through more than 1 day 0304 // Will be 1 for single day incidences 0305 int mItemPos; 0306 int mItemCount; 0307 0308 // Multi item pointers 0309 MultiItemInfo *mMultiItemInfo = nullptr; 0310 0311 QList<AgendaItem::QPtr> mConflictItems; 0312 0313 static QPixmap *alarmPxmp; 0314 static QPixmap *recurPxmp; 0315 static QPixmap *readonlyPxmp; 0316 static QPixmap *replyPxmp; 0317 static QPixmap *groupPxmp; 0318 static QPixmap *groupPxmpTent; 0319 static QPixmap *organizerPxmp; 0320 static QPixmap *eventPxmp; 0321 static QPixmap *todoPxmp; 0322 static QPixmap *completedPxmp; 0323 }; 0324 }