Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qdatetimeedit.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include <private/qapplication_p.h>
5#include <private/qdatetimeedit_p.h>
6#include <qabstractspinbox.h>
7#include <qapplication.h>
8#include <qdatetimeedit.h>
9#include <qdebug.h>
10#include <qevent.h>
11#include <qlineedit.h>
12#include <private/qlineedit_p.h>
13#include <qlocale.h>
14#include <qpainter.h>
15#include <qlayout.h>
16#include <qset.h>
17#include <qstyle.h>
18#include <qstylepainter.h>
19
20#include <algorithm>
21
22//#define QDATETIMEEDIT_QDTEDEBUG
23#ifdef QDATETIMEEDIT_QDTEDEBUG
24# define QDTEDEBUG qDebug() << QString::fromLatin1("%1:%2").arg(__FILE__).arg(__LINE__)
25# define QDTEDEBUGN qDebug
26#else
27# define QDTEDEBUG if (false) qDebug()
28# define QDTEDEBUGN if (false) qDebug
29#endif
30
32
33using namespace Qt::StringLiterals;
34
35// --- QDateTimeEdit ---
36
141{
142 Q_D(QDateTimeEdit);
143 d->init(QDATETIMEEDIT_DATE_INITIAL.startOfDay());
144}
145
153{
154 Q_D(QDateTimeEdit);
155 d->init(datetime.isValid() ? datetime : QDATETIMEEDIT_DATE_INITIAL.startOfDay());
156}
157
167{
168 Q_D(QDateTimeEdit);
170}
171
181{
182 Q_D(QDateTimeEdit);
184}
185
192 parent)
193{
194 Q_D(QDateTimeEdit);
195 d->parserType = parserType;
196 d->init(var);
197}
198
203{
204}
205
226{
227 Q_D(const QDateTimeEdit);
228 return d->value.toDateTime();
229}
230
232{
233 Q_D(QDateTimeEdit);
234 if (datetime.isValid()) {
235 QDateTime when = d->convertTimeZone(datetime);
236 Q_ASSERT(when.timeRepresentation() == d->timeZone);
237
238 d->clearCache();
239 const QDate date = when.date();
240 if (!(d->sections & DateSections_Mask))
242 d->setValue(when, EmitIfChanged);
243 }
244}
245
259{
260 Q_D(const QDateTimeEdit);
261 return d->value.toDate();
262}
263
265{
266 Q_D(QDateTimeEdit);
267 if (date.isValid()) {
268 if (!(d->sections & DateSections_Mask))
270
271 d->clearCache();
272 QDateTime when = d->dateTimeValue(date, d->value.toTime());
273 Q_ASSERT(when.isValid());
274 d->setValue(when, EmitIfChanged);
275 d->updateTimeZone();
276 }
277}
278
292{
293 Q_D(const QDateTimeEdit);
294 return d->value.toTime();
295}
296
298{
299 Q_D(QDateTimeEdit);
300 if (time.isValid()) {
301 d->clearCache();
302 d->setValue(d->dateTimeValue(d->value.toDate(), time), EmitIfChanged);
303 }
304}
305
306
308{
309 Q_D(const QDateTimeEdit);
310 return d->calendar;
311}
312
314{
315 Q_D(QDateTimeEdit);
316 // Set invalid date time to prevent runtime crashes on calendar change
317 QDateTime previousValue = d->value.toDateTime();
319 d->setCalendar(calendar);
320 setDateTime(previousValue);
321}
322
345{
346 Q_D(const QDateTimeEdit);
347 return d->minimum.toDateTime();
348}
349
351{
353}
354
356{
357 Q_D(QDateTimeEdit);
358 if (dt.isValid() && dt.date() >= QDATETIMEEDIT_DATE_MIN) {
359 const QDateTime m = dt.toTimeZone(d->timeZone);
360 const QDateTime max = d->maximum.toDateTime();
361 d->setRange(m, (max > m ? max : m));
362 }
363}
364
387{
388 Q_D(const QDateTimeEdit);
389 return d->maximum.toDateTime();
390}
391
393{
395}
396
398{
399 Q_D(QDateTimeEdit);
400 if (dt.isValid() && dt.date() <= QDATETIMEEDIT_DATE_MAX) {
401 const QDateTime m = dt.toTimeZone(d->timeZone);
402 const QDateTime min = d->minimum.toDateTime();
403 d->setRange((min < m ? min : m), m);
404 }
405}
406
432{
433 Q_D(QDateTimeEdit);
434 // FIXME: does none of the range checks applied to setMin/setMax methods !
435 const QDateTime minimum = min.toTimeZone(d->timeZone);
436 const QDateTime maximum = (min > max ? minimum : max.toTimeZone(d->timeZone));
437 d->setRange(minimum, maximum);
438}
439
463{
464 Q_D(const QDateTimeEdit);
465 return d->minimum.toDate();
466}
467
469{
470 Q_D(QDateTimeEdit);
471 if (min.isValid() && min >= QDATETIMEEDIT_DATE_MIN)
472 setMinimumDateTime(d->dateTimeValue(min, d->minimum.toTime()));
473}
474
476{
478}
479
503{
504 Q_D(const QDateTimeEdit);
505 return d->maximum.toDate();
506}
507
509{
510 Q_D(QDateTimeEdit);
511 if (max.isValid())
512 setMaximumDateTime(d->dateTimeValue(max, d->maximum.toTime()));
513}
514
516{
518}
519
541{
542 Q_D(const QDateTimeEdit);
543 return d->minimum.toTime();
544}
545
547{
548 Q_D(QDateTimeEdit);
549 if (min.isValid())
550 setMinimumDateTime(d->dateTimeValue(d->minimum.toDate(), min));
551}
552
554{
556}
557
578{
579 Q_D(const QDateTimeEdit);
580 return d->maximum.toTime();
581}
582
584{
585 Q_D(QDateTimeEdit);
586 if (max.isValid())
587 setMaximumDateTime(d->dateTimeValue(d->maximum.toDate(), max));
588}
589
591{
593}
594
622{
623 Q_D(QDateTimeEdit);
624 if (min.isValid() && max.isValid()) {
625 setDateTimeRange(d->dateTimeValue(min, d->minimum.toTime()),
626 d->dateTimeValue(max, d->maximum.toTime()));
627 }
628}
629
661{
662 Q_D(QDateTimeEdit);
663 if (min.isValid() && max.isValid()) {
664 setDateTimeRange(d->dateTimeValue(d->minimum.toDate(), min),
665 d->dateTimeValue(d->maximum.toDate(), max));
666 }
667}
668
679QDateTimeEdit::Sections QDateTimeEdit::displayedSections() const
680{
681 Q_D(const QDateTimeEdit);
682 return d->sections;
683}
684
692{
693 Q_D(const QDateTimeEdit);
694#ifdef QT_KEYPAD_NAVIGATION
695 if (QApplicationPrivate::keypadNavigationEnabled() && d->focusOnButton)
696 return NoSection;
697#endif
698 return QDateTimeEditPrivate::convertToPublic(d->sectionType(d->currentSectionIndex));
699}
700
702{
703 Q_D(QDateTimeEdit);
704 if (section == NoSection || !(section & d->sections))
705 return;
706
707 d->updateCache(d->value, d->displayText());
708 const int size = d->sectionNodes.size();
709 int index = d->currentSectionIndex + 1;
710 for (int i=0; i<2; ++i) {
711 while (index < size) {
712 if (QDateTimeEditPrivate::convertToPublic(d->sectionType(index)) == section) {
713 d->edit->setCursorPosition(d->sectionPos(index));
714 QDTEDEBUG << d->sectionPos(index);
715 return;
716 }
717 ++index;
718 }
719 index = 0;
720 }
721}
722
734{
735 Q_D(const QDateTimeEdit);
736 if (index < 0 || index >= d->sectionNodes.size())
737 return NoSection;
738 return QDateTimeEditPrivate::convertToPublic(d->sectionType(index));
739}
740
751{
752 Q_D(const QDateTimeEdit);
753 return d->sectionNodes.size();
754}
755
756
772{
773 Q_D(const QDateTimeEdit);
774 return d->currentSectionIndex;
775}
776
778{
779 Q_D(QDateTimeEdit);
780 if (index < 0 || index >= d->sectionNodes.size())
781 return;
782 d->edit->setCursorPosition(d->sectionPos(index));
783}
784
796{
797 Q_D(const QDateTimeEdit);
798 if (!d->calendarPopup || !(d->sections & QDateTimeParser::DateSectionMask))
799 return nullptr;
800 if (!d->monthCalendar) {
801 const_cast<QDateTimeEditPrivate*>(d)->initCalendarPopup();
802 }
803 return d->monthCalendar->calendarWidget();
804}
805
816{
817 Q_D(QDateTimeEdit);
819 qWarning("QDateTimeEdit::setCalendarWidget: Cannot set a null calendar widget");
820 return;
821 }
822
823 if (Q_UNLIKELY(!d->calendarPopup)) {
824 qWarning("QDateTimeEdit::setCalendarWidget: calendarPopup is set to false");
825 return;
826 }
827
828 if (Q_UNLIKELY(!(d->display & QDateTimeParser::DateSectionMask))) {
829 qWarning("QDateTimeEdit::setCalendarWidget: no date sections specified");
830 return;
831 }
832 d->initCalendarPopup(calendarWidget);
833}
834
835
849{
850 Q_D(QDateTimeEdit);
851 if (section == NoSection) {
852 d->edit->setSelection(d->edit->cursorPosition(), 0);
853 } else if (section & d->sections) {
854 if (currentSection() != section)
855 setCurrentSection(section);
856 d->setSelected(d->currentSectionIndex);
857 }
858}
859
860
861
871{
872 Q_D(const QDateTimeEdit);
873 if (section == QDateTimeEdit::NoSection || !(section & d->sections)) {
874 return QString();
875 }
876
877 d->updateCache(d->value, d->displayText());
878 const int sectionIndex = d->absoluteIndex(section, 0);
879 return d->sectionText(sectionIndex);
880}
881
908{
909 Q_D(const QDateTimeEdit);
910 return isRightToLeft() ? d->unreversedFormat : d->displayFormat;
911}
912
914{
915 Q_D(QDateTimeEdit);
916 if (d->parseFormat(format)) {
917 d->unreversedFormat.clear();
918 if (isRightToLeft()) {
919 d->unreversedFormat = format;
920 d->displayFormat.clear();
921 for (int i=d->sectionNodes.size() - 1; i>=0; --i) {
922 d->displayFormat += d->separators.at(i + 1);
923 d->displayFormat += d->sectionNode(i).format();
924 }
925 d->displayFormat += d->separators.at(0);
926 std::reverse(d->separators.begin(), d->separators.end());
927 std::reverse(d->sectionNodes.begin(), d->sectionNodes.end());
928 }
929
930 d->formatExplicitlySet = true;
931 d->sections = QDateTimeEditPrivate::convertSections(d->display);
932 d->clearCache();
933
934 d->currentSectionIndex = qMin(d->currentSectionIndex, d->sectionNodes.size() - 1);
935 const bool timeShown = (d->sections & TimeSections_Mask);
936 const bool dateShown = (d->sections & DateSections_Mask);
937 Q_ASSERT(dateShown || timeShown);
938 if (timeShown && !dateShown) {
939 QTime time = d->value.toTime();
940 setDateRange(d->value.toDate(), d->value.toDate());
941 if (d->minimum.toTime() >= d->maximum.toTime()) {
943 // if the time range became invalid during the adjustment, the time would have been reset
944 setTime(time);
945 }
946 } else if (dateShown && !timeShown) {
948 d->value = d->value.toDate().startOfDay(d->timeZone);
949 }
950 d->updateEdit();
951 d->_q_editorCursorPositionChanged(-1, 0);
952 }
953}
954
967{
968 Q_D(const QDateTimeEdit);
969 return d->calendarPopup;
970}
971
973{
974 Q_D(QDateTimeEdit);
975 if (enable == d->calendarPopup)
976 return;
978 d->calendarPopup = enable;
979#ifdef QT_KEYPAD_NAVIGATION
980 if (!enable)
981 d->focusOnButton = false;
982#endif
983 d->updateEditFieldGeometry();
984 update();
985}
986
994{
995 Q_D(const QDateTimeEdit);
996 return d->timeZone.timeSpec();
997}
998
1000{
1001 Q_D(QDateTimeEdit);
1002 if (spec != d->timeZone.timeSpec()) {
1003 switch (spec) {
1004 case Qt::UTC:
1005 d->timeZone = QTimeZone::UTC;
1006 break;
1007 case Qt::LocalTime:
1008 d->timeZone = QTimeZone::LocalTime;
1009 break;
1010 default:
1011 qWarning() << "Ignoring attempt to set time-spec" << spec
1012 << "which is not yet supported by QDateTimeEdit";
1013 // TODO: fix that QTBUG-80417.
1014 return;
1015 }
1016 d->updateTimeZone();
1017 }
1018}
1019
1025{
1026 Q_D(const QDateTimeEdit);
1027 if (d->cachedSizeHint.isEmpty()) {
1029
1030 const QFontMetrics fm(fontMetrics());
1031 int h = d->edit->sizeHint().height();
1032 int w = 0;
1033 QString s;
1034 s = d->textFromValue(d->minimum) + u' ';
1035 w = qMax<int>(w, fm.horizontalAdvance(s));
1036 s = d->textFromValue(d->maximum) + u' ';
1037 w = qMax<int>(w, fm.horizontalAdvance(s));
1038 if (d->specialValueText.size()) {
1039 s = d->specialValueText;
1040 w = qMax<int>(w, fm.horizontalAdvance(s));
1041 }
1042 w += 2; // cursor blinking space
1043
1044 QSize hint(w, h);
1045
1046#ifdef Q_OS_MAC
1047 if (d->calendarPopupEnabled()) {
1049 d->cachedSizeHint = style()->sizeFromContents(QStyle::CT_ComboBox, &opt, hint, this);
1050 } else
1051#endif
1052 {
1053 QStyleOptionSpinBox opt;
1055 d->cachedSizeHint = style()->sizeFromContents(QStyle::CT_SpinBox, &opt, hint, this);
1056 }
1057
1058 d->cachedMinimumSizeHint = d->cachedSizeHint;
1059 // essentially make minimumSizeHint return the same as sizeHint for datetimeedits
1060 }
1061 return d->cachedSizeHint;
1062}
1063
1064
1070{
1071 Q_D(QDateTimeEdit);
1072 switch (event->type()) {
1074 const bool was = d->formatExplicitlySet;
1075 const QString oldFormat = d->displayFormat;
1076 d->displayFormat.clear();
1077 setDisplayFormat(oldFormat);
1078 d->formatExplicitlySet = was;
1079 break; }
1081 d->updateEdit();
1082 break;
1084#ifdef Q_OS_MAC
1086#endif
1087 d->setLayoutItemMargins(QStyle::SE_DateTimeEditLayoutItem);
1088 break;
1089 default:
1090 break;
1091 }
1093}
1094
1100{
1101 Q_D(QDateTimeEdit);
1102 d->clearSection(d->currentSectionIndex);
1103}
1109{
1110 Q_D(QDateTimeEdit);
1111 int oldCurrent = d->currentSectionIndex;
1112 bool select = true;
1113 bool inserted = false;
1114
1115 switch (event->key()) {
1116#ifdef QT_KEYPAD_NAVIGATION
1117 case Qt::Key_NumberSign: //shortcut to popup calendar
1118 if (QApplicationPrivate::keypadNavigationEnabled() && d->calendarPopupEnabled()) {
1119 d->initCalendarPopup();
1120 d->positionCalendarPopup();
1121 d->monthCalendar->show();
1122 return;
1123 }
1124 break;
1125 case Qt::Key_Select:
1126 if (QApplicationPrivate::keypadNavigationEnabled()) {
1127 if (hasEditFocus()) {
1128 if (d->focusOnButton) {
1129 d->initCalendarPopup();
1130 d->positionCalendarPopup();
1131 d->monthCalendar->show();
1132 d->focusOnButton = false;
1133 return;
1134 }
1135 setEditFocus(false);
1136 selectAll();
1137 } else {
1138 setEditFocus(true);
1139
1140 //hide cursor
1141 d->edit->d_func()->setCursorVisible(false);
1142 d->edit->d_func()->control->setBlinkingCursorEnabled(false);
1143 d->setSelected(0);
1144 }
1145 }
1146 return;
1147#endif
1148 case Qt::Key_Enter:
1149 case Qt::Key_Return:
1150 d->interpret(AlwaysEmit);
1151 d->setSelected(d->currentSectionIndex, true);
1152 event->ignore();
1154 emit d->edit->returnPressed();
1155 return;
1156 default:
1157#ifdef QT_KEYPAD_NAVIGATION
1158 if (QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus()
1159 && !event->text().isEmpty() && event->text().at(0).isLetterOrNumber()) {
1160 setEditFocus(true);
1161
1162 //hide cursor
1163 d->edit->d_func()->setCursorVisible(false);
1164 d->edit->d_func()->control->setBlinkingCursorEnabled(false);
1165 d->setSelected(0);
1166 oldCurrent = 0;
1167 }
1168#endif
1169 if (!d->isSeparatorKey(event)) {
1170 inserted = select = !event->text().isEmpty() && event->text().at(0).isPrint()
1171 && !(event->modifiers() & ~(Qt::ShiftModifier|Qt::KeypadModifier));
1172 break;
1173 }
1174 Q_FALLTHROUGH();
1175 case Qt::Key_Left:
1176 case Qt::Key_Right:
1177 if (event->key() == Qt::Key_Left || event->key() == Qt::Key_Right) {
1178 if (
1179#ifdef QT_KEYPAD_NAVIGATION
1180 QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus()
1181 || !QApplicationPrivate::keypadNavigationEnabled() &&
1182#endif
1183 !(event->modifiers() & Qt::ControlModifier)) {
1184 select = false;
1185 break;
1186 }
1187 }
1188 Q_FALLTHROUGH();
1189 case Qt::Key_Backtab:
1190 case Qt::Key_Tab: {
1191 event->accept();
1192 if (d->specialValue()) {
1193 d->edit->setSelection(d->edit->cursorPosition(), 0);
1194 return;
1195 }
1196 const bool forward = event->key() != Qt::Key_Left && event->key() != Qt::Key_Backtab
1197 && (event->key() != Qt::Key_Tab || !(event->modifiers() & Qt::ShiftModifier));
1198#ifdef QT_KEYPAD_NAVIGATION
1199 int newSection = d->nextPrevSection(d->currentSectionIndex, forward);
1200 if (QApplicationPrivate::keypadNavigationEnabled()) {
1201 if (d->focusOnButton) {
1202 newSection = forward ? 0 : d->sectionNodes.size() - 1;
1203 d->focusOnButton = false;
1204 update();
1205 } else if (newSection < 0 && select && d->calendarPopupEnabled()) {
1207 d->focusOnButton = true;
1208 update();
1209 return;
1210 }
1211 }
1212 // only allow date/time sections to be selected.
1214 return;
1215#endif
1216 //key tab and backtab will be managed thrgout QWidget::event
1217 if (event->key() != Qt::Key_Backtab && event->key() != Qt::Key_Tab)
1218 focusNextPrevChild(forward);
1219
1220 return; }
1221 }
1223 if (select && !d->edit->hasSelectedText()) {
1224 if (inserted && d->sectionAt(d->edit->cursorPosition()) == QDateTimeParser::NoSectionIndex) {
1225 QString str = d->displayText();
1226 int pos = d->edit->cursorPosition();
1228 && (d->sectionNodes.at(oldCurrent).count != 1
1229 || d->sectionMaxSize(oldCurrent) == d->sectionSize(oldCurrent)
1230 || d->skipToNextSection(oldCurrent, d->value.toDateTime(), d->sectionText(oldCurrent)))) {
1231 QDTEDEBUG << "Setting currentsection to"
1232 << d->closestSection(d->edit->cursorPosition(), true) << event->key()
1233 << oldCurrent << str;
1234 const int tmp = d->closestSection(d->edit->cursorPosition(), true);
1235 if (tmp >= 0)
1236 d->currentSectionIndex = tmp;
1237 }
1238 }
1239 if (d->currentSectionIndex != oldCurrent) {
1240 d->setSelected(d->currentSectionIndex);
1241 }
1242 }
1243 if (d->specialValue()) {
1244 d->edit->setSelection(d->edit->cursorPosition(), 0);
1245 }
1246}
1247
1252#if QT_CONFIG(wheelevent)
1253void QDateTimeEdit::wheelEvent(QWheelEvent *event)
1254{
1255 QAbstractSpinBox::wheelEvent(event);
1256}
1257#endif
1258
1264{
1265 Q_D(QDateTimeEdit);
1267 const int oldPos = d->edit->cursorPosition();
1268 if (!d->formatExplicitlySet) {
1269 QString *frm = nullptr;
1270 if (d->displayFormat == d->defaultTimeFormat) {
1271 frm = &d->defaultTimeFormat;
1272 } else if (d->displayFormat == d->defaultDateFormat) {
1273 frm = &d->defaultDateFormat;
1274 } else if (d->displayFormat == d->defaultDateTimeFormat) {
1275 frm = &d->defaultDateTimeFormat;
1276 }
1277
1278 if (frm) {
1279 d->readLocaleSettings();
1280 if (d->displayFormat != *frm) {
1281 setDisplayFormat(*frm);
1282 d->formatExplicitlySet = false;
1283 d->edit->setCursorPosition(oldPos);
1284 }
1285 }
1286 }
1287 const bool oldHasHadFocus = d->hasHadFocus;
1288 d->hasHadFocus = true;
1289 bool first = true;
1290 switch (event->reason()) {
1292 first = false;
1293 break;
1296 return;
1298 if (oldHasHadFocus)
1299 return;
1301 case Qt::TabFocusReason:
1302 default:
1303 break;
1304 }
1305 if (isRightToLeft())
1306 first = !first;
1307 d->updateEdit(); // needed to make it update specialValueText
1308
1309 d->setSelected(first ? 0 : d->sectionNodes.size() - 1);
1310}
1311
1317{
1318 Q_D(QDateTimeEdit);
1319 const int newSection = d->nextPrevSection(d->currentSectionIndex, next);
1320 switch (d->sectionType(newSection)) {
1325 default:
1326 d->edit->deselect();
1327 d->edit->setCursorPosition(d->sectionPos(newSection));
1328 QDTEDEBUG << d->sectionPos(newSection);
1329 d->setSelected(newSection, true);
1330 return false;
1331 }
1332}
1333
1339{
1340 Q_D(QDateTimeEdit);
1341#ifdef QT_KEYPAD_NAVIGATION
1342 // with keypad navigation and not editFocus, left right change the date/time by a fixed amount.
1343 if (QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus()) {
1344 // if date based, shift by day. else shift by 15min
1345 if (d->sections & DateSections_Mask) {
1346 setDateTime(dateTime().addDays(steps));
1347 } else {
1348 int minutes = time().hour()*60 + time().minute();
1349 int blocks = minutes/15;
1350 blocks += steps;
1351 /* rounding involved */
1352 if (minutes % 15) {
1353 if (steps < 0) {
1354 blocks += 1; // do one less step;
1355 }
1356 }
1357
1358 minutes = blocks * 15;
1359
1360 /* need to take wrapping into account */
1361 if (!d->wrapping) {
1362 int max_minutes = d->maximum.toTime().hour()*60 + d->maximum.toTime().minute();
1363 int min_minutes = d->minimum.toTime().hour()*60 + d->minimum.toTime().minute();
1364
1365 if (minutes >= max_minutes) {
1367 return;
1368 } else if (minutes <= min_minutes) {
1370 return;
1371 }
1372 }
1373 setTime(QTime(minutes/60, minutes%60));
1374 }
1375 return;
1376 }
1377#endif
1378 // don't optimize away steps == 0. This is the only way to select
1379 // the currentSection in Qt 4.1.x
1380 if (d->specialValue() && displayedSections() != AmPmSection) {
1381 for (int i=0; i<d->sectionNodes.size(); ++i) {
1382 if (d->sectionType(i) != QDateTimeParser::AmPmSection) {
1383 d->currentSectionIndex = i;
1384 break;
1385 }
1386 }
1387 }
1388 d->setValue(d->stepBy(d->currentSectionIndex, steps, false), EmitIfChanged);
1389 d->updateCache(d->value, d->displayText());
1390
1391 d->setSelected(d->currentSectionIndex);
1392 d->updateTimeZone();
1393}
1394
1404{
1405 Q_D(const QDateTimeEdit);
1406 return locale().toString(dateTime, d->displayFormat, d->calendar);
1407}
1408
1409
1419{
1420 Q_D(const QDateTimeEdit);
1421 QString copy = text;
1422 int pos = d->edit->cursorPosition();
1424 // TODO: if the format specifies time-zone, d->timeZone should change as
1425 // determined by the parsed text.
1426 return d->validateAndInterpret(copy, pos, state);
1427}
1428
1434{
1435 Q_D(const QDateTimeEdit);
1437 d->validateAndInterpret(text, pos, state);
1438 return state;
1439}
1440
1447{
1448 Q_D(const QDateTimeEdit);
1450 int copy = d->edit->cursorPosition();
1451
1452 QDateTime value = d->validateAndInterpret(input, copy, state, true);
1453 /*
1454 String was valid, but the datetime still is not; use the time that
1455 has the same distance from epoch.
1456 CorrectToPreviousValue correction is handled by QAbstractSpinBox.
1457 */
1458 if (!value.isValid() && d->correctionMode == QAbstractSpinBox::CorrectToNearestValue) {
1459 value = QDateTime::fromMSecsSinceEpoch(value.toMSecsSinceEpoch(),
1460 value.timeRepresentation());
1462 }
1463}
1464
1465
1470QDateTimeEdit::StepEnabled QDateTimeEdit::stepEnabled() const
1471{
1472 Q_D(const QDateTimeEdit);
1473 if (d->readOnly)
1474 return {};
1475 if (d->specialValue()) {
1476 return (d->minimum == d->maximum ? StepEnabled{} : StepEnabled(StepUpEnabled));
1477 }
1478
1479 QAbstractSpinBox::StepEnabled ret = { };
1480
1481#ifdef QT_KEYPAD_NAVIGATION
1482 if (QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus()) {
1483 if (d->wrapping)
1484 return StepEnabled(StepUpEnabled | StepDownEnabled);
1485 // 3 cases. date, time, datetime. each case look
1486 // at just the relevant component.
1487 QVariant max, min, val;
1488 if (!(d->sections & DateSections_Mask)) {
1489 // time only, no date
1490 max = d->maximum.toTime();
1491 min = d->minimum.toTime();
1492 val = d->value.toTime();
1493 } else if (!(d->sections & TimeSections_Mask)) {
1494 // date only, no time
1495 max = d->maximum.toDate();
1496 min = d->minimum.toDate();
1497 val = d->value.toDate();
1498 } else {
1499 // both
1500 max = d->maximum;
1501 min = d->minimum;
1502 val = d->value;
1503 }
1504 if (val != min)
1506 if (val != max)
1508 return ret;
1509 }
1510#endif
1511 switch (d->sectionType(d->currentSectionIndex)) {
1514 case QDateTimeParser::LastSection: return { };
1515 default: break;
1516 }
1517 if (d->wrapping)
1518 return StepEnabled(StepDownEnabled|StepUpEnabled);
1519
1520 QVariant v = d->stepBy(d->currentSectionIndex, 1, true);
1521 if (v != d->value) {
1523 }
1524 v = d->stepBy(d->currentSectionIndex, -1, true);
1525 if (v != d->value) {
1527 }
1528
1529 return ret;
1530}
1531
1532
1538{
1539 Q_D(QDateTimeEdit);
1540 if (!d->calendarPopupEnabled()) {
1542 return;
1543 }
1544 d->updateHoverControl(event->position().toPoint());
1545 if (d->hoverControl == QStyle::SC_ComboBoxArrow) {
1546 event->accept();
1547 if (d->readOnly) {
1548 return;
1549 }
1550 d->updateArrow(QStyle::State_Sunken);
1551 d->initCalendarPopup();
1552 d->positionCalendarPopup();
1553 //Show the calendar
1554 d->monthCalendar->show();
1555 } else {
1557 }
1558}
1559
1593{
1595}
1596
1604{
1606}
1607
1612{
1613}
1614
1663{
1665}
1666
1674{
1676}
1677
1682{
1683}
1684
1701// --- QDateTimeEditPrivate ---
1702
1711 timeZone(zone)
1712{
1713 fixday = true;
1714 type = QMetaType::QDateTime;
1716
1717 first.pos = 0;
1721}
1722
1724{
1725 return datetime.toTimeZone(timeZone);
1726}
1727
1729{
1731 if (when.isValid())
1732 return when;
1733 // Hit a spring-forward gap
1735}
1736
1738{
1741 value = value.toDateTime().toTimeZone(timeZone);
1742
1743 // time zone changes can lead to 00:00:00 becomes 01:00:00 and 23:59:59 becomes 00:59:59 (invalid range)
1744 const bool dateShown = (sections & QDateTimeEdit::DateSections_Mask);
1745 if (!dateShown) {
1746 if (minimum.toTime() >= maximum.toTime()){
1749 }
1750 }
1751}
1752
1754{
1755 const QString newText = (specialValue() ? specialValueText : textFromValue(value));
1756 if (newText == displayText())
1757 return;
1758 int selsize = edit->selectedText().size();
1759 const QSignalBlocker blocker(edit);
1760
1761 edit->setText(newText);
1762
1763 if (!specialValue()
1764#ifdef QT_KEYPAD_NAVIGATION
1765 && !(QApplicationPrivate::keypadNavigationEnabled() && !edit->hasEditFocus())
1766#endif
1767 ) {
1769 QDTEDEBUG << "cursor is " << cursor << currentSectionIndex;
1770 cursor = qBound(0, cursor, displayText().size());
1771 QDTEDEBUG << cursor;
1772 if (selsize > 0) {
1773 edit->setSelection(cursor, selsize);
1774 QDTEDEBUG << cursor << selsize;
1775 } else {
1777 QDTEDEBUG << cursor;
1778
1779 }
1780 }
1781}
1782
1784{
1785 if (keyboardTracking)
1786 return minimum.toDateTime();
1787
1790
1791 return QDATETIMEEDIT_DATE_MIN.startOfDay(timeZone);
1792}
1793
1795{
1796 if (keyboardTracking)
1797 return maximum.toDateTime();
1798
1801
1802 return QDATETIMEEDIT_DATE_MAX.endOfDay(timeZone);
1803}
1804
1811void QDateTimeEditPrivate::setSelected(int sectionIndex, bool forward)
1812{
1813 if (specialValue()
1814#ifdef QT_KEYPAD_NAVIGATION
1815 || (QApplicationPrivate::keypadNavigationEnabled() && !edit->hasEditFocus())
1816#endif
1817 ) {
1818 edit->selectAll();
1819 } else {
1820 const SectionNode &node = sectionNode(sectionIndex);
1821 if (node.type == NoSection || node.type == LastSection || node.type == FirstSection)
1822 return;
1823
1825 const int size = sectionSize(sectionIndex);
1826 if (forward) {
1828 } else {
1829 edit->setSelection(sectionPos(node) + size, -size);
1830 }
1831 }
1832}
1833
1841{
1842 if (pos < separators.first().size())
1843 return (pos == 0 ? FirstSectionIndex : NoSectionIndex);
1844
1845 const QString text = displayText();
1846 const int textSize = text.size();
1847 if (textSize - pos < separators.last().size() + 1) {
1848 if (separators.last().size() == 0) {
1849 return sectionNodes.size() - 1;
1850 }
1851 return (pos == textSize ? LastSectionIndex : NoSectionIndex);
1852 }
1854
1855 for (int i=0; i<sectionNodes.size(); ++i) {
1856 const int tmp = sectionPos(i);
1857 if (pos < tmp + sectionSize(i)) {
1858 return (pos < tmp ? -1 : i);
1859 }
1860 }
1861 return -1;
1862}
1863
1871int QDateTimeEditPrivate::closestSection(int pos, bool forward) const
1872{
1873 Q_ASSERT(pos >= 0);
1874 if (pos < separators.first().size())
1875 return forward ? 0 : FirstSectionIndex;
1876
1877 const QString text = displayText();
1878 if (text.size() - pos < separators.last().size() + 1)
1879 return forward ? LastSectionIndex : int(sectionNodes.size() - 1);
1880
1882 for (int i=0; i<sectionNodes.size(); ++i) {
1883 const int tmp = sectionPos(sectionNodes.at(i));
1884 if (pos < tmp + sectionSize(i)) {
1885 if (pos < tmp && !forward) {
1886 return i-1;
1887 }
1888 return i;
1889 } else if (i == sectionNodes.size() - 1 && pos > tmp) {
1890 return i;
1891 }
1892 }
1893 qWarning("QDateTimeEdit: Internal Error: closestSection returned NoSection");
1894 return NoSectionIndex;
1895}
1896
1903int QDateTimeEditPrivate::nextPrevSection(int current, bool forward) const
1904{
1905 Q_Q(const QDateTimeEdit);
1906 if (q->isRightToLeft())
1907 forward = !forward;
1908
1909 switch (current) {
1910 case FirstSectionIndex: return forward ? 0 : FirstSectionIndex;
1911 case LastSectionIndex: return (forward ? LastSectionIndex : int(sectionNodes.size() - 1));
1912 case NoSectionIndex: return FirstSectionIndex;
1913 default: break;
1914 }
1915 Q_ASSERT(current >= 0 && current < sectionNodes.size());
1916
1917 current += (forward ? 1 : -1);
1918 if (current >= sectionNodes.size()) {
1919 return LastSectionIndex;
1920 } else if (current < 0) {
1921 return FirstSectionIndex;
1922 }
1923
1924 return current;
1925}
1926
1934{
1935 const auto space = u' ';
1936 int cursorPos = edit->cursorPosition();
1937 const QSignalBlocker blocker(edit);
1938 QString t = edit->text();
1939 const int pos = sectionPos(index);
1940 if (Q_UNLIKELY(pos == -1)) {
1941 qWarning("QDateTimeEdit: Internal error (%s:%d)", __FILE__, __LINE__);
1942 return;
1943 }
1944 const int size = sectionSize(index);
1945 t.replace(pos, size, QString().fill(space, size));
1946 edit->setText(t);
1947 edit->setCursorPosition(cursorPos);
1948 QDTEDEBUG << cursorPos;
1949}
1950
1951
1959{
1960 if (val != cachedValue || str != cachedText || cacheGuard) {
1961 cacheGuard = true;
1962 QString copy = str;
1963 int unused = edit->cursorPosition();
1964 QValidator::State unusedState;
1965 validateAndInterpret(copy, unused, unusedState);
1966 cacheGuard = false;
1967 }
1968}
1969
1977 QValidator::State &state, bool fixup) const
1978{
1979 if (input.isEmpty()) {
1980 if (sectionNodes.size() == 1 || !specialValueText.isEmpty()) {
1982 } else {
1984 }
1985 return getZeroVariant().toDateTime();
1986 } else if (cachedText == input && !fixup) {
1988 return cachedValue.toDateTime();
1989 } else if (!specialValueText.isEmpty()) {
1990 bool changeCase = false;
1991 const int max = qMin(specialValueText.size(), input.size());
1992 int i;
1993 for (i=0; i<max; ++i) {
1994 const QChar ic = input.at(i);
1995 const QChar sc = specialValueText.at(i);
1996 if (ic != sc) {
1997 if (sc.toLower() == ic.toLower()) {
1998 changeCase = true;
1999 } else {
2000 break;
2001 }
2002 }
2003 }
2004 if (i == max) {
2006 if (changeCase) {
2008 }
2009 return minimum.toDateTime();
2010 }
2011 }
2012
2013 StateNode tmp = parse(input, position, value.toDateTime(), fixup);
2014 // Take note of any corrections imposed during parsing:
2015 input = m_text;
2016 // Impose this widget's time system:
2017 tmp.value = tmp.value.toTimeZone(timeZone);
2018 // ... but that might turn a valid datetime into an invalid one:
2019 if (!tmp.value.isValid() && tmp.state == Acceptable)
2020 tmp.state = Intermediate;
2021
2022 position += tmp.padded;
2023 state = QValidator::State(int(tmp.state));
2025 if (tmp.conflicts && conflictGuard != tmp.value) {
2026 conflictGuard = tmp.value;
2027 clearCache();
2028 input = textFromValue(tmp.value);
2029 updateCache(tmp.value, input);
2031 } else {
2032 cachedText = input;
2034 cachedValue = tmp.value;
2035 }
2036 } else {
2037 clearCache();
2038 }
2039 return (tmp.value.isNull() ? getZeroVariant().toDateTime() : tmp.value);
2040}
2041
2042
2048{
2049 Q_Q(const QDateTimeEdit);
2050 return q->textFromDateTime(f.toDateTime());
2051}
2052
2061{
2062 Q_Q(const QDateTimeEdit);
2063 return q->dateTimeFromText(f).toTimeZone(timeZone);
2064}
2065
2066
2077QDateTime QDateTimeEditPrivate::stepBy(int sectionIndex, int steps, bool test) const
2078{
2079 Q_Q(const QDateTimeEdit);
2080 QDateTime v = value.toDateTime();
2082 int pos = edit->cursorPosition();
2083 const SectionNode sn = sectionNode(sectionIndex);
2084
2085 // to make sure it behaves reasonably when typing something and then stepping in non-tracking mode
2086 if (!test && pendingEmit && q->validate(str, pos) == QValidator::Acceptable)
2087 v = q->dateTimeFromText(str);
2088 int val = getDigit(v, sectionIndex);
2089
2090 const int min = absoluteMin(sectionIndex);
2091 const int max = absoluteMax(sectionIndex, value.toDateTime());
2092
2093 if (sn.type & DayOfWeekSectionMask) {
2094 // Must take locale's first day of week into account when *not*
2095 // wrapping; min and max don't help us.
2096#ifndef QT_ALWAYS_WRAP_WEEKDAY // (documentation, not an actual define)
2097 if (!wrapping) {
2098 /* It's not clear this is ever really a desirable behavior.
2099
2100 It refuses to step backwards from the first day of the week or
2101 forwards from the day before, only allowing day-of-week stepping
2102 from start to end of one week. That's strictly what non-wrapping
2103 behavior must surely mean, when put in locale-neutral terms.
2104
2105 It is, however, likely that users would prefer the "more natural"
2106 behavior of cycling through the week.
2107 */
2108 const int first = int(locale().firstDayOfWeek()); // Mon = 1 through 7 = Sun
2109 val = qBound(val < first ? first - 7 : first,
2110 val + steps,
2111 val < first ? first - 1 : first + 6);
2112 } else
2113#endif
2114 {
2115 val += steps;
2116 }
2117
2118 // Restore to range from 1 through 7:
2119 val = val % 7;
2120 if (val <= 0)
2121 val += 7;
2122 } else {
2123 val += steps;
2124 const int span = max - min + 1;
2125 if (val < min)
2126 val = wrapping ? val + span : min;
2127 else if (val > max)
2128 val = wrapping ? val - span : max;
2129 }
2130
2131 const int oldDay = v.date().day(calendar);
2132
2133 /*
2134 Stepping into a daylight saving time that doesn't exist (setDigit() is
2135 true when date and time are valid, even if the date-time returned
2136 isn't), so use the time that has the same distance from epoch.
2137 */
2138 if (setDigit(v, sectionIndex, val) && !v.isValid()) {
2139 auto msecsSinceEpoch = v.toMSecsSinceEpoch();
2140 // decreasing from e.g 3am to 2am would get us back to 3am, but we want 1am
2141 if (steps < 0 && sn.type & HourSectionMask)
2142 msecsSinceEpoch -= 3600 * 1000;
2143 v = QDateTime::fromMSecsSinceEpoch(msecsSinceEpoch, v.timeRepresentation());
2144 }
2145 // if this sets year or month it will make
2146 // sure that days are lowered if needed.
2147
2148 const QDateTime minimumDateTime = minimum.toDateTime();
2149 const QDateTime maximumDateTime = maximum.toDateTime();
2150 // changing one section should only modify that section, if possible
2151 if (sn.type != AmPmSection && !(sn.type & DayOfWeekSectionMask)
2152 && (v < minimumDateTime || v > maximumDateTime)) {
2153 const int localmin = getDigit(minimumDateTime, sectionIndex);
2154 const int localmax = getDigit(maximumDateTime, sectionIndex);
2155
2156 if (wrapping) {
2157 // just because we hit the roof in one direction, it
2158 // doesn't mean that we hit the floor in the other
2159 if (steps > 0) {
2160 setDigit(v, sectionIndex, min);
2161 if (!(sn.type & DaySectionMask) && sections & DateSectionMask) {
2162 const int daysInMonth = v.date().daysInMonth(calendar);
2163 if (v.date().day(calendar) < oldDay && v.date().day(calendar) < daysInMonth) {
2164 const int adds = qMin(oldDay, daysInMonth);
2165 v = v.addDays(adds - v.date().day(calendar));
2166 }
2167 }
2168
2169 if (v < minimumDateTime) {
2170 setDigit(v, sectionIndex, localmin);
2171 if (v < minimumDateTime)
2172 setDigit(v, sectionIndex, localmin + 1);
2173 }
2174 } else {
2175 setDigit(v, sectionIndex, max);
2176 if (!(sn.type & DaySectionMask) && sections & DateSectionMask) {
2177 const int daysInMonth = v.date().daysInMonth(calendar);
2178 if (v.date().day(calendar) < oldDay && v.date().day(calendar) < daysInMonth) {
2179 const int adds = qMin(oldDay, daysInMonth);
2180 v = v.addDays(adds - v.date().day(calendar));
2181 }
2182 }
2183
2184 if (v > maximumDateTime) {
2185 setDigit(v, sectionIndex, localmax);
2186 if (v > maximumDateTime)
2187 setDigit(v, sectionIndex, localmax - 1);
2188 }
2189 }
2190 } else {
2191 setDigit(v, sectionIndex, (steps > 0 ? localmax : localmin));
2192 }
2193 }
2194 if (!test && oldDay != v.date().day(calendar) && !(sn.type & DaySectionMask)) {
2195 // this should not happen when called from stepEnabled
2196 cachedDay = qMax<int>(oldDay, cachedDay);
2197 }
2198
2199 if (v < minimumDateTime) {
2200 if (wrapping) {
2201 QDateTime t = v;
2202 setDigit(t, sectionIndex, steps < 0 ? max : min);
2203 bool mincmp = (t >= minimumDateTime);
2204 bool maxcmp = (t <= maximumDateTime);
2205 if (!mincmp || !maxcmp) {
2206 setDigit(t, sectionIndex, getDigit(steps < 0
2207 ? maximumDateTime
2208 : minimumDateTime, sectionIndex));
2209 mincmp = (t >= minimumDateTime);
2210 maxcmp = (t <= maximumDateTime);
2211 }
2212 if (mincmp && maxcmp) {
2213 v = t;
2214 }
2215 } else {
2216 v = value.toDateTime();
2217 }
2218 } else if (v > maximumDateTime) {
2219 if (wrapping) {
2220 QDateTime t = v;
2221 setDigit(t, sectionIndex, steps > 0 ? min : max);
2222 bool mincmp = (t >= minimumDateTime);
2223 bool maxcmp = (t <= maximumDateTime);
2224 if (!mincmp || !maxcmp) {
2225 setDigit(t, sectionIndex, getDigit(steps > 0 ?
2226 minimumDateTime :
2227 maximumDateTime, sectionIndex));
2228 mincmp = (t >= minimumDateTime);
2229 maxcmp = (t <= maximumDateTime);
2230 }
2231 if (mincmp && maxcmp) {
2232 v = t;
2233 }
2234 } else {
2235 v = value.toDateTime();
2236 }
2237 }
2238
2239 return bound(v, value, steps).toDateTime().toTimeZone(timeZone);
2240}
2241
2247{
2248 Q_Q(QDateTimeEdit);
2249 if (ep == NeverEmit) {
2250 return;
2251 }
2252 pendingEmit = false;
2253
2254 const bool dodate = value.toDate().isValid() && (sections & DateSectionMask);
2255 const bool datechanged = (ep == AlwaysEmit || old.toDate() != value.toDate());
2256 const bool dotime = value.toTime().isValid() && (sections & TimeSectionMask);
2257 const bool timechanged = (ep == AlwaysEmit || old.toTime() != value.toTime());
2258
2260
2262 if (datechanged || timechanged)
2263 emit q->dateTimeChanged(value.toDateTime());
2264 if (dodate && datechanged)
2265 emit q->dateChanged(value.toDate());
2266 if (dotime && timechanged)
2267 emit q->timeChanged(value.toTime());
2268
2269}
2270
2276{
2278 return;
2279 const QString oldText = displayText();
2280 updateCache(value, oldText);
2281
2282 const bool allowChange = !edit->hasSelectedText();
2283 const bool forward = oldpos <= newpos;
2285 int s = sectionAt(newpos);
2286 if (s == NoSectionIndex && forward && newpos > 0) {
2287 s = sectionAt(newpos - 1);
2288 }
2289
2290 int c = newpos;
2291
2292 const int selstart = edit->selectionStart();
2293 const int selSection = sectionAt(selstart);
2294 const int l = selSection != -1 ? sectionSize(selSection) : 0;
2295
2296 if (s == NoSectionIndex) {
2297 if (l > 0 && selstart == sectionPos(selSection) && edit->selectedText().size() == l) {
2298 s = selSection;
2299 if (allowChange)
2300 setSelected(selSection, true);
2301 c = -1;
2302 } else {
2303 int closest = closestSection(newpos, forward);
2304 c = sectionPos(closest) + (forward ? 0 : qMax<int>(0, sectionSize(closest)));
2305
2306 if (allowChange) {
2308 QDTEDEBUG << c;
2309 }
2310 s = closest;
2311 }
2312 }
2313
2314 if (allowChange && currentSectionIndex != s) {
2316 }
2317 if (c == -1) {
2318 setSelected(s, true);
2319 } else if (!edit->hasSelectedText()) {
2320 if (oldpos < newpos) {
2321 edit->setCursorPosition(displayText().size() - (oldText.size() - c));
2322 } else {
2324 }
2325 }
2326
2327 QDTEDEBUG << "currentSectionIndex is set to" << sectionNode(s).name()
2328 << oldpos << newpos
2329 << "was" << sectionNode(currentSectionIndex).name();
2330
2333 "QDateTimeEditPrivate::_q_editorCursorPositionChanged()",
2334 qPrintable(QString::fromLatin1("Internal error (%1 %2)").
2336 arg(sectionNodes.size())));
2337
2339}
2340
2347{
2348 const QLocale loc;
2352}
2353
2355{
2356 switch (s & ~Internal) {
2365 case YearSection2Digits:
2367 case Hour12Section:
2369 case FirstSection:
2370 case NoSection:
2371 case LastSection: break;
2372 }
2374}
2375
2376QDateTimeEdit::Sections QDateTimeEditPrivate::convertSections(QDateTimeParser::Sections s)
2377{
2378 QDateTimeEdit::Sections ret;
2395
2396 return ret;
2397}
2398
2404{
2405 Q_D(QDateTimeEdit);
2406 if (!d->calendarPopupEnabled()) {
2408 return;
2409 }
2410
2411 QStyleOptionSpinBox opt;
2413
2414 QStyleOptionComboBox optCombo;
2415
2416 optCombo.initFrom(this);
2417 optCombo.editable = true;
2418 optCombo.frame = opt.frame;
2419 optCombo.subControls = opt.subControls;
2420 optCombo.activeSubControls = opt.activeSubControls;
2421 optCombo.state = opt.state;
2422 if (d->readOnly) {
2423 optCombo.state &= ~QStyle::State_Enabled;
2424 }
2425
2426 QStylePainter p(this);
2427 p.drawComplexControl(QStyle::CC_ComboBox, optCombo);
2428}
2429
2431{
2432 for (int i=0; i<sectionNodes.size(); ++i) {
2433 if (convertToPublic(sectionNodes.at(i).type) == s && index-- == 0) {
2434 return i;
2435 }
2436 }
2437 return NoSectionIndex;
2438}
2439
2441{
2442 return sectionNodes.indexOf(s);
2443}
2444
2446{
2447 Q_Q(QDateTimeEdit);
2448 QString tmp = displayText();
2449 int pos = edit->cursorPosition();
2450 const QValidator::State state = q->validate(tmp, pos);
2454 || currentSectionIndex < 0
2456 setValue(value, ep);
2458 } else {
2460 }
2461}
2462
2464{
2466 cachedDay = -1;
2467}
2468
2476void QDateTimeEdit::initStyleOption(QStyleOptionSpinBox *option) const
2477{
2478 if (!option)
2479 return;
2480
2481 Q_D(const QDateTimeEdit);
2483 if (d->calendarPopupEnabled()) {
2486 if (d->arrowState == QStyle::State_Sunken)
2487 option->state |= QStyle::State_Sunken;
2488 else
2489 option->state &= ~QStyle::State_Sunken;
2490 }
2491}
2492
2494{
2495 Q_Q(QDateTimeEdit);
2496 switch (var.userType()) {
2497 case QMetaType::QDate:
2500 q->setDisplayFormat(defaultDateFormat);
2501 if (sectionNodes.isEmpty()) // ### safeguard for broken locale
2502 q->setDisplayFormat("dd/MM/yyyy"_L1);
2503 break;
2504 case QMetaType::QDateTime:
2505 value = var;
2507 q->setDisplayFormat(defaultDateTimeFormat);
2508 if (sectionNodes.isEmpty()) // ### safeguard for broken locale
2509 q->setDisplayFormat("dd/MM/yyyy hh:mm:ss"_L1);
2510 break;
2511 case QMetaType::QTime:
2514 q->setDisplayFormat(defaultTimeFormat);
2515 if (sectionNodes.isEmpty()) // ### safeguard for broken locale
2516 q->setDisplayFormat("hh:mm:ss"_L1);
2517 break;
2518 default:
2519 Q_ASSERT_X(0, "QDateTimeEditPrivate::init", "Internal error");
2520 break;
2521 }
2522#ifdef QT_KEYPAD_NAVIGATION
2523 if (QApplicationPrivate::keypadNavigationEnabled())
2524 q->setCalendarPopup(true);
2525#endif
2526 q->setInputMethodHints(Qt::ImhPreferNumbers);
2528}
2529
2531{
2533}
2534
2536{
2537 Q_Q(QDateTimeEdit);
2538
2539 if (arrowState == state)
2540 return;
2541 arrowState = state;
2543 buttonState |= Mouse;
2544 else {
2545 buttonState = 0;
2547 }
2548 q->update();
2549}
2550
2557{
2558 if (!calendarPopupEnabled())
2560
2561 Q_Q(QDateTimeEdit);
2562
2563 QStyleOptionComboBox optCombo;
2564 optCombo.initFrom(q);
2565 optCombo.editable = true;
2566 optCombo.subControls = QStyle::SC_All;
2567 hoverControl = q->style()->hitTestComplexControl(QStyle::CC_ComboBox, &optCombo, pos, q);
2568 return hoverControl;
2569}
2570
2572{
2573 if (!calendarPopupEnabled()) {
2575 return;
2576 }
2577
2578 Q_Q(QDateTimeEdit);
2579
2580 QStyleOptionComboBox optCombo;
2581 optCombo.initFrom(q);
2582 optCombo.editable = true;
2584 edit->setGeometry(q->style()->subControlRect(QStyle::CC_ComboBox, &optCombo,
2586}
2587
2589{
2590 Q_ASSERT(type == QMetaType::QDateTime);
2591 return QDATETIMEEDIT_DATE_INITIAL.startOfDay(timeZone);
2592}
2593
2595{
2598}
2599
2600
2602{
2603 if (!ke->text().isEmpty() && currentSectionIndex + 1 < sectionNodes.size() && currentSectionIndex >= 0) {
2605 if (ke->text().at(0).isNumber())
2606 return false;
2607 } else if (ke->text().at(0).isLetterOrNumber()) {
2608 return false;
2609 }
2610 return separators.at(currentSectionIndex + 1).contains(ke->text());
2611 }
2612 return false;
2613}
2614
2616{
2617 Q_Q(QDateTimeEdit);
2618 if (!monthCalendar) {
2620 monthCalendar->setObjectName("qt_datetimedit_calendar"_L1);
2621 QObject::connect(monthCalendar, SIGNAL(newDateSelected(QDate)), q, SLOT(setDate(QDate)));
2622 QObject::connect(monthCalendar, SIGNAL(hidingCalendar(QDate)), q, SLOT(setDate(QDate)));
2623 QObject::connect(monthCalendar, SIGNAL(activated(QDate)), q, SLOT(setDate(QDate)));
2626 } else if (cw) {
2628 }
2630}
2631
2633{
2634 Q_Q(QDateTimeEdit);
2635 QPoint pos = (q->layoutDirection() == Qt::RightToLeft) ? q->rect().bottomRight() : q->rect().bottomLeft();
2636 QPoint pos2 = (q->layoutDirection() == Qt::RightToLeft) ? q->rect().topRight() : q->rect().topLeft();
2637 pos = q->mapToGlobal(pos);
2638 pos2 = q->mapToGlobal(pos2);
2641 if (!screen)
2643 const QRect screenRect = screen->availableGeometry();
2644 //handle popup falling "off screen"
2645 if (q->layoutDirection() == Qt::RightToLeft) {
2646 pos.setX(pos.x()-size.width());
2647 pos2.setX(pos2.x()-size.width());
2648 if (pos.x() < screenRect.left())
2649 pos.setX(qMax(pos.x(), screenRect.left()));
2650 else if (pos.x()+size.width() > screenRect.right())
2651 pos.setX(qMax(pos.x()-size.width(), screenRect.right()-size.width()));
2652 } else {
2653 if (pos.x()+size.width() > screenRect.right())
2654 pos.setX(screenRect.right()-size.width());
2655 pos.setX(qMax(pos.x(), screenRect.left()));
2656 }
2657 if (pos.y() + size.height() > screenRect.bottom())
2658 pos.setY(pos2.y() - size.height());
2659 else if (pos.y() < screenRect.top())
2660 pos.setY(screenRect.top());
2661 if (pos.y() < screenRect.top())
2662 pos.setY(screenRect.top());
2663 if (pos.y()+size.height() > screenRect.bottom())
2664 pos.setY(screenRect.bottom()-size.height());
2666}
2667
2669{
2670 return (calendarPopup && (sections & (DateSectionMask)));
2671}
2672
2674{
2675 Q_Q(QDateTimeEdit);
2676 if (monthCalendar) {
2677 const QSignalBlocker blocker(monthCalendar);
2678 monthCalendar->setDateRange(q->minimumDate(), q->maximumDate());
2679 monthCalendar->setDate(q->date());
2680 }
2681}
2682
2684 : QWidget(parent, Qt::Popup), calendarSystem(ca)
2685{
2687
2688 dateChanged = false;
2689 if (!cw) {
2690 verifyCalendarInstance();
2691 } else {
2693 }
2694}
2695
2696QCalendarWidget *QCalendarPopup::verifyCalendarInstance()
2697{
2698 if (calendar.isNull()) {
2699 QCalendarWidget *cw = new QCalendarWidget(this);
2700 cw->setCalendar(calendarSystem);
2701 cw->setVerticalHeaderFormat(QCalendarWidget::NoVerticalHeader);
2702#ifdef QT_KEYPAD_NAVIGATION
2703 if (QApplicationPrivate::keypadNavigationEnabled())
2704 cw->setHorizontalHeaderFormat(QCalendarWidget::SingleLetterDayNames);
2705#endif
2707 return cw;
2708 } else {
2709 return calendar.data();
2710 }
2711}
2712
2714{
2715 Q_ASSERT(cw);
2716 QVBoxLayout *widgetLayout = qobject_cast<QVBoxLayout*>(layout());
2717 if (!widgetLayout) {
2718 widgetLayout = new QVBoxLayout(this);
2719 widgetLayout->setContentsMargins(QMargins());
2720 widgetLayout->setSpacing(0);
2721 }
2722 delete calendar.data();
2723 calendar = QPointer<QCalendarWidget>(cw);
2724 widgetLayout->addWidget(cw);
2725
2726 connect(cw, SIGNAL(activated(QDate)), this, SLOT(dateSelected(QDate)));
2727 connect(cw, SIGNAL(clicked(QDate)), this, SLOT(dateSelected(QDate)));
2728 connect(cw, SIGNAL(selectionChanged()), this, SLOT(dateSelectionChanged()));
2729
2730 cw->setFocus();
2731}
2732
2733
2735{
2736 oldDate = date;
2737 verifyCalendarInstance()->setSelectedDate(date);
2738}
2739
2741{
2742 QCalendarWidget *cw = verifyCalendarInstance();
2743 cw->setMinimumDate(min);
2744 cw->setMaximumDate(max);
2745}
2746
2748{
2749 QDateTimeEdit *dateTime = qobject_cast<QDateTimeEdit *>(parentWidget());
2750 if (dateTime) {
2753 QRect arrowRect = dateTime->style()->subControlRect(QStyle::CC_ComboBox, &opt,
2755 arrowRect.moveTo(dateTime->mapToGlobal(arrowRect .topLeft()));
2756 if (arrowRect.contains(event->globalPosition().toPoint()) || rect().contains(event->position().toPoint()))
2758 }
2760}
2761
2763{
2764 emit resetButton();
2765}
2766
2768{
2769#if QT_CONFIG(shortcut)
2770 if (event->type() == QEvent::KeyPress) {
2771 QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
2772 if (keyEvent->matches(QKeySequence::Cancel))
2773 dateChanged = false;
2774 }
2775#endif
2776 return QWidget::event(event);
2777}
2778
2779void QCalendarPopup::dateSelectionChanged()
2780{
2781 dateChanged = true;
2782 emit newDateSelected(verifyCalendarInstance()->selectedDate());
2783}
2784void QCalendarPopup::dateSelected(QDate date)
2785{
2786 dateChanged = true;
2788 close();
2789}
2790
2792{
2793 emit resetButton();
2794 if (!dateChanged)
2795 emit hidingCalendar(oldDate);
2796}
2797
2799#include "moc_qdatetimeedit.cpp"
2800#include "moc_qdatetimeedit_p.cpp"
virtual QStyle::SubControl newHoverControl(const QPoint &pos)
virtual void setRange(const QVariant &min, const QVariant &max)
virtual void interpret(EmitPolicy ep)
QStyle::SubControl hoverControl
virtual void updateEditFieldGeometry()
virtual QVariant bound(const QVariant &val, const QVariant &old=QVariant(), int steps=0) const
virtual void clearCache() const
QValidator::State cachedState
void setValue(const QVariant &val, EmitPolicy ep, bool updateEdit=true)
QAbstractSpinBox::CorrectionMode correctionMode
The QAbstractSpinBox class provides a spinbox and a line edit to display values.
void selectAll()
Selects all the text in the spinbox except the prefix and suffix.
void editingFinished()
This signal is emitted editing is finished.
void focusInEvent(QFocusEvent *event) override
\reimp
QString text
the spin box's text, including any prefix and suffix
void paintEvent(QPaintEvent *event) override
\reimp
void mousePressEvent(QMouseEvent *event) override
\reimp
virtual void initStyleOption(QStyleOptionSpinBox *option) const
Initialize option with the values from this QSpinBox.
bool event(QEvent *event) override
\reimp
void keyPressEvent(QKeyEvent *event) override
\reimp
void addWidget(QWidget *, int stretch=0, Qt::Alignment alignment=Qt::Alignment())
Adds widget to the end of this box layout, with a stretch factor of stretch and alignment alignment.
void setSpacing(int spacing) override
Reimplements QLayout::setSpacing().
void activated(QDate date)
void mousePressEvent(QMouseEvent *e) override
This event handler, for event event, can be reimplemented in a subclass to receive mouse press events...
void mouseReleaseEvent(QMouseEvent *) override
This event handler, for event event, can be reimplemented in a subclass to receive mouse release even...
void hidingCalendar(QDate oldDate)
void setCalendarWidget(QCalendarWidget *cw)
void setDate(QDate date)
void hideEvent(QHideEvent *) override
This event handler can be reimplemented in a subclass to receive widget hide events.
void setDateRange(QDate min, QDate max)
bool event(QEvent *e) override
This virtual function receives events to an object and should return true if the event e was recogniz...
void newDateSelected(QDate newDate)
QCalendarPopup(QWidget *parent=nullptr, QCalendarWidget *cw=nullptr, QCalendar ca=QCalendar())
void resetButton()
The QCalendarWidget class provides a monthly based calendar widget allowing the user to select a date...
void setSelectedDate(QDate date)
The QCalendar class describes calendar systems.
Definition qcalendar.h:53
\inmodule QtCore
Definition qchar.h:48
constexpr bool isLetterOrNumber() const noexcept
Returns true if the character is a letter or number (Letter_* or Number_* categories); otherwise retu...
Definition qchar.h:472
QChar toLower() const noexcept
Returns the lowercase equivalent if the character is uppercase or titlecase; otherwise returns the ch...
Definition qchar.h:448
constexpr bool isNumber() const noexcept
Returns true if the character is a number (Number_* categories, not just 0-9); otherwise returns fals...
Definition qchar.h:471
QDateEdit(QWidget *parent=nullptr)
Constructs an empty date editor with a parent.
void userDateChanged(QDate date)
This signal only exists to fully implement the date Q_PROPERTY on the class.
~QDateEdit()
Destructor.
QDateTime getMaximum() const override
bool calendarPopupEnabled() const
void clearSection(int index)
int closestSection(int index, bool forward) const
QVariant valueFromText(const QString &f) const override
void emitSignals(EmitPolicy ep, const QVariant &old) override
QString textFromValue(const QVariant &f) const override
QDateTime stepBy(int index, int steps, bool test=false) const
QDateTimeEditPrivate(const QTimeZone &zone=QTimeZone::LocalTime)
int sectionAt(int pos) const
void clearCache() const override
bool isSeparatorKey(const QKeyEvent *k) const
void updateEditFieldGeometry() override
QCalendarPopup * monthCalendar
QLocale locale() const override
QDateTime convertTimeZone(const QDateTime &datetime)
void setSelected(int index, bool forward=false)
void updateEdit() override
static QDateTimeEdit::Sections convertSections(QDateTimeParser::Sections s)
static QDateTimeEdit::Section convertToPublic(QDateTimeParser::Section s)
QDateTime getMinimum() const override
void setRange(const QVariant &min, const QVariant &max) override
QStyle::SubControl newHoverControl(const QPoint &pos) override
QDateTime validateAndInterpret(QString &input, int &, QValidator::State &state, bool fixup=false) const
void updateCache(const QVariant &val, const QString &str) const
void initCalendarPopup(QCalendarWidget *cw=nullptr)
QDateTime dateTimeValue(QDate date, QTime time) const
QDateTimeEdit::Sections sections
int absoluteIndex(QDateTimeEdit::Section s, int index) const
QStyle::StateFlag arrowState
QVariant getZeroVariant() const override
int nextPrevSection(int index, bool forward) const
void _q_editorCursorPositionChanged(int oldpos, int newpos) override
void interpret(EmitPolicy ep) override
void updateArrow(QStyle::StateFlag state)
QString displayText() const override
The QDateTimeEdit class provides a widget for editing dates and times.
void setCurrentSectionIndex(int index)
void clearMaximumDateTime()
void setTimeRange(QTime min, QTime max)
Set the range of allowed times for the date time edit.
void setMinimumDate(QDate min)
QTime maximumTime
The maximum time of the date time edit.
void setDateTimeRange(const QDateTime &min, const QDateTime &max)
Set the range of allowed date-times for the date time edit.
void setMaximumTime(QTime max)
QString displayFormat
The format used to display the time/date of the date time edit.
int sectionCount
The number of sections displayed. If the format is 'yyyy/yy/yyyy', sectionCount returns 3.
void keyPressEvent(QKeyEvent *event) override
\reimp
Sections displayedSections
The currently displayed fields of the date time edit.
bool event(QEvent *event) override
\reimp
bool focusNextPrevChild(bool next) override
\reimp
QValidator::State validate(QString &input, int &pos) const override
\reimp
QCalendar calendar() const
void setDate(QDate date)
QCalendarWidget * calendarWidget() const
Returns the calendar widget for the editor if calendarPopup is set to true and (sections() & DateSect...
void focusInEvent(QFocusEvent *event) override
\reimp
QDateTime maximumDateTime
The maximum datetime of the date time edit.
QTime minimumTime
The minimum time of the date time edit.
void setCalendarPopup(bool enable)
void setTimeSpec(Qt::TimeSpec spec)
void setMaximumDate(QDate max)
void clear() override
\reimp
void setDateRange(QDate min, QDate max)
Set the range of allowed dates for the date time edit.
void setDisplayFormat(const QString &format)
void setSelectedSection(Section section)
virtual QString textFromDateTime(const QDateTime &dt) const
This virtual function is used by the date time edit whenever it needs to display dateTime.
void mousePressEvent(QMouseEvent *event) override
\reimp
virtual QDateTime dateTimeFromText(const QString &text) const
Returns an appropriate datetime for the given text.
void initStyleOption(QStyleOptionSpinBox *option) const override
Initialize option with the values from this QDataTimeEdit.
void setCurrentSection(Section section)
Qt::TimeSpec timeSpec
The current timespec used by the date time edit.
int currentSectionIndex
The current section index of the spinbox.
QString sectionText(Section section) const
Returns the text from the given section.
QDateTime minimumDateTime
The minimum datetime of the date time edit.
Section
\value NoSection \value AmPmSection \value MSecSection \value SecondSection \value MinuteSection \val...
Section currentSection
The current section of the spinbox.
void dateChanged(QDate date)
This signal is emitted whenever the date is changed.
void setCalendar(QCalendar calendar)
void setTime(QTime time)
QDateTimeEdit(QWidget *parent=nullptr)
Constructs an empty date time editor with a parent.
QTime time
The QTime that is set in the widget.
void setMinimumDateTime(const QDateTime &dt)
bool calendarPopup
The current calendar pop-up show mode.
void setDateTime(const QDateTime &dateTime)
void setMaximumDateTime(const QDateTime &dt)
void setMinimumTime(QTime min)
StepEnabled stepEnabled() const override
\reimp
~QDateTimeEdit()
Destructor.
Section sectionAt(int index) const
void setCalendarWidget(QCalendarWidget *calendarWidget)
void fixup(QString &input) const override
\reimp
void paintEvent(QPaintEvent *event) override
\reimp
QDate minimumDate
The minimum date of the date time edit.
void clearMinimumDateTime()
void timeChanged(QTime time)
This signal is emitted whenever the time is changed.
void stepBy(int steps) override
\reimp
QDateTime dateTime
The QDateTime that is set in the QDateTimeEdit.
QDate maximumDate
The maximum date of the date time edit.
QDate date
The QDate that is set in the widget.
QSize sizeHint() const override
\reimp
int absoluteMin(int index) const
int sectionSize(int index) const
int absoluteMax(int index, const QDateTime &value=QDateTime()) const
FieldInfo fieldInfo(int index) const
virtual QDateTime getMaximum() const
int getDigit(const QDateTime &dt, int index) const
StateNode parse(const QString &input, int position, const QDateTime &defaultValue, bool fixup) const
virtual QDateTime getMinimum() const
QList< SectionNode > sectionNodes
const SectionNode & sectionNode(int index) const
bool setDigit(QDateTime &t, int index, int newval) const
int sectionPos(int index) const
\inmodule QtCore\reentrant
Definition qdatetime.h:257
qint64 toMSecsSinceEpoch() const
static QDateTime fromMSecsSinceEpoch(qint64 msecs, const QTimeZone &timeZone)
bool isNull() const
Returns true if both the date and the time are null; otherwise returns false.
QDateTime toTimeZone(const QTimeZone &toZone) const
bool isValid() const
Returns true if this datetime represents a definite moment, otherwise false.
QTimeZone timeRepresentation() const
QDate date() const
Returns the date part of the datetime.
\inmodule QtCore \reentrant
Definition qdatetime.h:27
constexpr bool isValid() const
Returns true if this date is valid; otherwise returns false.
Definition qdatetime.h:86
QDateTime endOfDay(const QTimeZone &zone) const
QDateTime startOfDay(const QTimeZone &zone) const
\inmodule QtCore
Definition qcoreevent.h:45
@ ApplicationLayoutDirectionChange
Definition qcoreevent.h:92
@ StyleChange
Definition qcoreevent.h:136
@ LocaleChange
Definition qcoreevent.h:122
@ KeyPress
Definition qcoreevent.h:64
@ MacSizeChange
Definition qcoreevent.h:217
The QFocusEvent class contains event parameters for widget focus events.
Definition qevent.h:469
\reentrant \inmodule QtGui
int horizontalAdvance(const QString &, int len=-1) const
Returns the horizontal advance in pixels of the first len characters of text.
QScreen * primaryScreen
the primary (or default) screen of the application.
static QScreen * screenAt(const QPoint &point)
Returns the screen at point, or \nullptr if outside of any screen.
The QHideEvent class provides an event which is sent after a widget is hidden.
Definition qevent.h:585
The QKeyEvent class describes a key event.
Definition qevent.h:423
QString text() const
Returns the Unicode text that this key generated.
Definition qevent.h:442
void setContentsMargins(int left, int top, int right, int bottom)
Definition qlayout.cpp:288
int cursorPosition
the current cursor position for this line edit.
Definition qlineedit.h:37
void selectAll()
Selects all the text (i.e.
bool hasSelectedText
whether there is any text selected.
Definition qlineedit.h:40
int selectionStart() const
Returns the index of the first selected character in the line edit or -1 if no text is selected.
QString selectedText
the selected text.
Definition qlineedit.h:41
void setCursorPosition(int)
void setText(const QString &)
void setSelection(int, int)
Selects text from position start and for length characters.
QString text
the line edit's text.
Definition qlineedit.h:32
QString dateTimeFormat(FormatType format=LongFormat) const
Definition qlocale.cpp:2306
QString dateFormat(FormatType format=LongFormat) const
Definition qlocale.cpp:2244
@ ShortFormat
Definition qlocale.h:865
QString timeFormat(FormatType format=LongFormat) const
Definition qlocale.cpp:2275
QString toString(qlonglong i) const
Returns a localized string representation of i.
Definition qlocale.cpp:1962
\inmodule QtCore
Definition qmargins.h:23
\inmodule QtCore
Definition qmetatype.h:320
Type
\macro Q_DECLARE_OPAQUE_POINTER(PointerType)
Definition qmetatype.h:324
\inmodule QtGui
Definition qevent.h:195
uint unused
Definition qobject.h:75
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2823
Q_WEAK_OVERLOAD void setObjectName(const QString &name)
Sets the object's name to name.
Definition qobject.h:114
The QPaintEvent class contains event parameters for paint events.
Definition qevent.h:485
\inmodule QtCore\reentrant
Definition qpoint.h:23
constexpr int x() const noexcept
Returns the x coordinate of this point.
Definition qpoint.h:127
constexpr int y() const noexcept
Returns the y coordinate of this point.
Definition qpoint.h:132
constexpr void setX(int x) noexcept
Sets the x coordinate of this point to the given x coordinate.
Definition qpoint.h:137
\inmodule QtCore
Definition qpointer.h:18
T * data() const
Definition qpointer.h:56
bool isNull() const
Returns true if the referenced object has been destroyed or if there is no referenced object; otherwi...
Definition qpointer.h:67
\inmodule QtCore\reentrant
Definition qrect.h:30
constexpr int bottom() const noexcept
Returns the y-coordinate of the rectangle's bottom edge.
Definition qrect.h:181
constexpr QPoint topLeft() const noexcept
Returns the position of the rectangle's top-left corner.
Definition qrect.h:220
constexpr int top() const noexcept
Returns the y-coordinate of the rectangle's top edge.
Definition qrect.h:175
bool contains(const QRect &r, bool proper=false) const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qrect.cpp:851
constexpr int left() const noexcept
Returns the x-coordinate of the rectangle's left edge.
Definition qrect.h:172
constexpr void moveTo(int x, int t) noexcept
Moves the rectangle, leaving the top-left corner at the given position (x, y).
Definition qrect.h:269
constexpr int right() const noexcept
Returns the x-coordinate of the rectangle's right edge.
Definition qrect.h:178
The QScreen class is used to query screen properties. \inmodule QtGui.
Definition qscreen.h:32
QRect availableGeometry
the screen's available geometry in pixels
Definition qscreen.h:46
Exception-safe wrapper around QObject::blockSignals().
Definition qobject.h:443
\inmodule QtCore
Definition qsize.h:25
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5710
qsizetype size() const
Returns the number of characters in this string.
Definition qstring.h:182
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
Definition qstring.h:1079
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:1083
QString left(qsizetype n) const
Returns a substring that contains the n leftmost characters of the string.
Definition qstring.cpp:5161
\variable QStyleOptionToolButton::features
QStyle::SubControls subControls
QStyle::SubControls activeSubControls
QStyle::State state
void initFrom(const QWidget *w)
The QStylePainter class is a convenience class for drawing QStyle elements inside a widget.
The QStyle class is an abstract base class that encapsulates the look and feel of a GUI.
Definition qstyle.h:29
StateFlag
This enum describes flags that are used when drawing primitive elements.
Definition qstyle.h:65
@ State_Sunken
Definition qstyle.h:69
@ State_None
Definition qstyle.h:66
@ CT_SpinBox
Definition qstyle.h:560
@ CT_ComboBox
Definition qstyle.h:549
virtual QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &contentsSize, const QWidget *w=nullptr) const =0
Returns the size of the element described by the specified option and type, based on the provided con...
@ CC_ComboBox
Definition qstyle.h:333
@ SE_DateTimeEditLayoutItem
Definition qstyle.h:291
SubControl
This enum describes the available sub controls.
Definition qstyle.h:347
@ SC_ComboBoxFrame
Definition qstyle.h:364
@ SC_All
Definition qstyle.h:400
@ SC_ComboBoxEditField
Definition qstyle.h:365
@ SC_ComboBoxArrow
Definition qstyle.h:366
QTimeEdit(QWidget *parent=nullptr)
Constructs an empty time editor with a parent.
~QTimeEdit()
Destructor.
void userTimeChanged(QTime time)
This signal only exists to fully implement the time Q_PROPERTY on the class.
\inmodule QtCore
Definition qtimezone.h:25
constexpr Qt::TimeSpec timeSpec() const noexcept
Definition qtimezone.h:133
\inmodule QtCore \reentrant
Definition qdatetime.h:189
int hour() const
Returns the hour part (0 to 23) of the time.
int minute() const
Returns the minute part (0 to 59) of the time.
bool isValid() const
Returns true if the time is valid; otherwise returns false.
The QVBoxLayout class lines up widgets vertically.
Definition qboxlayout.h:91
State
This enum type defines the states in which a validated string can exist.
Definition qvalidator.h:30
\inmodule QtCore
Definition qvariant.h:64
void clear()
Convert this variant to type QMetaType::UnknownType and free up any resources used.
QDateTime toDateTime() const
Returns the variant as a QDateTime if the variant has userType() \l QMetaType::QDateTime,...
int userType() const
Definition qvariant.h:336
QTime toTime() const
Returns the variant as a QTime if the variant has userType() \l QMetaType::QTime, \l QMetaType::QDate...
QDate toDate() const
Returns the variant as a QDate if the variant has userType() \l QMetaType::QDate, \l QMetaType::QDate...
void setLayoutItemMargins(int left, int top, int right, int bottom)
The QWidget class is the base class of all user interface objects.
Definition qwidget.h:99
void setAttribute(Qt::WidgetAttribute, bool on=true)
Sets the attribute attribute on this widget if on is true; otherwise clears the attribute.
void setGeometry(int x, int y, int w, int h)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qwidget.h:886
QLayout * layout() const
Returns the layout manager that is installed on this widget, or \nullptr if no layout manager is inst...
virtual void mousePressEvent(QMouseEvent *event)
This event handler, for event event, can be reimplemented in a subclass to receive mouse press events...
Definition qwidget.cpp:9529
QPoint pos
the position of the widget within its parent widget
Definition qwidget.h:111
bool close()
Closes this widget.
Definition qwidget.cpp:8608
void move(int x, int y)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qwidget.h:880
QFontMetrics fontMetrics() const
Returns the font metrics for the widget's current font.
Definition qwidget.h:847
QLocale locale
the widget's locale
Definition qwidget.h:176
virtual bool focusNextPrevChild(bool next)
Finds a new widget to give the keyboard focus to, as appropriate for Tab and Shift+Tab,...
Definition qwidget.cpp:6800
QRect rect
the internal geometry of the widget excluding any window frame
Definition qwidget.h:116
void ensurePolished() const
Ensures that the widget and its children have been polished by QStyle (i.e., have a proper font and p...
void update()
Updates the widget unless updates are disabled or the widget is hidden.
QSize sizeHint
the recommended size for the widget
Definition qwidget.h:148
bool isRightToLeft() const
Definition qwidget.h:419
bool event(QEvent *event) override
This is the main event handler; it handles event event.
Definition qwidget.cpp:8912
QStyle * style() const
Definition qwidget.cpp:2607
QWidget * parentWidget() const
Returns the parent of this widget, or \nullptr if it does not have any parent widget.
Definition qwidget.h:904
QString str
[2]
QString text
QDate date
[1]
QCursor cursor
QStyleOptionButton opt
else opt state
[0]
short next
Definition keywords.cpp:445
Combined button and popup list for selecting options.
@ WA_WindowPropagation
Definition qnamespace.h:348
@ WA_NoMouseReplay
Definition qnamespace.h:319
@ WA_MacShowFocusRect
Definition qnamespace.h:358
@ RightToLeft
@ ImhPreferNumbers
@ Key_Tab
Definition qnamespace.h:659
@ Key_Select
@ Key_Return
Definition qnamespace.h:662
@ Key_Right
Definition qnamespace.h:674
@ Key_Enter
Definition qnamespace.h:663
@ Key_Backtab
Definition qnamespace.h:660
@ Key_Left
Definition qnamespace.h:672
@ Key_NumberSign
Definition qnamespace.h:516
@ UTC
@ LocalTime
@ ShiftModifier
@ ControlModifier
@ KeypadModifier
@ PopupFocusReason
@ BacktabFocusReason
@ MouseFocusReason
@ ActiveWindowFocusReason
@ TabFocusReason
@ ShortcutFocusReason
@ EmitIfChanged
@ NeverEmit
@ AlwaysEmit
static jboolean copy(JNIEnv *, jobject)
#define Q_FALLTHROUGH()
#define Q_UNLIKELY(x)
#define QDTEDEBUG
#define QDATETIMEEDIT_COMPAT_DATE_MIN
#define QDATETIMEEDIT_DATE_MIN
#define QDATETIMEEDIT_DATE_MAX
#define QDATETIMEEDIT_DATE_INITIAL
#define QDATETIMEEDIT_TIME_MIN
#define QDATETIMEEDIT_TIME_MAX
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define qWarning
Definition qlogging.h:162
return ret
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
constexpr const T & qBound(const T &min, const T &val, const T &max)
Definition qminmax.h:44
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
#define SLOT(a)
Definition qobjectdefs.h:51
#define SIGNAL(a)
Definition qobjectdefs.h:52
static bool contains(const QJsonArray &haystack, unsigned needle)
Definition qopengl.cpp:116
GLsizei const GLfloat * v
[13]
const GLfloat * m
GLfloat GLfloat GLfloat w
[0]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint index
[2]
GLfloat GLfloat f
GLenum type
GLboolean enable
GLint first
GLint GLsizei GLsizei GLenum format
GLfloat GLfloat GLfloat GLfloat h
struct _cl_event * event
const GLubyte * c
GLuint GLfloat * val
GLdouble GLdouble t
Definition qopenglext.h:243
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLenum GLenum GLsizei void GLsizei void void * span
GLdouble s
[6]
Definition qopenglext.h:235
GLfloat GLfloat p
[1]
GLuint GLenum option
GLenum GLenum GLenum input
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define Q_ASSERT_X(cond, x, msg)
Definition qrandom.cpp:48
static const struct TessellationWindingOrderTab cw[]
SSL_CTX int(*) void arg)
#define qPrintable(string)
Definition qstring.h:1391
static QT_BEGIN_NAMESPACE QVariant hint(QPlatformIntegration::StyleHint h)
QScreen * screen
[1]
Definition main.cpp:29
#define emit
static double UTC(double t, double localTZA)
static double LocalTime(double t, double localTZA)
connect(quitButton, &QPushButton::clicked, &app, &QCoreApplication::quit, Qt::QueuedConnection)
QDateTime dateTime
[12]
ba fill(true)
selection select(topLeft, bottomRight)
QCalendarWidget * calendar
[0]
static QString name(Section s)
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent