12#include "kdatepicker.h"
13#include "kdatepicker_p.h"
15#include "common_helpers_p.h"
16#include "kdatetable_p.h"
17#include <kpopupframe.h>
19#include <QApplication>
22#include <QFontDatabase>
29#include "loggingcategory.h"
30#include "moc_kdatepicker.cpp"
31#include "moc_kdatepicker_p.cpp"
56 QStringLiteral(
"yyyy-MM-dd"),
60 for (
const auto &format : formats) {
79KDatePickerPrivateYearSelector::KDatePickerPrivateYearSelector(
const QDate ¤tDate,
QWidget *parent)
83 , oldDate{currentDate}
97void KDatePickerPrivateYearSelector::yearEnteredSlot()
103 newYear = text().
toInt(&ok);
110 if (
QDate(newYear, oldDate.month(), oldDate.day()).
isValid()) {
118int KDatePickerPrivateYearSelector::year()
123void KDatePickerPrivateYearSelector::setYear(
const QDate &year)
125 setText(locale().
toString(year, QStringLiteral(
"yyyy")).rightJustified(4,
QLatin1Char(
'0')));
128class KDatePickerPrivate
138 void fillWeeksCombo();
139 QDate validDateInYearMonth(
int year,
int month);
164 DatePickerValidator *val =
nullptr;
166 KDateTable *table =
nullptr;
174void KDatePickerPrivate::fillWeeksCombo()
182 const QDate thisDate = q->date();
183 const int thisYear = thisDate.
year();
192 for (; day.isValid() && day <= lastDayOfYear; day = day.addDays(7)) {
195 int weekYear = thisYear;
196 const int week = day.weekNumber(&weekYear);
200 if (weekYear != thisYear) {
207 selectWeek->
addItem(weekString, targetDate);
211 if (day < lastDayOfYear
212 && day.daysTo(lastDayOfYear) < 7
213 && lastDayOfYear.
weekNumber() != day.weekNumber()) {
214 day = lastDayOfYear.
addDays(-7);
219QDate KDatePickerPrivate::validDateInYearMonth(
int year,
int month)
226 newDate =
QDate(year, month, 1);
238 , d(new KDatePickerPrivate(this))
245 , d(new KDatePickerPrivate(this))
250void KDatePicker::initWidget(
const QDate &date_)
256 topLayout->setContentsMargins(0, 0, 0, 0);
259 d->navigationLayout->setSpacing(0);
260 d->navigationLayout->setContentsMargins(0, 0, 0, 0);
261 topLayout->addLayout(d->navigationLayout);
262 d->navigationLayout->addStretch();
264 d->yearBackward->setAutoRaise(
true);
265 d->navigationLayout->addWidget(d->yearBackward);
267 d->monthBackward->setAutoRaise(
true);
268 d->navigationLayout->addWidget(d->monthBackward);
269 d->navigationLayout->addSpacing(horizontalSpacing);
272 d->selectMonth->setAutoRaise(
true);
273 d->navigationLayout->addWidget(d->selectMonth);
275 d->selectYear->setCheckable(
true);
276 d->selectYear->setAutoRaise(
true);
277 d->navigationLayout->addWidget(d->selectYear);
278 d->navigationLayout->addSpacing(horizontalSpacing);
281 d->monthForward->setAutoRaise(
true);
282 d->navigationLayout->addWidget(d->monthForward);
284 d->yearForward->setAutoRaise(
true);
285 d->navigationLayout->addWidget(d->yearForward);
286 d->navigationLayout->addStretch();
289 d->val =
new DatePickerValidator(
this);
290 d->table =
new KDateTable(
this);
294 if (d->fontsize == -1) {
305 d->yearForward->setToolTip(
tr(
"Next year",
"@info:tooltip"));
306 d->yearBackward->setToolTip(
tr(
"Previous year",
"@info:tooltip"));
307 d->monthForward->setToolTip(
tr(
"Next month",
"@info:tooltip"));
308 d->monthBackward->setToolTip(
tr(
"Previous month",
"@info:tooltip"));
309 d->selectWeek->setToolTip(
tr(
"Select a week",
"@info:tooltip"));
310 d->selectMonth->setToolTip(
tr(
"Select a month",
"@info:tooltip"));
311 d->selectYear->setToolTip(
tr(
"Select a year",
"@info:tooltip"));
312 d->todayButton->setToolTip(
tr(
"Select the current day",
"@info:tooltip"));
316 d->line->setValidator(d->val);
317 d->line->installEventFilter(
this);
319 d->yearForward->setIcon(
QIcon::fromTheme(QStringLiteral(
"arrow-left-double")));
320 d->yearBackward->setIcon(
QIcon::fromTheme(QStringLiteral(
"arrow-right-double")));
324 d->yearForward->setIcon(
QIcon::fromTheme(QStringLiteral(
"arrow-right-double")));
325 d->yearBackward->setIcon(
QIcon::fromTheme(QStringLiteral(
"arrow-left-double")));
330 connect(d->table, &KDateTable::dateChanged,
this, &KDatePicker::dateChangedSlot);
331 connect(d->table, &KDateTable::tableClicked,
this, &KDatePicker::tableClickedSlot);
353 d->table->setDate(
date_);
354 dateChangedSlot(
date_);
369 d->table->setFocus();
381void KDatePicker::dateChangedSlot(
const QDate &date_)
393 d->selectWeek->setCurrentIndex((
date_.dayOfYear() +
firstDay.dayOfWeek() - 2) / 7);
394 d->selectYear->setText(
locale().toString(
date_, QStringLiteral(
"yyyy")).rightJustified(4,
QLatin1Char(
'0')));
399void KDatePicker::tableClickedSlot()
406const QDate &KDatePicker::date()
const
408 return d->table->date();
415 return d->table->setDate(
date_);
418void KDatePicker::monthForwardClicked()
420 if (!
setDate(date().addMonths(1))) {
423 d->table->setFocus();
426void KDatePicker::monthBackwardClicked()
428 if (!
setDate(date().addMonths(-1))) {
431 d->table->setFocus();
434void KDatePicker::yearForwardClicked()
436 if (!
setDate(d->table->date().addYears(1))) {
439 d->table->setFocus();
442void KDatePicker::yearBackwardClicked()
444 if (!
setDate(d->table->date().addYears(-1))) {
447 d->table->setFocus();
450void KDatePicker::weekSelected(
int index)
452 QDate targetDay = d->selectWeek->itemData(index).toDateTime().date();
457 d->table->setFocus();
460void KDatePicker::selectMonthClicked()
463 d->table->setFocus();
465 QMenu popup(d->selectMonth);
469 for (
int m = 1;
m <= monthsInYear;
m++) {
470 popup.addAction(
locale().standaloneMonthName(
m))->setData(
m);
476 popup.setActiveAction(item);
480 if ((item = popup.exec(d->selectMonth->mapToGlobal(
QPoint(0, 0)), item)) ==
nullptr) {
498void KDatePicker::selectYearClicked()
500 if (!d->selectYear->isChecked()) {
508 picker->resize(picker->sizeHint());
515 if (popup->
exec(d->selectYear->mapToGlobal(
QPoint(0, d->selectMonth->height())))) {
531 d->selectYear->setChecked(
false);
534void KDatePicker::uncheckYearSelector()
536 d->selectYear->setChecked(
false);
537 d->selectYear->update();
540void KDatePicker::changeEvent(
QEvent *event)
544 d->table->setFocus();
549KDateTable *KDatePicker::dateTable()
const
554void KDatePicker::lineEnterPressed()
561 d->table->setFocus();
567void KDatePicker::todayButtonClicked()
570 d->table->setFocus();
588 for (
QWidget *button : buttons) {
589 font = button->font();
590 font.setPointSize(
s);
591 button->setFont(
font);
593 d->table->setFontSize(
s);
598 for (
int i = 1;; ++
i) {
605 if (
r.width() > d->maxMonthRect.width()) {
606 d->maxMonthRect.setWidth(
r.width());
609 if (
r.height() > d->maxMonthRect.height()) {
610 d->maxMonthRect.setHeight(
r.height());
615 opt.initFrom(d->selectMonth);
623 opt.rect.setHeight(h);
630int KDatePicker::fontSize()
const
637 if (enable == (d->closeButton !=
nullptr)) {
643 d->closeButton->setAutoRaise(
true);
645 d->navigationLayout->addSpacing(horizontalSpacing);
646 d->navigationLayout->addWidget(d->closeButton);
647 d->closeButton->setToolTip(
tr(
"Close",
"@action:button"));
651 delete d->closeButton;
652 d->closeButton =
nullptr;
660 return (d->closeButton);
663#include "kdatepicker.moc"
KDatePicker(QWidget *parent=nullptr)
The constructor.
bool setDate(const QDate &date)
Sets the date.
void dateEntered(const QDate &date)
This signal is emitted when enter is pressed and a VALID date has been entered before into the line e...
bool eventFilter(QObject *o, QEvent *e) override
to catch move keyEvents when QLineEdit has keyFocus
bool hasCloseButton() const
void dateSelected(const QDate &date)
This signal is emitted each time a day has been selected by clicking on the table (hitting a day in t...
void setFontSize(int)
Sets the font size of the widgets elements.
QSize sizeHint() const override
The size hint for date pickers.
~KDatePicker() override
The destructor.
void dateChanged(const QDate &date)
This signal is emitted each time the selected date is changed.
void setCloseButton(bool enable)
By calling this method with enable = true, KDatePicker will show a little close-button in the upper b...
void resizeEvent(QResizeEvent *) override
the resize event
void tableClicked()
This signal is emitted when the day has been selected by clicking on it in the table.
char * toString(const EngineQuery &query)
bool isValid(QStringView ifopt)
KGuiItem ok()
Returns the 'Ok' gui item.
QVariant data() const const
void activated(int index)
void addItem(const QIcon &icon, const QString &text, const QVariant &userData)
bool sendEvent(QObject *receiver, QEvent *event)
QDate addDays(qint64 ndays) const const
int dayOfWeek() const const
QDate fromJulianDay(qint64 jd)
bool isValid(int year, int month, int day)
int weekNumber(int *yearNumber) const const
int pointSize() const const
QFont systemFont(SystemFont type)
int pointSize() const const
virtual bool event(QEvent *e) override
QIcon fromTheme(const QString &name)
QDate toDate(const QString &string, FormatType format) const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
virtual bool eventFilter(QObject *watched, QEvent *event)
QObject * parent() const const
T qobject_cast(QObject *object)
QString tr(const char *sourceText, const char *disambiguation, int n)
QString arg(Args &&... args) const const
int toInt(bool *ok, int base) const const
PM_LayoutHorizontalSpacing
virtual int pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const const=0
virtual QSize sizeFromContents(ContentsType type, const QStyleOption *option, const QSize &contentsSize, const QWidget *widget) const const=0
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QLocale locale() const const
int toInt(bool *ok) const const