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