File indexing completed on 2024-05-12 04:20:40
0001 /* 0002 * SPDX-FileCopyrightText: 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. 0003 * 0004 * This file is part of the KGantt library. 0005 * 0006 * SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #ifndef KGANTTDATETIMEGRID_H 0010 #define KGANTTDATETIMEGRID_H 0011 0012 #include "kganttabstractgrid.h" 0013 0014 #include <QDateTime> 0015 #include <QSet> 0016 #include <QPair> 0017 0018 namespace KGantt { 0019 0020 class DateTimeScaleFormatter; 0021 class DateTimeTimeLine; 0022 0023 0024 /*!\class KGantt::DateTimeGrid 0025 * \ingroup KGantt 0026 * 0027 * This implementation of AbstractGrid works with QDateTime 0028 * and shows days and week numbers in the header 0029 */ 0030 class KGANTT_EXPORT DateTimeGrid : public AbstractGrid 0031 { 0032 Q_OBJECT 0033 KGANTT_DECLARE_PRIVATE_DERIVED( DateTimeGrid ) 0034 public: 0035 enum Scale { 0036 ScaleAuto, 0037 ScaleHour, 0038 ScaleDay, 0039 ScaleWeek, 0040 ScaleMonth, 0041 ScaleUserDefined 0042 }; 0043 enum HeaderType { 0044 NoHeader, 0045 UpperHeader, 0046 LowerHeader 0047 }; 0048 0049 DateTimeGrid(); 0050 ~DateTimeGrid() override; 0051 0052 /*! \returns The QDateTime used as start date for the grid. 0053 * 0054 * The default is three days before the current date. 0055 */ 0056 QDateTime startDateTime() const; 0057 0058 /*! \param dt The start date of the grid. It is used as the beginning of the 0059 * horizontal scrollbar in the view. 0060 * 0061 * Emits gridChanged() after the start date has changed. 0062 */ 0063 void setStartDateTime( const QDateTime& dt ); 0064 0065 /*! \returns The width in pixels for each day in the grid. 0066 * 0067 * The default is 100 pixels. 0068 */ 0069 qreal dayWidth() const; 0070 0071 /*! \param w The width in pixels for each day in the grid. 0072 * 0073 * The signal gridChanged() is emitted after the day width is changed. 0074 */ 0075 void setDayWidth( qreal ); 0076 0077 /*! Maps a given point in time \a dt to an X value in the scene. 0078 */ 0079 qreal mapFromDateTime( const QDateTime& dt) const; 0080 0081 /*! Maps a given X value \a x in scene coordinates to a point in time. 0082 */ 0083 QDateTime mapToDateTime( qreal x ) const; 0084 0085 /*! \param ws The start day of the week. 0086 * 0087 * A solid line is drawn on the grid to mark the beginning of a new week. 0088 * Emits gridChanged() after the start day has changed. 0089 */ 0090 void setWeekStart( Qt::DayOfWeek ); 0091 0092 /*! \returns The start day of the week */ 0093 Qt::DayOfWeek weekStart() const; 0094 0095 /*! \param fd A set of days to mark as free in the grid. 0096 * 0097 * Free days are filled with the alternate base brush of the 0098 * palette used by the view. 0099 * The signal gridChanged() is emitted after the free days are changed. 0100 */ 0101 void setFreeDays( const QSet<Qt::DayOfWeek>& fd ); 0102 0103 /*! \returns The days marked as free in the grid. */ 0104 QSet<Qt::DayOfWeek> freeDays() const; 0105 0106 /*! Sets the brush to use to paint free days. 0107 */ 0108 void setFreeDaysBrush(const QBrush brush); 0109 0110 /*! 0111 \returns The brush used to paint free days. 0112 */ 0113 QBrush freeDaysBrush() const; 0114 0115 /*! \param s The scale to be used to paint the grid. 0116 * 0117 * The signal gridChanged() is emitted after the scale has changed. 0118 * \sa Scale 0119 * 0120 * Following example demonstrates how to change the format of the header to use 0121 * a date-scaling with the header-label displayed with the ISO date-notation. 0122 * \code 0123 * DateTimeScaleFormatter* formatter = new DateTimeScaleFormatter(DateTimeScaleFormatter::Day, QString::fromLatin1("yyyy-MMMM-dddd")); 0124 * grid->setUserDefinedUpperScale( formatter ); 0125 * grid->setUserDefinedLowerScale( formatter ); 0126 * grid->setScale( DateTimeGrid::ScaleUserDefined ); 0127 * \endcode 0128 */ 0129 void setScale( Scale s ); 0130 0131 /*! \returns The scale used to paint the grid. 0132 * 0133 * The default is ScaleAuto, which means the day scale will be used 0134 * as long as the day width is less or equal to 500. 0135 * \sa Scale 0136 */ 0137 Scale scale() const; 0138 0139 /*! Sets the scale formatter for the lower part of the header to the 0140 * user defined formatter to \a lower. The DateTimeGrid object takes 0141 * ownership of the formatter, which has to be allocated with new. 0142 * 0143 * You have to set the scale to ScaleUserDefined for this setting to take effect. 0144 * \sa DateTimeScaleFormatter 0145 */ 0146 void setUserDefinedLowerScale( DateTimeScaleFormatter* lower ); 0147 0148 /*! Sets the scale formatter for the upper part of the header to the 0149 * user defined formatter to \a upper. The DateTimeGrid object takes 0150 * ownership of the formatter, which has to be allocated with new. 0151 * 0152 * You have to set the scale to ScaleUserDefined for this setting to take effect. 0153 * \sa DateTimeScaleFormatter 0154 */ 0155 void setUserDefinedUpperScale( DateTimeScaleFormatter* upper ); 0156 0157 /*! \return The DateTimeScaleFormatter being used to render the lower scale. 0158 */ 0159 DateTimeScaleFormatter* userDefinedLowerScale() const; 0160 0161 0162 /*! \return The DateTimeScaleFormatter being used to render the upper scale. 0163 */ 0164 DateTimeScaleFormatter* userDefinedUpperScale() const; 0165 0166 /*! \returns true if row separators are used. */ 0167 bool rowSeparators() const; 0168 0169 /*! \param enable Whether to use row separators or not. */ 0170 void setRowSeparators( bool enable ); 0171 0172 /*! Sets the brush used to display rows where no data is found. 0173 * Default is a red pattern. If set to QBrush() rows with no 0174 * information will not be marked. 0175 */ 0176 void setNoInformationBrush( const QBrush& brush ); 0177 0178 /*! \returns the brush used to mark rows with no information. 0179 */ 0180 QBrush noInformationBrush() const; 0181 0182 /*! \param idx The index to get the Span for. 0183 * \returns The start and end pixels, in a Span, of the specified index. 0184 */ 0185 /*reimp*/ Span mapToChart( const QModelIndex& idx ) const override; 0186 0187 /*! Maps the supplied Span to QDateTimes, and puts them as start time and 0188 * end time for the supplied index. 0189 * 0190 * \param span The span used to map from. 0191 * \param idx The index used for setting the start time and end time in the model. 0192 * \param constraints A list of hard constraints to match against the start time and 0193 * end time mapped from the span. 0194 * 0195 * \returns true if the start time and time was successfully added to the model, or false 0196 * if unsuccessful. 0197 * Also returns false if any of the constraints isn't satisfied. That is, if the start time of 0198 * the constrained index is before the end time of the dependency index, or the end time of the 0199 * constrained index is before the start time of the dependency index. 0200 */ 0201 /*reimp*/ bool mapFromChart( const Span& span, const QModelIndex& idx, 0202 const QList<Constraint>& constraints=QList<Constraint>() ) const override; 0203 0204 /*! 0205 * \param value The datetime to get the x value for. 0206 * \returns The x value corresponding to \a value or -1.0 if \a value is not a datetime variant. 0207 */ 0208 /*reimp*/ qreal mapToChart( const QVariant& value ) const override; 0209 0210 /*! 0211 * \param x The x value to get the datetime for. 0212 * \returns The datetime corresponding to \a x or an invalid datetime if x cannot be mapped. 0213 */ 0214 /*reimp*/ QVariant mapFromChart( qreal x ) const override; 0215 /*reimp*/ void paintGrid( QPainter* painter, 0216 const QRectF& sceneRect, const QRectF& exposedRect, 0217 AbstractRowController* rowController = nullptr, 0218 QWidget* widget = nullptr ) override; 0219 /*reimp*/ void paintHeader( QPainter* painter, 0220 const QRectF& headerRect, const QRectF& exposedRect, 0221 qreal offset, QWidget* widget = nullptr ) override; 0222 0223 /** 0224 * @return the timeline control object 0225 */ 0226 DateTimeTimeLine *timeLine() const; 0227 0228 HeaderType sectionHandleAtPos(int x, int y, const QRect &headerRect) const; 0229 0230 protected: 0231 /*! Paints the hour scale header. 0232 * \sa paintHeader() 0233 */ 0234 virtual void paintHourScaleHeader( QPainter* painter, 0235 const QRectF& headerRect, const QRectF& exposedRect, 0236 qreal offset, QWidget* widget = nullptr ); 0237 0238 /*! Paints the day scale header. 0239 * \sa paintHeader() 0240 */ 0241 virtual void paintDayScaleHeader( QPainter* painter, 0242 const QRectF& headerRect, const QRectF& exposedRect, 0243 qreal offset, QWidget* widget = nullptr ); 0244 0245 /*! Paints the week scale header. 0246 * \sa paintHeader() 0247 */ 0248 virtual void paintWeekScaleHeader( QPainter* painter, 0249 const QRectF& headerRect, const QRectF& exposedRect, 0250 qreal offset, QWidget* widget = nullptr ); 0251 0252 /*! Paints the week scale header. 0253 * \sa paintHeader() 0254 */ 0255 virtual void paintMonthScaleHeader( QPainter* painter, 0256 const QRectF& headerRect, const QRectF& exposedRect, 0257 qreal offset, QWidget* widget = nullptr ); 0258 0259 virtual void paintUserDefinedHeader( QPainter* painter, 0260 const QRectF& headerRect, const QRectF& exposedRect, 0261 qreal offset, const DateTimeScaleFormatter* formatter, 0262 QWidget* widget = nullptr ); 0263 0264 0265 /*! Draw the background for a day. 0266 */ 0267 virtual void drawDayBackground(QPainter* painter, const QRectF& rect, const QDate& date); 0268 0269 /*! Draw the foreground for a day. 0270 */ 0271 virtual void drawDayForeground(QPainter* painter, const QRectF& rect, const QDate& date); 0272 0273 /** Return the rectangle that represents the date-range. 0274 */ 0275 QRectF computeRect(const QDateTime& from, const QDateTime& to, const QRectF& rect) const; 0276 0277 0278 /** Return a date-range represented by the rectangle. 0279 */ 0280 QPair<QDateTime, QDateTime> dateTimeRange(const QRectF& rect) const; 0281 0282 /* reimp */ void drawBackground(QPainter* paint, const QRectF& rect) override; 0283 /* reimp */ void drawForeground(QPainter* paint, const QRectF& rect) override; 0284 }; 0285 0286 /*!\class KGantt::DateTimeScaleFormatter 0287 * \ingroup KGantt 0288 * 0289 * This class formats dates and times used in DateTimeGrid follawing a given format. 0290 * 0291 * The format follows the format of QDateTime::toString(), with one addition: 0292 * "w" is replaced with the week number of the date as number without a leading zero (1-53) 0293 * "ww" is replaced with the week number of the date as number with a leading zero (01-53) 0294 * 0295 * For example: 0296 * 0297 * \code 0298 * // formatter to print the complete date over the current week 0299 * // This leads to the first day of the week being printed 0300 * DateTimeScaleFormatter formatter = DateTimeScaleFormatter( DateTimeScaleFormatter::Week, "yyyy-MM-dd" ); 0301 * \endcode 0302 * 0303 * Optionally, you can set an user defined text alignment flag. The default value is Qt::AlignCenter. 0304 * \sa DateTimeScaleFormatter::DateTimeScaleFormatter 0305 * 0306 * This class even controls the range of the grid sections. 0307 * \sa KGanttDateTimeScaleFormatter::Range 0308 */ 0309 class KGANTT_EXPORT DateTimeScaleFormatter 0310 { 0311 KGANTT_DECLARE_PRIVATE_BASE_POLYMORPHIC( DateTimeScaleFormatter ) 0312 public: 0313 enum Range { 0314 Second, 0315 Minute, 0316 Hour, 0317 Day, 0318 Week, 0319 Month, 0320 Year 0321 }; 0322 0323 /*! Creates a DateTimeScaleFormatter using \a range and \a format. 0324 * The text on the header is aligned following \a alignment. 0325 */ 0326 DateTimeScaleFormatter( Range range, const QString& formatString, 0327 Qt::Alignment alignment = Qt::AlignCenter ); 0328 DateTimeScaleFormatter( Range range, const QString& formatString, 0329 const QString& templ, Qt::Alignment alignment = Qt::AlignCenter ); 0330 0331 /*! \returns The format being used for formatting dates and times. 0332 */ 0333 DateTimeScaleFormatter( const DateTimeScaleFormatter& other ); 0334 virtual ~DateTimeScaleFormatter(); 0335 0336 DateTimeScaleFormatter& operator=( const DateTimeScaleFormatter& other ); 0337 0338 /*! \returns The format string 0339 */ 0340 QString format() const; 0341 0342 /*! \returns The range of each item on a DateTimeGrid header. 0343 * \sa DateTimeScaleFormatter::Range */ 0344 Range range() const; 0345 Qt::Alignment alignment() const; 0346 0347 /*! \returns the QDateTime being the begin of the range after the one containing \a datetime 0348 * \sa currentRangeBegin 0349 */ 0350 virtual QDateTime nextRangeBegin( const QDateTime& datetime ) const; 0351 0352 /*! \returns the QDateTime being the begin of the range containing \a datetime 0353 * \sa nextRangeBegin 0354 */ 0355 virtual QDateTime currentRangeBegin( const QDateTime& datetime ) const; 0356 0357 /*! \returns The \a datetime as string respecting the format. 0358 */ 0359 QString format( const QDateTime& datetime ) const; 0360 virtual QString text( const QDateTime& datetime ) const; 0361 }; 0362 } 0363 0364 0365 0366 #ifndef QT_NO_DEBUG_STREAM 0367 QDebug KGANTT_EXPORT operator<<( QDebug dbg, KGantt::DateTimeScaleFormatter::Range ); 0368 #endif 0369 0370 #endif /* KGANTTDATETIMEGRID_H */ 0371