File indexing completed on 2024-05-26 05:15:28
0001 /* 0002 SPDX-FileCopyrightText: 2008 Bruno Virlet <bruno.virlet@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later WITH Qt-Commercial-exception-1.0 0005 */ 0006 0007 #pragma once 0008 0009 #include <Akonadi/Collection> 0010 #include <Akonadi/CollectionCalendar> 0011 #include <Akonadi/Item> 0012 0013 #include <QBasicTimer> 0014 #include <QDate> 0015 #include <QGraphicsScene> 0016 #include <QGraphicsView> 0017 #include <QMap> 0018 0019 namespace Akonadi 0020 { 0021 class IncidenceChanger; 0022 } 0023 0024 namespace EventViews 0025 { 0026 class MonthCell; 0027 class MonthItem; 0028 class MonthView; 0029 class ScrollIndicator; 0030 0031 class MonthScene : public QGraphicsScene 0032 { 0033 Q_OBJECT 0034 0035 enum ActionType { None, Move, Resize }; 0036 0037 public: 0038 enum ResizeType { ResizeLeft, ResizeRight }; 0039 0040 explicit MonthScene(MonthView *parent); 0041 ~MonthScene() override; 0042 0043 [[nodiscard]] int columnWidth() const; 0044 [[nodiscard]] int rowHeight() const; 0045 0046 MonthCell *firstCellForMonthItem(MonthItem *manager); 0047 [[nodiscard]] int height(MonthItem *manager); 0048 [[nodiscard]] int itemHeight(); 0049 [[nodiscard]] int itemHeightIncludingSpacing(); 0050 QList<MonthItem *> mManagerList; 0051 MonthView *mMonthView = nullptr; 0052 0053 MonthView *monthView() const 0054 { 0055 return mMonthView; 0056 } 0057 0058 QMap<QDate, MonthCell *> mMonthCellMap; 0059 0060 [[nodiscard]] bool initialized() const 0061 { 0062 return mInitialized; 0063 } 0064 0065 void setInitialized(bool i) 0066 { 0067 mInitialized = i; 0068 } 0069 0070 void resetAll(); 0071 Akonadi::IncidenceChanger *incidenceChanger() const; 0072 0073 int totalHeight(); 0074 0075 /** 0076 * Returns the vertical position where the top of the cell should be 0077 * painted taking in account margins, rowHeight 0078 */ 0079 [[nodiscard]] int cellVerticalPos(const MonthCell *cell) const; 0080 0081 /** 0082 * Idem, for the horizontal position 0083 */ 0084 [[nodiscard]] int cellHorizontalPos(const MonthCell *cell) const; 0085 0086 /** 0087 Select item. If the argument is 0, the currently selected item gets 0088 deselected. This function emits the itemSelected(bool) signal to inform 0089 about selection/deselection of events. 0090 */ 0091 void selectItem(MonthItem *); 0092 [[nodiscard]] int maxRowCount(); 0093 0094 MonthCell *selectedCell() const; 0095 MonthCell *previousCell() const; 0096 0097 /** 0098 Get the space on the right of the cell associated to the date @p date. 0099 */ 0100 [[nodiscard]] int getRightSpan(QDate date) const; 0101 0102 /** 0103 Get the space on the left of the cell associated to the date @p date. 0104 */ 0105 [[nodiscard]] int getLeftSpan(QDate date) const; 0106 0107 /** 0108 Returns the date in the first column of the row given by @p row. 0109 */ 0110 [[nodiscard]] QDate firstDateOnRow(int row) const; 0111 0112 /** 0113 Calls updateGeometry() on each MonthItem 0114 */ 0115 void updateGeometry(); 0116 0117 /** 0118 Returns the first height. Used for scrolling 0119 0120 @see MonthItem::height() 0121 */ 0122 [[nodiscard]] int startHeight() const 0123 { 0124 return mStartHeight; 0125 } 0126 0127 /** 0128 Set the current height using @p height. 0129 If height = 0, then the view is not scrolled. Else it will be scrolled 0130 by step of one item. 0131 */ 0132 void setStartHeight(int height) 0133 { 0134 mStartHeight = height; 0135 } 0136 0137 /** 0138 Returns the resize type. 0139 */ 0140 [[nodiscard]] ResizeType resizeType() const 0141 { 0142 return mResizeType; 0143 } 0144 0145 /** 0146 Returns the currently selected item. 0147 */ 0148 MonthItem *selectedItem() 0149 { 0150 return mSelectedItem; 0151 } 0152 0153 [[nodiscard]] QPixmap birthdayPixmap() const 0154 { 0155 return mBirthdayPixmap; 0156 } 0157 0158 [[nodiscard]] QPixmap anniversaryPixmap() const 0159 { 0160 return mAnniversaryPixmap; 0161 } 0162 0163 [[nodiscard]] QPixmap alarmPixmap() const 0164 { 0165 return mAlarmPixmap; 0166 } 0167 0168 [[nodiscard]] QPixmap recurPixmap() const 0169 { 0170 return mRecurPixmap; 0171 } 0172 0173 [[nodiscard]] QPixmap readonlyPixmap() const 0174 { 0175 return mReadonlyPixmap; 0176 } 0177 0178 [[nodiscard]] QPixmap replyPixmap() const 0179 { 0180 return mReplyPixmap; 0181 } 0182 0183 [[nodiscard]] QPixmap holidayPixmap() const 0184 { 0185 return mHolidayPixmap; 0186 } 0187 0188 /** 0189 Removes an incidence from the scene 0190 */ 0191 void removeIncidence(const QString &uid); 0192 0193 Q_SIGNALS: 0194 void incidenceSelected(const Akonadi::Item &incidence, const QDate &); 0195 void showIncidencePopupSignal(const Akonadi::CollectionCalendar::Ptr &, const Akonadi::Item &, const QDate &); 0196 void newEventSignal(); 0197 void showNewEventPopupSignal(); 0198 0199 protected: 0200 void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *mouseEvent) override; 0201 void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) override; 0202 void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) override; 0203 void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) override; 0204 void wheelEvent(QGraphicsSceneWheelEvent *wheelEvent) override; 0205 void timerEvent(QTimerEvent *e) override; 0206 void helpEvent(QGraphicsSceneHelpEvent *helpEvent) override; 0207 /** 0208 Scrolls all incidences in cells up 0209 */ 0210 virtual void scrollCellsUp(); 0211 0212 /** 0213 Scrolls all incidences in cells down 0214 */ 0215 virtual void scrollCellsDown(); 0216 0217 /** 0218 A click on a scroll indicator has occurred 0219 TODO : move this handler to the scrollindicator 0220 */ 0221 virtual void clickOnScrollIndicator(ScrollIndicator *scrollItem); 0222 0223 /** 0224 Handles drag and drop events. Called from eventFilter. 0225 */ 0226 // virtual bool eventFilter_drag( QObject *, QDropEvent * ); 0227 0228 /** 0229 Returns true if the last item is visible in the given @p cell. 0230 */ 0231 bool lastItemFit(MonthCell *cell); 0232 0233 private: 0234 /** 0235 * Returns the height of the header of the view 0236 */ 0237 int headerHeight() const; 0238 0239 int availableWidth() const; 0240 0241 /** 0242 * Height available to draw the cells. Doesn't include header. 0243 */ 0244 int availableHeight() const; 0245 0246 /** 0247 * Removes all the margins, frames, etc. to give the 0248 * X coordinate in the MonthGrid. 0249 */ 0250 int sceneXToMonthGridX(int xScene); 0251 0252 /** 0253 * Removes all the margins, frames, headers etc. to give the 0254 * Y coordinate in the MonthGrid. 0255 */ 0256 int sceneYToMonthGridY(int yScene); 0257 0258 /** 0259 * Given a pos in the scene coordinates, 0260 * returns the cell containing @p pos. 0261 */ 0262 MonthCell *getCellFromPos(QPointF pos); 0263 0264 /** 0265 Returns true if (x, y) is in the monthgrid, false else. 0266 */ 0267 bool isInMonthGrid(int x, int y) const; 0268 0269 bool mInitialized; 0270 0271 // User interaction. 0272 MonthItem *mClickedItem = nullptr; // todo ini in ctor 0273 MonthItem *mActionItem = nullptr; 0274 bool mActionInitiated; 0275 0276 MonthItem *mSelectedItem = nullptr; 0277 QDate mSelectedCellDate; 0278 MonthCell *mStartCell = nullptr; // start cell when dragging 0279 MonthCell *mPreviousCell = nullptr; // the cell before that one during dragging 0280 0281 ActionType mActionType; 0282 ResizeType mResizeType; 0283 0284 // The item height at the top of the cell. This is generally 0 unless 0285 // the user scroll the view when there are too many items. 0286 int mStartHeight; 0287 0288 // icons to draw in front of the events 0289 QPixmap mEventPixmap; 0290 QPixmap mBirthdayPixmap; 0291 QPixmap mAnniversaryPixmap; 0292 QPixmap mTodoPixmap; 0293 QPixmap mTodoDonePixmap; 0294 QPixmap mJournalPixmap; 0295 QPixmap mAlarmPixmap; 0296 QPixmap mRecurPixmap; 0297 QPixmap mReadonlyPixmap; 0298 QPixmap mReplyPixmap; 0299 QPixmap mHolidayPixmap; 0300 QBasicTimer repeatTimer; 0301 ScrollIndicator *mCurrentIndicator = nullptr; 0302 friend class MonthGraphicsView; 0303 }; 0304 0305 /** 0306 * Renders a MonthScene 0307 */ 0308 class MonthGraphicsView : public QGraphicsView 0309 { 0310 Q_OBJECT 0311 public: 0312 explicit MonthGraphicsView(MonthView *parent); 0313 0314 /** 0315 Draws the cells. 0316 */ 0317 void drawBackground(QPainter *painter, const QRectF &rect) override; 0318 0319 void setScene(MonthScene *scene); 0320 0321 /** 0322 Change the cursor according to @p actionType. 0323 */ 0324 void setActionCursor(MonthScene::ActionType actionType); 0325 0326 protected: 0327 void resizeEvent(QResizeEvent *) override; 0328 0329 private: 0330 MonthScene *mScene = nullptr; 0331 MonthView *mMonthView = nullptr; 0332 }; 0333 }