File indexing completed on 2025-02-16 13:11:40
0001 /* -*- C++ -*- 0002 This file is part of the KDE libraries 0003 SPDX-FileCopyrightText: 1997 Tim D. Gilman <tdgilman@best.org> 0004 SPDX-FileCopyrightText: 1998-2001 Mirko Boehm (mirko@kde.org) 0005 SPDX-FileCopyrightText: 2007 John Layt <john@layt.net> 0006 SPDX-FileCopyrightText: 2022 g10 Code GmbH 0007 SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de> 0008 0009 SPDX-License-Identifier: LGPL-2.0-or-later 0010 */ 0011 0012 #include "kdatepicker.h" 0013 #include "kdatepicker_p.h" 0014 0015 #include "common_helpers_p.h" 0016 #include "kdatetable_p.h" 0017 #include <kpopupframe.h> 0018 0019 #include <QApplication> 0020 #include <QComboBox> 0021 #include <QFont> 0022 #include <QFontDatabase> 0023 #include <QKeyEvent> 0024 #include <QLayout> 0025 #include <QMenu> 0026 #include <QStyle> 0027 #include <QToolButton> 0028 0029 #include "loggingcategory.h" 0030 #include "moc_kdatepicker.cpp" 0031 #include "moc_kdatepicker_p.cpp" 0032 0033 class DatePickerValidator : public QValidator 0034 { 0035 Q_OBJECT 0036 public: 0037 explicit DatePickerValidator(KDatePicker *parent) 0038 : QValidator(parent) 0039 , picker(parent) 0040 { 0041 } 0042 0043 State validate(QString &text, int &) const override 0044 { 0045 return toDate(text).isValid() ? QValidator::Acceptable : QValidator::Intermediate; 0046 } 0047 0048 QDate toDate(const QString &text) const 0049 { 0050 QLocale locale = picker->locale(); 0051 const QList<QString> formats{ 0052 locale.dateFormat(QLocale::LongFormat), 0053 locale.dateFormat(QLocale::ShortFormat), 0054 locale.dateFormat(QLocale::NarrowFormat), 0055 dateFormatWith4DigitYear(locale, QLocale::ShortFormat), 0056 QStringLiteral("yyyy-MM-dd"), 0057 }; 0058 0059 QDate date; 0060 for (const auto &format : formats) { 0061 date = locale.toDate(text, format); 0062 if (date.isValid()) { 0063 break; 0064 } 0065 } 0066 if (!date.isValid()) { 0067 qCDebug(KWidgetsAddonsLog) << "Could not parse text as date:" << text; 0068 } 0069 return date; 0070 } 0071 0072 private: 0073 KDatePicker *const picker; 0074 }; 0075 0076 // Week numbers are defined by ISO 8601 0077 // See http://www.merlyn.demon.co.uk/weekinfo.htm for details 0078 0079 KDatePickerPrivateYearSelector::KDatePickerPrivateYearSelector(const QDate ¤tDate, QWidget *parent) 0080 : QLineEdit(parent) 0081 , val(new QIntValidator(this)) 0082 , result(0) 0083 , oldDate{currentDate} 0084 { 0085 setFont(QFontDatabase::systemFont(QFontDatabase::GeneralFont)); 0086 0087 setFrame(false); 0088 0089 // TODO: Find a way to get that from QLocale 0090 // val->setRange( calendar->year( calendar->earliestValidDate() ), 0091 // calendar->year( calendar->latestValidDate() ) ); 0092 setValidator(val); 0093 0094 connect(this, &QLineEdit::returnPressed, this, &KDatePickerPrivateYearSelector::yearEnteredSlot); 0095 } 0096 0097 void KDatePickerPrivateYearSelector::yearEnteredSlot() 0098 { 0099 bool ok; 0100 int newYear; 0101 0102 // check if entered value is a number 0103 newYear = text().toInt(&ok); 0104 if (!ok) { 0105 QApplication::beep(); 0106 return; 0107 } 0108 0109 // check if new year will lead to a valid date 0110 if (QDate(newYear, oldDate.month(), oldDate.day()).isValid()) { 0111 result = newYear; 0112 Q_EMIT closeMe(1); 0113 } else { 0114 QApplication::beep(); 0115 } 0116 } 0117 0118 int KDatePickerPrivateYearSelector::year() 0119 { 0120 return result; 0121 } 0122 0123 void KDatePickerPrivateYearSelector::setYear(const QDate &year) 0124 { 0125 setText(locale().toString(year, QStringLiteral("yyyy")).rightJustified(4, QLatin1Char('0'))); 0126 } 0127 0128 class KDatePickerPrivate 0129 { 0130 Q_DECLARE_TR_FUNCTIONS(KDatePicker) 0131 0132 public: 0133 explicit KDatePickerPrivate(KDatePicker *qq) 0134 : q(qq) 0135 { 0136 } 0137 0138 void fillWeeksCombo(); 0139 QDate validDateInYearMonth(int year, int month); 0140 0141 /// the date table 0142 KDatePicker *q; 0143 0144 QToolButton *closeButton = nullptr; 0145 QComboBox *selectWeek = nullptr; 0146 QToolButton *todayButton = nullptr; 0147 QBoxLayout *navigationLayout = nullptr; 0148 0149 /// the year forward button 0150 QToolButton *yearForward = nullptr; 0151 /// the year backward button 0152 QToolButton *yearBackward = nullptr; 0153 /// the month forward button 0154 QToolButton *monthForward = nullptr; 0155 /// the month backward button 0156 QToolButton *monthBackward = nullptr; 0157 /// the button for selecting the month directly 0158 QToolButton *selectMonth = nullptr; 0159 /// the button for selecting the year directly 0160 QToolButton *selectYear = nullptr; 0161 /// the line edit to enter the date directly 0162 QLineEdit *line = nullptr; 0163 /// the validator for the line edit: 0164 DatePickerValidator *val = nullptr; 0165 /// the date table 0166 KDateTable *table = nullptr; 0167 /// the widest month string in pixels: 0168 QSize maxMonthRect; 0169 0170 /// the font size for the widget 0171 int fontsize = -1; 0172 }; 0173 0174 void KDatePickerPrivate::fillWeeksCombo() 0175 { 0176 // every year can have a different number of weeks 0177 // it could be that we had 53,1..52 and now 1..53 which is the same number but different 0178 // so always fill with new values 0179 // We show all week numbers for all weeks between first day of year to last day of year 0180 // This of course can be a list like 53,1,2..52 0181 0182 const QDate thisDate = q->date(); 0183 const int thisYear = thisDate.year(); 0184 QDate day(thisDate.year(), 1, 1); 0185 const QDate lastDayOfYear = QDate(thisDate.year() + 1, 1, 1).addDays(-1); 0186 0187 selectWeek->clear(); 0188 0189 // Starting from the first day in the year, loop through the year a week at a time 0190 // adding an entry to the week combo for each week in the year 0191 0192 for (; day.isValid() && day <= lastDayOfYear; day = day.addDays(7)) { 0193 // Get the ISO week number for the current day and what year that week is in 0194 // e.g. 1st day of this year may fall in week 53 of previous year 0195 int weekYear = thisYear; 0196 const int week = day.weekNumber(&weekYear); 0197 QString weekString = tr("Week %1").arg(q->locale().toString(week)); 0198 0199 // show that this is a week from a different year 0200 if (weekYear != thisYear) { 0201 weekString += QLatin1Char('*'); 0202 } 0203 0204 // when the week is selected, go to the same weekday as the one 0205 // that is currently selected in the date table 0206 QDate targetDate = day.addDays(thisDate.dayOfWeek() - day.dayOfWeek()); 0207 selectWeek->addItem(weekString, targetDate); 0208 0209 // make sure that the week of the lastDayOfYear is always inserted: in Chinese calendar 0210 // system, this is not always the case 0211 if (day < lastDayOfYear // 0212 && day.daysTo(lastDayOfYear) < 7 // 0213 && lastDayOfYear.weekNumber() != day.weekNumber()) { 0214 day = lastDayOfYear.addDays(-7); 0215 } 0216 } 0217 } 0218 0219 QDate KDatePickerPrivate::validDateInYearMonth(int year, int month) 0220 { 0221 QDate newDate; 0222 0223 // Try to create a valid date in this year and month 0224 // First try the first of the month, then try last of month 0225 if (QDate(year, month, 1).isValid()) { 0226 newDate = QDate(year, month, 1); 0227 } else if (QDate(year, month + 1, 1).isValid()) { 0228 newDate = QDate(year, month + 1, 1).addDays(-1); 0229 } else { 0230 newDate = QDate::fromJulianDay(0); 0231 } 0232 0233 return newDate; 0234 } 0235 0236 KDatePicker::KDatePicker(QWidget *parent) 0237 : QFrame(parent) 0238 , d(new KDatePickerPrivate(this)) 0239 { 0240 initWidget(QDate::currentDate()); 0241 } 0242 0243 KDatePicker::KDatePicker(const QDate &date_, QWidget *parent) 0244 : QFrame(parent) 0245 , d(new KDatePickerPrivate(this)) 0246 { 0247 initWidget(date_); 0248 } 0249 0250 void KDatePicker::initWidget(const QDate &date_) 0251 { 0252 const int horizontalSpacing = style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing); 0253 0254 QBoxLayout *topLayout = new QVBoxLayout(this); 0255 topLayout->setSpacing(0); 0256 topLayout->setContentsMargins(0, 0, 0, 0); 0257 0258 d->navigationLayout = new QHBoxLayout(); 0259 d->navigationLayout->setSpacing(0); 0260 d->navigationLayout->setContentsMargins(0, 0, 0, 0); 0261 topLayout->addLayout(d->navigationLayout); 0262 d->navigationLayout->addStretch(); 0263 d->yearBackward = new QToolButton(this); 0264 d->yearBackward->setAutoRaise(true); 0265 d->navigationLayout->addWidget(d->yearBackward); 0266 d->monthBackward = new QToolButton(this); 0267 d->monthBackward->setAutoRaise(true); 0268 d->navigationLayout->addWidget(d->monthBackward); 0269 d->navigationLayout->addSpacing(horizontalSpacing); 0270 0271 d->selectMonth = new QToolButton(this); 0272 d->selectMonth->setAutoRaise(true); 0273 d->navigationLayout->addWidget(d->selectMonth); 0274 d->selectYear = new QToolButton(this); 0275 d->selectYear->setCheckable(true); 0276 d->selectYear->setAutoRaise(true); 0277 d->navigationLayout->addWidget(d->selectYear); 0278 d->navigationLayout->addSpacing(horizontalSpacing); 0279 0280 d->monthForward = new QToolButton(this); 0281 d->monthForward->setAutoRaise(true); 0282 d->navigationLayout->addWidget(d->monthForward); 0283 d->yearForward = new QToolButton(this); 0284 d->yearForward->setAutoRaise(true); 0285 d->navigationLayout->addWidget(d->yearForward); 0286 d->navigationLayout->addStretch(); 0287 0288 d->line = new QLineEdit(this); 0289 d->val = new DatePickerValidator(this); 0290 d->table = new KDateTable(this); 0291 setFocusProxy(d->table); 0292 0293 d->fontsize = QFontDatabase::systemFont(QFontDatabase::GeneralFont).pointSize(); 0294 if (d->fontsize == -1) { 0295 d->fontsize = QFontInfo(QFontDatabase::systemFont(QFontDatabase::GeneralFont)).pointSize(); 0296 } 0297 0298 d->fontsize++; // Make a little bigger 0299 0300 d->selectWeek = new QComboBox(this); // read only week selection 0301 d->selectWeek->setFocusPolicy(Qt::NoFocus); 0302 d->todayButton = new QToolButton(this); 0303 d->todayButton->setIcon(QIcon::fromTheme(QStringLiteral("go-jump-today"))); 0304 0305 d->yearForward->setToolTip(tr("Next year", "@info:tooltip")); 0306 d->yearBackward->setToolTip(tr("Previous year", "@info:tooltip")); 0307 d->monthForward->setToolTip(tr("Next month", "@info:tooltip")); 0308 d->monthBackward->setToolTip(tr("Previous month", "@info:tooltip")); 0309 d->selectWeek->setToolTip(tr("Select a week", "@info:tooltip")); 0310 d->selectMonth->setToolTip(tr("Select a month", "@info:tooltip")); 0311 d->selectYear->setToolTip(tr("Select a year", "@info:tooltip")); 0312 d->todayButton->setToolTip(tr("Select the current day", "@info:tooltip")); 0313 0314 // ----- 0315 setFontSize(d->fontsize); 0316 d->line->setValidator(d->val); 0317 d->line->installEventFilter(this); 0318 if (QApplication::isRightToLeft()) { 0319 d->yearForward->setIcon(QIcon::fromTheme(QStringLiteral("arrow-left-double"))); 0320 d->yearBackward->setIcon(QIcon::fromTheme(QStringLiteral("arrow-right-double"))); 0321 d->monthForward->setIcon(QIcon::fromTheme(QStringLiteral("arrow-left"))); 0322 d->monthBackward->setIcon(QIcon::fromTheme(QStringLiteral("arrow-right"))); 0323 } else { 0324 d->yearForward->setIcon(QIcon::fromTheme(QStringLiteral("arrow-right-double"))); 0325 d->yearBackward->setIcon(QIcon::fromTheme(QStringLiteral("arrow-left-double"))); 0326 d->monthForward->setIcon(QIcon::fromTheme(QStringLiteral("arrow-right"))); 0327 d->monthBackward->setIcon(QIcon::fromTheme(QStringLiteral("arrow-left"))); 0328 } 0329 0330 connect(d->table, &KDateTable::dateChanged, this, &KDatePicker::dateChangedSlot); 0331 connect(d->table, &KDateTable::tableClicked, this, &KDatePicker::tableClickedSlot); 0332 connect(d->monthForward, &QAbstractButton::clicked, this, &KDatePicker::monthForwardClicked); 0333 connect(d->monthBackward, &QAbstractButton::clicked, this, &KDatePicker::monthBackwardClicked); 0334 connect(d->yearForward, &QAbstractButton::clicked, this, &KDatePicker::yearForwardClicked); 0335 connect(d->yearBackward, &QAbstractButton::clicked, this, &KDatePicker::yearBackwardClicked); 0336 connect(d->selectWeek, qOverload<int>(&QComboBox::activated), this, &KDatePicker::weekSelected); 0337 connect(d->todayButton, &QAbstractButton::clicked, this, &KDatePicker::todayButtonClicked); 0338 connect(d->selectMonth, &QAbstractButton::clicked, this, &KDatePicker::selectMonthClicked); 0339 connect(d->selectYear, &QAbstractButton::toggled, this, &KDatePicker::selectYearClicked); 0340 connect(d->line, &QLineEdit::returnPressed, this, &KDatePicker::lineEnterPressed); 0341 0342 topLayout->addWidget(d->table); 0343 0344 QBoxLayout *bottomLayout = new QHBoxLayout(); 0345 bottomLayout->setContentsMargins(0, 0, 0, 0); 0346 bottomLayout->setSpacing(0); 0347 topLayout->addLayout(bottomLayout); 0348 0349 bottomLayout->addWidget(d->todayButton); 0350 bottomLayout->addWidget(d->line); 0351 bottomLayout->addWidget(d->selectWeek); 0352 0353 d->table->setDate(date_); 0354 dateChangedSlot(date_); // needed because table emits changed only when newDate != oldDate 0355 } 0356 0357 KDatePicker::~KDatePicker() = default; 0358 0359 bool KDatePicker::eventFilter(QObject *o, QEvent *e) 0360 { 0361 if (e->type() == QEvent::KeyPress) { 0362 QKeyEvent *k = (QKeyEvent *)e; 0363 0364 if ((k->key() == Qt::Key_PageUp) // 0365 || (k->key() == Qt::Key_PageDown) // 0366 || (k->key() == Qt::Key_Up) // 0367 || (k->key() == Qt::Key_Down)) { 0368 QApplication::sendEvent(d->table, e); 0369 d->table->setFocus(); 0370 return true; // eat event 0371 } 0372 } 0373 return QFrame::eventFilter(o, e); 0374 } 0375 0376 void KDatePicker::resizeEvent(QResizeEvent *e) 0377 { 0378 QWidget::resizeEvent(e); 0379 } 0380 0381 void KDatePicker::dateChangedSlot(const QDate &date_) 0382 { 0383 d->line->setText(locale().toString(date_, dateFormatWith4DigitYear(locale(), QLocale::ShortFormat))); 0384 d->selectMonth->setText(locale().standaloneMonthName(date_.month(), QLocale::LongFormat)); 0385 d->fillWeeksCombo(); 0386 0387 // calculate the item num in the week combo box; normalize selected day so as if 1.1. is the first day of the week 0388 QDate firstDay(date_.year(), 1, 1); 0389 // If we cannot successfully create the 1st of the year, this can only mean that 0390 // the 1st is before the earliest valid date in the current calendar system, so use 0391 // the earliestValidDate as the first day. 0392 // In particular covers the case of Gregorian where 1/1/-4713 is not a valid QDate 0393 d->selectWeek->setCurrentIndex((date_.dayOfYear() + firstDay.dayOfWeek() - 2) / 7); 0394 d->selectYear->setText(locale().toString(date_, QStringLiteral("yyyy")).rightJustified(4, QLatin1Char('0'))); 0395 0396 Q_EMIT dateChanged(date_); 0397 } 0398 0399 void KDatePicker::tableClickedSlot() 0400 { 0401 Q_EMIT dateSelected(date()); 0402 Q_EMIT tableClicked(); 0403 } 0404 0405 // TODO KF6: remove the const & from the returned QDate 0406 const QDate &KDatePicker::date() const 0407 { 0408 return d->table->date(); 0409 } 0410 0411 bool KDatePicker::setDate(const QDate &date_) 0412 { 0413 // the table setDate does validity checking for us 0414 // this also emits dateChanged() which then calls our dateChangedSlot() 0415 return d->table->setDate(date_); 0416 } 0417 0418 void KDatePicker::monthForwardClicked() 0419 { 0420 if (!setDate(date().addMonths(1))) { 0421 QApplication::beep(); 0422 } 0423 d->table->setFocus(); 0424 } 0425 0426 void KDatePicker::monthBackwardClicked() 0427 { 0428 if (!setDate(date().addMonths(-1))) { 0429 QApplication::beep(); 0430 } 0431 d->table->setFocus(); 0432 } 0433 0434 void KDatePicker::yearForwardClicked() 0435 { 0436 if (!setDate(d->table->date().addYears(1))) { 0437 QApplication::beep(); 0438 } 0439 d->table->setFocus(); 0440 } 0441 0442 void KDatePicker::yearBackwardClicked() 0443 { 0444 if (!setDate(d->table->date().addYears(-1))) { 0445 QApplication::beep(); 0446 } 0447 d->table->setFocus(); 0448 } 0449 0450 void KDatePicker::weekSelected(int index) 0451 { 0452 QDate targetDay = d->selectWeek->itemData(index).toDateTime().date(); 0453 0454 if (!setDate(targetDay)) { 0455 QApplication::beep(); 0456 } 0457 d->table->setFocus(); 0458 } 0459 0460 void KDatePicker::selectMonthClicked() 0461 { 0462 QDate thisDate(date()); 0463 d->table->setFocus(); 0464 0465 QMenu popup(d->selectMonth); 0466 // Populate the pick list with all the month names, this may change by year 0467 // JPL do we need to do something here for months that fall outside valid range? 0468 const int monthsInYear = QDate(thisDate.year() + 1, 1, 1).addDays(-1).month(); 0469 for (int m = 1; m <= monthsInYear; m++) { 0470 popup.addAction(locale().standaloneMonthName(m))->setData(m); 0471 } 0472 0473 QAction *item = popup.actions()[thisDate.month() - 1]; 0474 // if this happens the above should already given an assertion 0475 if (item) { 0476 popup.setActiveAction(item); 0477 } 0478 0479 // cancelled 0480 if ((item = popup.exec(d->selectMonth->mapToGlobal(QPoint(0, 0)), item)) == nullptr) { 0481 return; 0482 } 0483 0484 // We need to create a valid date in the month selected so we can find out how many days are 0485 // in the month. 0486 QDate newDate(thisDate.year(), item->data().toInt(), 1); 0487 0488 // If we have succeeded in creating a date in the new month, then try to create the new date, 0489 // checking we don't set a day after the last day of the month 0490 newDate.setDate(newDate.year(), newDate.month(), qMin(thisDate.day(), newDate.daysInMonth())); 0491 0492 // Set the date, if it's invalid in any way then alert user and don't update 0493 if (!setDate(newDate)) { 0494 QApplication::beep(); 0495 } 0496 } 0497 0498 void KDatePicker::selectYearClicked() 0499 { 0500 if (!d->selectYear->isChecked()) { 0501 return; 0502 } 0503 0504 QDate thisDate(date()); 0505 0506 KPopupFrame *popup = new KPopupFrame(this); 0507 KDatePickerPrivateYearSelector *picker = new KDatePickerPrivateYearSelector(date(), popup); 0508 picker->resize(picker->sizeHint()); 0509 picker->setYear(thisDate); 0510 picker->selectAll(); 0511 popup->setMainWidget(picker); 0512 connect(picker, &KDatePickerPrivateYearSelector::closeMe, popup, &KPopupFrame::close); 0513 picker->setFocus(); 0514 0515 if (popup->exec(d->selectYear->mapToGlobal(QPoint(0, d->selectMonth->height())))) { 0516 // We need to create a valid date in the year/month selected so we can find out how many 0517 // days are in the month. 0518 QDate newDate(picker->year(), thisDate.month(), 1); 0519 0520 // If we have succeeded in creating a date in the new month, then try to create the new 0521 // date, checking we don't set a day after the last day of the month 0522 newDate = QDate(newDate.year(), newDate.month(), qMin(thisDate.day(), newDate.daysInMonth())); 0523 0524 // Set the date, if it's invalid in any way then alert user and don't update 0525 if (!setDate(newDate)) { 0526 QApplication::beep(); 0527 } 0528 } 0529 delete popup; 0530 0531 d->selectYear->setChecked(false); 0532 } 0533 0534 void KDatePicker::uncheckYearSelector() 0535 { 0536 d->selectYear->setChecked(false); 0537 d->selectYear->update(); 0538 } 0539 0540 void KDatePicker::changeEvent(QEvent *event) 0541 { 0542 if (event && event->type() == QEvent::EnabledChange) { 0543 if (isEnabled()) { 0544 d->table->setFocus(); 0545 } 0546 } 0547 } 0548 0549 KDateTable *KDatePicker::dateTable() const 0550 { 0551 return d->table; 0552 } 0553 0554 void KDatePicker::lineEnterPressed() 0555 { 0556 const QDate newDate = d->val->toDate(d->line->text()); 0557 0558 if (newDate.isValid()) { 0559 Q_EMIT dateEntered(newDate); 0560 setDate(newDate); 0561 d->table->setFocus(); 0562 } else { 0563 QApplication::beep(); 0564 } 0565 } 0566 0567 void KDatePicker::todayButtonClicked() 0568 { 0569 setDate(QDate::currentDate()); 0570 d->table->setFocus(); 0571 } 0572 0573 QSize KDatePicker::sizeHint() const 0574 { 0575 return QWidget::sizeHint(); 0576 } 0577 0578 void KDatePicker::setFontSize(int s) 0579 { 0580 QWidget *const buttons[] = { 0581 d->selectMonth, 0582 d->selectYear, 0583 }; 0584 QFont font; 0585 QRect r; 0586 // ----- 0587 d->fontsize = s; 0588 for (QWidget *button : buttons) { 0589 font = button->font(); 0590 font.setPointSize(s); 0591 button->setFont(font); 0592 } 0593 d->table->setFontSize(s); 0594 0595 QFontMetrics metrics(d->selectMonth->fontMetrics()); 0596 QString longestMonth; 0597 0598 for (int i = 1;; ++i) { 0599 QString str = locale().standaloneMonthName(i, QLocale::LongFormat); 0600 if (str.isNull()) { 0601 break; 0602 } 0603 r = metrics.boundingRect(str); 0604 0605 if (r.width() > d->maxMonthRect.width()) { 0606 d->maxMonthRect.setWidth(r.width()); 0607 longestMonth = str; 0608 } 0609 if (r.height() > d->maxMonthRect.height()) { 0610 d->maxMonthRect.setHeight(r.height()); 0611 } 0612 } 0613 0614 QStyleOptionToolButton opt; 0615 opt.initFrom(d->selectMonth); 0616 opt.text = longestMonth; 0617 0618 // stolen from QToolButton 0619 QSize textSize = metrics.size(Qt::TextShowMnemonic, longestMonth); 0620 textSize.setWidth(textSize.width() + metrics.horizontalAdvance(QLatin1Char(' ')) * 2); 0621 int w = textSize.width(); 0622 int h = textSize.height(); 0623 opt.rect.setHeight(h); // PM_MenuButtonIndicator depends on the height 0624 0625 QSize metricBound = style()->sizeFromContents(QStyle::CT_ToolButton, &opt, QSize(w, h), d->selectMonth); 0626 0627 d->selectMonth->setMinimumSize(metricBound); 0628 } 0629 0630 int KDatePicker::fontSize() const 0631 { 0632 return d->fontsize; 0633 } 0634 0635 void KDatePicker::setCloseButton(bool enable) 0636 { 0637 if (enable == (d->closeButton != nullptr)) { 0638 return; 0639 } 0640 0641 if (enable) { 0642 d->closeButton = new QToolButton(this); 0643 d->closeButton->setAutoRaise(true); 0644 const int horizontalSpacing = style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing); 0645 d->navigationLayout->addSpacing(horizontalSpacing); 0646 d->navigationLayout->addWidget(d->closeButton); 0647 d->closeButton->setToolTip(tr("Close", "@action:button")); 0648 d->closeButton->setIcon(QIcon::fromTheme(QStringLiteral("window-close"))); 0649 connect(d->closeButton, &QAbstractButton::clicked, topLevelWidget(), &QWidget::close); 0650 } else { 0651 delete d->closeButton; 0652 d->closeButton = nullptr; 0653 } 0654 0655 updateGeometry(); 0656 } 0657 0658 bool KDatePicker::hasCloseButton() const 0659 { 0660 return (d->closeButton); 0661 } 0662 0663 #include "kdatepicker.moc"