File indexing completed on 2024-05-12 05:14:40

0001 /*
0002  *  daymatrix.h  -  calendar day matrix display
0003  *  Program:  kalarm
0004  *  This class is adapted from KODayMatrix in KOrganizer.
0005  *
0006  *  SPDX-FileCopyrightText: 2001 Eitzenberger Thomas <thomas.eitzenberger@siemens.at>
0007  *  SPDX-FileCopyrightText: 2003 Cornelius Schumacher <schumacher@kde.org>
0008  *  SPDX-FileCopyrightText: 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
0009  *  SPDX-FileCopyrightText: 2021-2023 David Jarvie <djarvie@kde.org>
0010  *
0011  *  SPDX-License-Identifier: GPL-2.0-or-later WITH Qt-Commercial-exception-1.0
0012 */
0013 
0014 #pragma once
0015 
0016 #include "editdlg.h"
0017 #include "kalarmcalendar/kaevent.h"
0018 
0019 #include <QFrame>
0020 #include <QDate>
0021 #include <QSet>
0022 
0023 class Resource;
0024 namespace { struct TextColours; }
0025 
0026 /**
0027  *  Displays one month's dates in a grid, one line per week, highlighting days
0028  *  on which alarms occur. It has an option to allow one or more consecutive
0029  *  days to be selected by dragging the mouse. Days before today are disabled.
0030  */
0031 class DayMatrix : public QFrame
0032 {
0033     Q_OBJECT
0034 public:
0035     /** constructor to create a day matrix widget.
0036      *
0037      *  @param parent widget that is the parent of the day matrix.
0038      *  Normally this should be a KDateNavigator
0039      */
0040     explicit DayMatrix(QWidget* parent = nullptr);
0041 
0042     /** destructor that deallocates all dynamically allocated private members.
0043      */
0044     ~DayMatrix() override;
0045 
0046     /** Set a new start date for the matrix. If changed, or other changes are
0047      *  pending, recalculates which days in the matrix alarms occur on, and
0048      *  which are holidays/non-work days, and repaints.
0049      *
0050      *  @param startDate  The first day to be displayed in the matrix.
0051      */
0052     void setStartDate(const QDate& startDate);
0053 
0054     /** Notify the matrix that the current date has changed.
0055      *  The month currently being displayed will not be changed.
0056      */
0057     void updateToday(const QDate& newDate);
0058 
0059     /** Returns all selected dates, in date order. */
0060     QList<QDate> selectedDates() const;
0061 
0062     /** Clear all selections. */
0063     void clearSelection();
0064 
0065     void setRowHeight(int rowHeight);
0066 
0067 Q_SIGNALS:
0068     /** Emitted when the user selects or deselects dates.
0069      *
0070      *  @param dates       The dates selected, in date order, or empty if none.
0071      *  @param workChange  The holiday region or work days have changed.
0072      */
0073     void selected(const QList<QDate>& dates, bool workChange);
0074 
0075     void newAlarm(EditAlarmDlg::Type);
0076     void newAlarmFromTemplate(const KAlarmCal::KAEvent&);
0077 
0078 protected:
0079     bool event(QEvent*) override;
0080     void paintEvent(QPaintEvent*) override;
0081     void mousePressEvent(QMouseEvent*) override;
0082     void mouseReleaseEvent(QMouseEvent*) override;
0083     void mouseMoveEvent(QMouseEvent*) override;
0084     void resizeEvent(QResizeEvent*) override;
0085 
0086 private Q_SLOTS:
0087     void resourceUpdated(Resource&);
0088     void resourceRemoved(KAlarmCal::ResourceId);
0089     void resourceSettingsChanged(Resource&, ResourceType::Changes);
0090     void slotUpdateView();
0091 
0092 private:
0093     QString getHolidayLabel(int offset) const;
0094     void setMouseSelection(int start, int end, bool emitSignal);
0095     void popupMenu(const QPoint&);     // pop up a context menu for creating a new alarm
0096     int getDayIndex(const QPoint&) const;   // get index of the day located at a point in the matrix
0097 
0098     // If changes are pending, recalculates which days in the matrix have
0099     // alarms occurring, and which are holidays/non-work days, and repaints.
0100     void updateView(const Resource& = Resource());
0101     void updateEvents(const Resource& = Resource());
0102     void updateEvents(const Resource&, const KADateTime& before, const KADateTime& to);
0103     void colourBackground(QPainter&, const QColor&, int start, int end);
0104     QColor textColour(const TextColours&, const QPalette&, int dayIndex, bool workDay) const;
0105 
0106     int     mRowHeight {1};    // height of each row
0107     QDate   mStartDate;        // starting date of the matrix
0108 
0109     QList<QString> mDayLabels; // array of day labels, to optimize drawing performance
0110 
0111     QSet<QDate> mEventDates;   // days on which alarms occur, for any resource
0112     QHash<ResourceId, QSet<QDate>> mResourceEventDates;  // for each resource, days on which alarms occur
0113 
0114     QStringList mHolidays;     // holiday names, indexed by day index
0115 
0116     int    mTodayIndex {-1};   // index of today, or -1 if today is not visible in the matrix
0117     int    mMonthStartIndex;   // index of the first day of the main month shown
0118     int    mMonthEndIndex;     // index of the last day of the main month shown
0119 
0120     int    mSelInit;           // index of day where dragged selection was initiated
0121     int    mSelStart;          // index of the first selected day
0122     int    mSelEnd;            // index of the last selected day
0123     QList<QDate> mLastSelectedDates; // last dates emitted in selected() signal
0124 
0125     QRectF mDaySize;                  // the geometric size of each day in the matrix
0126 
0127     bool   mAllowMultipleSelection {false};  // selection may contain multiple days
0128     bool   mSelectionMustBeVisible {true};   // selection will be cancelled if not wholly visible
0129     bool   mPendingChanges {false};   // the display needs to be updated
0130 };
0131 
0132 // vim: et sw=4: