00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "kalarm.h"
00022
00023 #include <qvalidator.h>
00024 #include <qlineedit.h>
00025 #include <klocale.h>
00026
00027 #include "timespinbox.moc"
00028
00029
00030 class TimeSpinBox::TimeValidator : public QValidator
00031 {
00032 public:
00033 TimeValidator(int minMin, int maxMin, QWidget* parent, const char* name = 0)
00034 : QValidator(parent, name),
00035 minMinute(minMin), maxMinute(maxMin), m12Hour(false), mPm(false) { }
00036 virtual State validate(QString&, int&) const;
00037 int minMinute, maxMinute;
00038 bool m12Hour;
00039 bool mPm;
00040 };
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 TimeSpinBox::TimeSpinBox(bool use24hour, QWidget* parent, const char* name)
00058 : SpinBox2(0, 1439, 1, 60, parent, name),
00059 mMinimumValue(0),
00060 m12Hour(!use24hour),
00061 mPm(false),
00062 mInvalid(false),
00063 mEnteredSetValue(false)
00064 {
00065 mValidator = new TimeValidator(0, 1439, this, "TimeSpinBox validator");
00066 mValidator->m12Hour = m12Hour;
00067 setValidator(mValidator);
00068 setWrapping(true);
00069 setReverseWithLayout(false);
00070 setShiftSteps(5, 360);
00071 setSelectOnStep(false);
00072 setAlignment(Qt::AlignHCenter);
00073 connect(this, SIGNAL(valueChanged(int)), SLOT(slotValueChanged(int)));
00074 }
00075
00076
00077
00078
00079 TimeSpinBox::TimeSpinBox(int minMinute, int maxMinute, QWidget* parent, const char* name)
00080 : SpinBox2(minMinute, maxMinute, 1, 60, parent, name),
00081 mMinimumValue(minMinute),
00082 m12Hour(false),
00083 mInvalid(false),
00084 mEnteredSetValue(false)
00085 {
00086 mValidator = new TimeValidator(minMinute, maxMinute, this, "TimeSpinBox validator");
00087 setValidator(mValidator);
00088 setReverseWithLayout(false);
00089 setShiftSteps(5, 300);
00090 setSelectOnStep(false);
00091 setAlignment(QApplication::reverseLayout() ? Qt::AlignLeft : Qt::AlignRight);
00092 }
00093
00094 QString TimeSpinBox::shiftWhatsThis()
00095 {
00096 return i18n("Press the Shift key while clicking the spin buttons to adjust the time by a larger step (6 hours / 5 minutes).");
00097 }
00098
00099 QTime TimeSpinBox::time() const
00100 {
00101 return QTime(value() / 60, value() % 60);
00102 }
00103
00104 QString TimeSpinBox::mapValueToText(int v)
00105 {
00106 if (m12Hour)
00107 {
00108 if (v < 60)
00109 v += 720;
00110 else if (v >= 780)
00111 v -= 720;
00112 }
00113 QString s;
00114 s.sprintf((wrapping() ? "%02d:%02d" : "%d:%02d"), v/60, v%60);
00115 return s;
00116 }
00117
00118
00119
00120
00121
00122
00123
00124 int TimeSpinBox::mapTextToValue(bool* ok)
00125 {
00126 QString text = cleanText();
00127 int colon = text.find(':');
00128 if (colon >= 0)
00129 {
00130
00131 QString hour = text.left(colon).stripWhiteSpace();
00132 QString minute = text.mid(colon + 1).stripWhiteSpace();
00133 if (!minute.isEmpty())
00134 {
00135 bool okmin;
00136 bool okhour = true;
00137 int m = minute.toUInt(&okmin);
00138 int h = 0;
00139 if (!hour.isEmpty())
00140 h = hour.toUInt(&okhour);
00141 if (okhour && okmin && m < 60)
00142 {
00143 if (m12Hour)
00144 {
00145 if (h == 0 || h > 12)
00146 h = 100;
00147 else if (h == 12)
00148 h = 0;
00149 if (mPm)
00150 h += 12;
00151 }
00152 int t = h * 60 + m;
00153 if (t >= mMinimumValue && t <= maxValue())
00154 {
00155 if (ok)
00156 *ok = true;
00157 return t;
00158 }
00159 }
00160 }
00161 }
00162 else if (text.length() == 4)
00163 {
00164
00165 bool okn;
00166 int mins = text.toUInt(&okn);
00167 if (okn)
00168 {
00169 int m = mins % 100;
00170 int h = mins / 100;
00171 if (m12Hour)
00172 {
00173 if (h == 0 || h > 12)
00174 h = 100;
00175 else if (h == 12)
00176 h = 0;
00177 if (mPm)
00178 h += 12;
00179 }
00180 int t = h * 60 + m;
00181 if (h < 24 && m < 60 && t >= mMinimumValue && t <= maxValue())
00182 {
00183 if (ok)
00184 *ok = true;
00185 return t;
00186 }
00187 }
00188
00189 }
00190 if (ok)
00191 *ok = false;
00192 return 0;
00193 }
00194
00195
00196
00197
00198
00199
00200 void TimeSpinBox::setValid(bool valid)
00201 {
00202 if (valid && mInvalid)
00203 {
00204 mInvalid = false;
00205 if (value() < mMinimumValue)
00206 SpinBox2::setValue(mMinimumValue);
00207 setSpecialValueText(QString());
00208 setMinValue(mMinimumValue);
00209 }
00210 else if (!valid && !mInvalid)
00211 {
00212 mInvalid = true;
00213 setMinValue(mMinimumValue - 1);
00214 setSpecialValueText(QString::fromLatin1("**:**"));
00215 SpinBox2::setValue(mMinimumValue - 1);
00216 }
00217 }
00218
00219
00220
00221
00222 void TimeSpinBox::setValue(int minutes)
00223 {
00224 if (!mEnteredSetValue)
00225 {
00226 mEnteredSetValue = true;
00227 mPm = (minutes >= 720);
00228 if (minutes > maxValue())
00229 setValid(false);
00230 else
00231 {
00232 if (mInvalid)
00233 {
00234 mInvalid = false;
00235 setSpecialValueText(QString());
00236 setMinValue(mMinimumValue);
00237 }
00238 SpinBox2::setValue(minutes);
00239 mEnteredSetValue = false;
00240 }
00241 }
00242 }
00243
00244
00245
00246
00247
00248 void TimeSpinBox::stepUp()
00249 {
00250 if (mInvalid)
00251 setValid(true);
00252 else
00253 SpinBox2::stepUp();
00254 }
00255
00256 void TimeSpinBox::stepDown()
00257 {
00258 if (mInvalid)
00259 setValid(true);
00260 else
00261 SpinBox2::stepDown();
00262 }
00263
00264 bool TimeSpinBox::isValid() const
00265 {
00266 return value() >= mMinimumValue;
00267 }
00268
00269 void TimeSpinBox::slotValueChanged(int value)
00270 {
00271 mPm = mValidator->mPm = (value >= 720);
00272 }
00273
00274 QSize TimeSpinBox::sizeHint() const
00275 {
00276 QSize sz = SpinBox2::sizeHint();
00277 QFontMetrics fm(font());
00278 return QSize(sz.width() + fm.width(":"), sz.height());
00279 }
00280
00281 QSize TimeSpinBox::minimumSizeHint() const
00282 {
00283 QSize sz = SpinBox2::minimumSizeHint();
00284 QFontMetrics fm(font());
00285 return QSize(sz.width() + fm.width(":"), sz.height());
00286 }
00287
00288
00289
00290
00291
00292
00293 QValidator::State TimeSpinBox::TimeValidator::validate(QString& text, int& ) const
00294 {
00295 QString cleanText = text.stripWhiteSpace();
00296 if (cleanText.isEmpty())
00297 return QValidator::Intermediate;
00298 QValidator::State state = QValidator::Acceptable;
00299 QString hour;
00300 bool ok;
00301 int hr = 0;
00302 int mn = 0;
00303 int colon = cleanText.find(':');
00304 if (colon >= 0)
00305 {
00306 QString minute = cleanText.mid(colon + 1);
00307 if (minute.isEmpty())
00308 state = QValidator::Intermediate;
00309 else if ((mn = minute.toUInt(&ok)) >= 60 || !ok)
00310 return QValidator::Invalid;
00311
00312 hour = cleanText.left(colon);
00313 }
00314 else if (maxMinute >= 1440)
00315 {
00316
00317 hour = cleanText;
00318 state = QValidator::Intermediate;
00319 }
00320 else
00321 {
00322 if (cleanText.length() > 4)
00323 return QValidator::Invalid;
00324 if (cleanText.length() < 4)
00325 state = QValidator::Intermediate;
00326 hour = cleanText.left(2);
00327 QString minute = cleanText.mid(2);
00328 if (!minute.isEmpty()
00329 && ((mn = minute.toUInt(&ok)) >= 60 || !ok))
00330 return QValidator::Invalid;
00331 }
00332
00333 if (!hour.isEmpty())
00334 {
00335 hr = hour.toUInt(&ok);
00336 if (m12Hour)
00337 {
00338 if (hr == 0 || hr > 12)
00339 hr = 100;
00340 else if (hr == 12)
00341 hr = 0;
00342 if (mPm)
00343 hr += 12;
00344 }
00345 if (!ok || hr > maxMinute/60)
00346 return QValidator::Invalid;
00347 }
00348 if (state == QValidator::Acceptable)
00349 {
00350 int t = hr * 60 + mn;
00351 if (t < minMinute || t > maxMinute)
00352 return QValidator::Invalid;
00353 }
00354 return state;
00355 }