diff options
author | Edward Welbourne <edward.welbourne@qt.io> | 2020-08-28 09:23:13 +0200 |
---|---|---|
committer | Edward Welbourne <edward.welbourne@qt.io> | 2021-06-23 14:04:08 +0200 |
commit | d093ec8d03fe2f6ce4b93075229951689e7e3ebb (patch) | |
tree | 74b7c142cfcaf637bba8fcd20cf431456870d183 /src/widgets/widgets/qdatetimeedit.cpp | |
parent | b0a9825edb490de9e2af09bb91fb6f1819fd7616 (diff) |
Fix handling of day-of-week in QDateTimeParser and QDateTimeEdit
QDTP's absoluteMax(), setDigit() and getDigit() simply treated
day-of-week as synonym for day-of-month.
Consequently, QDTE::stepBy() did the same.
This meant that wrapping happened at the month boundary, so would jump
within the week if it wrapped around, otherwise the up/down arrow
would "jam" at a particular day of the week when further steps would
leave the month. Instead, when wrapping, wrap round the week while
still moving the day-of-month to match, jumping back or forward a week
to stay within the month on hitting a month boundary; otherwise, stop
backwards stepping on hitting the locale-specific day of the week, or
forward stepping when the step would be to or past this first day.
Fixed various bugs found in the course of testing this.
[ChangeLog][QtWidgets][QDateTimeEdit] Corrected handling of weekdays.
Previously, changes to the week-day were simply changes to the day of
the month. Weekday fields are now handled as such: changes to them do
change the day of the month, but a change that would step past the end
(or start) of the month is adjusted to the relevant day of the nearest
week within the month. When wrapping is disabled, the locale-specific
first and last days of the week are the bounds. Formats which specify
day of week but not day of month will now preserve day of week when
changing month or year, selecting the nearest day of month that
matches.
Change-Id: I7868b000fea7a4bc17a1b5687c44bcd56d42ae90
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Diffstat (limited to 'src/widgets/widgets/qdatetimeedit.cpp')
-rw-r--r-- | src/widgets/widgets/qdatetimeedit.cpp | 45 |
1 files changed, 38 insertions, 7 deletions
diff --git a/src/widgets/widgets/qdatetimeedit.cpp b/src/widgets/widgets/qdatetimeedit.cpp index 5b3d0f3c2a..b150827a4d 100644 --- a/src/widgets/widgets/qdatetimeedit.cpp +++ b/src/widgets/widgets/qdatetimeedit.cpp @@ -2101,15 +2101,45 @@ QDateTime QDateTimeEditPrivate::stepBy(int sectionIndex, int steps, bool test) c v = q->dateTimeFromText(str); int val = getDigit(v, sectionIndex); - val += steps; - const int min = absoluteMin(sectionIndex); const int max = absoluteMax(sectionIndex, value.toDateTime()); - if (val < min) { - val = (wrapping ? max - (min - val) + 1 : min); - } else if (val > max) { - val = (wrapping ? min + val - max - 1 : max); + if (sn.type & DayOfWeekSectionMask) { + // Must take locale's first day of week into account when *not* + // wrapping; min and max don't help us. +#ifndef QT_ALWAYS_WRAP_WEEKDAY // (documentation, not an actual define) + if (!wrapping) { + /* It's not clear this is ever really a desirable behavior. + + It refuses to step backwards from the first day of the week or + forwards from the day before, only allowing day-of-week stepping + from start to end of one week. That's strictly what non-wrapping + behavior must surely mean, when put in locale-neutral terms. + + It is, however, likely that users would prefer the "more natural" + behavior of cycling through the week. + */ + const int first = int(locale().firstDayOfWeek()); // Mon = 1 through 7 = Sun + val = qBound(val < first ? first - 7 : first, + val + steps, + val < first ? first - 1 : first + 6); + } else +#endif + { + val += steps; + } + + // Restore to range from 1 through 7: + val = val % 7; + if (val <= 0) + val += 7; + } else { + val += steps; + const int span = max - min + 1; + if (val < min) + val = wrapping ? val + span : min; + else if (val > max) + val = wrapping ? val - span : max; } const int oldDay = v.date().day(calendar); @@ -2132,7 +2162,8 @@ QDateTime QDateTimeEditPrivate::stepBy(int sectionIndex, int steps, bool test) c const QDateTime minimumDateTime = minimum.toDateTime(); const QDateTime maximumDateTime = maximum.toDateTime(); // changing one section should only modify that section, if possible - if (sn.type != AmPmSection && (v < minimumDateTime || v > maximumDateTime)) { + if (sn.type != AmPmSection && !(sn.type & DayOfWeekSectionMask) + && (v < minimumDateTime || v > maximumDateTime)) { const int localmin = getDigit(minimumDateTime, sectionIndex); const int localmax = getDigit(maximumDateTime, sectionIndex); |