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";
66 qreal 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.);
76 QDateTime 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;
81 QDateTime dt = startDateTime;
82 QDateTime result = dt.addDays(days)
83 .addSecs(
static_cast<int>(secs - (days * 24. * 60. * 60.)))
84 .addMSecs(qRound((secs -
static_cast<int>(secs)) * 1000.));
118 const QString &templ, Qt::Alignment alignment)
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()))
159 QString result =
d->format;
161 const QString shortWeekNumber = QString::number(datetime.date().weekNumber()) + QLatin1String(
"/")
162 + QString::number(datetime.date().year());
163 const QString longWeekNumber = (shortWeekNumber.length() == 1 ? QString::fromLatin1(
"0") : QString()) + shortWeekNumber;
164 result.replace(QString::fromLatin1(
"ww"), longWeekNumber);
165 result.replace(QString::fromLatin1(
"w"), shortWeekNumber);
166 result = datetime.toLocalTime().toString(result);
172 return d->templ.arg(
format(datetime));
192 QDateTime result = datetime;
195 result = result.addSecs(60);
199 result.setTime(QTime(result.time().hour(), result.time().minute()));
200 result = result.addSecs(60);
204 result.setTime(QTime(result.time().hour(), 0));
205 result = result.addSecs(60 * 60);
209 result.setTime(QTime(0, 0));
210 result = result.addDays(1);
214 result.setTime(QTime(0, 0));
217 const int weekNumber = result.date().weekNumber();
218 while (weekNumber == result.date().weekNumber())
219 result = result.addDays(1);
224 result.setTime(QTime(0, 0));
226 result.setDate(QDate(result.date().year(), result.date().month(), 1).addMonths(1));
230 result.setTime(QTime(0, 0));
232 result.setDate(QDate(result.date().year(), 1, 1).addYears(1));
236 assert(result != datetime);
246 QDateTime result = datetime;
252 result.setTime(QTime(result.time().hour(), result.time().minute()));
256 result.setTime(QTime(result.time().hour(), 0));
260 result.setTime(QTime(0, 0));
264 result.setTime(QTime(0, 0));
267 const int weekNumber = result.date().weekNumber();
268 while (weekNumber == result.date().addDays(-1).weekNumber())
269 result = result.addDays(-1);
274 result.setTime(QTime(0, 0));
276 result.setDate(QDate(result.date().year(), result.date().month(), 1));
280 result.setTime(QTime(0, 0));
282 result.setDate(QDate(result.date().year(), 1, 1));
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;
482 d->rowSeparators = enable;
491 d->noInformationBrush = brush;
499 return d->noInformationBrush;
508 if (!value.canConvert(QVariant::DateTime) || (value.type() == QVariant::String && value.toString().isEmpty())) {
511 return d->dateTimeToChartX(value.toDateTime());
520 return d->chartXtoDateTime(x);
531 assert(idx.model() ==
model());
534 if (sv.canConvert(QVariant::DateTime) && ev.canConvert(QVariant::DateTime) && !(sv.type() == QVariant::String && sv.toString().isEmpty()) && !(ev.type() == QVariant::String && ev.toString().isEmpty())) {
535 QDateTime st = sv.toDateTime();
536 QDateTime et = ev.toDateTime();
537 if (et.isValid() && st.isValid()) {
538 qreal sx =
d->dateTimeToChartX(st);
539 qreal ex =
d->dateTimeToChartX(et) - sx;
545 if (sv.canConvert(QVariant::DateTime) && !(sv.type() == QVariant::String && sv.toString().isEmpty())) {
546 QDateTime st = sv.toDateTime();
548 qreal sx =
d->dateTimeToChartX(st);
556 static void debug_print_idx(
const QModelIndex& idx )
558 if ( !idx.isValid() ) {
559 qDebug() <<
"[Invalid]";
563 QDateTime et = idx.data(
EndTimeRole ).toDateTime();
564 qDebug() << idx <<
"["<<st<<et<<
"]";
583 const QList<Constraint> &constraints)
const
588 assert(idx.model() ==
model());
590 QDateTime st =
d->chartXtoDateTime(span.
start());
591 QDateTime et =
d->chartXtoDateTime(span.
start() + span.
length());
596 if (c.startIndex() == idx) {
601 }
else if (c.endIndex() == idx) {
613 Qt::PenStyle DateTimeGrid::Private::gridLinePenStyle(QDateTime dt, Private::HeaderType headerType)
const
615 switch (headerType) {
616 case Private::HeaderHour:
618 if (dt.time().hour() == 0)
619 return Qt::SolidLine;
621 case Private::HeaderDay:
623 if (dt.date().dayOfWeek() == weekStart)
624 return Qt::SolidLine;
626 case Private::HeaderWeek:
628 if (dt.date().day() == 1)
629 return Qt::SolidLine;
631 if (dt.date().dayOfWeek() == weekStart)
634 case Private::HeaderMonth:
636 if (dt.date().dayOfYear() == 1)
637 return Qt::SolidLine;
639 if (dt.date().day() == 1)
651 QDateTime DateTimeGrid::Private::adjustDateTimeForHeader(QDateTime dt, Private::HeaderType headerType)
const
654 dt.setTime(QTime(0, 0, 0, 0));
656 switch (headerType) {
657 case Private::HeaderWeek:
659 while (dt.date().dayOfWeek() != weekStart)
662 case Private::HeaderMonth:
664 dt = dt.addDays(1 - dt.date().day());
666 case Private::HeaderYear:
668 dt = dt.addDays(1 - dt.date().dayOfYear());
678 void DateTimeGrid::Private::paintVerticalLines(QPainter *painter,
679 const QRectF &sceneRect,
680 const QRectF &exposedRect,
682 Private::HeaderType headerType)
684 QDateTime dt = chartXtoDateTime(exposedRect.left());
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)) {
700 QPen pen = painter->pen();
701 pen.setBrush(QApplication::palette().dark());
702 pen.setStyle(gridLinePenStyle(dt, headerType));
703 painter->setPen(pen);
704 if (freeDays.contains(
static_cast<Qt::DayOfWeek
>(dt.date().dayOfWeek()))) {
705 if (freeDaysBrush.style() == Qt::NoBrush)
706 painter->setBrush(widget ? widget->palette().midlight()
707 : QApplication::palette().midlight());
709 painter->setBrush(freeDaysBrush);
711 painter->fillRect(QRectF(x, exposedRect.top(), dayWidth, exposedRect.height()), painter->brush());
713 painter->drawLine(QPointF(x, sceneRect.top()), QPointF(x, sceneRect.bottom()));
718 void DateTimeGrid::Private::paintVerticalUserDefinedLines(QPainter *painter,
719 const QRectF &sceneRect,
720 const QRectF &exposedRect,
725 QDateTime dt = chartXtoDateTime(exposedRect.left());
727 QPen pen = painter->pen();
728 pen.setBrush(QApplication::palette().dark());
729 pen.setStyle(Qt::DashLine);
730 painter->setPen(pen);
731 for (qreal x = dateTimeToChartX(dt); x < exposedRect.right();
733 if (freeDays.contains(
static_cast<Qt::DayOfWeek
>(dt.date().dayOfWeek()))) {
734 QBrush oldBrush = painter->brush();
735 if (freeDaysBrush.style() == Qt::NoBrush)
736 painter->setBrush(widget ? widget->palette().midlight()
737 : QApplication::palette().midlight());
739 painter->setBrush(freeDaysBrush);
741 painter->fillRect(QRectF(x, exposedRect.top(), dayWidth, exposedRect.height()), painter->brush());
742 painter->setBrush(oldBrush);
748 painter->drawLine(QPointF(x, sceneRect.top()), QPointF(x, sceneRect.bottom()));
753 DateTimeGrid::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;
773 const QRectF &sceneRect,
774 const QRectF &exposedRect,
784 d->paintVerticalLines(painter, sceneRect, exposedRect, widget,
d->headerTypeForScale(
scale()));
787 const qreal tabw = QApplication::fontMetrics().horizontalAdvance(QLatin1String(
"XXXXX"));
789 if (dayw > 24 * 60 * 60 * tabw) {
791 d->paintVerticalUserDefinedLines(painter, sceneRect, exposedRect, &
d->minute_lower, widget);
792 }
else if (dayw > 24 * 60 * tabw) {
793 d->paintVerticalLines(painter, sceneRect, exposedRect, widget, Private::HeaderHour);
794 }
else if (dayw > 24 * tabw) {
795 d->paintVerticalLines(painter, sceneRect, exposedRect, widget, Private::HeaderDay);
796 }
else if (dayw > tabw) {
797 d->paintVerticalUserDefinedLines(painter, sceneRect, exposedRect, &
d->week_lower, widget);
798 }
else if (4 * dayw > tabw) {
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);
811 QPen pen = painter->pen();
812 pen.setBrush(QApplication::palette().dark());
813 pen.setStyle(Qt::DashLine);
814 painter->setPen(pen);
815 QModelIndex idx = rowController->
indexAt(qRound(exposedRect.top()));
819 while (y < exposedRect.bottom() && idx.isValid()) {
822 if (
d->rowSeparators) {
823 painter->drawLine(QPointF(sceneRect.left(), y),
824 QPointF(sceneRect.right(), y));
826 if (!idx.data(
ItemTypeRole).isValid() &&
d->noInformationBrush.style() != Qt::NoBrush) {
827 painter->fillRect(QRectF(exposedRect.left(), s.
start(), exposedRect.width(), s.
length()),
d->noInformationBrush);
836 int DateTimeGrid::Private::tabHeight(
const QString &txt, QWidget *widget)
const
838 QStyleOptionHeader opt;
840 opt.initFrom(widget);
844 style = widget->style();
846 style = QApplication::style();
847 QSize s = style->sizeFromContents(QStyle::CT_HeaderSection, &opt, QSize(), widget);
853 const qreal tabw = QApplication::fontMetrics().horizontalAdvance(QLatin1String(
"XXXXX"));
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;
877 qreal offset, QWidget *widget)
880 QPainterPath clipPath;
881 clipPath.addRect(headerRect);
882 painter->setClipPath(clipPath, Qt::IntersectClip);
898 d->getAutomaticFormatters(&lower, &upper);
901 const qreal upperRatio = upperHeight / (lowerHeight + upperHeight);
903 const QRectF upperHeaderRect(headerRect.x(), headerRect.top(), headerRect.width() - 1, headerRect.height() * upperRatio);
904 const QRectF lowerHeaderRect(headerRect.x(), upperHeaderRect.bottom() + 1, headerRect.width() - 1, headerRect.height() - upperHeaderRect.height() - 1);
911 const qreal lowerHeight =
d->tabHeight(
d->lower->text(
startDateTime()));
912 const qreal upperHeight =
d->tabHeight(
d->upper->text(
startDateTime()));
913 const qreal upperRatio = upperHeight / (lowerHeight + upperHeight);
915 const QRectF upperHeaderRect(headerRect.x(), headerRect.top(), headerRect.width() - 1, headerRect.height() * upperRatio);
916 const QRectF lowerHeaderRect(headerRect.x(), upperHeaderRect.bottom() + 1, headerRect.width() - 1, headerRect.height() - upperHeaderRect.height() - 1);
926 const QRectF &headerRect,
const QRectF &exposedRect,
930 const QStyle *
const style = widget ? widget->style() : QApplication::style();
932 QDateTime dt = formatter->
currentRangeBegin(
d->chartXtoDateTime(offset + exposedRect.left()));
933 qreal x =
d->dateTimeToChartX(dt);
935 while (x < exposedRect.right() + offset) {
937 const qreal nextx =
d->dateTimeToChartX(next);
939 QStyleOptionHeader opt;
941 opt.initFrom(widget);
942 opt.rect = QRectF(x - offset + 1, headerRect.top(), qMax<qreal>(1., nextx - x - 1), headerRect.height()).toAlignedRect();
943 opt.textAlignment = formatter->
alignment();
944 opt.text = formatter->
text(dt);
945 style->drawControl(QStyle::CE_Header, &opt, painter, widget);
952 void DateTimeGrid::Private::paintHeader(QPainter *painter,
953 const QRectF &headerRect,
const QRectF &exposedRect,
954 qreal offset, QWidget *widget,
955 Private::HeaderType headerType,
956 DateTextFormatter *formatter)
958 QStyle *style = widget ? widget->style() : QApplication::style();
960 const qreal left = exposedRect.left() + offset;
961 const qreal right = exposedRect.right() + offset;
964 QDateTime dt = chartXtoDateTime(left);
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;
994 dt = dt.addSecs(offsetSeconds), dt = dt.addDays(offsetDays), dt = dt.addMonths(offsetMonths),
995 x = dateTimeToChartX(dt)) {
996 QStyleOptionHeader opt;
998 opt.initFrom(widget);
999 opt.rect = formatter->textRect(x, offset, dayWidth, headerRect, dt);
1000 opt.text = formatter->format(dt);
1001 opt.textAlignment = Qt::AlignCenter;
1002 style->drawControl(QStyle::CE_Header, &opt, painter, widget);
1010 const QRectF &headerRect,
const QRectF &exposedRect,
1011 qreal offset, QWidget *widget)
1013 class HourFormatter :
public Private::DateTextFormatter
1016 ~HourFormatter()
override
1020 QString format(
const QDateTime &dt)
override
1022 return dt.time().toString(QString::fromLatin1(
"hh"));
1024 QRect textRect(qreal x, qreal offset, qreal
dayWidth,
const QRectF &headerRect,
const QDateTime &dt)
override
1028 return QRectF(QPointF(x, headerRect.top()) + QPointF(-offset + 1.0, headerRect.height() / 2.0),
1029 QSizeF(
dayWidth / 24.0, headerRect.height() / 2.0))
1033 d->paintHeader(painter, headerRect, exposedRect, offset, widget,
1034 Private::HeaderHour,
new HourFormatter);
1036 class DayFormatter :
public Private::DateTextFormatter
1039 ~DayFormatter()
override
1042 QString format(
const QDateTime &dt)
override
1044 return dt.date().toString();
1046 QRect textRect(qreal x, qreal offset, qreal
dayWidth,
const QRectF &headerRect,
const QDateTime &dt)
override
1050 return QRectF(QPointF(x, headerRect.top()) + QPointF(-offset, 0.0),
1051 QSizeF(
dayWidth, headerRect.height() / 2.0))
1055 d->paintHeader(painter, headerRect, exposedRect, offset, widget,
1056 Private::HeaderDay,
new DayFormatter);
1063 qreal offset, QWidget *widget)
1065 class DayFormatter :
public Private::DateTextFormatter
1069 : Private::DateTextFormatter()
1070 , m_formatter(DateTimeScaleFormatter::Range::Day, QString::fromLatin1(
"ddd"))
1073 ~DayFormatter()
override
1077 QString format(
const QDateTime &dt)
override
1079 return m_formatter.format(dt);
1081 QRect textRect(qreal x, qreal offset, qreal
dayWidth,
const QRectF &headerRect,
const QDateTime &dt)
override
1085 return QRectF(QPointF(x, headerRect.top()) + QPointF(-offset + 1.0, headerRect.height() / 2.0),
1086 QSizeF(
dayWidth, headerRect.height() / 2.0))
1091 d->paintHeader(painter, headerRect, exposedRect, offset, widget,
1092 Private::HeaderDay,
new DayFormatter);
1094 class WeekFormatter :
public Private::DateTextFormatter
1097 ~WeekFormatter()
override
1100 QString format(
const QDateTime &dt)
override
1102 return QString::number(dt.date().weekNumber()) + QLatin1String(
"/") + QString::number(dt.date().year());
1104 QRect textRect(qreal x, qreal offset, qreal
dayWidth,
const QRectF &headerRect,
const QDateTime &dt)
override
1108 return QRectF(QPointF(x, headerRect.top()) + QPointF(-offset, 0.0),
1109 QSizeF(
dayWidth * 7, headerRect.height() / 2.0))
1113 d->paintHeader(painter, headerRect, exposedRect, offset, widget,
1114 Private::HeaderWeek,
new WeekFormatter);
1121 qreal offset, QWidget *widget)
1123 class WeekFormatter :
public Private::DateTextFormatter
1126 ~WeekFormatter()
override
1130 QString format(
const QDateTime &dt)
override
1132 return QString::number(dt.date().weekNumber());
1134 QRect textRect(qreal x, qreal offset, qreal
dayWidth,
const QRectF &headerRect,
const QDateTime &dt)
override
1138 return QRectF(QPointF(x, headerRect.top()) + QPointF(-offset, headerRect.height() / 2.0),
1139 QSizeF(
dayWidth * 7, headerRect.height() / 2.0))
1143 d->paintHeader(painter, headerRect, exposedRect, offset, widget,
1144 Private::HeaderWeek,
new WeekFormatter);
1146 class MonthFormatter :
public Private::DateTextFormatter
1149 ~MonthFormatter()
override
1153 QString format(
const QDateTime &dt)
override
1155 return QLocale().monthName(dt.date().month(), QLocale::LongFormat) + QLatin1String(
"/") + QString::number(dt.date().year());
1157 QRect textRect(qreal x, qreal offset, qreal
dayWidth,
const QRectF &headerRect,
const QDateTime &dt)
override
1159 return QRectF(QPointF(x, headerRect.top()) + QPointF(-offset, 0.0),
1160 QSizeF(
dayWidth * dt.date().daysInMonth(), headerRect.height() / 2.0))
1164 d->paintHeader(painter, headerRect, exposedRect, offset, widget,
1165 Private::HeaderMonth,
new MonthFormatter);
1172 qreal offset, QWidget *widget)
1174 class MonthFormatter :
public Private::DateTextFormatter
1177 ~MonthFormatter()
override
1181 QString format(
const QDateTime &dt)
override
1183 return QLocale().monthName(dt.date().month(), QLocale::ShortFormat) + QLatin1String(
"/") + QString::number(dt.date().year());
1185 QRect textRect(qreal x, qreal offset, qreal
dayWidth,
const QRectF &headerRect,
const QDateTime &dt)
override
1187 return QRectF(QPointF(x, headerRect.top()) + QPointF(-offset, headerRect.height() / 2.0),
1188 QSizeF(
dayWidth * dt.date().daysInMonth(), headerRect.height() / 2.0))
1192 d->paintHeader(painter, headerRect, exposedRect, offset, widget,
1193 Private::HeaderMonth,
new MonthFormatter);
1195 class YearFormatter :
public Private::DateTextFormatter
1198 ~YearFormatter()
override
1202 QString format(
const QDateTime &dt)
override
1204 return QString::number(dt.date().year());
1206 QRect textRect(qreal x, qreal offset, qreal
dayWidth,
const QRectF &headerRect,
const QDateTime &dt)
override
1208 return QRectF(QPointF(x, headerRect.top()) + QPointF(-offset, 0.0),
1209 QSizeF(
dayWidth * dt.date().daysInYear(), headerRect.height() / 2.0))
1213 d->paintHeader(painter, headerRect, exposedRect, offset, widget,
1214 Private::HeaderYear,
new YearFormatter);
1239 qreal topLeft =
d->dateTimeToChartX(from);
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();
1266 int startx = rect.left();
1267 int endx = rect.right();
1274 QDate nextDate =
d->chartXtoDateTime(startx + 1).date();
1275 if (date != nextDate) {
1276 QRectF dayRect(startx -
dayWidth(), rect.top(),
dayWidth(), rect.height());
1277 dayRect = dayRect.adjusted(1, 0, 0, 0);
1286 for (
int i = startx; i < endx; i += offset) {
1287 date =
d->chartXtoDateTime(i + 1).date();
1289 QRectF dayRect(i, rect.top(),
dayWidth(), rect.height());
1290 dayRect = dayRect.adjusted(1, 0, 0, 0);
1303 QDate date =
d->chartXtoDateTime(rect.left()).date();
1306 int startx = rect.left();
1307 int endx = rect.right();
1314 QDate nextDate =
d->chartXtoDateTime(startx + 1).date();
1315 if (date != nextDate) {
1316 QRectF dayRect(startx -
dayWidth(), rect.top(),
dayWidth(), rect.height());
1317 dayRect = dayRect.adjusted(1, 0, 0, 0);
1326 for (
int i = startx; i < endx; i += offset) {
1327 date =
d->chartXtoDateTime(i + 1).date();
1329 QRectF dayRect(i, rect.top(),
dayWidth(), rect.height());
1330 dayRect = dayRect.adjusted(1, 0, 0, 0);
1340 #ifndef KDAB_NO_UNIT_TESTS
1342 #include "unittest/test.h"
1343 #include <QStandardItemModel>
1345 static std::ostream &
operator<<(std::ostream &os,
const QDateTime &dt)
1348 os << dt.toString().toLatin1().constData();
1350 os << dt.toString().toStdString();
1357 QStandardItemModel model(3, 2);
1359 QDateTime dt = QDateTime::currentDateTime();
1361 QDateTime startdt = dt.addDays(-10);
1365 model.setData(model.index(0, 0), dt.addDays(17),
EndTimeRole);
1367 model.setData(model.index(2, 0), dt.addDays(18),
StartTimeRole);
1368 model.setData(model.index(2, 0), dt.addDays(19),
EndTimeRole);
1373 assertTrue(s.
start() > 0);
1374 assertTrue(s.
length() > 0);
1380 QDateTime s1 = model.data(model.index(0, 0),
StartTimeRole).toDateTime();
1381 QDateTime e1 = model.data(model.index(0, 0),
EndTimeRole).toDateTime();
1382 QDateTime s2 = model.data(model.index(1, 0),
StartTimeRole).toDateTime();
1383 QDateTime e2 = model.data(model.index(1, 0),
EndTimeRole).toDateTime();
1385 assertTrue(s1.isValid());
1386 assertTrue(e1.isValid());
1387 assertTrue(s2.isValid());
1388 assertTrue(e2.isValid());
1390 assertEqual(s1, s2);
1391 assertEqual(e1, e2);
1400 assertEqual(s1, model.data(model.index(0, 0),
StartTimeRole).toDateTime());
1406 QDateTime startDateTime = QDateTime::currentDateTime();
1407 qreal dayWidth = 100;
1408 QDate currentDate = QDate::currentDate();
1409 QDateTime dt(QDate(currentDate.year(), 1, 1), QTime(0, 0, 0, 0));
1410 assert(dt.isValid());
1411 qreal result = startDateTime.date().daysTo(dt.date()) * 24. * 60. * 60.;
1412 result += startDateTime.time().msecsTo(dt.time()) / 1000.;
1413 result *= dayWidth / (24. * 60. * 60.);
1415 int days =
static_cast<int>(result / dayWidth);
1416 qreal secs = result * (24. * 60. * 60.) / dayWidth;
1417 QDateTime dt2 = startDateTime;
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"
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, DateTimeGrid, "test")
QDebug operator<<(QDebug dbg, KDGantt::DateTimeScaleFormatter::Range range)