KDEUI
kdatetimeedit.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 "kdatetimeedit.h" 00021 00022 #include <QtCore/QStringList> 00023 #include <QtGui/QKeyEvent> 00024 #include <QtGui/QMenu> 00025 #include <QtGui/QLineEdit> 00026 #include <QtGui/QWidgetAction> 00027 00028 #include "kdebug.h" 00029 #include "kdatetime.h" 00030 #include "ksystemtimezone.h" 00031 #include "kcalendarsystem.h" 00032 #include "kcombobox.h" 00033 #include "kdatepicker.h" 00034 #include "kdatecombobox.h" 00035 #include "kmessagebox.h" 00036 00037 #include "ui_kdatetimeedit.h" 00038 00039 class KDateTimeEditPrivate 00040 { 00041 public: 00042 KDateTimeEditPrivate(KDateTimeEdit *q); 00043 virtual ~KDateTimeEditPrivate(); 00044 00045 const KCalendarSystem *calendar() const; 00046 00047 KDateTime defaultMinDateTime(); 00048 KDateTime defaultMaxDateTime(); 00049 00050 void initWidgets(); 00051 void initDateWidget(); 00052 void initTimeWidget(); 00053 void initCalendarWidget(); 00054 void updateCalendarWidget(); 00055 void initTimeSpecWidget(); 00056 void updateTimeSpecWidget(); 00057 00058 void warnDateTime(); 00059 00060 //private slots: 00061 void selectCalendar(int index); 00062 void enterCalendar(KLocale::CalendarSystem calendarSystem); 00063 void selectTimeZone(int index); 00064 void enterTimeZone(const QString &zone); 00065 00066 KDateTimeEdit *const q; 00067 00068 KDateTimeEdit::Options m_options; 00069 KDateTime m_dateTime; 00070 KDateTime m_minDateTime; 00071 KDateTime m_maxDateTime; 00072 QString m_minWarnMsg; 00073 QString m_maxWarnMsg; 00074 00075 QList<KLocale::CalendarSystem> m_calendarSystems; 00076 KTimeZones::ZoneMap m_zones; 00077 00078 Ui::KDateTimeEdit ui; 00079 }; 00080 00081 KDateTimeEditPrivate::KDateTimeEditPrivate(KDateTimeEdit *q) 00082 :q(q) 00083 { 00084 m_options = KDateTimeEdit::ShowDate | KDateTimeEdit::EditDate | KDateTimeEdit::SelectDate | 00085 KDateTimeEdit::ShowTime | KDateTimeEdit::EditTime | KDateTimeEdit::SelectTime | 00086 KDateTimeEdit::DatePicker | KDateTimeEdit::DateKeywords; 00087 m_dateTime = KDateTime::currentLocalDateTime(); 00088 m_dateTime.setTime(QTime(0, 0, 0)); 00089 m_calendarSystems = KCalendarSystem::calendarSystemsList(); 00090 m_zones = KSystemTimeZones::zones(); 00091 } 00092 00093 KDateTimeEditPrivate::~KDateTimeEditPrivate() 00094 { 00095 } 00096 00097 const KCalendarSystem *KDateTimeEditPrivate::calendar() const 00098 { 00099 return ui.m_dateCombo->calendar(); 00100 } 00101 00102 KDateTime KDateTimeEditPrivate::defaultMinDateTime() 00103 { 00104 return KDateTime(calendar()->earliestValidDate(), QTime(0, 0, 0, 0)); 00105 } 00106 00107 KDateTime KDateTimeEditPrivate::defaultMaxDateTime() 00108 { 00109 return KDateTime(calendar()->latestValidDate(), QTime(23, 59, 59, 999)); 00110 } 00111 00112 void KDateTimeEditPrivate::initWidgets() 00113 { 00114 initDateWidget(); 00115 initTimeWidget(); 00116 initCalendarWidget(); 00117 initTimeSpecWidget(); 00118 } 00119 00120 void KDateTimeEditPrivate::initDateWidget() 00121 { 00122 ui.m_dateCombo->blockSignals(true); 00123 ui.m_dateCombo->setVisible((m_options &KDateTimeEdit::ShowDate) == KDateTimeEdit::ShowDate); 00124 KDateComboBox::Options options; 00125 if ((m_options & KDateTimeEdit::EditDate) == KDateTimeEdit::EditDate) { 00126 options = options | KDateComboBox::EditDate; 00127 } 00128 if ((m_options & KDateTimeEdit::SelectDate) == KDateTimeEdit::SelectDate) { 00129 options = options | KDateComboBox::SelectDate; 00130 } 00131 if ((m_options & KDateTimeEdit::DatePicker) == KDateTimeEdit::DatePicker) { 00132 options = options | KDateComboBox::DatePicker; 00133 } 00134 if ((m_options & KDateTimeEdit::DateKeywords) == KDateTimeEdit::DateKeywords) { 00135 options = options | KDateComboBox::DateKeywords; 00136 } 00137 ui.m_dateCombo->setOptions(options); 00138 ui.m_dateCombo->blockSignals(false); 00139 } 00140 00141 void KDateTimeEditPrivate::initTimeWidget() 00142 { 00143 ui.m_timeCombo->blockSignals(true); 00144 ui.m_timeCombo->setVisible((m_options &KDateTimeEdit::ShowDate) == KDateTimeEdit::ShowDate); 00145 KTimeComboBox::Options options; 00146 if ((m_options &KDateTimeEdit::EditTime) == KDateTimeEdit::EditTime) { 00147 options = options | KTimeComboBox::EditTime; 00148 } 00149 if ((m_options &KDateTimeEdit::SelectTime) == KDateTimeEdit::SelectTime) { 00150 options = options | KTimeComboBox::SelectTime; 00151 } 00152 if ((m_options &KDateTimeEdit::ForceTime) == KDateTimeEdit::ForceTime) { 00153 options = options | KTimeComboBox::ForceTime; 00154 } 00155 ui.m_timeCombo->setOptions(options); 00156 ui.m_timeCombo->blockSignals(false); 00157 } 00158 00159 void KDateTimeEditPrivate::initCalendarWidget() 00160 { 00161 ui.m_calendarCombo->blockSignals(true); 00162 ui.m_calendarCombo->clear(); 00163 foreach (KLocale::CalendarSystem calendar, m_calendarSystems) { 00164 ui.m_calendarCombo->addItem(KCalendarSystem::calendarLabel(calendar), calendar); 00165 } 00166 ui.m_calendarCombo->setCurrentIndex(ui.m_calendarCombo->findData(ui.m_dateCombo->calendarSystem())); 00167 ui.m_calendarCombo->setVisible((m_options &KDateTimeEdit::ShowCalendar) == KDateTimeEdit::ShowCalendar); 00168 ui.m_calendarCombo->setEnabled((m_options &KDateTimeEdit::SelectCalendar) == KDateTimeEdit::SelectCalendar); 00169 ui.m_calendarCombo->setEditable(false); 00170 ui.m_calendarCombo->blockSignals(false); 00171 } 00172 00173 void KDateTimeEditPrivate::updateCalendarWidget() 00174 { 00175 ui.m_calendarCombo->blockSignals(true); 00176 ui.m_calendarCombo->setCurrentIndex(ui.m_calendarCombo->findData(ui.m_dateCombo->calendarSystem())); 00177 ui.m_calendarCombo->blockSignals(false); 00178 } 00179 00180 void KDateTimeEditPrivate::selectCalendar(int index) 00181 { 00182 enterCalendar((KLocale::CalendarSystem) ui.m_calendarCombo->itemData(index).toInt()); 00183 } 00184 00185 void KDateTimeEditPrivate::enterCalendar(KLocale::CalendarSystem calendarSystem) 00186 { 00187 q->setCalendarSystem(calendarSystem); 00188 emit q->calendarEntered(ui.m_dateCombo->calendarSystem()); 00189 } 00190 00191 void KDateTimeEditPrivate::initTimeSpecWidget() 00192 { 00193 ui.m_timeSpecCombo->blockSignals(true); 00194 ui.m_timeSpecCombo->clear(); 00195 ui.m_timeSpecCombo->addItem(i18nc("UTC time zone", "UTC"), "UTC"); 00196 ui.m_timeSpecCombo->addItem(i18nc("No specific time zone", "Floating"), "Floating"); 00197 QStringList keys = m_zones.keys(); 00198 QMap<QString, QString> names; 00199 foreach (const QString &key, keys) { 00200 names.insert(i18n(key.toUtf8()).replace('_', ' '), key); 00201 } 00202 QMapIterator<QString, QString> i(names); 00203 while (i.hasNext()) { 00204 i.next(); 00205 ui.m_timeSpecCombo->addItem(i.key(), i.value()); 00206 } 00207 ui.m_timeSpecCombo->setVisible((m_options &KDateTimeEdit::ShowTimeSpec) == KDateTimeEdit::ShowTimeSpec); 00208 ui.m_timeSpecCombo->setEnabled((m_options &KDateTimeEdit::SelectTimeSpec) == KDateTimeEdit::SelectTimeSpec); 00209 ui.m_timeSpecCombo->setEditable(false); 00210 ui.m_timeSpecCombo->blockSignals(false); 00211 } 00212 00213 void KDateTimeEditPrivate::updateTimeSpecWidget() 00214 { 00215 ui.m_timeSpecCombo->blockSignals(true); 00216 ui.m_timeSpecCombo->blockSignals(false); 00217 } 00218 00219 void KDateTimeEditPrivate::selectTimeZone(int index) 00220 { 00221 enterTimeZone(ui.m_timeCombo->itemData(index).toString()); 00222 } 00223 00224 void KDateTimeEditPrivate::enterTimeZone(const QString &zone) 00225 { 00226 q->setTimeSpec(m_zones.value(zone)); 00227 emit q->dateTimeEntered(m_dateTime); 00228 emit q->timeSpecEntered(m_dateTime.timeSpec()); 00229 } 00230 00231 void KDateTimeEditPrivate::warnDateTime() 00232 { 00233 if (!q->isValid() && 00234 (m_options &KDateTimeEdit::WarnOnInvalid) == KDateTimeEdit::WarnOnInvalid) { 00235 QString warnMsg; 00236 if (!m_dateTime.isValid()) { 00237 //TODO Add missing string 00238 //warnMsg = i18n("The date or time you entered is invalid"); 00239 } else if (m_dateTime < m_minDateTime) { 00240 if (m_minWarnMsg.isEmpty()) { 00241 //TODO Add datetime to string 00242 //warnMsg = i18nc("@info", "Date and time cannot be earlier than %1", formatDate(m_minDate)); 00243 warnMsg = i18nc("@info", "The entered date and time is before the minimum allowed date and time."); 00244 } else { 00245 warnMsg = m_minWarnMsg; 00246 //TODO localize properly 00247 warnMsg.replace("%1", KGlobal::locale()->formatDateTime(m_minDateTime)); 00248 } 00249 } else if (m_dateTime > m_maxDateTime) { 00250 if (m_maxWarnMsg.isEmpty()) { 00251 //TODO Add datetime to string 00252 //warnMsg = i18nc("@info", "Date cannot be later than %1", formatDate(m_maxDate)); 00253 warnMsg = i18nc("@info", "The entered date and time is after the maximum allowed date and time."); 00254 } else { 00255 warnMsg = m_maxWarnMsg; 00256 warnMsg.replace("%1", KGlobal::locale()->formatDateTime(m_maxDateTime)); 00257 } 00258 } 00259 KMessageBox::sorry(q, warnMsg); 00260 } 00261 } 00262 00263 00264 KDateTimeEdit::KDateTimeEdit(QWidget *parent) 00265 :QWidget(parent), 00266 d(new KDateTimeEditPrivate(this)) 00267 { 00268 KGlobal::locale()->insertCatalog("timezones4"); 00269 d->ui.setupUi(this); 00270 //Need to do the min/max defaults here and not in private init as need to wait for ui to init 00271 //the KDateComboBox which holds the calendar object. Revisit this??? 00272 d->m_minDateTime = d->defaultMinDateTime(); 00273 d->m_maxDateTime = d->defaultMaxDateTime(); 00274 d->ui.m_calendarCombo->installEventFilter(this); 00275 d->ui.m_dateCombo->installEventFilter(this); 00276 d->ui.m_timeCombo->installEventFilter(this); 00277 d->ui.m_timeSpecCombo->installEventFilter(this); 00278 d->initWidgets(); 00279 00280 connect( d->ui.m_calendarCombo, SIGNAL(activated(int)), 00281 this, SLOT(selectCalendar(int))); 00282 connect( d->ui.m_timeSpecCombo, SIGNAL(activated(int)), 00283 this, SLOT(selectTimeZone(int))); 00284 } 00285 00286 KDateTimeEdit::~KDateTimeEdit() 00287 { 00288 delete d; 00289 } 00290 00291 KDateTime KDateTimeEdit::dateTime() const 00292 { 00293 return d->m_dateTime; 00294 } 00295 00296 KLocale::CalendarSystem KDateTimeEdit::calendarSystem() const 00297 { 00298 return d-> ui.m_dateCombo->calendarSystem(); 00299 } 00300 00301 QDate KDateTimeEdit::date() const 00302 { 00303 return d->m_dateTime.date(); 00304 } 00305 00306 QTime KDateTimeEdit::time() const 00307 { 00308 return d->m_dateTime.time(); 00309 } 00310 00311 KDateTime::Spec KDateTimeEdit::timeSpec() const 00312 { 00313 return d->m_dateTime.timeSpec(); 00314 } 00315 00316 bool KDateTimeEdit::isValid() const 00317 { 00318 return d->m_dateTime.isValid() && 00319 d->m_dateTime >= d->m_minDateTime && 00320 d->m_dateTime <= d->m_maxDateTime; 00321 } 00322 00323 bool KDateTimeEdit::isNull() const 00324 { 00325 return isNullDate() && isNullTime(); 00326 } 00327 00328 bool KDateTimeEdit::isValidDate() const 00329 { 00330 return d->ui.m_dateCombo->isValid(); 00331 } 00332 00333 bool KDateTimeEdit::isNullDate() const 00334 { 00335 return d->ui.m_dateCombo->isNull(); 00336 } 00337 00338 bool KDateTimeEdit::isValidTime() const 00339 { 00340 return d->ui.m_timeCombo->isValid(); 00341 } 00342 00343 bool KDateTimeEdit::isNullTime() const 00344 { 00345 return d->ui.m_timeCombo->isNull(); 00346 } 00347 00348 void KDateTimeEdit::setOptions(Options options) 00349 { 00350 if (options != d->m_options) { 00351 d->m_options = options; 00352 d->initWidgets(); 00353 } 00354 } 00355 00356 KDateTimeEdit::Options KDateTimeEdit::options() const 00357 { 00358 return d->m_options; 00359 } 00360 00361 void KDateTimeEdit::setDateTime(const KDateTime &dateTime) 00362 { 00363 if (dateTime != d->m_dateTime) { 00364 assignDateTime(dateTime); 00365 emit dateTimeChanged(d->m_dateTime); 00366 emit dateChanged(d->m_dateTime.date()); 00367 emit timeChanged(d->m_dateTime.time()); 00368 } 00369 } 00370 00371 void KDateTimeEdit::assignDateTime(const KDateTime &dateTime) 00372 { 00373 d->m_dateTime = dateTime; 00374 d->ui.m_dateCombo->setDate(dateTime.date()); 00375 d->ui.m_timeCombo->setTime(dateTime.time()); 00376 } 00377 00378 void KDateTimeEdit::setDate(const QDate &date) 00379 { 00380 if (date != d->m_dateTime.date()) { 00381 assignDate(date); 00382 emit dateTimeChanged(d->m_dateTime); 00383 emit dateChanged(d->m_dateTime.date()); 00384 } 00385 } 00386 00387 void KDateTimeEdit::assignDate(const QDate &date) 00388 { 00389 d->m_dateTime.setDate(date); 00390 d->ui.m_dateCombo->setDate(date); 00391 } 00392 00393 void KDateTimeEdit::setCalendarSystem(KLocale::CalendarSystem calendarSystem) 00394 { 00395 if (calendarSystem == d->ui.m_dateCombo->calendarSystem() || 00396 !d->m_calendarSystems.contains(calendarSystem)) { 00397 return; 00398 } 00399 00400 assignCalendarSystem(calendarSystem); 00401 emit calendarChanged(d->ui.m_dateCombo->calendarSystem()); 00402 } 00403 00404 void KDateTimeEdit::assignCalendarSystem(KLocale::CalendarSystem calendarSystem) 00405 { 00406 d->ui.m_dateCombo->setCalendarSystem(calendarSystem); 00407 d->updateCalendarWidget(); 00408 } 00409 00410 void KDateTimeEdit::setCalendar(KCalendarSystem *calendar) 00411 { 00412 d->ui.m_dateCombo->setCalendar(calendar); 00413 d->updateCalendarWidget(); 00414 } 00415 00416 void KDateTimeEdit::setTime(const QTime &time) 00417 { 00418 if (time != d->m_dateTime.time()) { 00419 assignTime(time); 00420 emit dateTimeChanged(d->m_dateTime); 00421 emit timeChanged(d->m_dateTime.time()); 00422 } 00423 } 00424 00425 void KDateTimeEdit::assignTime(const QTime &time) 00426 { 00427 d->m_dateTime.setTime(time); 00428 d->ui.m_timeCombo->setTime(time); 00429 } 00430 00431 void KDateTimeEdit::setTimeSpec(const KDateTime::Spec &spec) 00432 { 00433 if (spec == d->m_dateTime.timeSpec() || !spec.isValid()) { 00434 return; 00435 } 00436 00437 assignTimeSpec(spec); 00438 emit dateTimeChanged(d->m_dateTime); 00439 emit timeSpecChanged(d->m_dateTime.timeSpec()); 00440 } 00441 00442 void KDateTimeEdit::assignTimeSpec(const KDateTime::Spec &spec) 00443 { 00444 d->m_dateTime.setTimeSpec(spec); 00445 d->updateTimeSpecWidget(); 00446 } 00447 00448 void KDateTimeEdit::setMinimumDateTime(const KDateTime &minDateTime, const QString &minWarnMsg) 00449 { 00450 setDateTimeRange(minDateTime, maximumDateTime(), minWarnMsg, d->m_maxWarnMsg); 00451 } 00452 00453 KDateTime KDateTimeEdit::minimumDateTime() const 00454 { 00455 return d->m_minDateTime; 00456 } 00457 00458 void KDateTimeEdit::resetMinimumDateTime() 00459 { 00460 d->m_minDateTime = d->defaultMinDateTime(); 00461 } 00462 00463 void KDateTimeEdit::setMaximumDateTime(const KDateTime &maxDateTime, const QString &maxWarnMsg) 00464 { 00465 setDateTimeRange(minimumDateTime(), maxDateTime, d->m_minWarnMsg, maxWarnMsg); 00466 } 00467 00468 KDateTime KDateTimeEdit::maximumDateTime() const 00469 { 00470 return d->m_maxDateTime; 00471 } 00472 00473 void KDateTimeEdit::resetMaximumDateTime() 00474 { 00475 d->m_maxDateTime = d->defaultMaxDateTime(); 00476 } 00477 00478 void KDateTimeEdit::setDateTimeRange(const KDateTime &minDateTime, 00479 const KDateTime &maxDateTime, 00480 const QString &minErrorMsg, 00481 const QString &maxErrorMsg) 00482 { 00483 if (minDateTime.isValid() && 00484 maxDateTime.isValid() && 00485 minDateTime <= maxDateTime && 00486 d->calendar()->isValid(minDateTime.date()) && 00487 d->calendar()->isValid(maxDateTime.date())) { 00488 00489 d->m_minDateTime = minDateTime; 00490 d->m_minWarnMsg = minErrorMsg; 00491 d->m_maxDateTime = maxDateTime; 00492 d->m_maxWarnMsg = maxErrorMsg; 00493 00494 } 00495 } 00496 00497 void KDateTimeEdit::resetDateTimeRange() 00498 { 00499 setDateTimeRange(d->defaultMinDateTime(), d->defaultMaxDateTime()); 00500 } 00501 00502 void KDateTimeEdit::setCalendarSystemsList(QList<KLocale::CalendarSystem> calendars) 00503 { 00504 if (calendars != d->m_calendarSystems) { 00505 d->m_calendarSystems = calendars; 00506 d->updateCalendarWidget(); 00507 } 00508 } 00509 00510 QList<KLocale::CalendarSystem> KDateTimeEdit::calendarSystemsList() const 00511 { 00512 return d->m_calendarSystems; 00513 } 00514 00515 void KDateTimeEdit::setDateDisplayFormat(KLocale::DateFormat format) 00516 { 00517 d->ui.m_dateCombo->setDisplayFormat(format); 00518 } 00519 00520 KLocale::DateFormat KDateTimeEdit::dateDisplayFormat() const 00521 { 00522 return d->ui.m_dateCombo->displayFormat(); 00523 } 00524 00525 void KDateTimeEdit::setDateMap(QMap<QDate, QString> dateMap) 00526 { 00527 d->ui.m_dateCombo->setDateMap(dateMap); 00528 } 00529 00530 QMap<QDate, QString> KDateTimeEdit::dateMap() const 00531 { 00532 return d->ui.m_dateCombo->dateMap(); 00533 } 00534 00535 void KDateTimeEdit::setTimeDisplayFormat(KLocale::TimeFormatOptions formatOptions) 00536 { 00537 d->ui.m_timeCombo->setDisplayFormat(formatOptions); 00538 } 00539 00540 KLocale::TimeFormatOptions KDateTimeEdit::timeDisplayFormat() const 00541 { 00542 return d->ui.m_timeCombo->displayFormat(); 00543 } 00544 00545 void KDateTimeEdit::setTimeListInterval(int minutes) 00546 { 00547 d->ui.m_timeCombo->setTimeListInterval(minutes); 00548 } 00549 00550 int KDateTimeEdit::timeListInterval() const 00551 { 00552 return d->ui.m_timeCombo->timeListInterval(); 00553 } 00554 00555 void KDateTimeEdit::setTimeList(QList<QTime> timeList, 00556 const QString &minWarnMsg, 00557 const QString &maxWarnMsg) 00558 { 00559 d->ui.m_timeCombo->setTimeList(timeList, minWarnMsg, maxWarnMsg); 00560 } 00561 00562 QList<QTime> KDateTimeEdit::timeList() const 00563 { 00564 return d->ui.m_timeCombo->timeList(); 00565 } 00566 00567 void KDateTimeEdit::setTimeZones(const KTimeZones::ZoneMap &zones) 00568 { 00569 if (zones != d->m_zones) { 00570 d->m_zones = zones; 00571 d->updateTimeSpecWidget(); 00572 } 00573 } 00574 00575 KTimeZones::ZoneMap KDateTimeEdit::timeZones() const 00576 { 00577 return d->m_zones; 00578 } 00579 00580 bool KDateTimeEdit::eventFilter(QObject *object, QEvent *event) 00581 { 00582 return QWidget::eventFilter(object, event); 00583 } 00584 00585 void KDateTimeEdit::focusInEvent(QFocusEvent *event) 00586 { 00587 QWidget::focusInEvent(event); 00588 } 00589 00590 void KDateTimeEdit::focusOutEvent(QFocusEvent *event) 00591 { 00592 d->warnDateTime(); 00593 QWidget::focusOutEvent(event); 00594 } 00595 00596 void KDateTimeEdit::resizeEvent(QResizeEvent *event) 00597 { 00598 QWidget::resizeEvent(event); 00599 } 00600 00601 #include "kdatetimeedit.moc"
KDE 4.7 API Reference