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 | |
14 | class KDatePickerAction : public QWidgetAction |
15 | { |
16 | public: |
17 | KDatePickerAction(KDatePicker *widget, QObject *parent) |
18 | : QWidgetAction(parent) |
19 | , mDatePicker(widget) |
20 | , mOriginalParent(widget->parentWidget()) |
21 | { |
22 | } |
23 | |
24 | protected: |
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 | |
40 | private: |
41 | KDatePicker *const mDatePicker; |
42 | QWidget *const mOriginalParent; |
43 | }; |
44 | |
45 | class : public KDateRangeControlPrivate |
46 | { |
47 | public: |
48 | explicit (KDatePickerPopup *qq) |
49 | : q(qq) |
50 | { |
51 | } |
52 | |
53 | void addMenuAction(const QString &text, const QDate &date); |
54 | void buildMenu(); |
55 | void (QAction *action); |
56 | void slotDateChanged(QDate); |
57 | |
58 | KDatePickerPopup *const ; |
59 | KDatePicker * = nullptr; |
60 | KDatePickerPopup::Modes ; |
61 | QMap<QDate, QString> ; |
62 | }; |
63 | |
64 | void KDatePickerPopupPrivate::(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(sender: action, signal: &QAction::triggered, context: q, slot: [this, action]() { |
76 | Q_EMIT q->dateChanged(date: action->data().toDate()); |
77 | }); |
78 | q->addAction(action); |
79 | } |
80 | |
81 | void KDatePickerPopupPrivate::() |
82 | { |
83 | q->clear(); |
84 | |
85 | if (mModes & KDatePickerPopup::DatePicker) { |
86 | q->addAction(action: 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(text: KDatePickerPopup::tr(s: "Next Year" , c: "@option next year" ), date: today.addYears(years: 1)); |
97 | addMenuAction(text: KDatePickerPopup::tr(s: "Next Month" , c: "@option next month" ), date: today.addMonths(months: 1)); |
98 | addMenuAction(text: KDatePickerPopup::tr(s: "Next Week" , c: "@option next week" ), date: today.addDays(days: 7)); |
99 | addMenuAction(text: KDatePickerPopup::tr(s: "Tomorrow" , c: "@option tomorrow" ), date: today.addDays(days: 1)); |
100 | addMenuAction(text: KDatePickerPopup::tr(s: "Today" , c: "@option today" ), date: today); |
101 | addMenuAction(text: KDatePickerPopup::tr(s: "Yesterday" , c: "@option yesterday" ), date: today.addDays(days: -1)); |
102 | addMenuAction(text: KDatePickerPopup::tr(s: "Last Week" , c: "@option last week" ), date: today.addDays(days: -7)); |
103 | addMenuAction(text: KDatePickerPopup::tr(s: "Last Month" , c: "@option last month" ), date: today.addMonths(months: -1)); |
104 | addMenuAction(text: KDatePickerPopup::tr(s: "Last Year" , c: "@option last year" ), date: today.addYears(years: -1)); |
105 | } else { |
106 | for (auto it = m_dateMap.constBegin(); it != m_dateMap.constEnd(); ++it) { |
107 | if (it.value().isEmpty()) { |
108 | addMenuAction(text: QLocale().toString(date: it.key()), date: it.key()); |
109 | } else if (it.value().toLower() == QLatin1String("separator" )) { |
110 | q->addSeparator(); |
111 | } else { |
112 | addMenuAction(text: it.value(), date: it.key()); |
113 | } |
114 | } |
115 | } |
116 | |
117 | if (mModes & KDatePickerPopup::NoDate) { |
118 | q->addSeparator(); |
119 | } |
120 | } |
121 | |
122 | if (mModes & KDatePickerPopup::NoDate) { |
123 | addMenuAction(text: KDatePickerPopup::tr(s: "No Date" , c: "@option do not specify a date" ), date: QDate()); |
124 | } |
125 | } |
126 | |
127 | void KDatePickerPopupPrivate::(QDate date) |
128 | { |
129 | Q_EMIT q->dateChanged(date); |
130 | q->hide(); |
131 | } |
132 | |
133 | KDatePickerPopup::(Modes modes, QDate date, QWidget *parent) |
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(sender: d->mDatePicker, signal: &KDatePicker::dateEntered, context: this, slot: [this](QDate date) { |
143 | d->slotDateChanged(date); |
144 | }); |
145 | connect(sender: d->mDatePicker, signal: &KDatePicker::dateSelected, context: this, slot: [this](QDate date) { |
146 | d->slotDateChanged(date); |
147 | }); |
148 | |
149 | d->mDatePicker->setDate(date); |
150 | |
151 | connect(sender: this, signal: &QMenu::aboutToShow, context: this, slot: [this]() { |
152 | d->buildMenu(); |
153 | }); |
154 | } |
155 | |
156 | KDatePickerPopup::() = default; |
157 | |
158 | KDatePicker *KDatePickerPopup::() const |
159 | { |
160 | return d->mDatePicker; |
161 | } |
162 | |
163 | void KDatePickerPopup::(QDate date) |
164 | { |
165 | d->mDatePicker->setDate(date); |
166 | } |
167 | |
168 | KDatePickerPopup::Modes KDatePickerPopup::() const |
169 | { |
170 | return d->mModes; |
171 | } |
172 | |
173 | void KDatePickerPopup::(KDatePickerPopup::Modes modes) |
174 | { |
175 | d->mModes = modes; |
176 | } |
177 | |
178 | void KDatePickerPopup::(const QDate &minDate, const QDate &maxDate) |
179 | { |
180 | d->setDateRange(minDate, maxDate); |
181 | } |
182 | |
183 | QMap<QDate, QString> KDatePickerPopup::() const |
184 | { |
185 | return d->m_dateMap; |
186 | } |
187 | |
188 | void KDatePickerPopup::(const QMap<QDate, QString> &dateMap) |
189 | { |
190 | d->m_dateMap = dateMap; |
191 | } |
192 | |
193 | #include "moc_kdatepickerpopup.cpp" |
194 | |