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 <QGroupBox>
00024 #include <QVBoxLayout>
00025 #include <QHBoxLayout>
00026
00027 #include <kdialog.h>
00028 #include <klocale.h>
00029
00030 #include "buttongroup.h"
00031 #include "radiobutton.h"
00032 #include "spinbox.h"
00033 #include "timeperiod.h"
00034 #include "timeselector.h"
00035 #include "repetition.moc"
00036
00037 using namespace KCal;
00038
00039
00040
00041
00042
00043
00044
00045 RepetitionButton::RepetitionButton(const QString& caption, bool waitForInitialisation, QWidget* parent)
00046 : QPushButton(caption, parent),
00047 mDialog(0),
00048 mInterval(0),
00049 mCount(0),
00050 mMaxDuration(-1),
00051 mDateOnly(false),
00052 mWaitForInit(waitForInitialisation),
00053 mReadOnly(false)
00054 {
00055 setCheckable(true);
00056 setChecked(false);
00057 connect(this, SIGNAL(clicked()), SLOT(slotPressed()));
00058 }
00059
00060 void RepetitionButton::set(const Duration& interval, int count)
00061 {
00062 mInterval = interval;
00063 mCount = count;
00064 setChecked(mInterval && mCount);
00065 }
00066
00067
00068
00069
00070 void RepetitionButton::set(const Duration& interval, int count, bool dateOnly, int maxDuration)
00071 {
00072 mInterval = interval;
00073 mCount = count;
00074 mMaxDuration = maxDuration;
00075 mDateOnly = dateOnly;
00076 setChecked(mInterval && mCount);
00077 }
00078
00079
00080
00081
00082
00083
00084 void RepetitionButton::activate(bool waitForInitialisation)
00085 {
00086 if (!mDialog)
00087 mDialog = new RepetitionDlg(i18nc("@title:window", "Alarm Sub-Repetition"), mReadOnly, this);
00088 mDialog->set(mInterval, mCount, mDateOnly, mMaxDuration);
00089 if (waitForInitialisation)
00090 emit needsInitialisation();
00091 else
00092 displayDialog();
00093 }
00094
00095
00096
00097
00098
00099 void RepetitionButton::initialise(const Duration& interval, int count, bool dateOnly, int maxDuration)
00100 {
00101 if (maxDuration > 0 && interval.asSeconds()/60 > maxDuration)
00102 count = 0;
00103 mCount = count;
00104 mInterval = interval;
00105 mMaxDuration = maxDuration;
00106 mDateOnly = dateOnly;
00107 if (mDialog)
00108 {
00109 mDialog->set(interval, count, dateOnly, maxDuration);
00110 displayDialog();
00111 }
00112 else
00113 setChecked(mInterval && mCount);
00114 }
00115
00116
00117
00118
00119
00120
00121
00122
00123 void RepetitionButton::displayDialog()
00124 {
00125 bool change = false;
00126 if (mReadOnly)
00127 {
00128 mDialog->setReadOnly(true);
00129 mDialog->exec();
00130 }
00131 else if (mDialog->exec() == QDialog::Accepted)
00132 {
00133 mCount = mDialog->count();
00134 mInterval = mDialog->interval();
00135 change = true;
00136 }
00137 setChecked(mInterval && mCount);
00138 delete mDialog;
00139 mDialog = 0;
00140 if (change)
00141 emit changed();
00142 }
00143
00144
00145
00146
00147
00148
00149
00150 static const int MAX_COUNT = 9999;
00151
00152
00153 RepetitionDlg::RepetitionDlg(const QString& caption, bool readOnly, QWidget* parent)
00154 : KDialog(parent),
00155 mMaxDuration(-1),
00156 mDateOnly(false),
00157 mReadOnly(readOnly)
00158 {
00159 setCaption(caption);
00160 setButtons(Ok|Cancel);
00161 int spacing = spacingHint();
00162 QWidget* page = new QWidget(this);
00163 setMainWidget(page);
00164 QVBoxLayout* topLayout = new QVBoxLayout(page);
00165 topLayout->setMargin(0);
00166 topLayout->setSpacing(spacing);
00167
00168 mTimeSelector = new TimeSelector(i18nc("@option:check Repeat every 10 minutes", "Repeat every"), QString(),
00169 i18nc("@info:whatsthis", "Instead of the alarm triggering just once at each recurrence, "
00170 "checking this option makes the alarm trigger multiple times at each recurrence."),
00171 i18nc("@info:whatsthis", "Enter the time between repetitions of the alarm"),
00172 true, page);
00173 mTimeSelector->setFixedSize(mTimeSelector->sizeHint());
00174 connect(mTimeSelector, SIGNAL(valueChanged(const KCal::Duration&)), SLOT(intervalChanged(const KCal::Duration&)));
00175 connect(mTimeSelector, SIGNAL(toggled(bool)), SLOT(repetitionToggled(bool)));
00176 topLayout->addWidget(mTimeSelector, 0, Qt::AlignLeft);
00177
00178 mButtonBox = new QGroupBox(page);
00179 topLayout->addWidget(mButtonBox);
00180 mButtonGroup = new ButtonGroup(mButtonBox);
00181 connect(mButtonGroup, SIGNAL(buttonSet(QAbstractButton*)), SLOT(typeClicked()));
00182
00183 QVBoxLayout* vlayout = new QVBoxLayout(mButtonBox);
00184 vlayout->setMargin(marginHint());
00185 vlayout->setSpacing(spacing);
00186 QHBoxLayout* layout = new QHBoxLayout();
00187 layout->setMargin(0);
00188 vlayout->addLayout(layout);
00189 mCountButton = new RadioButton(i18nc("@option:radio", "Number of repetitions:"), mButtonBox);
00190 mCountButton->setFixedSize(mCountButton->sizeHint());
00191 mCountButton->setWhatsThis(i18nc("@info:whatsthis", "Check to specify the number of times the alarm should repeat after each recurrence"));
00192 mButtonGroup->addButton(mCountButton);
00193 layout->addWidget(mCountButton);
00194 mCount = new SpinBox(1, MAX_COUNT, mButtonBox);
00195 mCount->setFixedSize(mCount->sizeHint());
00196 mCount->setSingleShiftStep(10);
00197 mCount->setSelectOnStep(false);
00198 connect(mCount, SIGNAL(valueChanged(int)), SLOT(countChanged(int)));
00199 mCount->setWhatsThis(i18nc("@info:whatsthis", "Enter the number of times to trigger the alarm after its initial occurrence"));
00200 layout->addWidget(mCount);
00201 mCountButton->setFocusWidget(mCount);
00202 layout->addStretch();
00203
00204 layout = new QHBoxLayout();
00205 layout->setMargin(0);
00206 vlayout->addLayout(layout);
00207 mDurationButton = new RadioButton(i18nc("@option:radio", "Duration:"), mButtonBox);
00208 mDurationButton->setFixedSize(mDurationButton->sizeHint());
00209 mDurationButton->setWhatsThis(i18nc("@info:whatsthis", "Check to specify how long the alarm is to be repeated"));
00210 mButtonGroup->addButton(mDurationButton);
00211 layout->addWidget(mDurationButton);
00212 mDuration = new TimePeriod(true, mButtonBox);
00213 mDuration->setFixedSize(mDuration->sizeHint());
00214 connect(mDuration, SIGNAL(valueChanged(const KCal::Duration&)), SLOT(durationChanged(const KCal::Duration&)));
00215 mDuration->setWhatsThis(i18nc("@info:whatsthis", "Enter the length of time to repeat the alarm"));
00216 layout->addWidget(mDuration);
00217 mDurationButton->setFocusWidget(mDuration);
00218 layout->addStretch();
00219
00220 mCountButton->setChecked(true);
00221 repetitionToggled(false);
00222 setReadOnly(mReadOnly);
00223 }
00224
00225
00226
00227
00228 void RepetitionDlg::set(const Duration& interval, int count, bool dateOnly, int maxDuration)
00229 {
00230 Duration inter = interval;
00231 if (!interval)
00232 count = 0;
00233 else if (!count)
00234 inter = 0;
00235 if (dateOnly != mDateOnly)
00236 {
00237 mDateOnly = dateOnly;
00238 mTimeSelector->setDateOnly(mDateOnly);
00239 mDuration->setDateOnly(mDateOnly);
00240 }
00241 mMaxDuration = maxDuration;
00242 if (mMaxDuration)
00243 {
00244 int maxhm = (mMaxDuration > 0) ? mMaxDuration : 9999;
00245 int maxdw = (mMaxDuration > 0) ? mMaxDuration / 1440 : 9999;
00246 mTimeSelector->setMaximum(maxhm, maxdw);
00247 mDuration->setMaximum(maxhm, maxdw);
00248 }
00249
00250 TimePeriod::Units units = mDateOnly ? TimePeriod::Days : TimePeriod::HoursMinutes;
00251 mTimeSelector->setPeriod(inter, mDateOnly, units);
00252 if (!mMaxDuration || !count)
00253 mTimeSelector->setChecked(false);
00254 else
00255 {
00256 bool on = mTimeSelector->isChecked();
00257 repetitionToggled(on);
00258 if (on)
00259 intervalChanged(inter);
00260 mCount->setValue(count);
00261 mDuration->setPeriod(inter * count, mDateOnly, units);
00262 mCountButton->setChecked(true);
00263 }
00264 mTimeSelector->setEnabled(mMaxDuration);
00265 }
00266
00267
00268
00269
00270 void RepetitionDlg::setReadOnly(bool ro)
00271 {
00272 ro = ro || mReadOnly;
00273 mTimeSelector->setReadOnly(ro);
00274 mCountButton->setReadOnly(ro);
00275 mCount->setReadOnly(ro);
00276 mDurationButton->setReadOnly(ro);
00277 mDuration->setReadOnly(ro);
00278 }
00279
00280
00281
00282
00283 Duration RepetitionDlg::interval() const
00284 {
00285 return mTimeSelector->period();
00286 }
00287
00288
00289
00290
00291 int RepetitionDlg::count() const
00292 {
00293 Duration interval = mTimeSelector->period();
00294 if (interval)
00295 {
00296 if (mCountButton->isChecked())
00297 return mCount->value();
00298 if (mDurationButton->isChecked())
00299 return mDuration->period().asSeconds() / interval.asSeconds();
00300 }
00301 return 0;
00302 }
00303
00304
00305
00306
00307
00308 void RepetitionDlg::intervalChanged(const KCal::Duration& interval)
00309 {
00310 if (mTimeSelector->isChecked() && interval.asSeconds() > 0)
00311 {
00312 mCount->setRange(1, (mMaxDuration >= 0 ? mMaxDuration / (interval.asSeconds()/60) : MAX_COUNT));
00313 if (mCountButton->isChecked())
00314 countChanged(mCount->value());
00315 else
00316 durationChanged(mDuration->period());
00317 }
00318 }
00319
00320
00321
00322
00323
00324 void RepetitionDlg::countChanged(int count)
00325 {
00326 Duration interval = mTimeSelector->period();
00327 if (interval)
00328 {
00329 bool blocked = mDuration->signalsBlocked();
00330 mDuration->blockSignals(true);
00331 mDuration->setPeriod(interval * count, mDateOnly,
00332 (mDateOnly ? TimePeriod::Days : TimePeriod::HoursMinutes));
00333 mDuration->blockSignals(blocked);
00334 }
00335 }
00336
00337
00338
00339
00340
00341 void RepetitionDlg::durationChanged(const KCal::Duration& duration)
00342 {
00343 Duration interval = mTimeSelector->period();
00344 if (interval)
00345 {
00346 bool blocked = mCount->signalsBlocked();
00347 mCount->blockSignals(true);
00348 mCount->setValue(duration.asSeconds() / interval.asSeconds());
00349 mCount->blockSignals(blocked);
00350 }
00351 }
00352
00353
00354
00355
00356 void RepetitionDlg::repetitionToggled(bool on)
00357 {
00358 if (mMaxDuration == 0)
00359 on = false;
00360 mButtonBox->setEnabled(on);
00361 mCount->setEnabled(on && mCountButton->isChecked());
00362 mDuration->setEnabled(on && mDurationButton->isChecked());
00363 }
00364
00365
00366
00367
00368 void RepetitionDlg::typeClicked()
00369 {
00370 if (mTimeSelector->isChecked())
00371 {
00372 mCount->setEnabled(mCountButton->isChecked());
00373 mDuration->setEnabled(mDurationButton->isChecked());
00374 }
00375 }