KWidgetsAddons

kdatepickerpopup.cpp
1/*
2 SPDX-FileCopyrightText: 2004 Bram Schoenmakers <bramschoenmakers@kde.nl>
3 SPDX-License-Identifier: LGPL-2.0-or-later
4*/
5
6#include "kdatepickerpopup.h"
7#include "kdatepicker.h"
8#include "kdaterangecontrol_p.h"
9
10#include <QDateTime>
11#include <QLocale>
12#include <QWidgetAction>
13
14class KDatePickerAction : public QWidgetAction
15{
16public:
17 KDatePickerAction(KDatePicker *widget, QObject *parent)
19 , mDatePicker(widget)
20 , mOriginalParent(widget->parentWidget())
21 {
22 }
23
24protected:
25 QWidget *createWidget(QWidget *parent) override
26 {
27 mDatePicker->setParent(parent);
28 return mDatePicker;
29 }
30
31 void deleteWidget(QWidget *widget) override
32 {
33 if (widget != mDatePicker) {
34 return;
35 }
36
37 mDatePicker->setParent(mOriginalParent);
38 }
39
40private:
41 KDatePicker *const mDatePicker;
42 QWidget *const mOriginalParent;
43};
44
45class KDatePickerPopupPrivate : public KDateRangeControlPrivate
46{
47public:
48 explicit KDatePickerPopupPrivate(KDatePickerPopup *qq)
49 : q(qq)
50 {
51 }
52
53 void addMenuAction(const QString &text, const QDate &date);
54 void buildMenu();
55 void menuActionTriggered(QAction *action);
56 void slotDateChanged(QDate);
57
58 KDatePickerPopup *const q;
59 KDatePicker *mDatePicker = nullptr;
61 QMap<QDate, QString> m_dateMap;
62};
63
64void KDatePickerPopupPrivate::addMenuAction(const QString &text, const QDate &date)
65{
66 // skip out-of-range dates
67 // an invalid date is ok though, that's for the "No Date" action
68 if (date.isValid() && !isInDateRange(date)) {
69 return;
70 }
71
72 QAction *action = new QAction(q);
73 action->setText(text);
74 action->setData(date);
75 QObject::connect(action, &QAction::triggered, q, [this, action]() {
76 Q_EMIT q->dateChanged(action->data().toDate());
77 });
78 q->addAction(action);
79}
80
81void KDatePickerPopupPrivate::buildMenu()
82{
83 q->clear();
84
85 if (mModes & KDatePickerPopup::DatePicker) {
86 q->addAction(new KDatePickerAction(mDatePicker, q));
87
88 if ((mModes & KDatePickerPopup::NoDate) || (mModes & KDatePickerPopup::Words)) {
89 q->addSeparator();
90 }
91 }
92
93 if (mModes & KDatePickerPopup::Words) {
94 if (m_dateMap.isEmpty()) {
95 const QDate today = QDate::currentDate();
96 addMenuAction(KDatePickerPopup::tr("Next Year", "@option next year"), today.addYears(1));
97 addMenuAction(KDatePickerPopup::tr("Next Month", "@option next month"), today.addMonths(1));
98 addMenuAction(KDatePickerPopup::tr("Next Week", "@option next week"), today.addDays(7));
99 addMenuAction(KDatePickerPopup::tr("Tomorrow", "@option tomorrow"), today.addDays(1));
100 addMenuAction(KDatePickerPopup::tr("Today", "@option today"), today);
101 addMenuAction(KDatePickerPopup::tr("Yesterday", "@option yesterday"), today.addDays(-1));
102 addMenuAction(KDatePickerPopup::tr("Last Week", "@option last week"), today.addDays(-7));
103 addMenuAction(KDatePickerPopup::tr("Last Month", "@option last month"), today.addMonths(-1));
104 addMenuAction(KDatePickerPopup::tr("Last Year", "@option last year"), today.addYears(-1));
105 } else {
106 for (auto it = m_dateMap.constBegin(); it != m_dateMap.constEnd(); ++it) {
107 if (it.value().isEmpty()) {
108 addMenuAction(QLocale().toString(it.key()), it.key());
109 } else if (it.value().toLower() == QLatin1String("separator")) {
110 q->addSeparator();
111 } else {
112 addMenuAction(it.value(), it.key());
113 }
114 }
115 }
116
117 if (mModes & KDatePickerPopup::NoDate) {
118 q->addSeparator();
119 }
120 }
121
122 if (mModes & KDatePickerPopup::NoDate) {
123 addMenuAction(KDatePickerPopup::tr("No Date", "@option do not specify a date"), QDate());
124 }
125}
126
127void KDatePickerPopupPrivate::slotDateChanged(QDate date)
128{
129 Q_EMIT q->dateChanged(date);
130 q->hide();
131}
132
134 : QMenu(parent)
135 , d(new KDatePickerPopupPrivate(this))
136{
137 d->mModes = modes;
138
139 d->mDatePicker = new KDatePicker(this);
140 d->mDatePicker->setCloseButton(false);
141
142 connect(d->mDatePicker, &KDatePicker::dateEntered, this, [this](QDate date) {
143 d->slotDateChanged(date);
144 });
145 connect(d->mDatePicker, &KDatePicker::dateSelected, this, [this](QDate date) {
146 d->slotDateChanged(date);
147 });
148
149 d->mDatePicker->setDate(date);
150
151 connect(this, &QMenu::aboutToShow, this, [this]() {
152 d->buildMenu();
153 });
154}
155
157
159{
160 return d->mDatePicker;
161}
162
164{
165 d->mDatePicker->setDate(date);
166}
167
168KDatePickerPopup::Modes KDatePickerPopup::modes() const
169{
170 return d->mModes;
171}
172
174{
175 d->mModes = modes;
176}
177
178void KDatePickerPopup::setDateRange(const QDate &minDate, const QDate &maxDate)
179{
180 d->setDateRange(minDate, maxDate);
181}
182
184{
185 return d->m_dateMap;
186}
187
189{
190 d->m_dateMap = dateMap;
191}
192
193#include "moc_kdatepickerpopup.cpp"
This menu helps the user to select a date quickly.
void setDateRange(const QDate &minDate, const QDate &maxDate)
Sets the range of dates that can be accepted.
KDatePickerPopup(Modes modes=DatePicker, QDate date=QDate::currentDate(), QWidget *parent=nullptr)
Creates a new date picker popup.
void setDateMap(const QMap< QDate, QString > &dateMap)
Sets the list of dates in the drop-down menu that the user can select from and the text string to dis...
~KDatePickerPopup() override
Destroys the date picker popup.
KDatePicker * datePicker() const
Returns the used KDatePicker object.
QMap< QDate, QString > dateMap() const
Return the map of dates listed in the drop-down and their displayed string forms.
@ Words
A menu-item with list of words that describe a date.
@ NoDate
A menu-item with "No Date". Will always return an invalid date.
@ DatePicker
A menu-item with a KDatePicker.
void dateChanged(const QDate &date)
This signal is emitted whenever the user has selected a new date.
void setModes(Modes modes)
Set the selection modes to use.
void setDate(QDate date)
Sets the current date.
A date selection widget.
Definition kdatepicker.h:40
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...
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...
char * toString(const EngineQuery &query)
QWidget * parentWidget() const const
QVariant data() const const
void setData(const QVariant &data)
void setText(const QString &text)
void triggered(bool checked)
QDate addDays(qint64 ndays) const const
QDate addMonths(int nmonths) const const
QDate addYears(int nyears) const const
QDate currentDate()
bool isValid(int year, int month, int day)
const_iterator constBegin() const const
const_iterator constEnd() const const
bool isEmpty() const const
QAction * addAction(const QIcon &icon, const QString &text, Functor functor, const QKeySequence &shortcut)
void aboutToShow()
QAction * addSeparator()
void clear()
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QObject * parent() const const
T qobject_cast(QObject *object)
QString tr(const char *sourceText, const char *disambiguation, int n)
QDate toDate() const const
void hide()
void setParent(QWidget *parent)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:14:43 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.