cf12defd28
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
664 lines
21 KiB
C++
664 lines
21 KiB
C++
/* -*- C++ -*-
|
|
This file is part of the KDE libraries
|
|
SPDX-FileCopyrightText: 1997 Tim D. Gilman <tdgilman@best.org>
|
|
SPDX-FileCopyrightText: 1998-2001 Mirko Boehm (mirko@kde.org)
|
|
SPDX-FileCopyrightText: 2007 John Layt <john@layt.net>
|
|
SPDX-FileCopyrightText: 2022 g10 Code GmbH
|
|
SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
|
|
|
|
SPDX-License-Identifier: LGPL-2.0-or-later
|
|
*/
|
|
|
|
#include "kdatepicker.h"
|
|
#include "kdatepicker_p.h"
|
|
|
|
#include "common_helpers_p.h"
|
|
#include "kdatetable_p.h"
|
|
#include <kpopupframe.h>
|
|
|
|
#include <QApplication>
|
|
#include <QComboBox>
|
|
#include <QFont>
|
|
#include <QFontDatabase>
|
|
#include <QKeyEvent>
|
|
#include <QLayout>
|
|
#include <QMenu>
|
|
#include <QStyle>
|
|
#include <QToolButton>
|
|
|
|
#include "loggingcategory.h"
|
|
#include "moc_kdatepicker.cpp"
|
|
#include "moc_kdatepicker_p.cpp"
|
|
|
|
class DatePickerValidator : public QValidator
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
explicit DatePickerValidator(KDatePicker *parent)
|
|
: QValidator(parent)
|
|
, picker(parent)
|
|
{
|
|
}
|
|
|
|
State validate(QString &text, int &) const override
|
|
{
|
|
return toDate(text).isValid() ? QValidator::Acceptable : QValidator::Intermediate;
|
|
}
|
|
|
|
QDate toDate(const QString &text) const
|
|
{
|
|
QLocale locale = picker->locale();
|
|
const QList<QString> formats{
|
|
locale.dateFormat(QLocale::LongFormat),
|
|
locale.dateFormat(QLocale::ShortFormat),
|
|
locale.dateFormat(QLocale::NarrowFormat),
|
|
dateFormatWith4DigitYear(locale, QLocale::ShortFormat),
|
|
QStringLiteral("yyyy-MM-dd"),
|
|
};
|
|
|
|
QDate date;
|
|
for (const auto &format : formats) {
|
|
date = locale.toDate(text, format);
|
|
if (date.isValid()) {
|
|
break;
|
|
}
|
|
}
|
|
if (!date.isValid()) {
|
|
qCDebug(KWidgetsAddonsLog) << "Could not parse text as date:" << text;
|
|
}
|
|
return date;
|
|
}
|
|
|
|
private:
|
|
KDatePicker *const picker;
|
|
};
|
|
|
|
// Week numbers are defined by ISO 8601
|
|
// See http://www.merlyn.demon.co.uk/weekinfo.htm for details
|
|
|
|
KDatePickerPrivateYearSelector::KDatePickerPrivateYearSelector(const QDate ¤tDate, QWidget *parent)
|
|
: QLineEdit(parent)
|
|
, val(new QIntValidator(this))
|
|
, result(0)
|
|
, oldDate{currentDate}
|
|
{
|
|
setFont(QFontDatabase::systemFont(QFontDatabase::GeneralFont));
|
|
|
|
setFrame(false);
|
|
|
|
// TODO: Find a way to get that from QLocale
|
|
// val->setRange( calendar->year( calendar->earliestValidDate() ),
|
|
// calendar->year( calendar->latestValidDate() ) );
|
|
setValidator(val);
|
|
|
|
connect(this, &QLineEdit::returnPressed, this, &KDatePickerPrivateYearSelector::yearEnteredSlot);
|
|
}
|
|
|
|
void KDatePickerPrivateYearSelector::yearEnteredSlot()
|
|
{
|
|
bool ok;
|
|
int newYear;
|
|
|
|
// check if entered value is a number
|
|
newYear = text().toInt(&ok);
|
|
if (!ok) {
|
|
QApplication::beep();
|
|
return;
|
|
}
|
|
|
|
// check if new year will lead to a valid date
|
|
if (QDate(newYear, oldDate.month(), oldDate.day()).isValid()) {
|
|
result = newYear;
|
|
Q_EMIT closeMe(1);
|
|
} else {
|
|
QApplication::beep();
|
|
}
|
|
}
|
|
|
|
int KDatePickerPrivateYearSelector::year()
|
|
{
|
|
return result;
|
|
}
|
|
|
|
void KDatePickerPrivateYearSelector::setYear(const QDate &year)
|
|
{
|
|
setText(locale().toString(year, QStringLiteral("yyyy")).rightJustified(4, QLatin1Char('0')));
|
|
}
|
|
|
|
class KDatePickerPrivate
|
|
{
|
|
Q_DECLARE_TR_FUNCTIONS(KDatePicker)
|
|
|
|
public:
|
|
explicit KDatePickerPrivate(KDatePicker *qq)
|
|
: q(qq)
|
|
{
|
|
}
|
|
|
|
void fillWeeksCombo();
|
|
QDate validDateInYearMonth(int year, int month);
|
|
|
|
/// the date table
|
|
KDatePicker *q;
|
|
|
|
QToolButton *closeButton = nullptr;
|
|
QComboBox *selectWeek = nullptr;
|
|
QToolButton *todayButton = nullptr;
|
|
QBoxLayout *navigationLayout = nullptr;
|
|
|
|
/// the year forward button
|
|
QToolButton *yearForward = nullptr;
|
|
/// the year backward button
|
|
QToolButton *yearBackward = nullptr;
|
|
/// the month forward button
|
|
QToolButton *monthForward = nullptr;
|
|
/// the month backward button
|
|
QToolButton *monthBackward = nullptr;
|
|
/// the button for selecting the month directly
|
|
QToolButton *selectMonth = nullptr;
|
|
/// the button for selecting the year directly
|
|
QToolButton *selectYear = nullptr;
|
|
/// the line edit to enter the date directly
|
|
QLineEdit *line = nullptr;
|
|
/// the validator for the line edit:
|
|
DatePickerValidator *val = nullptr;
|
|
/// the date table
|
|
KDateTable *table = nullptr;
|
|
/// the widest month string in pixels:
|
|
QSize maxMonthRect;
|
|
|
|
/// the font size for the widget
|
|
int fontsize = -1;
|
|
};
|
|
|
|
void KDatePickerPrivate::fillWeeksCombo()
|
|
{
|
|
// every year can have a different number of weeks
|
|
// it could be that we had 53,1..52 and now 1..53 which is the same number but different
|
|
// so always fill with new values
|
|
// We show all week numbers for all weeks between first day of year to last day of year
|
|
// This of course can be a list like 53,1,2..52
|
|
|
|
const QDate thisDate = q->date();
|
|
const int thisYear = thisDate.year();
|
|
QDate day(thisDate.year(), 1, 1);
|
|
const QDate lastDayOfYear = QDate(thisDate.year() + 1, 1, 1).addDays(-1);
|
|
|
|
selectWeek->clear();
|
|
|
|
// Starting from the first day in the year, loop through the year a week at a time
|
|
// adding an entry to the week combo for each week in the year
|
|
|
|
for (; day.isValid() && day <= lastDayOfYear; day = day.addDays(7)) {
|
|
// Get the ISO week number for the current day and what year that week is in
|
|
// e.g. 1st day of this year may fall in week 53 of previous year
|
|
int weekYear = thisYear;
|
|
const int week = day.weekNumber(&weekYear);
|
|
QString weekString = tr("Week %1").arg(q->locale().toString(week));
|
|
|
|
// show that this is a week from a different year
|
|
if (weekYear != thisYear) {
|
|
weekString += QLatin1Char('*');
|
|
}
|
|
|
|
// when the week is selected, go to the same weekday as the one
|
|
// that is currently selected in the date table
|
|
QDate targetDate = day.addDays(thisDate.dayOfWeek() - day.dayOfWeek());
|
|
selectWeek->addItem(weekString, targetDate);
|
|
|
|
// make sure that the week of the lastDayOfYear is always inserted: in Chinese calendar
|
|
// system, this is not always the case
|
|
if (day < lastDayOfYear //
|
|
&& day.daysTo(lastDayOfYear) < 7 //
|
|
&& lastDayOfYear.weekNumber() != day.weekNumber()) {
|
|
day = lastDayOfYear.addDays(-7);
|
|
}
|
|
}
|
|
}
|
|
|
|
QDate KDatePickerPrivate::validDateInYearMonth(int year, int month)
|
|
{
|
|
QDate newDate;
|
|
|
|
// Try to create a valid date in this year and month
|
|
// First try the first of the month, then try last of month
|
|
if (QDate(year, month, 1).isValid()) {
|
|
newDate = QDate(year, month, 1);
|
|
} else if (QDate(year, month + 1, 1).isValid()) {
|
|
newDate = QDate(year, month + 1, 1).addDays(-1);
|
|
} else {
|
|
newDate = QDate::fromJulianDay(0);
|
|
}
|
|
|
|
return newDate;
|
|
}
|
|
|
|
KDatePicker::KDatePicker(QWidget *parent)
|
|
: QFrame(parent)
|
|
, d(new KDatePickerPrivate(this))
|
|
{
|
|
initWidget(QDate::currentDate());
|
|
}
|
|
|
|
KDatePicker::KDatePicker(const QDate &date_, QWidget *parent)
|
|
: QFrame(parent)
|
|
, d(new KDatePickerPrivate(this))
|
|
{
|
|
initWidget(date_);
|
|
}
|
|
|
|
void KDatePicker::initWidget(const QDate &date_)
|
|
{
|
|
const int horizontalSpacing = style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing);
|
|
|
|
QBoxLayout *topLayout = new QVBoxLayout(this);
|
|
topLayout->setSpacing(0);
|
|
topLayout->setContentsMargins(0, 0, 0, 0);
|
|
|
|
d->navigationLayout = new QHBoxLayout();
|
|
d->navigationLayout->setSpacing(0);
|
|
d->navigationLayout->setContentsMargins(0, 0, 0, 0);
|
|
topLayout->addLayout(d->navigationLayout);
|
|
d->navigationLayout->addStretch();
|
|
d->yearBackward = new QToolButton(this);
|
|
d->yearBackward->setAutoRaise(true);
|
|
d->navigationLayout->addWidget(d->yearBackward);
|
|
d->monthBackward = new QToolButton(this);
|
|
d->monthBackward->setAutoRaise(true);
|
|
d->navigationLayout->addWidget(d->monthBackward);
|
|
d->navigationLayout->addSpacing(horizontalSpacing);
|
|
|
|
d->selectMonth = new QToolButton(this);
|
|
d->selectMonth->setAutoRaise(true);
|
|
d->navigationLayout->addWidget(d->selectMonth);
|
|
d->selectYear = new QToolButton(this);
|
|
d->selectYear->setCheckable(true);
|
|
d->selectYear->setAutoRaise(true);
|
|
d->navigationLayout->addWidget(d->selectYear);
|
|
d->navigationLayout->addSpacing(horizontalSpacing);
|
|
|
|
d->monthForward = new QToolButton(this);
|
|
d->monthForward->setAutoRaise(true);
|
|
d->navigationLayout->addWidget(d->monthForward);
|
|
d->yearForward = new QToolButton(this);
|
|
d->yearForward->setAutoRaise(true);
|
|
d->navigationLayout->addWidget(d->yearForward);
|
|
d->navigationLayout->addStretch();
|
|
|
|
d->line = new QLineEdit(this);
|
|
d->val = new DatePickerValidator(this);
|
|
d->table = new KDateTable(this);
|
|
setFocusProxy(d->table);
|
|
|
|
d->fontsize = QFontDatabase::systemFont(QFontDatabase::GeneralFont).pointSize();
|
|
if (d->fontsize == -1) {
|
|
d->fontsize = QFontInfo(QFontDatabase::systemFont(QFontDatabase::GeneralFont)).pointSize();
|
|
}
|
|
|
|
d->fontsize++; // Make a little bigger
|
|
|
|
d->selectWeek = new QComboBox(this); // read only week selection
|
|
d->selectWeek->setFocusPolicy(Qt::NoFocus);
|
|
d->todayButton = new QToolButton(this);
|
|
d->todayButton->setIcon(QIcon::fromTheme(QStringLiteral("go-jump-today")));
|
|
|
|
d->yearForward->setToolTip(tr("Next year", "@info:tooltip"));
|
|
d->yearBackward->setToolTip(tr("Previous year", "@info:tooltip"));
|
|
d->monthForward->setToolTip(tr("Next month", "@info:tooltip"));
|
|
d->monthBackward->setToolTip(tr("Previous month", "@info:tooltip"));
|
|
d->selectWeek->setToolTip(tr("Select a week", "@info:tooltip"));
|
|
d->selectMonth->setToolTip(tr("Select a month", "@info:tooltip"));
|
|
d->selectYear->setToolTip(tr("Select a year", "@info:tooltip"));
|
|
d->todayButton->setToolTip(tr("Select the current day", "@info:tooltip"));
|
|
|
|
// -----
|
|
setFontSize(d->fontsize);
|
|
d->line->setValidator(d->val);
|
|
d->line->installEventFilter(this);
|
|
if (QApplication::isRightToLeft()) {
|
|
d->yearForward->setIcon(QIcon::fromTheme(QStringLiteral("arrow-left-double")));
|
|
d->yearBackward->setIcon(QIcon::fromTheme(QStringLiteral("arrow-right-double")));
|
|
d->monthForward->setIcon(QIcon::fromTheme(QStringLiteral("arrow-left")));
|
|
d->monthBackward->setIcon(QIcon::fromTheme(QStringLiteral("arrow-right")));
|
|
} else {
|
|
d->yearForward->setIcon(QIcon::fromTheme(QStringLiteral("arrow-right-double")));
|
|
d->yearBackward->setIcon(QIcon::fromTheme(QStringLiteral("arrow-left-double")));
|
|
d->monthForward->setIcon(QIcon::fromTheme(QStringLiteral("arrow-right")));
|
|
d->monthBackward->setIcon(QIcon::fromTheme(QStringLiteral("arrow-left")));
|
|
}
|
|
|
|
connect(d->table, &KDateTable::dateChanged, this, &KDatePicker::dateChangedSlot);
|
|
connect(d->table, &KDateTable::tableClicked, this, &KDatePicker::tableClickedSlot);
|
|
connect(d->monthForward, &QAbstractButton::clicked, this, &KDatePicker::monthForwardClicked);
|
|
connect(d->monthBackward, &QAbstractButton::clicked, this, &KDatePicker::monthBackwardClicked);
|
|
connect(d->yearForward, &QAbstractButton::clicked, this, &KDatePicker::yearForwardClicked);
|
|
connect(d->yearBackward, &QAbstractButton::clicked, this, &KDatePicker::yearBackwardClicked);
|
|
connect(d->selectWeek, &QComboBox::activated, this, &KDatePicker::weekSelected);
|
|
connect(d->todayButton, &QAbstractButton::clicked, this, &KDatePicker::todayButtonClicked);
|
|
connect(d->selectMonth, &QAbstractButton::clicked, this, &KDatePicker::selectMonthClicked);
|
|
connect(d->selectYear, &QAbstractButton::toggled, this, &KDatePicker::selectYearClicked);
|
|
connect(d->line, &QLineEdit::returnPressed, this, &KDatePicker::lineEnterPressed);
|
|
|
|
topLayout->addWidget(d->table);
|
|
|
|
QBoxLayout *bottomLayout = new QHBoxLayout();
|
|
bottomLayout->setContentsMargins(0, 0, 0, 0);
|
|
bottomLayout->setSpacing(0);
|
|
topLayout->addLayout(bottomLayout);
|
|
|
|
bottomLayout->addWidget(d->todayButton);
|
|
bottomLayout->addWidget(d->line);
|
|
bottomLayout->addWidget(d->selectWeek);
|
|
|
|
d->table->setDate(date_);
|
|
dateChangedSlot(date_); // needed because table emits changed only when newDate != oldDate
|
|
}
|
|
|
|
KDatePicker::~KDatePicker() = default;
|
|
|
|
bool KDatePicker::eventFilter(QObject *o, QEvent *e)
|
|
{
|
|
if (e->type() == QEvent::KeyPress) {
|
|
QKeyEvent *k = (QKeyEvent *)e;
|
|
|
|
if ((k->key() == Qt::Key_PageUp) //
|
|
|| (k->key() == Qt::Key_PageDown) //
|
|
|| (k->key() == Qt::Key_Up) //
|
|
|| (k->key() == Qt::Key_Down)) {
|
|
QApplication::sendEvent(d->table, e);
|
|
d->table->setFocus();
|
|
return true; // eat event
|
|
}
|
|
}
|
|
return QFrame::eventFilter(o, e);
|
|
}
|
|
|
|
void KDatePicker::resizeEvent(QResizeEvent *e)
|
|
{
|
|
QWidget::resizeEvent(e);
|
|
}
|
|
|
|
void KDatePicker::dateChangedSlot(const QDate &date_)
|
|
{
|
|
d->line->setText(locale().toString(date_, dateFormatWith4DigitYear(locale(), QLocale::ShortFormat)));
|
|
d->selectMonth->setText(locale().standaloneMonthName(date_.month(), QLocale::LongFormat));
|
|
d->fillWeeksCombo();
|
|
|
|
// calculate the item num in the week combo box; normalize selected day so as if 1.1. is the first day of the week
|
|
QDate firstDay(date_.year(), 1, 1);
|
|
// If we cannot successfully create the 1st of the year, this can only mean that
|
|
// the 1st is before the earliest valid date in the current calendar system, so use
|
|
// the earliestValidDate as the first day.
|
|
// In particular covers the case of Gregorian where 1/1/-4713 is not a valid QDate
|
|
d->selectWeek->setCurrentIndex((date_.dayOfYear() + firstDay.dayOfWeek() - 2) / 7);
|
|
d->selectYear->setText(locale().toString(date_, QStringLiteral("yyyy")).rightJustified(4, QLatin1Char('0')));
|
|
|
|
Q_EMIT dateChanged(date_);
|
|
}
|
|
|
|
void KDatePicker::tableClickedSlot()
|
|
{
|
|
Q_EMIT dateSelected(date());
|
|
Q_EMIT tableClicked();
|
|
}
|
|
|
|
// TODO KF6: remove the const & from the returned QDate
|
|
const QDate &KDatePicker::date() const
|
|
{
|
|
return d->table->date();
|
|
}
|
|
|
|
bool KDatePicker::setDate(const QDate &date_)
|
|
{
|
|
// the table setDate does validity checking for us
|
|
// this also emits dateChanged() which then calls our dateChangedSlot()
|
|
return d->table->setDate(date_);
|
|
}
|
|
|
|
void KDatePicker::monthForwardClicked()
|
|
{
|
|
if (!setDate(date().addMonths(1))) {
|
|
QApplication::beep();
|
|
}
|
|
d->table->setFocus();
|
|
}
|
|
|
|
void KDatePicker::monthBackwardClicked()
|
|
{
|
|
if (!setDate(date().addMonths(-1))) {
|
|
QApplication::beep();
|
|
}
|
|
d->table->setFocus();
|
|
}
|
|
|
|
void KDatePicker::yearForwardClicked()
|
|
{
|
|
if (!setDate(d->table->date().addYears(1))) {
|
|
QApplication::beep();
|
|
}
|
|
d->table->setFocus();
|
|
}
|
|
|
|
void KDatePicker::yearBackwardClicked()
|
|
{
|
|
if (!setDate(d->table->date().addYears(-1))) {
|
|
QApplication::beep();
|
|
}
|
|
d->table->setFocus();
|
|
}
|
|
|
|
void KDatePicker::weekSelected(int index)
|
|
{
|
|
QDate targetDay = d->selectWeek->itemData(index).toDateTime().date();
|
|
|
|
if (!setDate(targetDay)) {
|
|
QApplication::beep();
|
|
}
|
|
d->table->setFocus();
|
|
}
|
|
|
|
void KDatePicker::selectMonthClicked()
|
|
{
|
|
QDate thisDate(date());
|
|
d->table->setFocus();
|
|
|
|
QMenu popup(d->selectMonth);
|
|
// Populate the pick list with all the month names, this may change by year
|
|
// JPL do we need to do something here for months that fall outside valid range?
|
|
const int monthsInYear = QDate(thisDate.year() + 1, 1, 1).addDays(-1).month();
|
|
for (int m = 1; m <= monthsInYear; m++) {
|
|
popup.addAction(locale().standaloneMonthName(m))->setData(m);
|
|
}
|
|
|
|
QAction *item = popup.actions()[thisDate.month() - 1];
|
|
// if this happens the above should already given an assertion
|
|
if (item) {
|
|
popup.setActiveAction(item);
|
|
}
|
|
|
|
// cancelled
|
|
if ((item = popup.exec(d->selectMonth->mapToGlobal(QPoint(0, 0)), item)) == nullptr) {
|
|
return;
|
|
}
|
|
|
|
// We need to create a valid date in the month selected so we can find out how many days are
|
|
// in the month.
|
|
QDate newDate(thisDate.year(), item->data().toInt(), 1);
|
|
|
|
// If we have succeeded in creating a date in the new month, then try to create the new date,
|
|
// checking we don't set a day after the last day of the month
|
|
newDate.setDate(newDate.year(), newDate.month(), qMin(thisDate.day(), newDate.daysInMonth()));
|
|
|
|
// Set the date, if it's invalid in any way then alert user and don't update
|
|
if (!setDate(newDate)) {
|
|
QApplication::beep();
|
|
}
|
|
}
|
|
|
|
void KDatePicker::selectYearClicked()
|
|
{
|
|
if (!d->selectYear->isChecked()) {
|
|
return;
|
|
}
|
|
|
|
QDate thisDate(date());
|
|
|
|
KPopupFrame *popup = new KPopupFrame(this);
|
|
KDatePickerPrivateYearSelector *picker = new KDatePickerPrivateYearSelector(date(), popup);
|
|
picker->resize(picker->sizeHint());
|
|
picker->setYear(thisDate);
|
|
picker->selectAll();
|
|
popup->setMainWidget(picker);
|
|
connect(picker, &KDatePickerPrivateYearSelector::closeMe, popup, &KPopupFrame::close);
|
|
picker->setFocus();
|
|
|
|
if (popup->exec(d->selectYear->mapToGlobal(QPoint(0, d->selectMonth->height())))) {
|
|
// We need to create a valid date in the year/month selected so we can find out how many
|
|
// days are in the month.
|
|
QDate newDate(picker->year(), thisDate.month(), 1);
|
|
|
|
// If we have succeeded in creating a date in the new month, then try to create the new
|
|
// date, checking we don't set a day after the last day of the month
|
|
newDate = QDate(newDate.year(), newDate.month(), qMin(thisDate.day(), newDate.daysInMonth()));
|
|
|
|
// Set the date, if it's invalid in any way then alert user and don't update
|
|
if (!setDate(newDate)) {
|
|
QApplication::beep();
|
|
}
|
|
}
|
|
delete popup;
|
|
|
|
d->selectYear->setChecked(false);
|
|
}
|
|
|
|
void KDatePicker::uncheckYearSelector()
|
|
{
|
|
d->selectYear->setChecked(false);
|
|
d->selectYear->update();
|
|
}
|
|
|
|
void KDatePicker::changeEvent(QEvent *event)
|
|
{
|
|
if (event && event->type() == QEvent::EnabledChange) {
|
|
if (isEnabled()) {
|
|
d->table->setFocus();
|
|
}
|
|
}
|
|
}
|
|
|
|
KDateTable *KDatePicker::dateTable() const
|
|
{
|
|
return d->table;
|
|
}
|
|
|
|
void KDatePicker::lineEnterPressed()
|
|
{
|
|
const QDate newDate = d->val->toDate(d->line->text());
|
|
|
|
if (newDate.isValid()) {
|
|
Q_EMIT dateEntered(newDate);
|
|
setDate(newDate);
|
|
d->table->setFocus();
|
|
} else {
|
|
QApplication::beep();
|
|
}
|
|
}
|
|
|
|
void KDatePicker::todayButtonClicked()
|
|
{
|
|
setDate(QDate::currentDate());
|
|
d->table->setFocus();
|
|
}
|
|
|
|
QSize KDatePicker::sizeHint() const
|
|
{
|
|
return QWidget::sizeHint();
|
|
}
|
|
|
|
void KDatePicker::setFontSize(int s)
|
|
{
|
|
QWidget *const buttons[] = {
|
|
d->selectMonth,
|
|
d->selectYear,
|
|
};
|
|
QFont font;
|
|
QRect r;
|
|
// -----
|
|
d->fontsize = s;
|
|
for (QWidget *button : buttons) {
|
|
font = button->font();
|
|
font.setPointSize(s);
|
|
button->setFont(font);
|
|
}
|
|
d->table->setFontSize(s);
|
|
|
|
QFontMetrics metrics(d->selectMonth->fontMetrics());
|
|
QString longestMonth;
|
|
|
|
for (int i = 1;; ++i) {
|
|
QString str = locale().standaloneMonthName(i, QLocale::LongFormat);
|
|
if (str.isNull()) {
|
|
break;
|
|
}
|
|
r = metrics.boundingRect(str);
|
|
|
|
if (r.width() > d->maxMonthRect.width()) {
|
|
d->maxMonthRect.setWidth(r.width());
|
|
longestMonth = str;
|
|
}
|
|
if (r.height() > d->maxMonthRect.height()) {
|
|
d->maxMonthRect.setHeight(r.height());
|
|
}
|
|
}
|
|
|
|
QStyleOptionToolButton opt;
|
|
opt.initFrom(d->selectMonth);
|
|
opt.text = longestMonth;
|
|
|
|
// stolen from QToolButton
|
|
QSize textSize = metrics.size(Qt::TextShowMnemonic, longestMonth);
|
|
textSize.setWidth(textSize.width() + metrics.horizontalAdvance(QLatin1Char(' ')) * 2);
|
|
int w = textSize.width();
|
|
int h = textSize.height();
|
|
opt.rect.setHeight(h); // PM_MenuButtonIndicator depends on the height
|
|
|
|
QSize metricBound = style()->sizeFromContents(QStyle::CT_ToolButton, &opt, QSize(w, h), d->selectMonth);
|
|
|
|
d->selectMonth->setMinimumSize(metricBound);
|
|
}
|
|
|
|
int KDatePicker::fontSize() const
|
|
{
|
|
return d->fontsize;
|
|
}
|
|
|
|
void KDatePicker::setCloseButton(bool enable)
|
|
{
|
|
if (enable == (d->closeButton != nullptr)) {
|
|
return;
|
|
}
|
|
|
|
if (enable) {
|
|
d->closeButton = new QToolButton(this);
|
|
d->closeButton->setAutoRaise(true);
|
|
const int horizontalSpacing = style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing);
|
|
d->navigationLayout->addSpacing(horizontalSpacing);
|
|
d->navigationLayout->addWidget(d->closeButton);
|
|
d->closeButton->setToolTip(tr("Close", "@action:button"));
|
|
d->closeButton->setIcon(QIcon::fromTheme(QStringLiteral("window-close")));
|
|
connect(d->closeButton, &QAbstractButton::clicked, topLevelWidget(), &QWidget::close);
|
|
} else {
|
|
delete d->closeButton;
|
|
d->closeButton = nullptr;
|
|
}
|
|
|
|
updateGeometry();
|
|
}
|
|
|
|
bool KDatePicker::hasCloseButton() const
|
|
{
|
|
return (d->closeButton);
|
|
}
|
|
|
|
#include "kdatepicker.moc"
|