kalarm/lib
timeperiod.cpp
Go to the documentation of this file.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 <QStackedWidget>
00024
00025 #include <klocale.h>
00026 #include <kdialog.h>
00027
00028 #include "combobox.h"
00029 #include "spinbox.h"
00030 #include "timespinbox.h"
00031 #include "timeperiod.moc"
00032
00033 using namespace KCal;
00034
00035
00036
00037 QString TimePeriod::i18n_minutes() { return i18nc("@item:inlistbox Time units", "minutes"); }
00038 QString TimePeriod::i18n_hours_mins() { return i18nc("@item:inlistbox Time units", "hours/minutes"); }
00039 QString TimePeriod::i18n_days() { return i18nc("@item:inlistbox Time units", "days"); }
00040 QString TimePeriod::i18n_weeks() { return i18nc("@item:inlistbox Time units", "weeks"); }
00041
00042 static const int maxMinutes = 1000*60-1;
00043
00044
00045
00046
00047
00048
00049 TimePeriod::TimePeriod(bool allowHourMinute, QWidget* parent)
00050 : KHBox(parent),
00051 mMaxDays(9999),
00052 mNoHourMinute(!allowHourMinute),
00053 mReadOnly(false)
00054 {
00055 setSpacing(KDialog::spacingHint());
00056
00057 mSpinStack = new QStackedWidget(this);
00058 mSpinBox = new SpinBox(mSpinStack);
00059 mSpinBox->setSingleStep(1);
00060 mSpinBox->setSingleShiftStep(10);
00061 mSpinBox->setRange(1, mMaxDays);
00062 connect(mSpinBox, SIGNAL(valueChanged(int)), SLOT(slotDaysChanged(int)));
00063 mSpinStack->addWidget(mSpinBox);
00064
00065 mTimeSpinBox = new TimeSpinBox(0, 99999, mSpinStack);
00066 mTimeSpinBox->setRange(1, maxMinutes);
00067 connect(mTimeSpinBox, SIGNAL(valueChanged(int)), SLOT(slotTimeChanged(int)));
00068 mSpinStack->addWidget(mTimeSpinBox);
00069
00070 mSpinStack->setFixedSize(mSpinBox->sizeHint().expandedTo(mTimeSpinBox->sizeHint()));
00071 mHourMinuteRaised = mNoHourMinute;
00072 showHourMin(!mNoHourMinute);
00073
00074 mUnitsCombo = new ComboBox(this);
00075 mUnitsCombo->setEditable(false);
00076 if (mNoHourMinute)
00077 mDateOnlyOffset = 2;
00078 else
00079 {
00080 mDateOnlyOffset = 0;
00081 mUnitsCombo->addItem(i18n_minutes());
00082 mUnitsCombo->addItem(i18n_hours_mins());
00083 }
00084 mUnitsCombo->addItem(i18n_days());
00085 mUnitsCombo->addItem(i18n_weeks());
00086 mMaxUnitShown = Weeks;
00087 mUnitsCombo->setFixedSize(mUnitsCombo->sizeHint());
00088 connect(mUnitsCombo, SIGNAL(activated(int)), SLOT(slotUnitsSelected(int)));
00089
00090 setFocusProxy(mUnitsCombo);
00091 setTabOrder(mUnitsCombo, mSpinStack);
00092 }
00093
00094 void TimePeriod::setReadOnly(bool ro)
00095 {
00096 if (ro != mReadOnly)
00097 {
00098 mReadOnly = ro;
00099 mSpinBox->setReadOnly(ro);
00100 mTimeSpinBox->setReadOnly(ro);
00101 mUnitsCombo->setReadOnly(ro);
00102 }
00103 }
00104
00105
00106
00107
00108
00109 void TimePeriod::setSelectOnStep(bool sel)
00110 {
00111 mSpinBox->setSelectOnStep(sel);
00112 mTimeSpinBox->setSelectOnStep(sel);
00113 }
00114
00115
00116
00117
00118 void TimePeriod::setFocusOnCount()
00119 {
00120 mSpinStack->setFocus();
00121 }
00122
00123
00124
00125
00126
00127 void TimePeriod::setMaximum(int hourmin, int days)
00128 {
00129 Duration oldmins = period();
00130 if (hourmin > 0)
00131 {
00132 if (hourmin > maxMinutes)
00133 hourmin = maxMinutes;
00134 mTimeSpinBox->setRange(1, hourmin);
00135 }
00136 mMaxDays = (days >= 0) ? days : 0;
00137 adjustDayWeekShown();
00138 setUnitRange();
00139 Duration mins = period();
00140 if (mins != oldmins)
00141 emit valueChanged(mins);
00142 }
00143
00144
00145
00146
00147
00148 Duration TimePeriod::period() const
00149 {
00150 int factor = 1;
00151 switch (mUnitsCombo->currentIndex() + mDateOnlyOffset)
00152 {
00153 case HoursMinutes:
00154 return Duration(mTimeSpinBox->value() * 60, Duration::Seconds);
00155 case Minutes:
00156 return Duration(mSpinBox->value() * 60, Duration::Seconds);
00157 case Weeks:
00158 factor = 7;
00159
00160 case Days:
00161 return Duration(mSpinBox->value() * factor, Duration::Days);
00162 }
00163 return 0;
00164 }
00165
00166
00167
00168
00169
00170
00171 void TimePeriod::setPeriod(const Duration& perod, bool dateOnly, TimePeriod::Units defaultUnits)
00172 {
00173 Duration oldinterval = period();
00174 if (!dateOnly && mNoHourMinute)
00175 dateOnly = true;
00176 int item;
00177 if (perod)
00178 {
00179 int count = perod.value();
00180 if (perod.isDaily())
00181 {
00182 if (count % 7)
00183 item = Days;
00184 else
00185 {
00186 item = Weeks;
00187 count /= 7;
00188 }
00189 }
00190 else
00191 {
00192 count /= 60;
00193 item = (defaultUnits == Minutes && count <= mSpinBox->maximum()) ? Minutes : HoursMinutes;
00194 }
00195 if (item < mDateOnlyOffset)
00196 item = mDateOnlyOffset;
00197 else if (item > mMaxUnitShown)
00198 item = mMaxUnitShown;
00199 mUnitsCombo->setCurrentIndex(item - mDateOnlyOffset);
00200 if (item == HoursMinutes)
00201 mTimeSpinBox->setValue(count);
00202 else
00203 mSpinBox->setValue(count);
00204 item = setDateOnly(perod, dateOnly, false);
00205 }
00206 else
00207 {
00208 item = defaultUnits;
00209 if (item < mDateOnlyOffset)
00210 item = mDateOnlyOffset;
00211 else if (item > mMaxUnitShown)
00212 item = mMaxUnitShown;
00213 mUnitsCombo->setCurrentIndex(item - mDateOnlyOffset);
00214 if ((dateOnly && !mDateOnlyOffset) || (!dateOnly && mDateOnlyOffset))
00215 item = setDateOnly(perod, dateOnly, false);
00216 }
00217 showHourMin(item == HoursMinutes && !mNoHourMinute);
00218
00219 Duration newinterval = period();
00220 if (newinterval != oldinterval)
00221 emit valueChanged(newinterval);
00222 }
00223
00224
00225
00226
00227
00228 TimePeriod::Units TimePeriod::setDateOnly(const Duration& perod, bool dateOnly, bool signal)
00229 {
00230 Duration oldinterval = 0;
00231 if (signal)
00232 oldinterval = period();
00233 int index = mUnitsCombo->currentIndex();
00234 Units units = static_cast<Units>(index + mDateOnlyOffset);
00235 if (!mNoHourMinute)
00236 {
00237 if (!dateOnly && mDateOnlyOffset)
00238 {
00239
00240 mUnitsCombo->insertItem(0, i18n_minutes());
00241 mUnitsCombo->insertItem(1, i18n_hours_mins());
00242 mDateOnlyOffset = 0;
00243 adjustDayWeekShown();
00244 mUnitsCombo->setCurrentIndex(index += 2);
00245 }
00246 else if (dateOnly && !mDateOnlyOffset)
00247 {
00248
00249 mUnitsCombo->removeItem(0);
00250 mUnitsCombo->removeItem(0);
00251 mDateOnlyOffset = 2;
00252 if (index > 2)
00253 index -= 2;
00254 else
00255 index = 0;
00256 adjustDayWeekShown();
00257 mUnitsCombo->setCurrentIndex(index);
00258 if (units == HoursMinutes || units == Minutes)
00259 {
00260
00261 units = Days;
00262 mUnitsCombo->setCurrentIndex(Days - mDateOnlyOffset);
00263 mSpinBox->setValue(perod.asDays());
00264 }
00265 showHourMin(false);
00266 }
00267 }
00268
00269 if (signal)
00270 {
00271 Duration newinterval = period();
00272 if (newinterval != oldinterval)
00273 emit valueChanged(newinterval);
00274 }
00275 return units;
00276 }
00277
00278
00279
00280
00281 void TimePeriod::adjustDayWeekShown()
00282 {
00283 Units newMaxUnitShown = (mMaxDays >= 7) ? Weeks : (mMaxDays || mDateOnlyOffset) ? Days : HoursMinutes;
00284 if (newMaxUnitShown > mMaxUnitShown)
00285 {
00286 if (mMaxUnitShown < Days)
00287 mUnitsCombo->addItem(i18n_days());
00288 if (newMaxUnitShown == Weeks)
00289 mUnitsCombo->addItem(i18n_weeks());
00290 }
00291 else if (newMaxUnitShown < mMaxUnitShown)
00292 {
00293 if (mMaxUnitShown == Weeks)
00294 mUnitsCombo->removeItem(Weeks - mDateOnlyOffset);
00295 if (newMaxUnitShown < Days)
00296 mUnitsCombo->removeItem(Days - mDateOnlyOffset);
00297 }
00298 mMaxUnitShown = newMaxUnitShown;
00299 }
00300
00301
00302
00303
00304
00305 void TimePeriod::setUnitRange()
00306 {
00307 int maxval;
00308 switch (static_cast<Units>(mUnitsCombo->currentIndex() + mDateOnlyOffset))
00309 {
00310 case Weeks:
00311 maxval = mMaxDays / 7;
00312 if (maxval)
00313 break;
00314 mUnitsCombo->setCurrentIndex(Days - mDateOnlyOffset);
00315
00316 case Days:
00317 maxval = mMaxDays ? mMaxDays : 1;
00318 break;
00319 case Minutes:
00320 maxval = mTimeSpinBox->maximum();
00321 break;
00322 case HoursMinutes:
00323 default:
00324 return;
00325 }
00326 mSpinBox->setRange(1, maxval);
00327 }
00328
00329
00330
00331
00332 void TimePeriod::slotUnitsSelected(int index)
00333 {
00334 setUnitRange();
00335 showHourMin(index + mDateOnlyOffset == HoursMinutes);
00336 emit valueChanged(period());
00337 }
00338
00339
00340
00341
00342 void TimePeriod::slotDaysChanged(int)
00343 {
00344 if (!mHourMinuteRaised)
00345 emit valueChanged(period());
00346 }
00347
00348
00349
00350
00351 void TimePeriod::slotTimeChanged(int)
00352 {
00353 if (mHourMinuteRaised)
00354 emit valueChanged(period());
00355 }
00356
00357
00358
00359
00360 void TimePeriod::showHourMin(bool hourMinute)
00361 {
00362 if (hourMinute != mHourMinuteRaised)
00363 {
00364 mHourMinuteRaised = hourMinute;
00365 if (hourMinute)
00366 {
00367 mSpinStack->setCurrentWidget(mTimeSpinBox);
00368 mSpinStack->setFocusProxy(mTimeSpinBox);
00369 }
00370 else
00371 {
00372 mSpinStack->setCurrentWidget(mSpinBox);
00373 mSpinStack->setFocusProxy(mSpinBox);
00374 }
00375 }
00376 }
00377
00378
00379
00380
00381
00382
00383 void TimePeriod::setWhatsThises(const QString& units, const QString& dayWeek, const QString& hourMin)
00384 {
00385 mUnitsCombo->setWhatsThis(units);
00386 mSpinBox->setWhatsThis(dayWeek);
00387 mTimeSpinBox->setWhatsThis(hourMin.isNull() ? dayWeek : hourMin);
00388 }