7#include <qabstractitemmodel.h>
8#include <qstyleditemdelegate.h>
10#include <qtableview.h>
13#include <qtextformat.h>
14#include <qheaderview.h>
15#include <private/qwidget_p.h>
16#include <qpushbutton.h>
17#include <qtoolbutton.h>
21#include <qapplication.h>
22#include <private/qapplication_p.h>
23#include <qbasictimer.h>
24#include <qstylepainter.h>
31using namespace Qt::StringLiterals;
43 return QString::number(number).rightJustified(fieldWidth, u'0');
61 virtual QDate
applyToDate(QDate date, QCalendar cal = QCalendar())
const = 0;
62 virtual void setDate(QDate date, QCalendar cal = QCalendar()) = 0;
63 virtual QString
text()
const = 0;
64 virtual QString
text(QDate date, QCalendar cal,
int repeat)
const = 0;
75 return "<b>"_L1 + str +
"</b>"_L1;
76 int startPos = str.size() - pos;
77 return QStringView{str}.mid(0, startPos) +
"<b>"_L1 + QStringView{str}.mid(startPos, pos) +
"</b>"_L1;
87 virtual QDate
applyToDate(QDate date, QCalendar cal)
const override;
88 virtual void setDate(QDate date, QCalendar cal)
override;
89 virtual QString
text()
const override;
90 virtual QString
text(QDate date, QCalendar cal,
int repeat)
const override;
104 if (key == Qt::Key_Right || key == Qt::Key_Left) {
107 }
else if (key == Qt::Key_Up) {
113 }
else if (key == Qt::Key_Down) {
119 }
else if (key == Qt::Key_Back || key == Qt::Key_Backspace) {
134 if (key < Qt::Key_0 || key > Qt::Key_9)
136 int pressedKey = key - Qt::Key_0;
140 m_day = m_day % 10 * 10 + pressedKey;
153 auto parts = cal.partsFromDate(date);
154 if (!parts.isValid())
156 parts.day = qMin(qMax(1, m_day), cal.daysInMonth(parts.month, parts.year));
157 return cal.dateFromParts(parts);
162 m_day = m_oldDay = date.day(cal);
168 return highlightString(formatNumber(m_day, 2), m_pos);
174 return QString::number(date.day(cal));
175 }
else if (repeat == 2) {
176 return formatNumber(date.day(cal), 2);
177 }
else if (repeat == 3) {
178 return m_locale.dayName(date.dayOfWeek(cal), QLocale::ShortFormat);
180 return m_locale.dayName(date.dayOfWeek(cal), QLocale::LongFormat);
192 virtual QDate
applyToDate(QDate date, QCalendar cal)
const override;
193 virtual void setDate(QDate date, QCalendar cal)
override;
194 virtual QString
text()
const override;
195 virtual QString
text(QDate date, QCalendar cal,
int repeat)
const override;
209 if (key == Qt::Key_Right || key == Qt::Key_Left) {
212 }
else if (key == Qt::Key_Up) {
218 }
else if (key == Qt::Key_Down) {
224 }
else if (key == Qt::Key_Back || key == Qt::Key_Backspace) {
230 m_month = m_oldMonth;
232 m_month = m_month / 10;
239 if (key < Qt::Key_0 || key > Qt::Key_9)
241 int pressedKey = key - Qt::Key_0;
243 m_month = pressedKey;
245 m_month = m_month % 10 * 10 + pressedKey;
258 auto parts = cal.partsFromDate(date);
259 if (!parts.isValid())
261 parts.month = qMin(qMax(1, m_month), cal.monthsInYear(parts.year));
262 parts.day = qMin(parts.day, cal.daysInMonth(m_month, parts.year));
263 return cal.dateFromParts(parts);
268 m_month = m_oldMonth = date.month(cal);
274 return highlightString(formatNumber(m_month, 2), m_pos);
279 const auto parts = cal.partsFromDate(date);
282 return QString::number(parts.month);
284 return formatNumber(parts.month, 2);
287 return cal.standaloneMonthName(m_locale, parts.month, parts.year, QLocale::ShortFormat);
289 return cal.standaloneMonthName(m_locale, parts.month, parts.year, QLocale::LongFormat);
300 virtual QDate
applyToDate(QDate date, QCalendar cal)
const override;
301 virtual void setDate(QDate date, QCalendar cal)
override;
302 virtual QString
text()
const override;
303 virtual QString
text(QDate date, QCalendar cal,
int repeat)
const override;
321 for (
int i = 0; i < n; i++)
328 if (key == Qt::Key_Right || key == Qt::Key_Left) {
331 }
else if (key == Qt::Key_Up) {
335 }
else if (key == Qt::Key_Down) {
339 }
else if (key == Qt::Key_Back || key == Qt::Key_Backspace) {
344 int pow = pow10(m_pos);
345 m_year = m_oldYear / pow * pow + m_year % (pow * 10) / 10;
351 if (key < Qt::Key_0 || key > Qt::Key_9)
353 int pressedKey = key - Qt::Key_0;
354 int pow = pow10(m_pos);
355 m_year = m_year / (pow * 10) * (pow * 10) + m_year % pow * 10 + pressedKey;
366 auto parts = cal.partsFromDate(date);
367 if (!parts.isValid())
370 parts.year = qMax(1, m_year);
371 parts.day = qMin(parts.day, cal.daysInMonth(parts.month, parts.year));
372 return cal.dateFromParts(parts);
377 m_year = m_oldYear = date.year(cal);
383 return highlightString(formatNumber(m_year, 4), m_pos);
389 return formatNumber(date.year(cal) % 100, 2);
390 return QString::number(date.year(cal));
424 void toPreviousToken();
425 void applyToDate(QCalendar cal);
427 int countRepeat(
const QString &str,
int index)
const;
430 QStringList m_separators;
431 std::vector<SectionToken> m_tokens;
445 : m_currentToken(-1),
454 m_yearValidator.m_locale = locale;
455 m_monthValidator.m_locale = locale;
456 m_dayValidator.m_locale = locale;
467 Q_ASSERT(index >= 0 && index < str.size());
469 const QChar ch = str.at(index);
470 while (index + count < str.size() && str.at(index + count) == ch)
477 m_yearValidator.setDate(date, cal);
478 m_monthValidator.setDate(date, cal);
479 m_dayValidator.setDate(date, cal);
480 m_initialDate = date;
481 m_currentDate = date;
488 const int numSeps = m_separators.size();
489 const int numTokens =
int(m_tokens.size());
490 for (
int i = 0; i < numSeps; ++i) {
491 str += m_separators.at(i);
494 if (i == m_currentToken)
497 str += token.validator->text(m_currentDate, cal, token.repeat);
506 m_separators.clear();
516 const auto quote = u'\'';
517 bool quoting =
false;
519 while (pos < format.size()) {
520 const QStringView mid = QStringView{format}.mid(pos);
523 if (mid.startsWith(quote)) {
526 const QChar nextChar = format.at(pos);
528 separator += nextChar;
532 if (nextChar == u'd') {
533 offset = qMin(4, countRepeat(format, pos));
534 validator = &m_dayValidator;
535 }
else if (nextChar == u'M') {
536 offset = qMin(4, countRepeat(format, pos));
537 validator = &m_monthValidator;
538 }
else if (nextChar == u'y') {
539 offset = qMin(4, countRepeat(format, pos));
540 validator = &m_yearValidator;
542 separator += nextChar;
545 m_tokens.push_back(SectionToken(validator, offset));
546 m_separators.append(separator);
547 separator = QString();
548 if (m_currentToken < 0)
549 m_currentToken =
int(m_tokens.size()) - 1;
556 m_separators += separator;
561 m_currentDate = m_yearValidator.applyToDate(m_currentDate, cal);
562 m_currentDate = m_monthValidator.applyToDate(m_currentDate, cal);
563 m_currentDate = m_dayValidator.applyToDate(m_currentDate, cal);
568 if (m_currentToken < 0)
571 m_currentToken %= m_tokens.size();
576 if (m_currentToken < 0)
579 m_currentToken %= m_tokens.size();
633 void updateDateLabel();
634 void createDateLabel();
635 void removeDateLabel();
639 QBasicTimer m_acceptTimer;
645 const QCalendar m_calendar;
668 m_acceptTimer.start(m_editDelay,
this);
670 m_dateText->setText(m_dateValidator->currentText(m_calendar));
672 QSize s = m_dateFrame->sizeHint();
673 QRect r = m_widget->geometry();
674 QRect newRect((r.width() - s.width()) / 2, (r.height() - s.height()) / 2, s.width(), s.height());
675 m_dateFrame->setGeometry(newRect);
678 QPalette p = m_dateFrame->palette();
679 p.setBrush(QPalette::Window, m_dateFrame->window()->palette().brush(QPalette::Window));
680 m_dateFrame->setPalette(p);
682 m_dateFrame->raise();
688 QDate date = m_dateValidator->currentDate();
693 emit dateChanged(date);
700 m_dateFrame =
new QFrame(m_widget);
701 QVBoxLayout *vl =
new QVBoxLayout;
702 m_dateText =
new QLabel;
703 vl->addWidget(m_dateText);
704 m_dateFrame->setLayout(vl);
705 m_dateFrame->setFrameShadow(QFrame::Plain);
706 m_dateFrame->setFrameShape(QFrame::Box);
708 m_dateValidator->setLocale(m_widget->locale());
709 m_dateValidator->setFormat(m_widget->locale().dateFormat(QLocale::ShortFormat));
710 m_dateValidator->setInitialDate(m_date, m_calendar);
712 m_dateFrame->setAutoFillBackground(
true);
713 m_dateFrame->setBackgroundRole(QPalette::Window);
720 m_acceptTimer.stop();
722 m_dateFrame->deleteLater();
723 delete m_dateValidator;
724 m_dateFrame =
nullptr;
725 m_dateText =
nullptr;
726 m_dateValidator =
nullptr;
732 if (e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease) {
733 QKeyEvent *ke =
static_cast<QKeyEvent *>(e);
734 if ((ke->text().size() > 0 && ke->text().at(0).isPrint()) || m_dateFrame) {
735 if (ke->key() == Qt::Key_Return || ke->key() == Qt::Key_Enter || ke->key() == Qt::Key_Select) {
737 emit editingFinished();
739#if QT_CONFIG(shortcut)
740 }
else if (ke->matches(QKeySequence::Cancel)) {
743 }
else if (e->type() == QEvent::KeyPress) {
745 m_dateValidator->handleKeyEvent(ke, m_calendar);
754
755
756
757
758
759
760
763 return QObject::eventFilter(o,e);
768 if (e->timerId() == m_acceptTimer.timerId()) {
791QT_WARNING_DISABLE_MSVC(4351)
830 if (parent.isValid())
837 if (parent.isValid())
880 return m_calendar.standaloneMonthName(locale, month, m_shownYear, QLocale::LongFormat);
921#if QT_CONFIG(wheelevent)
931 bool validDateClicked;
932#ifdef QT_KEYPAD_NAVIGATION
938 : QAbstractTableModel(parent),
941 m_date(QDate::currentDate()),
942 m_minimumDate(QDate::fromJulianDay(1)),
943 m_maximumDate(9999, 12, 31),
944 m_shownYear(m_date.year(m_calendar)),
945 m_shownMonth(m_date.month(m_calendar)),
946 m_firstDay(QLocale().firstDayOfWeek()),
947 m_horizontalHeaderFormat(QCalendarWidget::ShortDayNames),
956 if (col < 0 || col > 6)
958 int day = m_firstDay + col;
961 return Qt::DayOfWeek(day);
966 if (day < 1 ||
unsigned(day) >
unsigned(7))
968 int column = (
int)day - (
int)m_firstDay;
975
976
977
978
979
980
981
982
983
984
985
990 while (refDay <= 31) {
991 QDate refDate(m_shownYear, m_shownMonth, refDay, m_calendar);
992 if (refDate.isValid())
1001 return (columnForDayOfWeek(
static_cast<Qt::DayOfWeek>(m_calendar.dayOfWeek(date)))
1002 - (date.day(m_calendar) % 7) + 8) % 7;
1010 const QDate refDate = referenceDate();
1011 if (!refDate.isValid())
1018 const int requestedDay =
1019 7 * (row - m_firstRow) + column - columnForFirstOfShownMonth - refDate.day(m_calendar) + 1;
1020 return refDate.addDays(requestedDay);
1025 if (!row && !column)
1033 const QDate refDate = referenceDate();
1034 if (!refDate.isValid())
1038 const int requestedPosition = (refDate.daysTo(date) - m_firstColumn +
1039 columnForFirstOfShownMonth + refDate.day(m_calendar) - 1);
1041 int c = requestedPosition % 7;
1042 int r = requestedPosition / 7;
1062 switch (m_horizontalHeaderFormat) {
1063 case QCalendarWidget::SingleLetterDayNames: {
1064 QString standaloneDayName = m_view->locale().standaloneDayName(day, QLocale::NarrowFormat);
1065 if (standaloneDayName == m_view->locale().dayName(day, QLocale::NarrowFormat))
1066 return standaloneDayName.left(1);
1067 return standaloneDayName;
1069 case QCalendarWidget::ShortDayNames:
1070 return m_view->locale().dayName(day, QLocale::ShortFormat);
1071 case QCalendarWidget::LongDayNames:
1072 return m_view->locale().dayName(day, QLocale::LongFormat);
1082 QPalette::ColorGroup cg = QPalette::Active;
1083 QTextCharFormat format;
1087 if (!m_view->isEnabled())
1088 cg = QPalette::Disabled;
1089 else if (!m_view->isActiveWindow())
1090 cg = QPalette::Inactive;
1091 format.setFont(
m_view->font());
1094 bool header = (m_weekNumbersShown && col == HeaderColumn)
1095 || (m_horizontalHeaderFormat != QCalendarWidget::NoHorizontalHeader && row == HeaderRow);
1096 format.setBackground(pal.brush(cg, header ? QPalette::AlternateBase : QPalette::Base));
1097 format.setForeground(pal.brush(cg, QPalette::Text));
1099 format.merge(m_headerFormat);
1103 Qt::DayOfWeek dayOfWeek = dayOfWeekForColumn(col);
1104 if (m_dayFormats.contains(dayOfWeek))
1105 format.merge(m_dayFormats.value(dayOfWeek));
1109 QDate date = dateForCell(row, col);
1110 format.merge(m_dateFormats.value(date));
1111 if (date < m_minimumDate || date > m_maximumDate)
1112 format.setBackground(pal.brush(cg, QPalette::Window));
1113 if (m_shownMonth != date.month(m_calendar))
1114 format.setForeground(pal.brush(QPalette::Disabled, QPalette::Text));
1121 if (role == Qt::TextAlignmentRole)
1122 return (
int) Qt::AlignCenter;
1124 int row = index.row();
1125 int column = index.column();
1127 if (role == Qt::DisplayRole) {
1130 QDate date = dateForCell(row, columnForDayOfWeek(Qt::Monday));
1132 return date.weekNumber();
1134 if (m_horizontalHeaderFormat != QCalendarWidget::NoHorizontalHeader && row == HeaderRow
1135 && column >= m_firstColumn && column < m_firstColumn + ColumnCount)
1136 return dayName(dayOfWeekForColumn(column));
1137 QDate date = dateForCell(row, column);
1139 return date.day(m_calendar);
1143 QTextCharFormat fmt = formatForCell(row, column);
1144 if (role == Qt::BackgroundRole)
1145 return fmt.background().color();
1146 if (role == Qt::ForegroundRole)
1147 return fmt.foreground().color();
1148 if (role == Qt::FontRole)
1150 if (role == Qt::ToolTipRole)
1151 return fmt.toolTip();
1157 QDate date = dateForCell(index.row(), index.column());
1158 if (!date.isValid())
1159 return QAbstractTableModel::flags(index);
1160 if (date < m_minimumDate)
1162 if (date > m_maximumDate)
1164 return QAbstractTableModel::flags(index);
1170 if (m_date < m_minimumDate)
1171 m_date = m_minimumDate;
1172 else if (m_date > m_maximumDate)
1173 m_date = m_maximumDate;
1179 m_shownYear = m_date.year(c);
1180 m_shownMonth = m_date.month(c);
1203 if (!d.isValid() || d == m_minimumDate)
1207 if (m_maximumDate < m_minimumDate)
1208 m_maximumDate = m_minimumDate;
1209 if (m_date < m_minimumDate)
1210 m_date = m_minimumDate;
1216 if (!d.isValid() || d == m_maximumDate)
1220 if (m_minimumDate > m_maximumDate)
1221 m_minimumDate = m_maximumDate;
1222 if (m_date > m_maximumDate)
1223 m_date = m_maximumDate;
1229 m_minimumDate = min;
1230 m_maximumDate = max;
1231 if (m_minimumDate > m_maximumDate)
1232 qSwap(m_minimumDate, m_maximumDate);
1233 if (m_date < m_minimumDate)
1234 m_date = m_minimumDate;
1235 if (m_date > m_maximumDate)
1236 m_date = m_maximumDate;
1244 emit dataChanged(begin, end);
1245 emit headerDataChanged(Qt::Vertical, 0, m_firstRow + RowCount - 1);
1246 emit headerDataChanged(Qt::Horizontal, 0, m_firstColumn + ColumnCount - 1);
1251 if (m_horizontalHeaderFormat == format)
1254 int oldFormat = m_horizontalHeaderFormat;
1255 m_horizontalHeaderFormat = format;
1256 if (oldFormat == QCalendarWidget::NoHorizontalHeader) {
1260 }
else if (m_horizontalHeaderFormat == QCalendarWidget::NoHorizontalHeader) {
1270 if (m_firstDay == dayOfWeek)
1273 m_firstDay = dayOfWeek;
1306 : QTableView(parent),
1308 validDateClicked(
false)
1310 setTabKeyNavigation(
false);
1312 verticalHeader()->setVisible(
false);
1313 horizontalHeader()->setVisible(
false);
1314 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1315 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1322 return QTableView::moveCursor(cursorAction, modifiers);
1324 QCalendar cal = calendarModel->calendar();
1327 return currentIndex();
1330 QDate currentDate =
static_cast<QCalendarModel*>(model())->dateForCell(index.row(), index.column());
1331 switch (cursorAction) {
1332 case QAbstractItemView::MoveUp:
1333 currentDate = currentDate.addDays(-7);
1335 case QAbstractItemView::MoveDown:
1336 currentDate = currentDate.addDays(7);
1338 case QAbstractItemView::MoveLeft:
1339 currentDate = currentDate.addDays(isRightToLeft() ? 1 : -1);
1341 case QAbstractItemView::MoveRight:
1342 currentDate = currentDate.addDays(isRightToLeft() ? -1 : 1);
1344 case QAbstractItemView::MoveHome: {
1345 auto parts = cal.partsFromDate(currentDate);
1346 if (parts.isValid()) {
1348 currentDate = cal.dateFromParts(parts);
1352 case QAbstractItemView::MoveEnd: {
1353 auto parts = cal.partsFromDate(currentDate);
1354 if (parts.isValid()) {
1355 parts.day = cal.daysInMonth(parts.month, parts.year);
1356 currentDate = cal.dateFromParts(parts);
1360 case QAbstractItemView::MovePageUp:
1361 currentDate = currentDate.addMonths(-1, cal);
1363 case QAbstractItemView::MovePageDown:
1364 currentDate = currentDate.addMonths(1, cal);
1366 case QAbstractItemView::MoveNext:
1367 case QAbstractItemView::MovePrevious:
1368 return currentIndex();
1372 emit changeDate(currentDate,
true);
1373 return currentIndex();
1378#ifdef QT_KEYPAD_NAVIGATION
1411#if QT_CONFIG(wheelevent)
1426#ifdef QT_KEYPAD_NAVIGATION
1427 if (event->type() == QEvent::FocusIn) {
1428 if (QCalendarModel *calendarModel = qobject_cast<QCalendarModel *>(model())) {
1429 origDate = calendarModel->m_date;
1434 return QTableView::event(event);
1443 QPoint pos = event->position().toPoint();
1445 QDate date = calendarModel->dateForCell(index.row(), index.column());
1446 if (date.isValid() && date >= calendarModel->m_minimumDate
1447 && date <= calendarModel->m_maximumDate) {
1456 if (!calendarModel) {
1457 QTableView::mouseDoubleClickEvent(event);
1464 QDate date = handleMouseEvent(event);
1465 validDateClicked =
false;
1466 if (date == calendarModel->m_date &&
1467 !style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick,
nullptr,
this)) {
1468 emit editingFinished();
1475 if (!calendarModel) {
1476 QTableView::mousePressEvent(event);
1483 if (event->button() != Qt::LeftButton)
1486 QDate date = handleMouseEvent(event);
1487 if (date.isValid()) {
1488 validDateClicked =
true;
1489 int row = -1, col = -1;
1491 if (row != -1 && col != -1) {
1492 selectionModel()->setCurrentIndex(model()->index(row, col), QItemSelectionModel::NoUpdate);
1495 validDateClicked =
false;
1503 if (!calendarModel) {
1504 QTableView::mouseMoveEvent(event);
1511 if (validDateClicked) {
1512 QDate date = handleMouseEvent(event);
1513 if (date.isValid()) {
1514 int row = -1, col = -1;
1516 if (row != -1 && col != -1) {
1517 selectionModel()->setCurrentIndex(model()->index(row, col), QItemSelectionModel::NoUpdate);
1528 if (!calendarModel) {
1529 QTableView::mouseReleaseEvent(event);
1533 if (event->button() != Qt::LeftButton)
1539 if (validDateClicked) {
1540 QDate date = handleMouseEvent(event);
1541 if (date.isValid()) {
1542 emit changeDate(date,
true);
1544 if (style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick,
nullptr,
this))
1545 emit editingFinished();
1547 validDateClicked =
false;
1562 void paintCell(QPainter *painter,
const QRect &rect, QDate date)
const;
1566 mutable QStyleOptionViewItem storedOption;
1582 QStyleOptionToolButton opt;
1583 initStyleOption(&opt);
1586 if (!opt.state.testFlag(QStyle::State_MouseOver) || isDown())
1587 opt.palette.setColor(QPalette::ButtonText, opt.palette.color(QPalette::HighlightedText));
1589 painter.drawComplexControl(QStyle::CC_ToolButton, opt);
1625 Q_DECLARE_PUBLIC(QCalendarWidget)
1631 void paintCell(QPainter *painter,
const QRect &rect, QDate date)
const;
1677 QDate date = calendarWidgetPrivate->m_model->dateForCell(index.row(), index.column());
1678 if (date.isValid()) {
1679 storedOption = option;
1680 QRect rect = option.rect;
1681 calendarWidgetPrivate->paintCell(painter, rect, date);
1683 QStyledItemDelegate::paint(painter, option, index);
1689 storedOption.rect = rect;
1694 QStyledItemDelegate::paint(painter, storedOption, idx);
1703 m_selection =
nullptr;
1707 oldFocusPolicy = Qt::StrongFocus;
1712 Q_Q(QCalendarWidget);
1714 bool navigatorEnabled = (
m_navigator->widget() !=
nullptr);
1715 if (enable == navigatorEnabled)
1719 m_navigator->setWidget(q);
1720 q->connect(m_navigator, SIGNAL(dateChanged(QDate)),
1721 q, SLOT(_q_slotChangeDate(QDate)));
1722 q->connect(m_navigator, SIGNAL(editingFinished()),
1723 q, SLOT(_q_editingFinished()));
1727 q->disconnect(m_navigator, SIGNAL(dateChanged(QDate)),
1728 q, SLOT(_q_slotChangeDate(QDate)));
1729 q->disconnect(m_navigator, SIGNAL(editingFinished()),
1730 q, SLOT(_q_editingFinished()));
1737 Q_Q(QCalendarWidget);
1738 navBarBackground =
new QWidget(widget);
1739 navBarBackground->setObjectName(
"qt_calendar_navigationbar"_L1);
1740 navBarBackground->setAutoFillBackground(
true);
1741 navBarBackground->setBackgroundRole(QPalette::Highlight);
1743 prevMonth =
new QPrevNextCalButton(navBarBackground);
1744 nextMonth =
new QPrevNextCalButton(navBarBackground);
1745 prevMonth->setAutoRaise(
true);
1746 nextMonth->setAutoRaise(
true);
1747 prevMonth->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
1748 nextMonth->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
1749 nextMonth->setAutoRaise(
true);
1751 prevMonth->setAutoRepeat(
true);
1752 nextMonth->setAutoRepeat(
true);
1754 monthButton =
new QCalToolButton(navBarBackground);
1755 monthButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
1757 monthButton->setPopupMode(QToolButton::InstantPopup);
1758 monthMenu =
new QMenu(monthButton);
1759 for (
int i = 1, e =
m_model->m_calendar.maximumMonthsInYear(); i <= e; i++) {
1760 QString monthName(m_model->monthName(q->locale(), i));
1761 QAction *act =
monthMenu->addAction(monthName);
1763 monthToAction[i] = act;
1766 yearButton =
new QCalToolButton(navBarBackground);
1767 yearButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
1769 yearEdit =
new QSpinBox(navBarBackground);
1771 QFont font = q->font();
1775 yearEdit->setFrame(
false);
1776 yearEdit->setMinimum(m_model->m_minimumDate.year(m_model->m_calendar));
1777 yearEdit->setMaximum(m_model->m_maximumDate.year(m_model->m_calendar));
1779 spaceHolder =
new QSpacerItem(0,0);
1781 QHBoxLayout *headerLayout =
new QHBoxLayout;
1782 headerLayout->setContentsMargins(QMargins());
1783 headerLayout->setSpacing(0);
1784 headerLayout->addWidget(prevMonth);
1785 headerLayout->insertStretch(headerLayout->count());
1787 headerLayout->addItem(spaceHolder);
1789 headerLayout->insertStretch(headerLayout->count());
1790 headerLayout->addWidget(nextMonth);
1791 navBarBackground->setLayout(headerLayout);
1793 yearEdit->setFocusPolicy(Qt::StrongFocus);
1794 prevMonth->setFocusPolicy(Qt::NoFocus);
1795 nextMonth->setFocusPolicy(Qt::NoFocus);
1796 yearButton->setFocusPolicy(Qt::NoFocus);
1797 monthButton->setFocusPolicy(Qt::NoFocus);
1800 prevMonth->setObjectName(
"qt_calendar_prevmonth"_L1);
1801 nextMonth->setObjectName(
"qt_calendar_nextmonth"_L1);
1802 monthButton->setObjectName(
"qt_calendar_monthbutton"_L1);
1803 yearButton->setObjectName(
"qt_calendar_yearbutton"_L1);
1804 yearEdit->setObjectName(
"qt_calendar_yearedit"_L1);
1812 Q_Q(QCalendarWidget);
1813 prevMonth->setIcon(q->style()->standardIcon(q->isRightToLeft() ? QStyle::SP_ArrowRight : QStyle::SP_ArrowLeft,
nullptr, q));
1814 nextMonth->setIcon(q->style()->standardIcon(q->isRightToLeft() ? QStyle::SP_ArrowLeft : QStyle::SP_ArrowRight,
nullptr, q));
1820 int beg = 1, end = maxMonths;
1821 bool prevEnabled =
true;
1822 bool nextEnabled =
true;
1824 if (m_model->m_shownYear == m_model->m_minimumDate.year(cal)) {
1825 beg = m_model->m_minimumDate.month(cal);
1826 if (m_model->m_shownMonth == m_model->m_minimumDate.month(cal))
1827 prevEnabled =
false;
1829 if (m_model->m_shownYear == m_model->m_maximumDate.year(cal)) {
1830 end = m_model->m_maximumDate.month(cal);
1831 if (m_model->m_shownMonth == m_model->m_maximumDate.month(cal))
1832 nextEnabled =
false;
1834 prevMonth->setEnabled(prevEnabled);
1835 nextMonth->setEnabled(nextEnabled);
1836 for (
int i = 1; i <= maxMonths; i++) {
1837 bool monthEnabled =
true;
1838 if (i < beg || i > end)
1839 monthEnabled =
false;
1840 monthToAction[i]->setEnabled(monthEnabled);
1846 Q_Q(QCalendarWidget);
1848 for (
int i = 1; i <= 12; i++) {
1849 QString monthName(m_model->monthName(q->locale(), i));
1850 monthToAction[i]->setText(monthName);
1856 Q_Q(QCalendarWidget);
1859 QDate newDate = date;
1860 QDate minDate = q->minimumDate();
1861 QDate maxDate = q->maximumDate();
1862 if (minDate.isValid()&& minDate.daysTo(newDate) < 0)
1864 if (maxDate.isValid()&& maxDate.daysTo(newDate) > 0)
1866 showMonth(newDate.year(cal), newDate.month(cal));
1867 int row = -1, col = -1;
1869 if (row != -1 && col != -1)
1871 m_view->selectionModel()->setCurrentIndex(m_model->index(row, col),
1872 QItemSelectionModel::NoUpdate);
1879 QDate currentDate = getCurrentDate();
1880 QDate newDate = currentDate.addMonths(act->data().toInt() - currentDate.month(m_model->m_calendar), m_model->m_calendar);
1887 return m_model->dateForCell(index.row(), index.column());
1892 QDate currentDate = getCurrentDate().addMonths(-1, m_model->m_calendar);
1898 QDate currentDate = getCurrentDate().addMonths(1, m_model->m_calendar);
1904 Q_Q(QCalendarWidget);
1906 q->setFocusPolicy(oldFocusPolicy);
1907 qApp->removeEventFilter(q);
1908 spaceHolder->changeSize(0, 0);
1910 QDate currentDate = getCurrentDate();
1911 int newYear = q->locale().toInt(yearEdit->text());
1912 currentDate = currentDate.addYears(newYear - currentDate.year(
m_model->m_calendar),
m_model->m_calendar);
1913 yearButton->setText(q->locale().toString(currentDate, u"yyyy", m_model->m_calendar));
1919 Q_Q(QCalendarWidget);
1921 yearEdit->setGeometry(yearButton->x(), yearButton->y(),
1922 yearEdit->sizeHint().width(), yearButton->height());
1923 spaceHolder->changeSize(yearButton->width(), 0);
1925 oldFocusPolicy = q->focusPolicy();
1926 q->setFocusPolicy(Qt::NoFocus);
1928 qApp->installEventFilter(q);
1930 yearEdit->selectAll();
1931 yearEdit->setFocus(Qt::MouseFocusReason);
1938 Q_Q(QCalendarWidget);
1941 emit q->currentPageChanged(year, month);
1943 cachedSizeHint = QSize();
1950 Q_Q(QCalendarWidget);
1952 QString monthName = m_model->monthName(q->locale(), m_model->m_shownMonth);
1955 yearEdit->setValue(m_model->m_shownYear);
1956 yearButton->setText(yearEdit->text());
1961 QDate currentDate = m_model->m_date;
1965 m_selection->clear();
1966 if (row != -1 && column != -1) {
1967 idx =
m_model->index(row, column);
1968 m_selection->setCurrentIndex(idx, QItemSelectionModel::SelectCurrent);
1974 Q_Q(
const QCalendarWidget);
1975 q->paintCell(painter, rect, date);
1985 _q_slotChangeDate(date,
true);
1990 QDate oldDate = m_model->m_date;
1992 QDate newDate = m_model->m_date;
1995 if (oldDate != newDate) {
1997 Q_Q(QCalendarWidget);
1999 emit q->selectionChanged();
2005 Q_Q(QCalendarWidget);
2006 emit q->activated(m_model->m_date);
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2095
2096
2097
2098
2099
2100
2101
2102QCalendarWidget::QCalendarWidget(QWidget *parent)
2103 : QWidget(*
new QCalendarWidgetPrivate, parent, { })
2105 Q_D(QCalendarWidget);
2107 setAutoFillBackground(
true);
2108 setBackgroundRole(QPalette::Window);
2110 QVBoxLayout *layoutV =
new QVBoxLayout(
this);
2111 layoutV->setContentsMargins(QMargins());
2112 d->m_model =
new QCalendarModel(
this);
2113 QTextCharFormat fmt;
2114 fmt.setForeground(QBrush(Qt::red));
2115 d->m_model->m_dayFormats.insert(Qt::Saturday, fmt);
2116 d->m_model->m_dayFormats.insert(Qt::Sunday, fmt);
2117 d->m_view =
new QCalendarView(
this);
2118 d->m_view->setObjectName(
"qt_calendar_calendarview"_L1);
2119 d->m_view->setModel(d->m_model);
2120 d->m_model->setView(d->m_view);
2121 d->m_view->setSelectionBehavior(QAbstractItemView::SelectItems);
2122 d->m_view->setSelectionMode(QAbstractItemView::SingleSelection);
2123 d->m_view->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
2124 d->m_view->horizontalHeader()->setSectionsClickable(
false);
2125 d->m_view->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
2126 d->m_view->verticalHeader()->setSectionsClickable(
false);
2127 d->m_selection = d->m_view->selectionModel();
2128 d->createNavigationBar(
this);
2129 d->m_view->setFrameStyle(QFrame::NoFrame);
2130 d->m_delegate =
new QCalendarDelegate(d,
this);
2131 d->m_view->setItemDelegate(d->m_delegate);
2133 d->updateNavigationBar();
2134 setFocusPolicy(Qt::StrongFocus);
2135 setFocusProxy(d->m_view);
2136 setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
2138 connect(d->m_view, SIGNAL(showDate(QDate)),
2139 this, SLOT(_q_slotShowDate(QDate)));
2140 connect(d->m_view, SIGNAL(changeDate(QDate,
bool)),
2141 this, SLOT(_q_slotChangeDate(QDate,
bool)));
2142 connect(d->m_view, SIGNAL(clicked(QDate)),
2143 this, SIGNAL(clicked(QDate)));
2144 connect(d->m_view, SIGNAL(editingFinished()),
2145 this, SLOT(_q_editingFinished()));
2147 connect(d->prevMonth, SIGNAL(clicked(
bool)),
2148 this, SLOT(_q_prevMonthClicked()));
2149 connect(d->nextMonth, SIGNAL(clicked(
bool)),
2150 this, SLOT(_q_nextMonthClicked()));
2151 connect(d->yearButton, SIGNAL(clicked(
bool)),
2152 this, SLOT(_q_yearClicked()));
2153 connect(d->monthMenu, SIGNAL(triggered(QAction*)),
2154 this, SLOT(_q_monthChanged(QAction*)));
2155 connect(d->yearEdit, SIGNAL(editingFinished()),
2156 this, SLOT(_q_yearEditingFinished()));
2158 layoutV->setContentsMargins(QMargins());
2159 layoutV->setSpacing(0);
2160 layoutV->addWidget(d->navBarBackground);
2161 layoutV->addWidget(d->m_view);
2163 d->m_navigator =
new QCalendarTextNavigator(
this);
2164 setDateEditEnabled(
true);
2168
2169
2170QCalendarWidget::~QCalendarWidget()
2175
2176
2177QSize QCalendarWidget::sizeHint()
const
2179 return minimumSizeHint();
2183
2184
2185QSize QCalendarWidget::minimumSizeHint()
const
2187 Q_D(
const QCalendarWidget);
2188 if (d->cachedSizeHint.isValid())
2189 return d->cachedSizeHint;
2200 QStyleOption option;
2201 option.initFrom(
this);
2202 const int marginH = (style()->pixelMetric(QStyle::PM_FocusFrameHMargin, &option,
this) + 1) * 2;
2204 if (horizontalHeaderFormat() == QCalendarWidget::NoHorizontalHeader) {
2207 for (
int i = 1; i <= 7; i++) {
2208 QFontMetrics fm(d->m_model->formatForCell(0, i).font());
2209 w = qMax(w, fm.horizontalAdvance(d->m_model->dayName(d->m_model->dayOfWeekForColumn(i))) + marginH);
2210 h = qMax(h, fm.height());
2214 if (verticalHeaderFormat() == QCalendarWidget::NoVerticalHeader) {
2217 for (
int i = 1; i <= 6; i++) {
2218 QFontMetrics fm(d->m_model->formatForCell(i, 0).font());
2219 for (
int j = 1; j < end; j++)
2220 w = qMax(w, fm.horizontalAdvance(QString::number(j)) + marginH);
2221 h = qMax(h, fm.height());
2225 QFontMetrics fm(d->m_model->formatForCell(1, 1).font());
2226 for (
int i = 1; i <= end; i++) {
2227 w = qMax(w, fm.horizontalAdvance(QString::number(i)) + marginH);
2228 h = qMax(h, fm.height());
2231 if (d->m_view->showGrid()) {
2239 h = qMax(h, d->m_view->verticalHeader()->minimumSectionSize());
2240 w = qMax(w, d->m_view->horizontalHeader()->minimumSectionSize());
2243 QSize headerSize(0, 0);
2244 if (d->navBarVisible) {
2245 int headerH = d->navBarBackground->sizeHint().height();
2248 headerW += d->prevMonth->sizeHint().width();
2249 headerW += d->nextMonth->sizeHint().width();
2251 QFontMetrics fm = d->monthButton->fontMetrics();
2253 for (
int i = 1; i < 12; i++) {
2254 QString monthName = d->m_model->monthName(locale(), i);
2255 monthW = qMax(monthW, fm.boundingRect(monthName).width());
2257 const int buttonDecoMargin = d->monthButton->sizeHint().width() - fm.boundingRect(d->monthButton->text()).width();
2258 headerW += monthW + buttonDecoMargin;
2260 fm = d->yearButton->fontMetrics();
2261 headerW += fm.boundingRect(
"5555"_L1).width() + buttonDecoMargin;
2263 headerSize = QSize(headerW, headerH);
2266 w = qMax(headerSize.width(), w);
2267 h = (h * rows) + headerSize.height();
2268 QMargins cm = contentsMargins();
2269 w += cm.left() + cm.right();
2270 h += cm.top() + cm.bottom();
2271 d->cachedSizeHint = QSize(w, h);
2272 return d->cachedSizeHint;
2276
2277
2279void QCalendarWidget::paintCell(QPainter *painter,
const QRect &rect, QDate date)
const
2281 Q_D(
const QCalendarWidget);
2282 d->m_delegate->paintCell(painter, rect, date);
2286
2287
2288
2289
2290
2291
2292
2293
2294
2296QDate QCalendarWidget::selectedDate()
const
2298 Q_D(
const QCalendarWidget);
2299 return d->m_model->m_date;
2302void QCalendarWidget::setSelectedDate(QDate date)
2304 Q_D(QCalendarWidget);
2305 if (d->m_model->m_date == date && date == d->getCurrentDate())
2308 if (!date.isValid())
2311 d->m_model->setDate(date);
2313 QDate newDate = d->m_model->m_date;
2314 QCalendar cal = d->m_model->m_calendar;
2315 d->showMonth(newDate.year(cal), newDate.month(cal));
2316 emit selectionChanged();
2320
2321
2322
2323
2324
2326int QCalendarWidget::yearShown()
const
2328 Q_D(
const QCalendarWidget);
2329 return d->m_model->m_shownYear;
2333
2334
2335
2336
2337
2339int QCalendarWidget::monthShown()
const
2341 Q_D(
const QCalendarWidget);
2342 return d->m_model->m_shownMonth;
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2357void QCalendarWidget::setCurrentPage(
int year,
int month)
2359 Q_D(QCalendarWidget);
2360 QDate currentDate = d->getCurrentDate();
2361 QCalendar cal = d->m_model->m_calendar;
2362 int day = currentDate.day(cal);
2363 int daysInMonths = cal.daysInMonth(month, year);
2364 if (day > daysInMonths)
2367 d->showMonth(year, month);
2369 QDate newDate(year, month, day, d->m_model->m_calendar);
2370 int row = -1, col = -1;
2371 d->m_model->cellForDate(newDate, &row, &col);
2372 if (row != -1 && col != -1) {
2373 d->m_view->selectionModel()->setCurrentIndex(d->m_model->index(row, col),
2374 QItemSelectionModel::NoUpdate);
2379
2380
2381
2382
2383
2385void QCalendarWidget::showNextMonth()
2387 Q_D(
const QCalendarWidget);
2388 int year = yearShown();
2389 int month = monthShown();
2390 if (month == d->m_model->m_calendar.maximumMonthsInYear()) {
2396 setCurrentPage(year, month);
2400
2401
2402
2403
2404
2406void QCalendarWidget::showPreviousMonth()
2408 Q_D(
const QCalendarWidget);
2410 int year = yearShown();
2411 int month = monthShown();
2414 month = d->m_model->m_calendar.maximumMonthsInYear();
2418 setCurrentPage(year, month);
2422
2423
2424
2425
2426
2427
2429void QCalendarWidget::showNextYear()
2431 int year = yearShown();
2432 int month = monthShown();
2434 setCurrentPage(year, month);
2438
2439
2440
2441
2442
2443
2445void QCalendarWidget::showPreviousYear()
2447 int year = yearShown();
2448 int month = monthShown();
2450 setCurrentPage(year, month);
2454
2455
2456
2457
2458void QCalendarWidget::showSelectedDate()
2460 Q_D(
const QCalendarWidget);
2462 QDate currentDate = selectedDate();
2463 setCurrentPage(currentDate.year(d->m_model->m_calendar), currentDate.month(d->m_model->m_calendar));
2467
2468
2469
2470
2471void QCalendarWidget::showToday()
2473 Q_D(
const QCalendarWidget);
2475 QDate currentDate = QDate::currentDate();
2476 setCurrentPage(currentDate.year(d->m_model->m_calendar), currentDate.month(d->m_model->m_calendar));
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2506QDate QCalendarWidget::minimumDate()
const
2508 Q_D(
const QCalendarWidget);
2509 return d->m_model->m_minimumDate;
2512void QCalendarWidget::setMinimumDate(QDate date)
2514 Q_D(QCalendarWidget);
2515 if (!date.isValid() || d->m_model->m_minimumDate == date)
2518 QDate oldDate = d->m_model->m_date;
2519 d->m_model->setMinimumDate(date);
2520 d->yearEdit->setMinimum(d->m_model->m_minimumDate.year(d->m_model->m_calendar));
2521 d->updateMonthMenu();
2522 QDate newDate = d->m_model->m_date;
2523 if (oldDate != newDate) {
2525 d->showMonth(newDate.year(d->m_model->m_calendar), newDate.month(d->m_model->m_calendar));
2526 d->m_navigator->setDate(newDate);
2527 emit selectionChanged();
2531void QCalendarWidget::clearMinimumDate()
2533 setMinimumDate(QDate::fromJulianDay(1));
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2563QDate QCalendarWidget::maximumDate()
const
2565 Q_D(
const QCalendarWidget);
2566 return d->m_model->m_maximumDate;
2569void QCalendarWidget::setMaximumDate(QDate date)
2571 Q_D(QCalendarWidget);
2572 if (!date.isValid() || d->m_model->m_maximumDate == date)
2575 QDate oldDate = d->m_model->m_date;
2576 d->m_model->setMaximumDate(date);
2577 d->yearEdit->setMaximum(d->m_model->m_maximumDate.year(d->m_model->m_calendar));
2578 d->updateMonthMenu();
2579 QDate newDate = d->m_model->m_date;
2580 if (oldDate != newDate) {
2582 d->showMonth(newDate.year(d->m_model->m_calendar), newDate.month(d->m_model->m_calendar));
2583 d->m_navigator->setDate(newDate);
2584 emit selectionChanged();
2588void QCalendarWidget::clearMaximumDate()
2590 setMaximumDate(QDate(9999, 12, 31));
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2612void QCalendarWidget::setDateRange(QDate min, QDate max)
2614 Q_D(QCalendarWidget);
2615 if (d->m_model->m_minimumDate == min && d->m_model->m_maximumDate == max)
2617 if (!min.isValid() || !max.isValid())
2620 QDate oldDate = d->m_model->m_date;
2621 d->m_model->setRange(min, max);
2622 d->yearEdit->setMinimum(d->m_model->m_minimumDate.year(d->m_model->m_calendar));
2623 d->yearEdit->setMaximum(d->m_model->m_maximumDate.year(d->m_model->m_calendar));
2624 d->updateMonthMenu();
2625 QDate newDate = d->m_model->m_date;
2626 if (oldDate != newDate) {
2628 d->showMonth(newDate.year(d->m_model->m_calendar), newDate.month(d->m_model->m_calendar));
2629 d->m_navigator->setDate(newDate);
2630 emit selectionChanged();
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2648
2649
2650
2651
2652
2654void QCalendarWidget::setHorizontalHeaderFormat(QCalendarWidget::HorizontalHeaderFormat format)
2656 Q_D(QCalendarWidget);
2657 if (d->m_model->m_horizontalHeaderFormat == format)
2660 d->m_model->setHorizontalHeaderFormat(format);
2661 d->cachedSizeHint = QSize();
2662 d->m_view->viewport()->update();
2663 d->m_view->updateGeometry();
2666QCalendarWidget::HorizontalHeaderFormat QCalendarWidget::horizontalHeaderFormat()
const
2668 Q_D(
const QCalendarWidget);
2669 return d->m_model->m_horizontalHeaderFormat;
2674
2675
2676
2677
2678
2679
2680
2681
2682
2685
2686
2687
2688
2689
2691QCalendarWidget::VerticalHeaderFormat QCalendarWidget::verticalHeaderFormat()
const
2693 Q_D(
const QCalendarWidget);
2694 bool shown = d->m_model->weekNumbersShown();
2696 return QCalendarWidget::ISOWeekNumbers;
2697 return QCalendarWidget::NoVerticalHeader;
2700void QCalendarWidget::setVerticalHeaderFormat(QCalendarWidget::VerticalHeaderFormat format)
2702 Q_D(QCalendarWidget);
2704 if (format == QCalendarWidget::ISOWeekNumbers)
2706 if (d->m_model->weekNumbersShown() == show)
2708 d->m_model->setWeekNumbersShown(show);
2709 d->cachedSizeHint = QSize();
2710 d->m_view->viewport()->update();
2711 d->m_view->updateGeometry();
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2730bool QCalendarWidget::isGridVisible()
const
2732 Q_D(
const QCalendarWidget);
2733 return d->m_view->showGrid();
2737
2738
2739
2740
2741
2743QCalendar QCalendarWidget::calendar()
const
2745 Q_D(
const QCalendarWidget);
2746 return d->m_model->m_calendar;
2750
2751
2752
2753
2754
2755
2756
2757
2759void QCalendarWidget::setCalendar(QCalendar c)
2761 Q_D(QCalendarWidget);
2762 d->m_model->setCalendar(c);
2763 d->updateMonthMenuNames();
2764 d->yearEdit->setMinimum(d->m_model->m_minimumDate.year(d->m_model->m_calendar));
2765 d->yearEdit->setMaximum(d->m_model->m_maximumDate.year(d->m_model->m_calendar));
2766 d->updateNavigationBar();
2769void QCalendarWidget::setGridVisible(
bool show)
2771 Q_D(QCalendarWidget);
2772 d->m_view->setShowGrid(show);
2773 d->cachedSizeHint = QSize();
2774 d->m_view->viewport()->update();
2775 d->m_view->updateGeometry();
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2794QCalendarWidget::SelectionMode QCalendarWidget::selectionMode()
const
2796 Q_D(
const QCalendarWidget);
2797 return d->m_view->readOnly ? QCalendarWidget::NoSelection : QCalendarWidget::SingleSelection;
2800void QCalendarWidget::setSelectionMode(SelectionMode mode)
2802 Q_D(QCalendarWidget);
2803 d->m_view->readOnly = (mode == QCalendarWidget::NoSelection);
2804 d->setNavigatorEnabled(isDateEditEnabled() && (selectionMode() != QCalendarWidget::NoSelection));
2809
2810
2811
2812
2813
2814
2816void QCalendarWidget::setFirstDayOfWeek(Qt::DayOfWeek dayOfWeek)
2818 Q_D(QCalendarWidget);
2819 if ((Qt::DayOfWeek)d->m_model->firstColumnDay() == dayOfWeek)
2822 d->m_model->setFirstColumnDay(dayOfWeek);
2826Qt::DayOfWeek QCalendarWidget::firstDayOfWeek()
const
2828 Q_D(
const QCalendarWidget);
2829 return (Qt::DayOfWeek)d->m_model->firstColumnDay();
2833
2834
2835QTextCharFormat QCalendarWidget::headerTextFormat()
const
2837 Q_D(
const QCalendarWidget);
2838 return d->m_model->m_headerFormat;
2842
2843
2844
2845
2846
2847
2848void QCalendarWidget::setHeaderTextFormat(
const QTextCharFormat &format)
2850 Q_D(QCalendarWidget);
2851 d->m_model->m_headerFormat = format;
2852 d->cachedSizeHint = QSize();
2853 d->m_view->viewport()->update();
2854 d->m_view->updateGeometry();
2858
2859
2860
2861
2862QTextCharFormat QCalendarWidget::weekdayTextFormat(Qt::DayOfWeek dayOfWeek)
const
2864 Q_D(
const QCalendarWidget);
2865 return d->m_model->m_dayFormats.value(dayOfWeek);
2869
2870
2871
2872
2873
2874
2875void QCalendarWidget::setWeekdayTextFormat(Qt::DayOfWeek dayOfWeek,
const QTextCharFormat &format)
2877 Q_D(QCalendarWidget);
2878 d->m_model->m_dayFormats[dayOfWeek] = format;
2879 d->cachedSizeHint = QSize();
2880 d->m_view->viewport()->update();
2881 d->m_view->updateGeometry();
2885
2886
2887
2888QMap<QDate, QTextCharFormat> QCalendarWidget::dateTextFormat()
const
2890 Q_D(
const QCalendarWidget);
2891 return d->m_model->m_dateFormats;
2895
2896
2897
2898QTextCharFormat QCalendarWidget::dateTextFormat(QDate date)
const
2900 Q_D(
const QCalendarWidget);
2901 return d->m_model->m_dateFormats.value(date);
2905
2906
2907
2908
2909void QCalendarWidget::setDateTextFormat(QDate date,
const QTextCharFormat &format)
2911 Q_D(QCalendarWidget);
2913 d->m_model->m_dateFormats.clear();
2915 d->m_model->m_dateFormats[date] = format;
2916 d->m_view->viewport()->update();
2917 d->m_view->updateGeometry();
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938bool QCalendarWidget::isDateEditEnabled()
const
2940 Q_D(
const QCalendarWidget);
2941 return d->m_dateEditEnabled;
2944void QCalendarWidget::setDateEditEnabled(
bool enable)
2946 Q_D(QCalendarWidget);
2947 if (isDateEditEnabled() == enable)
2950 d->m_dateEditEnabled = enable;
2952 d->setNavigatorEnabled(enable && (selectionMode() != QCalendarWidget::NoSelection));
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967int QCalendarWidget::dateEditAcceptDelay()
const
2969 Q_D(
const QCalendarWidget);
2970 return d->m_navigator->dateEditAcceptDelay();
2973void QCalendarWidget::setDateEditAcceptDelay(
int delay)
2975 Q_D(QCalendarWidget);
2976 d->m_navigator->setDateEditAcceptDelay(delay);
2980
2981
2982
2983
2984
2985
2986
2987void QCalendarWidget::updateCell(QDate date)
2989 if (Q_UNLIKELY(!date.isValid())) {
2990 qWarning(
"QCalendarWidget::updateCell: Invalid date");
2997 Q_D(QCalendarWidget);
2999 d->m_model->cellForDate(date, &row, &column);
3000 if (row == -1 || column == -1)
3003 QModelIndex modelIndex = d->m_model->index(row, column);
3004 if (!modelIndex.isValid())
3007 d->m_view->viewport()->update(d->m_view->visualRect(modelIndex));
3011
3012
3013
3014
3015
3016
3017void QCalendarWidget::updateCells()
3019 Q_D(QCalendarWidget);
3021 d->m_view->viewport()->update();
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3037
3038
3039
3040
3041
3042
3043
3046
3047
3048
3049
3050
3051
3054
3055
3056
3057
3058
3059
3060
3061
3062
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3077bool QCalendarWidget::isNavigationBarVisible()
const
3079 Q_D(
const QCalendarWidget);
3080 return d->navBarVisible;
3084void QCalendarWidget::setNavigationBarVisible(
bool visible)
3086 Q_D(QCalendarWidget);
3087 d->navBarVisible = visible;
3088 d->cachedSizeHint = QSize();
3089 d->navBarBackground->setVisible(visible);
3094
3095
3096bool QCalendarWidget::event(QEvent *event)
3098 Q_D(QCalendarWidget);
3099 switch (event->type()) {
3100 case QEvent::LayoutDirectionChange:
3101 d->updateButtonIcons();
3103 case QEvent::LocaleChange:
3104 d->m_model->setFirstColumnDay(locale().firstDayOfWeek());
3105 d->cachedSizeHint = QSize();
3106 d->updateMonthMenuNames();
3107 d->updateNavigationBar();
3108 d->m_view->updateGeometry();
3113 case QEvent::FontChange:
3114 case QEvent::ApplicationFontChange:
3115 d->cachedSizeHint = QSize();
3116 d->m_view->updateGeometry();
3118 case QEvent::StyleChange:
3119 d->cachedSizeHint = QSize();
3120 d->m_view->updateGeometry();
3125 return QWidget::event(event);
3129
3130
3131bool QCalendarWidget::eventFilter(QObject *watched, QEvent *event)
3133 Q_D(QCalendarWidget);
3134 if (event->type() == QEvent::MouseButtonPress && d->yearEdit->hasFocus()) {
3139 QWidget *tlw = window();
3140 QWidget *widget = qobject_cast<QWidget *>(watched);
3141 if (!widget || widget->window() != tlw)
3142 return QWidget::eventFilter(watched, event);
3144 QPoint mousePos = widget->mapTo(tlw,
static_cast<QMouseEvent *>(event)->position().toPoint());
3145 QRect geom = QRect(d->yearEdit->mapTo(tlw, QPoint(0, 0)), d->yearEdit->size());
3146 if (!geom.contains(mousePos)) {
3148 d->_q_yearEditingFinished();
3153 return QWidget::eventFilter(watched, event);
3157
3158
3159void QCalendarWidget::mousePressEvent(QMouseEvent *event)
3161 setAttribute(Qt::WA_NoMouseReplay);
3162 QWidget::mousePressEvent(event);
3167
3168
3169void QCalendarWidget::resizeEvent(QResizeEvent * event)
3171 Q_D(QCalendarWidget);
3176 if (d->yearEdit->isVisible() && event->size().width() != event->oldSize().width())
3177 d->_q_yearEditingFinished();
3179 QWidget::resizeEvent(event);
3183
3184
3185void QCalendarWidget::keyPressEvent(QKeyEvent * event)
3187#if QT_CONFIG(shortcut)
3188 Q_D(QCalendarWidget);
3189 if (d->yearEdit->isVisible()&& event->matches(QKeySequence::Cancel)) {
3190 d->yearEdit->setValue(yearShown());
3191 d->_q_yearEditingFinished();
3195 QWidget::keyPressEvent(event);
3200#include "qcalendarwidget.moc"
3201#include "moc_qcalendarwidget.cpp"
The QCalendar class describes calendar systems.
constexpr QModelIndex() noexcept
Creates a new empty model index.
The QStylePainter class is a convenience class for drawing QStyle elements inside a widget.
virtual Section handleKey(int key)=0
virtual void setDate(QDate date, QCalendar cal=QCalendar())=0
virtual QDate applyToDate(QDate date, QCalendar cal=QCalendar()) const =0
QCalendarDateSectionValidator()
virtual QString text(QDate date, QCalendar cal, int repeat) const =0
static QString highlightString(const QString &str, int pos)
virtual QString text() const =0
virtual ~QCalendarDateSectionValidator()
void setLocale(const QLocale &locale)
void setInitialDate(QDate date, QCalendar cal)
~QCalendarDateValidator()
void handleKeyEvent(QKeyEvent *keyEvent, QCalendar cal)
void setFormat(const QString &format)
QString currentText(QCalendar cal) const
QDate currentDate() const
virtual QDate applyToDate(QDate date, QCalendar cal) const override
virtual Section handleKey(int key) override
virtual void setDate(QDate date, QCalendar cal) override
virtual QString text() const override
virtual QString text(QDate date, QCalendar cal, int repeat) const override
void paintCell(QPainter *painter, const QRect &rect, QDate date) const
QString dayName(Qt::DayOfWeek day) const
void showMonth(int year, int month)
QCalendar calendar() const
QTextCharFormat formatForCell(int row, int col) const
int columnCount(const QModelIndex &parent) const override
Returns the number of columns for the children of the given parent.
QTextCharFormat m_headerFormat
QString monthName(const QLocale &locale, int month)
void setFirstColumnDay(Qt::DayOfWeek dayOfWeek)
int columnForDayOfWeek(Qt::DayOfWeek day) const
void setCalendar(QCalendar c)
Qt::ItemFlags flags(const QModelIndex &index) const override
\reimp
StaticDayOfWeekAssociativeArray< QTextCharFormat > m_dayFormats
int columnForFirstOfMonth(QDate date) const
void setMinimumDate(QDate date)
void cellForDate(QDate date, int *row, int *column) const
bool weekNumbersShown() const
QVariant data(const QModelIndex &index, int role) const override
Returns the data stored under the given role for the item referred to by the index.
void setMaximumDate(QDate date)
Qt::DayOfWeek firstColumnDay() const
void setHorizontalHeaderFormat(QCalendarWidget::HorizontalHeaderFormat format)
Qt::DayOfWeek dayOfWeekForColumn(int section) const
QDate referenceDate() const
void setView(QCalendarView *view)
int rowCount(const QModelIndex &parent) const override
Returns the number of rows under the given parent.
void setRange(QDate min, QDate max)
QMap< QDate, QTextCharFormat > m_dateFormats
QDate dateForCell(int row, int column) const
void setWeekNumbersShown(bool show)
virtual QDate applyToDate(QDate date, QCalendar cal) const override
QCalendarMonthValidator()
virtual Section handleKey(int key) override
virtual QString text(QDate date, QCalendar cal, int repeat) const override
virtual void setDate(QDate date, QCalendar cal) override
virtual QString text() const override
int dateEditAcceptDelay() const
void setDateEditAcceptDelay(int delay)
void timerEvent(QTimerEvent *e) override
This event handler can be reimplemented in a subclass to receive timer events for the object.
void setWidget(QWidget *widget)
bool eventFilter(QObject *o, QEvent *e) override
Filters events if this object has been installed as an event filter for the watched object.
virtual void keyboardSearch(const QString &) override
Moves to and selects the item best matching the string search.
void mouseReleaseEvent(QMouseEvent *event) override
void mousePressEvent(QMouseEvent *event) override
bool event(QEvent *event) override
void keyPressEvent(QKeyEvent *event) override
void changeDate(QDate date, bool changeMonth)
void setReadOnly(bool enable)
QDate handleMouseEvent(QMouseEvent *event)
QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers) override
Returns a QModelIndex object pointing to the next object in the view, based on the given cursorAction...
void mouseDoubleClickEvent(QMouseEvent *event) override
void mouseMoveEvent(QMouseEvent *event) override
virtual QDate applyToDate(QDate date, QCalendar cal) const override
virtual QString text(QDate date, QCalendar cal, int repeat) const override
virtual void setDate(QDate date, QCalendar cal) override
virtual Section handleKey(int key) override
virtual QString text() const override
constexpr SectionToken(QCalendarDateSectionValidator *v, int rep)
QCalendarDateSectionValidator * validator