12#include "kdganttdatetimegrid_p.h"
16#include <QApplication>
21#include <QPainterPath>
24#include <QStyleOptionHeader>
35 dbg <<
"KDGantt::DateTimeScaleFormatter::Second";
38 dbg <<
"KDGantt::DateTimeScaleFormatter::Minute";
41 dbg <<
"KDGantt::DateTimeScaleFormatter::Hour";
44 dbg <<
"KDGantt::DateTimeScaleFormatter::Day";
47 dbg <<
"KDGantt::DateTimeScaleFormatter::Week";
50 dbg <<
"KDGantt::DateTimeScaleFormatter::Month";
53 dbg <<
"KDGantt::DateTimeScaleFormatter::Year";
66qreal DateTimeGrid::Private::dateTimeToChartX(
const QDateTime &dt)
const
68 assert(startDateTime.isValid());
69 qreal result = startDateTime.date().daysTo(dt.
date()) * 24. * 60. * 60.;
70 result += startDateTime.time().msecsTo(dt.
time()) / 1000.;
71 result *= dayWidth / (24. * 60. * 60.);
76QDateTime DateTimeGrid::Private::chartXtoDateTime(qreal x)
const
78 assert(startDateTime.isValid());
79 int days =
static_cast<int>(x / dayWidth);
80 qreal secs = x * (24. * 60. * 60.) / dayWidth;
83 .
addSecs(
static_cast<int>(secs - (days * 24. * 60. * 60.)))
84 .
addMSecs(qRound((secs -
static_cast<int>(secs)) * 1000.));
119 : _d(new Private(range, format, templ, alignment))
124 : _d(new Private(range, format,
QString::fromLatin1(
"%1"), alignment))
129 : _d(new Private(other.range(), other.format(), other.
d->templ, other.alignment()))
205 result = result.
addSecs(60 * 60);
236 assert(result != datetime);
303 return d->startDateTime;
313 d->startDateTime =
dt;
330 return d->dateTimeToChartX(
dt);
337 return d->chartXtoDateTime(x);
463 d->freeDaysBrush = brush;
471 return d->freeDaysBrush;
477 return d->rowSeparators;
491 d->noInformationBrush = brush;
499 return d->noInformationBrush;
520 return d->chartXtoDateTime(x);
537 if (
et.isValid() &&
st.isValid()) {
556static void debug_print_idx(
const QModelIndex& idx )
559 qDebug() <<
"[Invalid]";
564 qDebug() << idx <<
"["<<st<<et<<
"]";
596 if (c.startIndex() ==
idx) {
601 }
else if (c.endIndex() ==
idx) {
613Qt::PenStyle DateTimeGrid::Private::gridLinePenStyle(
QDateTime dt, Private::HeaderType headerType)
const
615 switch (headerType) {
616 case Private::HeaderHour:
621 case Private::HeaderDay:
626 case Private::HeaderWeek:
634 case Private::HeaderMonth:
651QDateTime DateTimeGrid::Private::adjustDateTimeForHeader(
QDateTime dt, Private::HeaderType headerType)
const
656 switch (headerType) {
657 case Private::HeaderWeek:
662 case Private::HeaderMonth:
666 case Private::HeaderYear:
678void DateTimeGrid::Private::paintVerticalLines(
QPainter *painter,
680 const QRectF &exposedRect,
682 Private::HeaderType headerType)
685 dt = adjustDateTimeForHeader(dt, headerType);
687 int offsetSeconds = 0;
690 if (headerType == Private::HeaderHour)
691 offsetSeconds = 60 * 60;
695 for (qreal x = dateTimeToChartX(dt); x < exposedRect.
right();
696 dt = dt.
addSecs(offsetSeconds), dt = dt.
addDays(offsetDays), x = dateTimeToChartX(dt)) {
702 pen.
setStyle(gridLinePenStyle(dt, headerType));
718void DateTimeGrid::Private::paintVerticalUserDefinedLines(
QPainter *painter,
720 const QRectF &exposedRect,
731 for (qreal x = dateTimeToChartX(dt); x < exposedRect.
right();
753DateTimeGrid::Private::HeaderType DateTimeGrid::Private::headerTypeForScale(
DateTimeGrid::Scale scale)
757 return Private::HeaderHour;
759 return Private::HeaderDay;
761 return Private::HeaderWeek;
763 return Private::HeaderMonth;
769 return Private::HeaderDay;
774 const QRectF &exposedRect,
784 d->paintVerticalLines(painter, sceneRect,
exposedRect, widget,
d->headerTypeForScale(
scale()));
791 d->paintVerticalUserDefinedLines(painter, sceneRect,
exposedRect, &
d->minute_lower, widget);
793 d->paintVerticalLines(painter, sceneRect,
exposedRect, widget, Private::HeaderHour);
795 d->paintVerticalLines(painter, sceneRect,
exposedRect, widget, Private::HeaderDay);
797 d->paintVerticalUserDefinedLines(painter, sceneRect,
exposedRect, &
d->week_lower, widget);
799 d->paintVerticalUserDefinedLines(painter, sceneRect,
exposedRect, &
d->month_lower, widget);
801 d->paintVerticalUserDefinedLines(painter, sceneRect,
exposedRect, &
d->year_lower, widget);
806 d->paintVerticalUserDefinedLines(painter, sceneRect,
exposedRect,
d->lower, widget);
822 if (
d->rowSeparators) {
836int DateTimeGrid::Private::tabHeight(
const QString &txt,
QWidget *widget)
const
844 style = widget->
style();
854 const qreal dayw = dayWidth;
855 if (dayw > 24 * 60 * 60 * tabw) {
856 *lower = &minute_lower;
857 *upper = &minute_upper;
858 }
else if (dayw > 24 * 60 * tabw) {
859 *lower = &hour_lower;
860 *upper = &hour_upper;
861 }
else if (dayw > 24 * tabw) {
864 }
else if (dayw > tabw) {
865 *lower = &week_lower;
866 *upper = &week_upper;
867 }
else if (4 * dayw > tabw) {
868 *lower = &month_lower;
869 *upper = &month_upper;
871 *lower = &year_lower;
872 *upper = &year_upper;
898 d->getAutomaticFormatters(&lower, &
upper);
952void DateTimeGrid::Private::paintHeader(
QPainter *painter,
955 Private::HeaderType headerType,
956 DateTextFormatter *formatter)
960 const qreal left = exposedRect.
left() + offset;
961 const qreal right = exposedRect.
right() + offset;
965 dt = adjustDateTimeForHeader(dt, headerType);
967 int offsetSeconds = 0;
969 int offsetMonths = 0;
971 switch (headerType) {
972 case Private::HeaderHour:
973 offsetSeconds = 60 * 60;
975 case Private::HeaderDay:
978 case Private::HeaderWeek:
981 case Private::HeaderMonth:
984 case Private::HeaderYear:
993 for (qreal x = dateTimeToChartX(dt); x < right;
995 x = dateTimeToChartX(dt)) {
999 opt.rect = formatter->textRect(x, offset, dayWidth, headerRect, dt);
1000 opt.text = formatter->format(dt);
1011 qreal offset,
QWidget *widget)
1044 return dt.date().toString();
1063 qreal offset,
QWidget *widget)
1069 : Private::DateTextFormatter()
1121 qreal offset,
QWidget *widget)
1172 qreal offset,
QWidget *widget)
1240 qreal topRight =
d->dateTimeToChartX(
to);
1242 return QRectF(topLeft, rect.
top(), topRight - topLeft, rect.
height());
1252 start =
d->chartXtoDateTime(rect.
left());
1253 end =
d->chartXtoDateTime(rect.
right());
1255 return qMakePair(start, end);
1263 QDate date =
d->chartXtoDateTime(rect.
left()).date();
1287 date =
d->chartXtoDateTime(
i + 1).date();
1303 QDate date =
d->chartXtoDateTime(rect.
left()).date();
1327 date =
d->chartXtoDateTime(
i + 1).date();
1340#ifndef KDAB_NO_UNIT_TESTS
1342#include "unittest/test.h"
1343#include <QStandardItemModel>
1373 assertTrue(s.
start() > 0);
1374 assertTrue(s.
length() > 0);
1390 assertEqual(s1, s2);
1391 assertEqual(e1, e2);
1407 qreal dayWidth = 100;
1411 qreal result = startDateTime.
date().
daysTo(dt.
date()) * 24. * 60. * 60.;
1413 result *= dayWidth / (24. * 60. * 60.);
1415 int days =
static_cast<int>(result / dayWidth);
1416 qreal secs = result * (24. * 60. * 60.) / dayWidth;
1418 QDateTime result2 = dt2.
addDays(days).
addSecs(
static_cast<int>(secs - (days * 24. * 60. * 60.))).
addMSecs(qRound((secs -
static_cast<int>(secs)) * 1000.));
1420 assertEqual(dt, result2);
1426#include "moc_kdganttdatetimegrid.cpp"
QDebug operator<<(QDebug dbg, const KDChart::ThreeDBarAttributes &a)
Abstract baseclass for grids.
QAbstractItemModel * model() const
bool isSatisfiedConstraint(const Constraint &c) const
virtual void setModel(QAbstractItemModel *model)
Sets the QAbstractItemModel used by this grid implementation.
Abstract baseclass for row controllers.
virtual QModelIndex indexAbove(const QModelIndex &idx) const =0
virtual QModelIndex indexBelow(const QModelIndex &idx) const =0
virtual Span rowGeometry(const QModelIndex &idx) const =0
virtual QModelIndex indexAt(int height) const =0
A class used to represent a dependency.
This implementation of AbstractGrid works with QDateTime and shows days and week numbers in the heade...
virtual void paintHourScaleHeader(QPainter *painter, const QRectF &headerRect, const QRectF &exposedRect, qreal offset, QWidget *widget=nullptr)
Paints the hour scale header.
virtual void drawDayForeground(QPainter *painter, const QRectF &rect, const QDate &date)
Draw the foreground for a day.
bool mapFromChart(const Span &span, const QModelIndex &idx, const QList< Constraint > &constraints=QList< Constraint >()) const override
Maps the supplied Span to QDateTimes, and puts them as start time and end time for the supplied index...
bool rowSeparators() const
virtual void paintDayScaleHeader(QPainter *painter, const QRectF &headerRect, const QRectF &exposedRect, qreal offset, QWidget *widget=nullptr)
Paints the day scale header.
void paintHeader(QPainter *painter, const QRectF &headerRect, const QRectF &exposedRect, qreal offset, QWidget *widget=nullptr) override
Implement this to paint the header part of the view.
QBrush noInformationBrush() const
DateTimeScaleFormatter * userDefinedUpperScale() const
QDateTime startDateTime() const
void setStartDateTime(const QDateTime &dt)
virtual void drawDayBackground(QPainter *painter, const QRectF &rect, const QDate &date)
Draw the background for a day.
void drawForeground(QPainter *paint, const QRectF &rect) override
void setRowSeparators(bool enable)
DateTimeScaleFormatter * userDefinedLowerScale() const
qreal mapFromDateTime(const QDateTime &dt) const
Maps a given point in time dt to an X value in the scene.
void setWeekStart(Qt::DayOfWeek)
Span mapToChart(const QModelIndex &idx) const override
QRectF computeRect(const QDateTime &from, const QDateTime &to, const QRectF &rect) const
void setNoInformationBrush(const QBrush &brush)
Sets the brush used to display rows where no data is found.
void drawBackground(QPainter *paint, const QRectF &rect) override
QPair< QDateTime, QDateTime > dateTimeRange(const QRectF &rect) const
QDateTime mapToDateTime(qreal x) const
Maps a given X value x in scene coordinates to a point in time.
virtual void paintWeekScaleHeader(QPainter *painter, const QRectF &headerRect, const QRectF &exposedRect, qreal offset, QWidget *widget=nullptr)
Paints the week scale header.
QBrush freeDaysBrush() const
Qt::DayOfWeek weekStart() const
void setUserDefinedLowerScale(DateTimeScaleFormatter *lower)
Sets the scale formatter for the lower part of the header to the user defined formatter to lower.
virtual void paintMonthScaleHeader(QPainter *painter, const QRectF &headerRect, const QRectF &exposedRect, qreal offset, QWidget *widget=nullptr)
Paints the week scale header.
void paintGrid(QPainter *painter, const QRectF &sceneRect, const QRectF &exposedRect, AbstractRowController *rowController=nullptr, QWidget *widget=nullptr) override
Implement this to paint the background of the view – typically with some grid lines.
QSet< Qt::DayOfWeek > freeDays() const
virtual void paintUserDefinedHeader(QPainter *painter, const QRectF &headerRect, const QRectF &exposedRect, qreal offset, const DateTimeScaleFormatter *formatter, QWidget *widget=nullptr)
void setUserDefinedUpperScale(DateTimeScaleFormatter *upper)
Sets the scale formatter for the upper part of the header to the user defined formatter to upper.
void setFreeDaysBrush(const QBrush brush)
Sets the brush to use to paint free days.
void setFreeDays(const QSet< Qt::DayOfWeek > &fd)
A class representing a start point and a length.
KDAB_SCOPED_UNITTEST_SIMPLE(KDGantt, Constraint, "test")
QDebug operator<<(QDebug dbg, KDGantt::DateTimeScaleFormatter::Range range)
virtual QVariant data(const QModelIndex &index, int role) const const=0
virtual bool setData(const QModelIndex &index, const QVariant &value, int role)
QFontMetrics fontMetrics()
const char * constData() const const
QDate addDays(qint64 ndays) const const
QDate addMonths(int nmonths) const const
QDate addYears(int nyears) const const
int dayOfWeek() const const
int dayOfYear() const const
qint64 daysTo(const QDate &d) const const
int weekNumber(int *yearNumber) const const
QDateTime addDays(qint64 ndays) const const
QDateTime addMSecs(qint64 msecs) const const
QDateTime addMonths(int nmonths) const const
QDateTime addSecs(qint64 s) const const
QDateTime currentDateTime()
bool isValid() const const
void setDate(const QDate &date)
void setTime(const QTime &time)
QDateTime toLocalTime() const const
QString toString(Qt::DateFormat format) const const
int horizontalAdvance(const QString &text, int len) const const
QString monthName(int month, QLocale::FormatType type) const const
QVariant data(int role) const const
bool isValid() const const
T qobject_cast(QObject *object)
const QBrush & brush() const const
void drawLine(const QLineF &line)
void fillRect(const QRectF &rectangle, const QBrush &brush)
const QPen & pen() const const
void setBrush(const QBrush &brush)
void setClipPath(const QPainterPath &path, Qt::ClipOperation operation)
void setPen(const QColor &color)
void addRect(const QRectF &rectangle)
void setBrush(const QBrush &brush)
void setStyle(Qt::PenStyle style)
qreal bottom() const const
qreal height() const const
qreal right() const const
QRect toAlignedRect() const const
QRect toRect() const const
virtual QVariant data(const QModelIndex &index, int role) const const override
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const override
virtual bool setData(const QModelIndex &index, const QVariant &value, int role) override
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
QString fromLatin1(const char *str, int size)
bool isEmpty() const const
QString number(int n, int base)
QString & replace(int position, int n, QChar after)
QByteArray toLatin1() const const
std::string toStdString() const const
virtual void drawControl(QStyle::ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const const=0
virtual QSize sizeFromContents(QStyle::ContentsType type, const QStyleOption *option, const QSize &contentsSize, const QWidget *widget) const const=0
void initFrom(const QWidget *widget)
int msecsTo(const QTime &t) const const
bool canConvert(int targetTypeId) const const
QVariant fromValue(const T &value)
QDateTime toDateTime() const const
QString toString() const const
QVariant::Type type() const const