• Skip to content
  • Skip to link menu
KDE 4.7 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->addItem(m_date.formatDate(m_displayFormat));
00129     q->setCurrentIndex(0);
00130     q->setSizeAdjustPolicy(QComboBox::AdjustToContents);
00131 
00132     m_dateMenu->clear();
00133 
00134     if ((m_options &KDateComboBox::SelectDate) == KDateComboBox::SelectDate) {
00135 
00136         if ((m_options &KDateComboBox::DatePicker) == KDateComboBox::DatePicker) {
00137             m_dateMenu->addAction(m_datePickerAction);
00138             m_dateMenu->addSeparator();
00139         }
00140 
00141         if ((m_options &KDateComboBox::DateKeywords) == KDateComboBox::DateKeywords) {
00142             if (m_dateMap.isEmpty()) {
00143                 addMenuAction(i18nc("@option next year",  "Next Year" ), m_date.addYears(1).date());
00144                 addMenuAction(i18nc("@option next month", "Next Month"), m_date.addMonths(1).date());
00145                 addMenuAction(i18nc("@option next week",  "Next Week" ), m_date.addDays(m_date.daysInWeek()).date());
00146                 addMenuAction(i18nc("@option tomorrow",   "Tomorrow"  ), m_date.addDays(1).date());
00147                 addMenuAction(i18nc("@option today",      "Today"     ), m_date.date());
00148                 addMenuAction(i18nc("@option yesterday",  "Yesterday" ), m_date.addDays(-1).date());
00149                 addMenuAction(i18nc("@option last week",  "Last Week" ), m_date.addDays(-m_date.daysInWeek()).date());
00150                 addMenuAction(i18nc("@option last month", "Last Month"), m_date.addMonths(-1).date());
00151                 addMenuAction(i18nc("@option last year",  "Last Year" ), m_date.addYears(-1).date());
00152                 m_dateMenu->addSeparator();
00153                 addMenuAction(i18nc("@option do not specify a date", "No Date"), QDate());
00154             } else {
00155                 QMapIterator<QDate, QString> i(m_dateMap);
00156                 while (i.hasNext()) {
00157                     i.next();
00158                     if (i.value().isEmpty()) {
00159                         addMenuAction(formatDate(i.key()), i.key());
00160                     } else if (i.value().toLower() == QLatin1String("separator")) {
00161                         m_dateMenu->addSeparator();
00162                     } else {
00163                         addMenuAction(i.value(), i.key());
00164                     }
00165                 }
00166             }
00167         }
00168 
00169     }
00170 }
00171 
00172 void KDateComboBoxPrivate::addMenuAction(const QString &text, const QDate &date)
00173 {
00174     QAction *action = new QAction(m_dateMenu);
00175     action->setText(text);
00176     action->setData(date);
00177     m_dateMenu->addAction(action);
00178 }
00179 
00180 void KDateComboBoxPrivate::updateDateWidget()
00181 {
00182     q->blockSignals(true);
00183     m_datePicker->blockSignals(true);
00184     m_datePicker->setDate(m_date.date());
00185     int pos = q->lineEdit()->cursorPosition();
00186     q->setItemText(0, m_date.formatDate(m_displayFormat));
00187     q->lineEdit()->setText(m_date.formatDate(m_displayFormat));
00188     q->lineEdit()->setCursorPosition(pos);
00189     m_datePicker->blockSignals(false);
00190     q->blockSignals(false);
00191 }
00192 
00193 void KDateComboBoxPrivate::selectDate(QAction *action)
00194 {
00195     if (action->objectName() != QLatin1String("DatePicker")) {
00196         enterDate(action->data().toDate());
00197     }
00198 }
00199 
00200 void KDateComboBoxPrivate::clickDate()
00201 {
00202     enterDate(m_datePicker->date());
00203 }
00204 
00205 void KDateComboBoxPrivate::editDate(const QString &text)
00206 {
00207     m_warningShown = false;
00208     emit q->dateEdited(m_date.readDate(text).date());
00209 }
00210 
00211 void KDateComboBoxPrivate::parseDate()
00212 {
00213     m_date.setDate(m_date.readDate(q->lineEdit()->text()).date());
00214 }
00215 
00216 void KDateComboBoxPrivate::enterDate(const QDate &date)
00217 {
00218     q->setDate(date);
00219     m_dateMenu->hide();
00220     warnDate();
00221     emit q->dateEntered(m_date.date());
00222 }
00223 
00224 void KDateComboBoxPrivate::warnDate()
00225 {
00226     if (!m_warningShown && !q->isValid() &&
00227         (m_options &KDateComboBox::WarnOnInvalid) == KDateComboBox::WarnOnInvalid) {
00228         QString warnMsg;
00229         if (!m_date.date().isValid()) {
00230             warnMsg = i18nc("@info", "The date you entered is invalid");
00231         } else if (m_date.date() < m_minDate) {
00232             if (m_minWarnMsg.isEmpty()) {
00233                 warnMsg = i18nc("@info", "Date cannot be earlier than %1", formatDate(m_minDate));
00234             } else {
00235                 warnMsg = m_minWarnMsg;
00236                 warnMsg.replace("%1", formatDate(m_minDate));
00237             }
00238         } else if (m_date.date() > m_maxDate) {
00239             if (m_maxWarnMsg.isEmpty()) {
00240                 warnMsg = i18nc("@info", "Date cannot be later than %1", formatDate(m_maxDate));
00241             } else {
00242                 warnMsg = m_maxWarnMsg;
00243                 warnMsg.replace("%1", formatDate(m_maxDate));
00244             }
00245         }
00246         m_warningShown = true;
00247         KMessageBox::sorry(q, warnMsg);
00248     }
00249 }
00250 
00251 
00252 KDateComboBox::KDateComboBox(QWidget *parent)
00253               :KComboBox(parent),
00254                d(new KDateComboBoxPrivate(this))
00255 {
00256     setEditable(true);
00257     setMaxVisibleItems(1);
00258     setInsertPolicy(QComboBox::NoInsert);
00259     setSizeAdjustPolicy(QComboBox::AdjustToContents);
00260     d->m_datePicker->installEventFilter(this);
00261     d->initDateWidget();
00262     d->updateDateWidget();
00263 
00264     connect(d->m_dateMenu,         SIGNAL(triggered(QAction*)),
00265             this,                  SLOT(selectDate(QAction*)));
00266     connect(this,                  SIGNAL(editTextChanged(const QString&)),
00267             this,                  SLOT(editDate(const QString&)));
00268     connect(d->m_datePicker,       SIGNAL(dateEntered(const QDate&)),
00269             this,                  SLOT(enterDate(const QDate&)));
00270     connect(d->m_datePicker,       SIGNAL(tableClicked()),
00271             this,                  SLOT(clickDate()));
00272 }
00273 
00274 KDateComboBox::~KDateComboBox()
00275 {
00276     delete d;
00277 }
00278 
00279 QDate KDateComboBox::date() const
00280 {
00281     d->parseDate();
00282     return d->m_date.date();
00283 }
00284 
00285 void KDateComboBox::setDate(const QDate &date)
00286 {
00287     if (date == d->m_date.date()) {
00288         return;
00289     }
00290 
00291     assignDate(date);
00292     d->updateDateWidget();
00293     emit dateChanged(d->m_date.date());
00294 }
00295 
00296 void KDateComboBox::assignDate(const QDate &date)
00297 {
00298     d->m_date = date;
00299 }
00300 
00301 KLocale::CalendarSystem KDateComboBox::calendarSystem() const
00302 {
00303     return d->m_date.calendarSystem();
00304 }
00305 
00306 void KDateComboBox::setCalendarSystem(KLocale::CalendarSystem calendarSystem)
00307 {
00308     if (calendarSystem != d->m_date.calendarSystem()) {
00309         assignCalendarSystem(calendarSystem);
00310     }
00311 }
00312 
00313 void KDateComboBox::assignCalendarSystem(KLocale::CalendarSystem calendarSystem)
00314 {
00315     d->m_date.setCalendarSystem(calendarSystem);
00316 }
00317 
00318 const KCalendarSystem *KDateComboBox::calendar() const
00319 {
00320     return d->m_date.calendar();
00321 }
00322 
00323 void KDateComboBox::setCalendar(KCalendarSystem *calendar)
00324 {
00325     d->m_date = KLocalizedDate(d->m_date.date(), calendar);
00326 }
00327 
00328 bool KDateComboBox::isValid() const
00329 {
00330     d->parseDate();
00331     return d->m_date.isValid() &&
00332            d->m_date >= d->m_minDate &&
00333            d->m_date <= d->m_maxDate;
00334 }
00335 
00336 bool KDateComboBox::isNull() const
00337 {
00338     return lineEdit()->text().isEmpty();
00339 }
00340 
00341 KDateComboBox::Options KDateComboBox::options() const
00342 {
00343     return d->m_options;
00344 }
00345 
00346 void KDateComboBox::setOptions(Options options)
00347 {
00348     if (options != d->m_options) {
00349         d->m_options = options;
00350         d->initDateWidget();
00351         d->updateDateWidget();
00352     }
00353 }
00354 
00355 QDate KDateComboBox::minimumDate() const
00356 {
00357     return d->m_minDate;
00358 }
00359 
00360 void KDateComboBox::setMinimumDate(const QDate &minDate, const QString &minWarnMsg)
00361 {
00362     setDateRange(minDate, d->m_maxDate, minWarnMsg, d->m_maxWarnMsg);
00363 }
00364 
00365 void KDateComboBox::resetMinimumDate()
00366 {
00367     setDateRange(d->defaultMinDate(), d->m_maxDate, QString(), d->m_maxWarnMsg);
00368 }
00369 
00370 QDate KDateComboBox::maximumDate() const
00371 {
00372     return d->m_maxDate;
00373 }
00374 
00375 void KDateComboBox::setMaximumDate(const QDate &maxDate, const QString &maxWarnMsg)
00376 {
00377     setDateRange(d->m_minDate, maxDate, d->m_minWarnMsg, maxWarnMsg);
00378 }
00379 
00380 void KDateComboBox::resetMaximumDate()
00381 {
00382     setDateRange(d->m_minDate, d->defaultMaxDate(), d->m_minWarnMsg, QString());
00383 }
00384 
00385 void KDateComboBox::setDateRange(const QDate &minDate,
00386                                  const QDate &maxDate,
00387                                  const QString &minWarnMsg,
00388                                  const QString &maxWarnMsg)
00389 {
00390     if (!minDate.isValid() || !maxDate.isValid() || minDate > maxDate) {
00391         return;
00392     }
00393 
00394     if (minDate != d->m_minDate || maxDate != d->m_maxDate ||
00395         minWarnMsg != d->m_minWarnMsg || maxWarnMsg != d->m_maxWarnMsg) {
00396         d->m_minDate = minDate;
00397         d->m_maxDate = maxDate;
00398         d->m_minWarnMsg = minWarnMsg;
00399         d->m_maxWarnMsg = maxWarnMsg;
00400     }
00401 }
00402 
00403 void KDateComboBox::resetDateRange()
00404 {
00405     setDateRange(d->defaultMinDate(), d->defaultMaxDate(), QString(), QString());
00406 }
00407 
00408 KLocale::DateFormat KDateComboBox::displayFormat() const
00409 {
00410     return d->m_displayFormat;
00411 }
00412 
00413 void KDateComboBox::setDisplayFormat(KLocale::DateFormat format)
00414 {
00415     if (format != d->m_displayFormat) {
00416         d->m_displayFormat = format;
00417         d->initDateWidget();
00418         d->updateDateWidget();
00419     }
00420 }
00421 
00422 QMap<QDate, QString> KDateComboBox::dateMap() const
00423 {
00424     return d->m_dateMap;
00425 }
00426 
00427 void KDateComboBox::setDateMap(QMap<QDate, QString> dateMap)
00428 {
00429     if (dateMap != d->m_dateMap) {
00430         d->m_dateMap.clear();
00431         d->m_dateMap = dateMap;
00432         d->initDateWidget();
00433     }
00434 }
00435 
00436 bool KDateComboBox::eventFilter(QObject *object, QEvent *event)
00437 {
00438     return KComboBox::eventFilter(object, event);
00439 }
00440 
00441 void KDateComboBox::keyPressEvent(QKeyEvent *keyEvent)
00442 {
00443     QDate temp;
00444     switch (keyEvent->key()) {
00445     case Qt::Key_Down:
00446         temp = d->m_date.addDays(-1).date();
00447         return;
00448     case Qt::Key_Up:
00449         temp = d->m_date.addDays(1).date();
00450         return;
00451     case Qt::Key_PageDown:
00452         temp = d->m_date.addMonths(-1).date();
00453         return;
00454     case Qt::Key_PageUp:
00455         temp = d->m_date.addMonths(1).date();
00456         return;
00457     default:
00458         KComboBox::keyPressEvent(keyEvent);
00459     }
00460     if (temp.isValid() && temp >= d->m_minDate && temp <= d->m_maxDate) {
00461         d->enterDate(temp);
00462     }
00463 }
00464 
00465 void KDateComboBox::focusOutEvent(QFocusEvent *event)
00466 {
00467     d->parseDate();
00468     d->warnDate();
00469     KComboBox::focusOutEvent(event);
00470 }
00471 
00472 void KDateComboBox::showPopup()
00473 {
00474     if (!isEditable() ||
00475         !d->m_dateMenu ||
00476         (d->m_options &KDateComboBox::SelectDate) != KDateComboBox::SelectDate) {
00477         return;
00478     }
00479 
00480     d->m_datePicker->blockSignals(true);
00481     d->m_datePicker->setDate(d->m_date.date());
00482     d->m_datePicker->blockSignals(false);
00483 
00484     const QRect desk = KGlobalSettings::desktopGeometry(this);
00485 
00486     QPoint popupPoint = mapToGlobal(QPoint(0, 0));
00487 
00488     const int dateFrameHeight = d->m_dateMenu->sizeHint().height();
00489     if (popupPoint.y() + height() + dateFrameHeight > desk.bottom()) {
00490         popupPoint.setY(popupPoint.y() - dateFrameHeight);
00491     } else {
00492         popupPoint.setY(popupPoint.y() + height());
00493     }
00494 
00495     const int dateFrameWidth = d->m_dateMenu->sizeHint().width();
00496     if (popupPoint.x() + dateFrameWidth > desk.right()) {
00497         popupPoint.setX(desk.right() - dateFrameWidth);
00498     }
00499 
00500     if (popupPoint.x() < desk.left()) {
00501         popupPoint.setX(desk.left());
00502     }
00503 
00504     if (popupPoint.y() < desk.top()) {
00505         popupPoint.setY(desk.top());
00506     }
00507 
00508     d->m_dateMenu->popup(popupPoint);
00509 }
00510 
00511 void KDateComboBox::hidePopup()
00512 {
00513     KComboBox::hidePopup();
00514 }
00515 
00516 void KDateComboBox::mousePressEvent(QMouseEvent *event)
00517 {
00518     KComboBox::mousePressEvent(event);
00519 }
00520 
00521 void KDateComboBox::wheelEvent(QWheelEvent *event)
00522 {
00523     KComboBox::wheelEvent(event);
00524 }
00525 
00526 void KDateComboBox::focusInEvent(QFocusEvent *event)
00527 {
00528     KComboBox::focusInEvent(event);
00529 }
00530 
00531 void KDateComboBox::resizeEvent(QResizeEvent *event)
00532 {
00533     KComboBox::resizeEvent(event);
00534 }
00535 
00536 #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.5
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