22 #include <QtGui/QAbstractItemView>
23 #include <QtGui/QApplication>
24 #include <QtGui/QKeyEvent>
25 #include <QtGui/QMenu>
26 #include <QtGui/QLineEdit>
27 #include <QtGui/QWidgetAction>
28 #include <QtCore/QVector>
37 class KDateComboBoxPrivate
42 virtual ~KDateComboBoxPrivate();
44 QDate defaultMinDate();
45 QDate defaultMaxDate();
47 QString formatDate(
const QDate &date);
49 void initDateWidget();
50 void addMenuAction(
const QString &text,
const QDate &date);
51 void enableMenuDates();
52 void updateDateWidget();
56 void selectDate(
QAction *action);
57 void editDate(
const QString &text);
58 void enterDate(
const QDate &date);
64 QVector<QAction*> m_actions;
69 KDateComboBox::Options m_options;
81 m_dateMenu(new
QMenu(q)),
84 m_displayFormat(
KLocale::ShortDate)
87 m_date.setDate(QDate::currentDate());
88 m_minDate = defaultMinDate();
89 m_maxDate = defaultMaxDate();
90 m_datePicker->setCloseButton(
false);
91 m_datePickerAction->setObjectName(QLatin1String(
"DatePicker"));
92 m_datePickerAction->setDefaultWidget(m_datePicker);
95 KDateComboBoxPrivate::~KDateComboBoxPrivate()
99 QDate KDateComboBoxPrivate::defaultMinDate()
101 return m_date.calendar()->earliestValidDate();
104 QDate KDateComboBoxPrivate::defaultMaxDate()
106 return m_date.calendar()->latestValidDate();
109 QString KDateComboBoxPrivate::formatDate(
const QDate &date)
111 return m_date.calendar()->formatDate(date, m_displayFormat);
114 void KDateComboBoxPrivate::initDateWidget()
116 q->blockSignals(
true);
126 q->setMaxVisibleItems(1);
128 q->setMaxVisibleItems(0);
131 q->setSizeAdjustPolicy(QComboBox::AdjustToContents);
132 q->addItem(m_date.formatDate(m_displayFormat));
133 q->setCurrentIndex(0);
134 q->setSizeAdjustPolicy(QComboBox::AdjustToContentsOnFirstShow);
135 q->blockSignals(
false);
140 if ((m_options & KDateComboBox::SelectDate) == KDateComboBox::SelectDate) {
142 if ((m_options & KDateComboBox::DatePicker) == KDateComboBox::DatePicker) {
143 m_dateMenu->addAction(m_datePickerAction);
144 m_dateMenu->addSeparator();
148 if (m_dateMap.isEmpty()) {
149 addMenuAction(
i18nc(
"@option next year",
"Next Year" ), m_date.addYears(1).date());
150 addMenuAction(
i18nc(
"@option next month",
"Next Month"), m_date.addMonths(1).date());
151 addMenuAction(
i18nc(
"@option next week",
"Next Week" ), m_date.addDays(m_date.daysInWeek()).date());
152 addMenuAction(
i18nc(
"@option tomorrow",
"Tomorrow" ), m_date.addDays(1).date());
153 addMenuAction(
i18nc(
"@option today",
"Today" ), m_date.date());
154 addMenuAction(
i18nc(
"@option yesterday",
"Yesterday" ), m_date.addDays(-1).date());
155 addMenuAction(
i18nc(
"@option last week",
"Last Week" ), m_date.addDays(-m_date.daysInWeek()).date());
156 addMenuAction(
i18nc(
"@option last month",
"Last Month"), m_date.addMonths(-1).date());
157 addMenuAction(
i18nc(
"@option last year",
"Last Year" ), m_date.addYears(-1).date());
158 m_dateMenu->addSeparator();
159 addMenuAction(
i18nc(
"@option do not specify a date",
"No Date"), QDate());
161 QMapIterator<QDate, QString> i(m_dateMap);
162 while (i.hasNext()) {
164 if (i.value().isEmpty()) {
165 addMenuAction(formatDate(i.key()), i.key());
166 }
else if (i.value().toLower() == QLatin1String(
"separator")) {
167 m_dateMenu->addSeparator();
169 addMenuAction(i.value(), i.key());
178 void KDateComboBoxPrivate::addMenuAction(
const QString &text,
const QDate &date)
181 action->setText(text);
182 action->setData(date);
183 m_dateMenu->addAction(action);
187 void KDateComboBoxPrivate::enableMenuDates()
190 for (
int i = 0; i < m_actions.count(); ++i) {
191 QDate date = m_actions[i]->data().toDate();
192 m_actions[i]->setVisible(!date.isValid() || (date >= m_minDate && date <= m_maxDate));
196 void KDateComboBoxPrivate::updateDateWidget()
198 q->blockSignals(
true);
199 m_datePicker->blockSignals(
true);
200 m_datePicker->
setDate(m_date.date());
202 q->setItemText(0, m_date.formatDate(m_displayFormat));
203 q->lineEdit()->setText(m_date.formatDate(m_displayFormat));
204 q->lineEdit()->setCursorPosition(pos);
205 m_datePicker->blockSignals(
false);
206 q->blockSignals(
false);
209 void KDateComboBoxPrivate::selectDate(
QAction *action)
211 if (action->objectName() != QLatin1String(
"DatePicker")) {
212 enterDate(action->data().toDate());
216 void KDateComboBoxPrivate::clickDate()
218 enterDate(m_datePicker->date());
221 void KDateComboBoxPrivate::editDate(
const QString &text)
223 m_warningShown =
false;
224 emit q->
dateEdited(m_date.readDate(text).date());
227 void KDateComboBoxPrivate::parseDate()
229 m_date.setDate(m_date.readDate(q->lineEdit()->text()).date());
232 void KDateComboBoxPrivate::enterDate(
const QDate &date)
236 q->blockSignals(
true);
238 q->setSizeAdjustPolicy(QComboBox::AdjustToContents);
239 q->addItem(m_date.formatDate(m_displayFormat));
240 q->setCurrentIndex(0);
241 q->setSizeAdjustPolicy(QComboBox::AdjustToContentsOnFirstShow);
242 q->blockSignals(
false);
249 void KDateComboBoxPrivate::warnDate()
251 if (!m_warningShown && !q->
isValid() &&
254 if (!m_date.date().isValid()) {
255 warnMsg =
i18nc(
"@info",
"The date you entered is invalid");
256 }
else if (m_date.date() < m_minDate) {
257 if (m_minWarnMsg.isEmpty()) {
258 warnMsg =
i18nc(
"@info",
"Date cannot be earlier than %1", formatDate(m_minDate));
260 warnMsg = m_minWarnMsg;
261 warnMsg.replace(
"%1", formatDate(m_minDate));
263 }
else if (m_date.date() > m_maxDate) {
264 if (m_maxWarnMsg.isEmpty()) {
265 warnMsg =
i18nc(
"@info",
"Date cannot be later than %1", formatDate(m_maxDate));
267 warnMsg = m_maxWarnMsg;
268 warnMsg.replace(
"%1", formatDate(m_maxDate));
271 m_warningShown =
true;
279 d(new KDateComboBoxPrivate(this))
282 setMaxVisibleItems(1);
283 setInsertPolicy(QComboBox::NoInsert);
284 d->m_datePicker->installEventFilter(
this);
286 d->updateDateWidget();
288 connect(d->m_dateMenu, SIGNAL(triggered(
QAction*)),
289 this, SLOT(selectDate(
QAction*)));
290 connect(
this, SIGNAL(editTextChanged(
QString)),
291 this, SLOT(editDate(
QString)));
292 connect(d->m_datePicker, SIGNAL(
dateEntered(QDate)),
293 this, SLOT(enterDate(QDate)));
294 connect(d->m_datePicker, SIGNAL(tableClicked()),
295 this, SLOT(clickDate()));
306 return d->m_date.date();
311 if (date == d->m_date.date()) {
316 d->updateDateWidget();
327 return d->m_date.calendarSystem();
332 if (calendarSystem != d->m_date.calendarSystem()) {
339 d->m_date.setCalendarSystem(calendarSystem);
344 return d->m_date.calendar();
355 return d->m_date.isValid() &&
356 d->m_date >= d->m_minDate &&
357 d->m_date <= d->m_maxDate;
362 return lineEdit()->text().isEmpty();
372 if (options != d->m_options) {
375 d->updateDateWidget();
386 setDateRange(minDate, d->m_maxDate, minWarnMsg, d->m_maxWarnMsg);
401 setDateRange(d->m_minDate, maxDate, d->m_minWarnMsg, maxWarnMsg);
410 const QDate &maxDate,
414 if (!minDate.isValid() || !maxDate.isValid() || minDate > maxDate) {
418 if (minDate != d->m_minDate || maxDate != d->m_maxDate ||
419 minWarnMsg != d->m_minWarnMsg || maxWarnMsg != d->m_maxWarnMsg) {
420 d->m_minDate = minDate;
421 d->m_maxDate = maxDate;
422 d->m_minWarnMsg = minWarnMsg;
423 d->m_maxWarnMsg = maxWarnMsg;
425 d->enableMenuDates();
435 return d->m_displayFormat;
440 if (format != d->m_displayFormat) {
441 d->m_displayFormat = format;
443 d->updateDateWidget();
454 if (dateMap != d->m_dateMap) {
455 d->m_dateMap.clear();
469 switch (keyEvent->key()) {
471 temp = d->m_date.addDays(-1).date();
474 temp = d->m_date.addDays(1).date();
476 case Qt::Key_PageDown:
477 temp = d->m_date.addMonths(-1).date();
480 temp = d->m_date.addMonths(1).date();
483 KComboBox::keyPressEvent(keyEvent);
486 if (temp.isValid() && temp >= d->m_minDate && temp <= d->m_maxDate) {
495 KComboBox::focusOutEvent(event);
502 (d->m_options &KDateComboBox::SelectDate) != KDateComboBox::SelectDate) {
506 d->m_datePicker->blockSignals(
true);
507 d->m_datePicker->setDate(d->m_date.date());
508 d->m_datePicker->blockSignals(
false);
514 const int dateFrameHeight = d->m_dateMenu->sizeHint().height();
515 if (popupPoint.y() + height() + dateFrameHeight > desk.bottom()) {
516 popupPoint.setY(popupPoint.y() - dateFrameHeight);
518 popupPoint.setY(popupPoint.y() + height());
521 const int dateFrameWidth = d->m_dateMenu->sizeHint().width();
522 if (popupPoint.x() + dateFrameWidth > desk.right()) {
523 popupPoint.setX(desk.right() - dateFrameWidth);
526 if (popupPoint.x() < desk.left()) {
527 popupPoint.setX(desk.left());
530 if (popupPoint.y() < desk.top()) {
531 popupPoint.setY(desk.top());
534 d->m_dateMenu->popup(popupPoint);
539 KComboBox::hidePopup();
544 KComboBox::mousePressEvent(event);
554 KComboBox::focusInEvent(event);
559 KComboBox::resizeEvent(event);
562 #include "kdatecombobox.moc"
virtual bool eventFilter(QObject *object, QEvent *event)
Re-implemented for internal reasons.
void setEditable(bool editable)
"Re-implemented" so that setEditable(true) creates a KLineEdit instead of QLineEdit.
Allow the user to select the date from a drop-down menu.
void setCalendar(KCalendarSystem *calendar=0)
Changes the calendar system to use.
void resetDateRange()
Reset the minimum and maximum date to the default values.
QMap< QDate, QString > dateMap() const
Return the map of dates listed in the drop-down and their displayed string forms. ...
void dateEdited(const QDate &date)
Signal if the date is being manually edited by the user.
void dateEntered(const QDate &date)
Signal if the date has been manually entered or selected by the user.
virtual ~KDateComboBox()
Destroy the widget.
static QRect desktopGeometry(const QPoint &point)
This function returns the desktop geometry for an application that needs to set the geometry of a wid...
virtual void focusInEvent(QFocusEvent *event)
virtual void assignDate(const QDate &date)
Assign the date for the widget.
int cursorPosition() const
Returns the current cursor position.
virtual void keyPressEvent(QKeyEvent *event)
QDate minimumDate() const
Return the current minimum date.
virtual void focusOutEvent(QFocusEvent *event)
QString i18nc(const char *ctxt, const char *text)
void setMinimumDate(const QDate &minTime, const QString &minWarnMsg=QString())
Set the minimum allowed date.
QDate date() const
Return the currently selected date.
const KCalendarSystem * calendar() const
Returns a pointer to the Calendar System object used by this widget.
KDateComboBox(QWidget *parent=0)
Create a new KDateComboBox widget.
virtual void resizeEvent(QResizeEvent *event)
void setMaximumDate(const QDate &maxDate, const QString &maxWarnMsg=QString())
Set the maximum allowed date.
virtual void assignCalendarSystem(KLocale::CalendarSystem calendarSystem)
Assign the calendar system for the widget.
bool isNull() const
Return if the current user input is null.
Show date keywords in the drop-down.
void setDateMap(QMap< QDate, QString > dateMap)
Set the list of dates able to be selected from the drop-down and the string form to display for those...
static void sorry(QWidget *parent, const QString &text, const QString &caption=QString(), Options options=Notify)
Display an "Sorry" dialog.
void dateChanged(const QDate &date)
Signal if the date has been changed either manually by the user or programatically.
QDate maximumDate() const
Return the current maximum date.
void resetMinimumDate()
Reset the minimum date to the default.
virtual void wheelEvent(QWheelEvent *event)
void setOptions(Options options)
Set the new widget options.
void setCalendarSystem(KLocale::CalendarSystem calendarSystem)
Set the Calendar System used for this widget.
void setDate(const QDate &date)
Set the currently selected date.
Options options() const
Return the currently set widget options.
KLocale::DateFormat displayFormat() const
Return the currently set date display format.
virtual void mousePressEvent(QMouseEvent *event)
void setDisplayFormat(KLocale::DateFormat format)
Sets the date format to display.
Show a date picker in the drop-down.
Allow the user to manually edit the date in the combo line edit.
void resetMaximumDate()
Reset the maximum date to the default.
Show a warning on focus out if the date is invalid.
virtual bool eventFilter(QObject *, QEvent *)
Re-implemented for internal reasons.
void setDateRange(const QDate &minDate, const QDate &maxDate, const QString &minWarnMsg=QString(), const QString &maxWarnMsg=QString())
Set the valid date range to be applied by isValid().
bool isValid() const
Return if the current user input is valid.
virtual void wheelEvent(QWheelEvent *ev)
KLocale::CalendarSystem calendarSystem() const
Returns the Calendar System type used by the widget.