• Skip to content
  • Skip to link menu
KDE 4.8 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • Contact Us
 

KDEUI

kdatecombobox.cpp
Go to the documentation of this file.
00001 /*
00002     Copyright 2011 John Layt <john@layt.net>
00003 
00004     This library is free software; you can redistribute it and/or
00005     modify it under the terms of the GNU Library General Public
00006     License as published by the Free Software Foundation; either
00007     version 2 of the License, or (at your option) any later version.
00008 
00009     This library is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012     Library General Public License for more details.
00013 
00014     You should have received a copy of the GNU Library General Public License
00015     along with this library; see the file COPYING.LIB.  If not, write to
00016     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017     Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include "kdatecombobox.h"
00021 
00022 #include <QtGui/QAbstractItemView>
00023 #include <QtGui/QApplication>
00024 #include <QtGui/QKeyEvent>
00025 #include <QtGui/QMenu>
00026 #include <QtGui/QLineEdit>
00027 #include <QtGui/QWidgetAction>
00028 
00029 #include "kdebug.h"
00030 #include "klocale.h"
00031 #include "klocalizeddate.h"
00032 #include "kcombobox.h"
00033 #include "kdatepicker.h"
00034 #include "kmessagebox.h"
00035 
00036 class KDateComboBoxPrivate
00037 {
00038 public:
00039 
00040     KDateComboBoxPrivate(KDateComboBox *q);
00041     virtual ~KDateComboBoxPrivate();
00042 
00043     QDate defaultMinDate();
00044     QDate defaultMaxDate();
00045 
00046     QString formatDate(const QDate &date);
00047 
00048     void initDateWidget();
00049     void addMenuAction(const QString &text, const QDate &date);
00050     void updateDateWidget();
00051 
00052 // Q_PRIVATE_SLOTs
00053     void clickDate();
00054     void selectDate(QAction *action);
00055     void editDate(const QString &text);
00056     void enterDate(const QDate &date);
00057     void parseDate();
00058     void warnDate();
00059 
00060     KDateComboBox *const q;
00061     QMenu *m_dateMenu;
00062     KDatePicker *m_datePicker;
00063     QWidgetAction *m_datePickerAction;
00064 
00065     KLocalizedDate m_date;
00066     KDateComboBox::Options m_options;
00067     QDate m_minDate;
00068     QDate m_maxDate;
00069     QString m_minWarnMsg;
00070     QString m_maxWarnMsg;
00071     bool m_warningShown;
00072     KLocale::DateFormat m_displayFormat;
00073     QMap<QDate, QString> m_dateMap;
00074 };
00075 
00076 KDateComboBoxPrivate::KDateComboBoxPrivate(KDateComboBox *q)
00077                      :q(q),
00078                       m_dateMenu(new QMenu(q)),
00079                       m_datePicker(new KDatePicker(q)),
00080                       m_datePickerAction(new QWidgetAction(q)),
00081                       m_displayFormat(KLocale::ShortDate)
00082 {
00083     m_options = KDateComboBox::EditDate | KDateComboBox::SelectDate | KDateComboBox::DatePicker | KDateComboBox::DateKeywords;
00084     m_date.setDate(QDate::currentDate());
00085     m_minDate = defaultMinDate();
00086     m_maxDate = defaultMaxDate();
00087     m_datePicker->setCloseButton(false);
00088     m_datePickerAction->setObjectName(QLatin1String("DatePicker"));
00089     m_datePickerAction->setDefaultWidget(m_datePicker);
00090 }
00091 
00092 KDateComboBoxPrivate::~KDateComboBoxPrivate()
00093 {
00094 }
00095 
00096 QDate KDateComboBoxPrivate::defaultMinDate()
00097 {
00098     return m_date.calendar()->earliestValidDate();
00099 }
00100 
00101 QDate KDateComboBoxPrivate::defaultMaxDate()
00102 {
00103     return m_date.calendar()->latestValidDate();
00104 }
00105 
00106 QString KDateComboBoxPrivate::formatDate(const QDate &date)
00107 {
00108     return m_date.calendar()->formatDate(date, m_displayFormat);
00109 }
00110 
00111 void KDateComboBoxPrivate::initDateWidget()
00112 {
00113     q->blockSignals(true);
00114     q->clear();
00115 
00116     // If EditTime then set the line edit
00117     q->lineEdit()->setReadOnly((m_options &KDateComboBox::EditDate) != KDateComboBox::EditDate);
00118 
00119     // If SelectTime then make list items visible
00120     if ((m_options &KDateComboBox::SelectDate) == KDateComboBox::SelectDate ||
00121         (m_options &KDateComboBox::DatePicker) == KDateComboBox::DatePicker ||
00122         (m_options &KDateComboBox::DatePicker) == KDateComboBox::DateKeywords) {
00123         q->setMaxVisibleItems(1);
00124     } else {
00125         q->setMaxVisibleItems(0);
00126     }
00127 
00128     q->setSizeAdjustPolicy(QComboBox::AdjustToContents);
00129     q->addItem(m_date.formatDate(m_displayFormat));
00130     q->setCurrentIndex(0);
00131     q->setSizeAdjustPolicy(QComboBox::AdjustToContentsOnFirstShow);
00132     q->blockSignals(false);
00133 
00134     m_dateMenu->clear();
00135 
00136     if ((m_options &KDateComboBox::SelectDate) == KDateComboBox::SelectDate) {
00137 
00138         if ((m_options &KDateComboBox::DatePicker) == KDateComboBox::DatePicker) {
00139             m_dateMenu->addAction(m_datePickerAction);
00140             m_dateMenu->addSeparator();
00141         }
00142 
00143         if ((m_options &KDateComboBox::DateKeywords) == KDateComboBox::DateKeywords) {
00144             if (m_dateMap.isEmpty()) {
00145                 addMenuAction(i18nc("@option next year",  "Next Year" ), m_date.addYears(1).date());
00146                 addMenuAction(i18nc("@option next month", "Next Month"), m_date.addMonths(1).date());
00147                 addMenuAction(i18nc("@option next week",  "Next Week" ), m_date.addDays(m_date.daysInWeek()).date());
00148                 addMenuAction(i18nc("@option tomorrow",   "Tomorrow"  ), m_date.addDays(1).date());
00149                 addMenuAction(i18nc("@option today",      "Today"     ), m_date.date());
00150                 addMenuAction(i18nc("@option yesterday",  "Yesterday" ), m_date.addDays(-1).date());
00151                 addMenuAction(i18nc("@option last week",  "Last Week" ), m_date.addDays(-m_date.daysInWeek()).date());
00152                 addMenuAction(i18nc("@option last month", "Last Month"), m_date.addMonths(-1).date());
00153                 addMenuAction(i18nc("@option last year",  "Last Year" ), m_date.addYears(-1).date());
00154                 m_dateMenu->addSeparator();
00155                 addMenuAction(i18nc("@option do not specify a date", "No Date"), QDate());
00156             } else {
00157                 QMapIterator<QDate, QString> i(m_dateMap);
00158                 while (i.hasNext()) {
00159                     i.next();
00160                     if (i.value().isEmpty()) {
00161                         addMenuAction(formatDate(i.key()), i.key());
00162                     } else if (i.value().toLower() == QLatin1String("separator")) {
00163                         m_dateMenu->addSeparator();
00164                     } else {
00165                         addMenuAction(i.value(), i.key());
00166                     }
00167                 }
00168             }
00169         }
00170 
00171     }
00172 }
00173 
00174 void KDateComboBoxPrivate::addMenuAction(const QString &text, const QDate &date)
00175 {
00176     QAction *action = new QAction(m_dateMenu);
00177     action->setText(text);
00178     action->setData(date);
00179     m_dateMenu->addAction(action);
00180 }
00181 
00182 void KDateComboBoxPrivate::updateDateWidget()
00183 {
00184     q->blockSignals(true);
00185     m_datePicker->blockSignals(true);
00186     m_datePicker->setDate(m_date.date());
00187     int pos = q->lineEdit()->cursorPosition();
00188     q->setItemText(0, m_date.formatDate(m_displayFormat));
00189     q->lineEdit()->setText(m_date.formatDate(m_displayFormat));
00190     q->lineEdit()->setCursorPosition(pos);
00191     m_datePicker->blockSignals(false);
00192     q->blockSignals(false);
00193 }
00194 
00195 void KDateComboBoxPrivate::selectDate(QAction *action)
00196 {
00197     if (action->objectName() != QLatin1String("DatePicker")) {
00198         enterDate(action->data().toDate());
00199     }
00200 }
00201 
00202 void KDateComboBoxPrivate::clickDate()
00203 {
00204     enterDate(m_datePicker->date());
00205 }
00206 
00207 void KDateComboBoxPrivate::editDate(const QString &text)
00208 {
00209     m_warningShown = false;
00210     emit q->dateEdited(m_date.readDate(text).date());
00211 }
00212 
00213 void KDateComboBoxPrivate::parseDate()
00214 {
00215     m_date.setDate(m_date.readDate(q->lineEdit()->text()).date());
00216 }
00217 
00218 void KDateComboBoxPrivate::enterDate(const QDate &date)
00219 {
00220     q->setDate(date);
00221     // Re-add the combo box item in order to retain the correct widget width
00222     q->blockSignals(true);
00223     q->clear();
00224     q->setSizeAdjustPolicy(QComboBox::AdjustToContents);
00225     q->addItem(m_date.formatDate(m_displayFormat));
00226     q->setCurrentIndex(0);
00227     q->setSizeAdjustPolicy(QComboBox::AdjustToContentsOnFirstShow);
00228     q->blockSignals(false);
00229 
00230     m_dateMenu->hide();
00231     warnDate();
00232     emit q->dateEntered(m_date.date());
00233 }
00234 
00235 void KDateComboBoxPrivate::warnDate()
00236 {
00237     if (!m_warningShown && !q->isValid() &&
00238         (m_options &KDateComboBox::WarnOnInvalid) == KDateComboBox::WarnOnInvalid) {
00239         QString warnMsg;
00240         if (!m_date.date().isValid()) {
00241             warnMsg = i18nc("@info", "The date you entered is invalid");
00242         } else if (m_date.date() < m_minDate) {
00243             if (m_minWarnMsg.isEmpty()) {
00244                 warnMsg = i18nc("@info", "Date cannot be earlier than %1", formatDate(m_minDate));
00245             } else {
00246                 warnMsg = m_minWarnMsg;
00247                 warnMsg.replace("%1", formatDate(m_minDate));
00248             }
00249         } else if (m_date.date() > m_maxDate) {
00250             if (m_maxWarnMsg.isEmpty()) {
00251                 warnMsg = i18nc("@info", "Date cannot be later than %1", formatDate(m_maxDate));
00252             } else {
00253                 warnMsg = m_maxWarnMsg;
00254                 warnMsg.replace("%1", formatDate(m_maxDate));
00255             }
00256         }
00257         m_warningShown = true;
00258         KMessageBox::sorry(q, warnMsg);
00259     }
00260 }
00261 
00262 
00263 KDateComboBox::KDateComboBox(QWidget *parent)
00264               :KComboBox(parent),
00265                d(new KDateComboBoxPrivate(this))
00266 {
00267     setEditable(true);
00268     setMaxVisibleItems(1);
00269     setInsertPolicy(QComboBox::NoInsert);
00270     d->m_datePicker->installEventFilter(this);
00271     d->initDateWidget();
00272     d->updateDateWidget();
00273 
00274     connect(d->m_dateMenu,         SIGNAL(triggered(QAction*)),
00275             this,                  SLOT(selectDate(QAction*)));
00276     connect(this,                  SIGNAL(editTextChanged(const QString&)),
00277             this,                  SLOT(editDate(const QString&)));
00278     connect(d->m_datePicker,       SIGNAL(dateEntered(const QDate&)),
00279             this,                  SLOT(enterDate(const QDate&)));
00280     connect(d->m_datePicker,       SIGNAL(tableClicked()),
00281             this,                  SLOT(clickDate()));
00282 }
00283 
00284 KDateComboBox::~KDateComboBox()
00285 {
00286     delete d;
00287 }
00288 
00289 QDate KDateComboBox::date() const
00290 {
00291     d->parseDate();
00292     return d->m_date.date();
00293 }
00294 
00295 void KDateComboBox::setDate(const QDate &date)
00296 {
00297     if (date == d->m_date.date()) {
00298         return;
00299     }
00300 
00301     assignDate(date);
00302     d->updateDateWidget();
00303     emit dateChanged(d->m_date.date());
00304 }
00305 
00306 void KDateComboBox::assignDate(const QDate &date)
00307 {
00308     d->m_date = date;
00309 }
00310 
00311 KLocale::CalendarSystem KDateComboBox::calendarSystem() const
00312 {
00313     return d->m_date.calendarSystem();
00314 }
00315 
00316 void KDateComboBox::setCalendarSystem(KLocale::CalendarSystem calendarSystem)
00317 {
00318     if (calendarSystem != d->m_date.calendarSystem()) {
00319         assignCalendarSystem(calendarSystem);
00320     }
00321 }
00322 
00323 void KDateComboBox::assignCalendarSystem(KLocale::CalendarSystem calendarSystem)
00324 {
00325     d->m_date.setCalendarSystem(calendarSystem);
00326 }
00327 
00328 const KCalendarSystem *KDateComboBox::calendar() const
00329 {
00330     return d->m_date.calendar();
00331 }
00332 
00333 void KDateComboBox::setCalendar(KCalendarSystem *calendar)
00334 {
00335     d->m_date = KLocalizedDate(d->m_date.date(), calendar);
00336 }
00337 
00338 bool KDateComboBox::isValid() const
00339 {
00340     d->parseDate();
00341     return d->m_date.isValid() &&
00342            d->m_date >= d->m_minDate &&
00343            d->m_date <= d->m_maxDate;
00344 }
00345 
00346 bool KDateComboBox::isNull() const
00347 {
00348     return lineEdit()->text().isEmpty();
00349 }
00350 
00351 KDateComboBox::Options KDateComboBox::options() const
00352 {
00353     return d->m_options;
00354 }
00355 
00356 void KDateComboBox::setOptions(Options options)
00357 {
00358     if (options != d->m_options) {
00359         d->m_options = options;
00360         d->initDateWidget();
00361         d->updateDateWidget();
00362     }
00363 }
00364 
00365 QDate KDateComboBox::minimumDate() const
00366 {
00367     return d->m_minDate;
00368 }
00369 
00370 void KDateComboBox::setMinimumDate(const QDate &minDate, const QString &minWarnMsg)
00371 {
00372     setDateRange(minDate, d->m_maxDate, minWarnMsg, d->m_maxWarnMsg);
00373 }
00374 
00375 void KDateComboBox::resetMinimumDate()
00376 {
00377     setDateRange(d->defaultMinDate(), d->m_maxDate, QString(), d->m_maxWarnMsg);
00378 }
00379 
00380 QDate KDateComboBox::maximumDate() const
00381 {
00382     return d->m_maxDate;
00383 }
00384 
00385 void KDateComboBox::setMaximumDate(const QDate &maxDate, const QString &maxWarnMsg)
00386 {
00387     setDateRange(d->m_minDate, maxDate, d->m_minWarnMsg, maxWarnMsg);
00388 }
00389 
00390 void KDateComboBox::resetMaximumDate()
00391 {
00392     setDateRange(d->m_minDate, d->defaultMaxDate(), d->m_minWarnMsg, QString());
00393 }
00394 
00395 void KDateComboBox::setDateRange(const QDate &minDate,
00396                                  const QDate &maxDate,
00397                                  const QString &minWarnMsg,
00398                                  const QString &maxWarnMsg)
00399 {
00400     if (!minDate.isValid() || !maxDate.isValid() || minDate > maxDate) {
00401         return;
00402     }
00403 
00404     if (minDate != d->m_minDate || maxDate != d->m_maxDate ||
00405         minWarnMsg != d->m_minWarnMsg || maxWarnMsg != d->m_maxWarnMsg) {
00406         d->m_minDate = minDate;
00407         d->m_maxDate = maxDate;
00408         d->m_minWarnMsg = minWarnMsg;
00409         d->m_maxWarnMsg = maxWarnMsg;
00410     }
00411 }
00412 
00413 void KDateComboBox::resetDateRange()
00414 {
00415     setDateRange(d->defaultMinDate(), d->defaultMaxDate(), QString(), QString());
00416 }
00417 
00418 KLocale::DateFormat KDateComboBox::displayFormat() const
00419 {
00420     return d->m_displayFormat;
00421 }
00422 
00423 void KDateComboBox::setDisplayFormat(KLocale::DateFormat format)
00424 {
00425     if (format != d->m_displayFormat) {
00426         d->m_displayFormat = format;
00427         d->initDateWidget();
00428         d->updateDateWidget();
00429     }
00430 }
00431 
00432 QMap<QDate, QString> KDateComboBox::dateMap() const
00433 {
00434     return d->m_dateMap;
00435 }
00436 
00437 void KDateComboBox::setDateMap(QMap<QDate, QString> dateMap)
00438 {
00439     if (dateMap != d->m_dateMap) {
00440         d->m_dateMap.clear();
00441         d->m_dateMap = dateMap;
00442         d->initDateWidget();
00443     }
00444 }
00445 
00446 bool KDateComboBox::eventFilter(QObject *object, QEvent *event)
00447 {
00448     return KComboBox::eventFilter(object, event);
00449 }
00450 
00451 void KDateComboBox::keyPressEvent(QKeyEvent *keyEvent)
00452 {
00453     QDate temp;
00454     switch (keyEvent->key()) {
00455     case Qt::Key_Down:
00456         temp = d->m_date.addDays(-1).date();
00457         break;
00458     case Qt::Key_Up:
00459         temp = d->m_date.addDays(1).date();
00460         break;
00461     case Qt::Key_PageDown:
00462         temp = d->m_date.addMonths(-1).date();
00463         break;
00464     case Qt::Key_PageUp:
00465         temp = d->m_date.addMonths(1).date();
00466         break;
00467     default:
00468         KComboBox::keyPressEvent(keyEvent);
00469         return;
00470     }
00471     if (temp.isValid() && temp >= d->m_minDate && temp <= d->m_maxDate) {
00472         d->enterDate(temp);
00473     }
00474 }
00475 
00476 void KDateComboBox::focusOutEvent(QFocusEvent *event)
00477 {
00478     d->parseDate();
00479     d->warnDate();
00480     KComboBox::focusOutEvent(event);
00481 }
00482 
00483 void KDateComboBox::showPopup()
00484 {
00485     if (!isEditable() ||
00486         !d->m_dateMenu ||
00487         (d->m_options &KDateComboBox::SelectDate) != KDateComboBox::SelectDate) {
00488         return;
00489     }
00490 
00491     d->m_datePicker->blockSignals(true);
00492     d->m_datePicker->setDate(d->m_date.date());
00493     d->m_datePicker->blockSignals(false);
00494 
00495     const QRect desk = KGlobalSettings::desktopGeometry(this);
00496 
00497     QPoint popupPoint = mapToGlobal(QPoint(0, 0));
00498 
00499     const int dateFrameHeight = d->m_dateMenu->sizeHint().height();
00500     if (popupPoint.y() + height() + dateFrameHeight > desk.bottom()) {
00501         popupPoint.setY(popupPoint.y() - dateFrameHeight);
00502     } else {
00503         popupPoint.setY(popupPoint.y() + height());
00504     }
00505 
00506     const int dateFrameWidth = d->m_dateMenu->sizeHint().width();
00507     if (popupPoint.x() + dateFrameWidth > desk.right()) {
00508         popupPoint.setX(desk.right() - dateFrameWidth);
00509     }
00510 
00511     if (popupPoint.x() < desk.left()) {
00512         popupPoint.setX(desk.left());
00513     }
00514 
00515     if (popupPoint.y() < desk.top()) {
00516         popupPoint.setY(desk.top());
00517     }
00518 
00519     d->m_dateMenu->popup(popupPoint);
00520 }
00521 
00522 void KDateComboBox::hidePopup()
00523 {
00524     KComboBox::hidePopup();
00525 }
00526 
00527 void KDateComboBox::mousePressEvent(QMouseEvent *event)
00528 {
00529     KComboBox::mousePressEvent(event);
00530 }
00531 
00532 void KDateComboBox::wheelEvent(QWheelEvent *event)
00533 {
00534     KComboBox::wheelEvent(event);
00535 }
00536 
00537 void KDateComboBox::focusInEvent(QFocusEvent *event)
00538 {
00539     KComboBox::focusInEvent(event);
00540 }
00541 
00542 void KDateComboBox::resizeEvent(QResizeEvent *event)
00543 {
00544     KComboBox::resizeEvent(event);
00545 }
00546 
00547 #include "kdatecombobox.moc"

KDEUI

Skip menu "KDEUI"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal