diff --git a/src/ktimecombobox.cpp b/src/ktimecombobox.cpp --- a/src/ktimecombobox.cpp +++ b/src/ktimecombobox.cpp @@ -22,9 +22,76 @@ #include #include #include +#include #include "kmessagebox.h" +class KTimeValidator : public QValidator +{ + Q_OBJECT +public: + KTimeValidator(QString timeFormat, QObject *parent = Q_NULLPTR); + KTimeValidator(QString timeFormat, QTime min, QTime max, QObject *parent = Q_NULLPTR); + ~KTimeValidator(); + virtual State validate(QString &input, int &pos) const Q_DECL_OVERRIDE; + void setMin(QTime min); + void setMax(QTime max); + +private: + QString m_timeFormat; + QTime m_min, m_max; +}; + +KTimeValidator::KTimeValidator(QString timeFormat, QObject *parent) + : + QValidator(parent), + m_timeFormat(timeFormat) +{ +} + +KTimeValidator::KTimeValidator(QString timeFormat, QTime min, QTime max, QObject *parent) + : + QValidator(parent), + m_timeFormat(timeFormat), + m_min(min), + m_max(max) +{ +} + +KTimeValidator::~KTimeValidator() +{ +} + + +void KTimeValidator::setMax(QTime max) +{ + m_max = max; +} + +void KTimeValidator::setMin(QTime min) +{ + m_min = min; +} + + +KTimeValidator::QValidator::State KTimeValidator::validate(QString& input, int& pos) const +{ + Q_UNUSED(pos); + QTime t = QTime::fromString(input, m_timeFormat); + if (t.isValid()){ + if (m_min.isValid() && t < m_min) + return State::Invalid; + if (m_max.isValid() && t > m_max) + return State::Invalid; + + return State::Acceptable; + } + else{ + return State::Invalid; + } +} + + class KTimeComboBoxPrivate { public: @@ -35,7 +102,6 @@ QTime defaultMinTime(); QTime defaultMaxTime(); - QString timeFormatToInputMask(const QString &format, bool nullMask = false); QTime nearestIntervalTime(const QTime &time); QString formatTime(const QTime &time); @@ -62,6 +128,7 @@ QLocale::FormatType m_displayFormat; int m_timeListInterval; QList m_timeList; + KTimeValidator *m_validator; }; KTimeComboBoxPrivate::KTimeComboBoxPrivate(KTimeComboBox *q) @@ -69,7 +136,8 @@ m_time(QTime(0, 0, 0)), m_warningShown(false), m_displayFormat(QLocale::ShortFormat), - m_timeListInterval(15) + m_timeListInterval(15), + m_validator(Q_NULLPTR) { m_options = KTimeComboBox::EditTime | KTimeComboBox::SelectTime; m_minTime = defaultMinTime(); @@ -78,6 +146,8 @@ KTimeComboBoxPrivate::~KTimeComboBoxPrivate() { + if (m_validator) + delete m_validator; } QTime KTimeComboBoxPrivate::defaultMinTime() @@ -90,41 +160,6 @@ return QTime(23, 59, 59, 999); } -QString KTimeComboBoxPrivate::timeFormatToInputMask(const QString &format, bool nullMask) -{ - const QLocale locale = q->locale(); - - //TODO not sure this will always work, does it support DigitSets, am/pm is dodgy? - QString mask = formatTime(QTime(12, 34, 56, 789)); - QString null = mask; - mask.replace(locale.toString(12), QLatin1String("09")); - null.replace(locale.toString(12), QLatin1String("")); - mask.replace(locale.toString(34), QLatin1String("99")); - null.replace(locale.toString(34), QLatin1String("")); - mask.replace(locale.toString(56), QLatin1String("99")); - null.replace(locale.toString(56), QLatin1String("")); - mask.replace(locale.toString(789), QLatin1String("900")); - null.replace(locale.toString(789), QLatin1String("")); - if (format.contains(QLatin1String("ap")) || - format.contains(QLatin1String("AP"))) { - QString am = locale.amText(); - QString pm = locale.pmText(); - int ampmLen = qMax(am.length(), pm.length()); - QString ampmMask; - for (int i = 0; i < ampmLen; ++i) { - ampmMask.append(QLatin1Char('a')); - } - mask.replace(pm, ampmMask); - null.replace(pm, QLatin1String("")); - } - - if (nullMask) { - return null; - } else { - return mask; - } -} - QTime KTimeComboBoxPrivate::nearestIntervalTime(const QTime &time) { int i = 0; @@ -150,10 +185,15 @@ q->blockSignals(true); q->clear(); - // Set the input mask from the current format + // Set the validator for the current format const QLocale locale = q->locale(); - q->lineEdit()->setInputMask(timeFormatToInputMask(locale.timeFormat(m_displayFormat))); - m_nullString = timeFormatToInputMask(locale.timeFormat(m_displayFormat), true); + if (m_validator){ + q->lineEdit()->setValidator(Q_NULLPTR); + delete m_validator; + } + m_validator = new KTimeValidator(locale.timeFormat(m_displayFormat), + m_minTime, m_maxTime); + q->lineEdit()->setValidator(m_validator); // If EditTime then set the line edit q->lineEdit()->setReadOnly((m_options & KTimeComboBox::EditTime) != KTimeComboBox::EditTime); @@ -532,3 +572,4 @@ } #include "moc_ktimecombobox.cpp" +#include "ktimecombobox.moc"