22#include <QtCore/QTime>
23#include <QtGui/QKeyEvent>
24#include <QtGui/QLineEdit>
32class KTimeComboBoxPrivate
37 virtual ~KTimeComboBoxPrivate();
39 QTime defaultMinTime();
40 QTime defaultMaxTime();
42 QString timeFormatToInputMask(
const QString &format,
bool nullMask =
false);
43 QTime nearestIntervalTime(
const QTime &time);
44 QString formatTime(
const QTime &time);
45 QString convertDigits(
const QString &digits);
47 void initTimeWidget();
48 void updateTimeWidget();
51 void selectTime(
int index);
52 void editTime(
const QString &text);
53 void enterTime(
const QTime &time);
60 KTimeComboBox::Options m_options;
67 KLocale::TimeFormatOptions m_displayFormat;
68 int m_timeListInterval;
74 m_time(QTime(0, 0, 0)),
75 m_warningShown(false),
76 m_displayFormat(
KLocale::TimeDefault),
77 m_timeListInterval(15)
80 m_minTime = defaultMinTime();
81 m_maxTime = defaultMaxTime();
84KTimeComboBoxPrivate::~KTimeComboBoxPrivate()
88QTime KTimeComboBoxPrivate::defaultMinTime()
90 return QTime(0, 0, 0, 0);
93QTime KTimeComboBoxPrivate::defaultMaxTime()
95 return QTime(23, 59, 59, 999);
98QString KTimeComboBoxPrivate::timeFormatToInputMask(
const QString &format,
bool nullMask)
101 QString
mask = formatTime(QTime(12,34,56,789));
103 mask.replace(convertDigits(QLatin1String(
"12")), QLatin1String(
"09"));
104 null.replace(convertDigits(QLatin1String(
"12")), QLatin1String(
""));
105 mask.replace(convertDigits(QLatin1String(
"34")), QLatin1String(
"99"));
106 null.replace(convertDigits(QLatin1String(
"34")), QLatin1String(
""));
107 mask.replace(convertDigits(QLatin1String(
"56")), QLatin1String(
"99"));
108 null.replace(convertDigits(QLatin1String(
"56")), QLatin1String(
""));
109 mask.replace(convertDigits(QLatin1String(
"789")), QLatin1String(
"900"));
110 null.replace(convertDigits(QLatin1String(
"789")), QLatin1String(
""));
111 if (format.contains(QLatin1String(
"%p")) ||
112 format.contains(QLatin1String(
"%P"))) {
115 int ampmLen = qMax(am.length(), pm.length());
117 for (
int i = 0; i < ampmLen; ++i) {
118 ampmMask.append(QLatin1Char(
'a'));
120 mask.replace(pm, ampmMask);
121 null.replace(pm, QLatin1String(
""));
131QTime KTimeComboBoxPrivate::nearestIntervalTime(
const QTime &time)
134 while (q->itemData(i).toTime() < time) {
137 QTime before = q->itemData(i).toTime();
138 QTime after = q->itemData(i + 1).toTime();
139 if (before.secsTo(time) <= time.secsTo(after)) {
146QString KTimeComboBoxPrivate::formatTime(
const QTime &time)
151QString KTimeComboBoxPrivate::convertDigits(
const QString &digits)
156void KTimeComboBoxPrivate::initTimeWidget()
158 q->blockSignals(
true);
162 q->lineEdit()->setInputMask(timeFormatToInputMask(
KGlobal::locale()->timeFormat()));
163 m_nullString = timeFormatToInputMask(
KGlobal::locale()->timeFormat(),
true);
170 q->setMaxVisibleItems(10);
172 q->setMaxVisibleItems(0);
177 if (m_timeList.isEmpty()) {
178 QTime startTime = m_minTime;
179 QTime thisTime(startTime.hour(), 0, 0, 0);
180 while (thisTime.isValid() && thisTime <= startTime) {
181 thisTime = thisTime.addSecs(m_timeListInterval * 60);
183 QTime endTime = m_maxTime;
184 q->addItem(formatTime(startTime), startTime);
185 while (thisTime.isValid() && thisTime < endTime) {
186 q->addItem(formatTime(thisTime), thisTime);
187 QTime newTime = thisTime.addSecs(m_timeListInterval * 60);
188 if (newTime.isValid() && newTime > thisTime) {
194 q->addItem(formatTime(endTime), endTime);
196 foreach (
const QTime &thisTime, m_timeList) {
197 if (thisTime.isValid() && thisTime >= m_minTime && thisTime <= m_maxTime) {
198 q->addItem(formatTime(thisTime), thisTime);
202 q->blockSignals(
false);
205void KTimeComboBoxPrivate::updateTimeWidget()
207 q->blockSignals(
true);
208 int pos = q->lineEdit()->cursorPosition();
211 if (!m_time.isValid() || m_time < m_minTime) {
213 }
else if (m_time > m_maxTime) {
216 while (q->itemData(i).toTime() < m_time && i < q->count() - 1) {
220 q->setCurrentIndex(i);
221 if (m_time.isValid()) {
222 q->lineEdit()->setText(formatTime(m_time));
224 q->lineEdit()->setText(QString());
226 q->lineEdit()->setCursorPosition(pos);
227 q->blockSignals(
false);
230void KTimeComboBoxPrivate::selectTime(
int index)
232 enterTime(q->itemData(index).toTime());
235void KTimeComboBoxPrivate::editTime(
const QString &text)
237 m_warningShown =
false;
241void KTimeComboBoxPrivate::parseTime()
246void KTimeComboBoxPrivate::enterTime(
const QTime &time)
250 emit q->timeEntered(m_time);
253void KTimeComboBoxPrivate::warnTime()
255 if (!m_warningShown && !q->isValid() &&
258 if (!m_time.isValid()) {
259 warnMsg =
i18nc(
"@info",
"The time you entered is invalid");
260 }
else if (m_time < m_minTime) {
261 if (m_minWarnMsg.isEmpty()) {
262 warnMsg =
i18nc(
"@info",
"Time cannot be earlier than %1", formatTime(m_minTime));
264 warnMsg = m_minWarnMsg;
265 warnMsg.replace(
"%1", formatTime(m_minTime));
267 }
else if (m_time > m_maxTime) {
268 if (m_maxWarnMsg.isEmpty()) {
269 warnMsg =
i18nc(
"@info",
"Time cannot be later than %1", formatTime(m_maxTime));
271 warnMsg = m_maxWarnMsg;
272 warnMsg.replace(
"%1", formatTime(m_maxTime));
275 m_warningShown =
true;
282 d(new KTimeComboBoxPrivate(this))
285 setInsertPolicy(QComboBox::NoInsert);
286 setSizeAdjustPolicy(QComboBox::AdjustToContents);
288 d->updateTimeWidget();
290 connect(
this, SIGNAL(activated(
int)),
291 this, SLOT(selectTime(
int)));
292 connect(
this, SIGNAL(editTextChanged(QString)),
293 this, SLOT(editTime(QString)));
309 if (time == d->m_time) {
319 d->updateTimeWidget();
331 return d->m_time.isValid() &&
332 d->m_time >= d->m_minTime &&
333 d->m_time <= d->m_maxTime;
338 return lineEdit()->text() == d->m_nullString;
348 if (options != d->m_options) {
349 d->m_options = options;
351 d->updateTimeWidget();
362 setTimeRange(minTime, d->m_maxTime, minWarnMsg, d->m_maxWarnMsg);
367 setTimeRange(d->defaultMinTime(), d->m_maxTime, QString(), d->m_maxWarnMsg);
377 setTimeRange(d->m_minTime, maxTime, d->m_minWarnMsg, maxWarnMsg);
382 setTimeRange(d->m_minTime, d->defaultMaxTime(), d->m_minWarnMsg, QString());
386 const QString &minWarnMsg,
const QString &maxWarnMsg)
388 if (!minTime.isValid() || !maxTime.isValid() || minTime > maxTime) {
392 if (minTime != d->m_minTime || maxTime != d->m_maxTime ||
393 minWarnMsg != d->m_minWarnMsg || maxWarnMsg != d->m_maxWarnMsg) {
394 d->m_minTime = minTime;
395 d->m_maxTime = maxTime;
396 d->m_minWarnMsg = minWarnMsg;
397 d->m_maxWarnMsg = maxWarnMsg;
399 d->updateTimeWidget();
405 setTimeRange(d->defaultMinTime(), d->defaultMaxTime(), QString(), QString());
410 return d->m_displayFormat;
415 if (format != d->m_displayFormat) {
416 d->m_displayFormat = format;
418 d->updateTimeWidget();
424 return d->m_timeListInterval;
429 if (minutes != d->m_timeListInterval) {
431 int lowMins = (d->m_minTime.hour() * 60) + d->m_minTime.minute();
432 int hiMins = (d->m_maxTime.hour() * 60) + d->m_maxTime.minute();
433 if (d->m_minTime.minute() == 0 && d->m_maxTime.minute() == 59) {
436 if ((hiMins - lowMins) % minutes == 0) {
437 d->m_timeListInterval = minutes;
438 d->m_timeList.clear();
451 for (
int i = 0; i < c; ++i) {
452 list.append(itemData(i).toTime());
458 const QString &minWarnMsg,
const QString &maxWarnMsg)
460 if (timeList != d->m_timeList) {
461 d->m_timeList.clear();
462 foreach (
const QTime &time, timeList) {
463 if (time.isValid() && !d->m_timeList.contains(time)) {
464 d->m_timeList.append(time);
467 qSort(d->m_timeList);
469 setTimeRange(d->m_timeList.first(), d->m_timeList.last(),
470 minWarnMsg, maxWarnMsg);
482 switch (keyEvent->key()) {
484 temp = d->m_time.addSecs(-60);
487 temp = d->m_time.addSecs(60);
489 case Qt::Key_PageDown:
490 temp = d->m_time.addSecs(-3600);
493 temp = d->m_time.addSecs(3600);
496 KComboBox::keyPressEvent(keyEvent);
499 if (temp.isValid() && temp >= d->m_minTime && temp <= d->m_maxTime) {
508 KComboBox::focusOutEvent(event);
513 KComboBox::showPopup();
518 KComboBox::hidePopup();
523 KComboBox::mousePressEvent(event);
533 KComboBox::focusInEvent(event);
538 KComboBox::resizeEvent(event);
541#include "ktimecombobox.moc"
virtual bool eventFilter(QObject *, QEvent *)
Re-implemented for internal reasons.
virtual void wheelEvent(QWheelEvent *ev)
void setEditable(bool editable)
"Re-implemented" so that setEditable(true) creates a KLineEdit instead of QLineEdit.
QString convertDigits(const QString &str, DigitSet digitSet, bool ignoreContext=false) const
QString formatTime(const QTime &pTime, bool includeSecs=false, bool isDuration=false) const
QTime readTime(const QString &str, bool *ok=0) const
QString dayPeriodText(const QTime &time, DateTimeComponentFormat format=DefaultComponentFormat) const
static void sorry(QWidget *parent, const QString &text, const QString &caption=QString(), Options options=Notify)
Display an "Sorry" dialog.
virtual void mousePressEvent(QMouseEvent *event)
void setTimeListInterval(int minutes)
Set the interval between times able to be selected from the drop-down.
@ ForceTime
Any set or entered time will be forced to one of the drop-down times.
@ SelectTime
Allow the user to select the time from a drop-down menu.
@ WarnOnInvalid
Show a warning box on focus out if the user enters an invalid time.
@ EditTime
Allow the user to manually edit the time in the combo line edit.
KLocale::TimeFormatOptions displayFormat() const
Return the currently set time format.
virtual void wheelEvent(QWheelEvent *event)
void resetMinimumTime()
Reset the minimum time to the default of 00:00:00.000.
virtual void focusOutEvent(QFocusEvent *event)
void setMaximumTime(const QTime &maxTime, const QString &maxWarnMsg=QString())
Set the maximum allowed time.
void resetMaximumTime()
Reset the maximum time to the default of 23:59:59.999.
virtual bool eventFilter(QObject *object, QEvent *event)
Re-implemented for internal reasons.
virtual void assignTime(const QTime &time)
Assign the time for the widget.
bool isNull() const
Return if the current user input is null.
virtual void resizeEvent(QResizeEvent *event)
void resetTimeRange()
Reset the minimum and maximum time to the default values.
void setOptions(Options options)
Set the new widget options.
virtual ~KTimeComboBox()
Destroy the widget.
void setTimeRange(const QTime &minTime, const QTime &maxTime, const QString &minWarnMsg=QString(), const QString &maxWarnMsg=QString())
Set the minimum and maximum time range.
virtual void focusInEvent(QFocusEvent *event)
virtual void keyPressEvent(QKeyEvent *event)
void setTime(const QTime &time)
Set the currently selected time.
QList< QTime > timeList() const
Return the list of times able to be selected in the drop-down.
void setDisplayFormat(KLocale::TimeFormatOptions formatOptions)
Sets the time format to display.
bool isValid() const
Return if the current user input is valid.
void setTimeList(QList< QTime > timeList, const QString &minWarnMsg=QString(), const QString &maxWarnMsg=QString())
Set the list of times able to be selected from the drop-down.
KTimeComboBox(QWidget *parent=0)
Create a new KTimeComboBox widget.
void setMinimumTime(const QTime &minTime, const QString &minWarnMsg=QString())
Set the minimum allowed time.
void timeChanged(const QTime &time)
Signal if the time has been changed either manually by the user or programatically.
QString i18nc(const char *ctxt, const char *text)