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