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_warningShown(false),
85 m_displayFormat(
KLocale::ShortDate)
88 m_date.setDate(QDate::currentDate());
89 m_minDate = defaultMinDate();
90 m_maxDate = defaultMaxDate();
91 m_datePicker->setCloseButton(
false);
92 m_datePickerAction->setObjectName(QLatin1String(
"DatePicker"));
93 m_datePickerAction->setDefaultWidget(m_datePicker);
96 KDateComboBoxPrivate::~KDateComboBoxPrivate()
100 QDate KDateComboBoxPrivate::defaultMinDate()
102 return m_date.calendar()->earliestValidDate();
105 QDate KDateComboBoxPrivate::defaultMaxDate()
107 return m_date.calendar()->latestValidDate();
110 QString KDateComboBoxPrivate::formatDate(
const QDate &date)
112 return m_date.calendar()->formatDate(date, m_displayFormat);
115 void KDateComboBoxPrivate::initDateWidget()
117 q->blockSignals(
true);
127 q->setMaxVisibleItems(1);
129 q->setMaxVisibleItems(0);
132 q->setSizeAdjustPolicy(QComboBox::AdjustToContents);
133 q->addItem(m_date.formatDate(m_displayFormat));
134 q->setCurrentIndex(0);
135 q->setSizeAdjustPolicy(QComboBox::AdjustToContentsOnFirstShow);
136 q->blockSignals(
false);
141 if ((m_options & KDateComboBox::SelectDate) == KDateComboBox::SelectDate) {
143 if ((m_options & KDateComboBox::DatePicker) == KDateComboBox::DatePicker) {
144 m_dateMenu->addAction(m_datePickerAction);
145 m_dateMenu->addSeparator();
149 if (m_dateMap.isEmpty()) {
150 addMenuAction(
i18nc(
"@option next year",
"Next Year" ), m_date.addYears(1).date());
151 addMenuAction(
i18nc(
"@option next month",
"Next Month"), m_date.addMonths(1).date());
152 addMenuAction(
i18nc(
"@option next week",
"Next Week" ), m_date.addDays(m_date.daysInWeek()).date());
153 addMenuAction(
i18nc(
"@option tomorrow",
"Tomorrow" ), m_date.addDays(1).date());
154 addMenuAction(
i18nc(
"@option today",
"Today" ), m_date.date());
155 addMenuAction(
i18nc(
"@option yesterday",
"Yesterday" ), m_date.addDays(-1).date());
156 addMenuAction(
i18nc(
"@option last week",
"Last Week" ), m_date.addDays(-m_date.daysInWeek()).date());
157 addMenuAction(
i18nc(
"@option last month",
"Last Month"), m_date.addMonths(-1).date());
158 addMenuAction(
i18nc(
"@option last year",
"Last Year" ), m_date.addYears(-1).date());
159 m_dateMenu->addSeparator();
160 addMenuAction(
i18nc(
"@option do not specify a date",
"No Date"), QDate());
162 QMapIterator<QDate, QString> i(m_dateMap);
163 while (i.hasNext()) {
165 if (i.value().isEmpty()) {
166 addMenuAction(formatDate(i.key()), i.key());
167 }
else if (i.value().toLower() == QLatin1String(
"separator")) {
168 m_dateMenu->addSeparator();
170 addMenuAction(i.value(), i.key());
179 void KDateComboBoxPrivate::addMenuAction(
const QString &text,
const QDate &date)
182 action->setText(text);
183 action->setData(date);
184 m_dateMenu->addAction(action);
188 void KDateComboBoxPrivate::enableMenuDates()
191 for (
int i = 0; i < m_actions.count(); ++i) {
192 QDate date = m_actions[i]->data().toDate();
193 m_actions[i]->setVisible(!date.isValid() || (date >= m_minDate && date <= m_maxDate));
197 void KDateComboBoxPrivate::updateDateWidget()
199 q->blockSignals(
true);
200 m_datePicker->blockSignals(
true);
201 m_datePicker->
setDate(m_date.date());
203 q->setItemText(0, m_date.formatDate(m_displayFormat));
204 q->lineEdit()->setText(m_date.formatDate(m_displayFormat));
205 q->lineEdit()->setCursorPosition(pos);
206 m_datePicker->blockSignals(
false);
207 q->blockSignals(
false);
210 void KDateComboBoxPrivate::selectDate(
QAction *action)
212 if (action->objectName() != QLatin1String(
"DatePicker")) {
213 enterDate(action->data().toDate());
217 void KDateComboBoxPrivate::clickDate()
219 enterDate(m_datePicker->date());
222 void KDateComboBoxPrivate::editDate(
const QString &text)
224 m_warningShown =
false;
225 emit q->
dateEdited(m_date.readDate(text).date());
228 void KDateComboBoxPrivate::parseDate()
230 m_date.setDate(m_date.readDate(q->lineEdit()->text()).date());
233 void KDateComboBoxPrivate::enterDate(
const QDate &date)
237 q->blockSignals(
true);
239 q->setSizeAdjustPolicy(QComboBox::AdjustToContents);
240 q->addItem(m_date.formatDate(m_displayFormat));
241 q->setCurrentIndex(0);
242 q->setSizeAdjustPolicy(QComboBox::AdjustToContentsOnFirstShow);
243 q->blockSignals(
false);
250 void KDateComboBoxPrivate::warnDate()
252 if (!m_warningShown && !q->
isValid() &&
255 if (!m_date.date().isValid()) {
256 warnMsg =
i18nc(
"@info",
"The date you entered is invalid");
257 }
else if (m_date.date() < m_minDate) {
258 if (m_minWarnMsg.isEmpty()) {
259 warnMsg =
i18nc(
"@info",
"Date cannot be earlier than %1", formatDate(m_minDate));
261 warnMsg = m_minWarnMsg;
262 warnMsg.replace(
"%1", formatDate(m_minDate));
264 }
else if (m_date.date() > m_maxDate) {
265 if (m_maxWarnMsg.isEmpty()) {
266 warnMsg =
i18nc(
"@info",
"Date cannot be later than %1", formatDate(m_maxDate));
268 warnMsg = m_maxWarnMsg;
269 warnMsg.replace(
"%1", formatDate(m_maxDate));
272 m_warningShown =
true;
280 d(new KDateComboBoxPrivate(this))
283 setMaxVisibleItems(1);
284 setInsertPolicy(QComboBox::NoInsert);
285 d->m_datePicker->installEventFilter(
this);
287 d->updateDateWidget();
289 connect(d->m_dateMenu, SIGNAL(triggered(
QAction*)),
290 this, SLOT(selectDate(
QAction*)));
291 connect(
this, SIGNAL(editTextChanged(
QString)),
292 this, SLOT(editDate(
QString)));
293 connect(d->m_datePicker, SIGNAL(
dateEntered(QDate)),
294 this, SLOT(enterDate(QDate)));
295 connect(d->m_datePicker, SIGNAL(tableClicked()),
296 this, SLOT(clickDate()));
307 return d->m_date.date();
312 if (date == d->m_date.date()) {
317 d->updateDateWidget();
328 return d->m_date.calendarSystem();
333 if (calendarSystem != d->m_date.calendarSystem()) {
340 d->m_date.setCalendarSystem(calendarSystem);
345 return d->m_date.calendar();
356 return d->m_date.isValid() &&
357 d->m_date >= d->m_minDate &&
358 d->m_date <= d->m_maxDate;
363 return lineEdit()->text().isEmpty();
373 if (options != d->m_options) {
376 d->updateDateWidget();
387 setDateRange(minDate, d->m_maxDate, minWarnMsg, d->m_maxWarnMsg);
402 setDateRange(d->m_minDate, maxDate, d->m_minWarnMsg, maxWarnMsg);
411 const QDate &maxDate,
415 if (!minDate.isValid() || !maxDate.isValid() || minDate > maxDate) {
419 if (minDate != d->m_minDate || maxDate != d->m_maxDate ||
420 minWarnMsg != d->m_minWarnMsg || maxWarnMsg != d->m_maxWarnMsg) {
421 d->m_minDate = minDate;
422 d->m_maxDate = maxDate;
423 d->m_minWarnMsg = minWarnMsg;
424 d->m_maxWarnMsg = maxWarnMsg;
426 d->enableMenuDates();
436 return d->m_displayFormat;
441 if (format != d->m_displayFormat) {
442 d->m_displayFormat = format;
444 d->updateDateWidget();
455 if (dateMap != d->m_dateMap) {
456 d->m_dateMap.clear();
470 switch (keyEvent->key()) {
472 temp = d->m_date.addDays(-1).date();
475 temp = d->m_date.addDays(1).date();
477 case Qt::Key_PageDown:
478 temp = d->m_date.addMonths(-1).date();
481 temp = d->m_date.addMonths(1).date();
484 KComboBox::keyPressEvent(keyEvent);
487 if (temp.isValid() && temp >= d->m_minDate && temp <= d->m_maxDate) {
496 KComboBox::focusOutEvent(event);
503 (d->m_options &KDateComboBox::SelectDate) != KDateComboBox::SelectDate) {
507 d->m_datePicker->blockSignals(
true);
508 d->m_datePicker->setDate(d->m_date.date());
509 d->m_datePicker->blockSignals(
false);
515 const int dateFrameHeight = d->m_dateMenu->sizeHint().height();
516 if (popupPoint.y() + height() + dateFrameHeight > desk.bottom()) {
517 popupPoint.setY(popupPoint.y() - dateFrameHeight);
519 popupPoint.setY(popupPoint.y() + height());
522 const int dateFrameWidth = d->m_dateMenu->sizeHint().width();
523 if (popupPoint.x() + dateFrameWidth > desk.right()) {
524 popupPoint.setX(desk.right() - dateFrameWidth);
527 if (popupPoint.x() < desk.left()) {
528 popupPoint.setX(desk.left());
531 if (popupPoint.y() < desk.top()) {
532 popupPoint.setY(desk.top());
535 d->m_dateMenu->popup(popupPoint);
540 KComboBox::hidePopup();
545 KComboBox::mousePressEvent(event);
555 KComboBox::focusInEvent(event);
560 KComboBox::resizeEvent(event);
563 #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.