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 <QGridLayout>
00025 #include <QLabel>
00026
00027 #include <kdialog.h>
00028 #include <kmessagebox.h>
00029 #include <klocale.h>
00030
00031 #include "buttongroup.h"
00032 #include "checkbox.h"
00033 #include "dateedit.h"
00034 #include "datetime.h"
00035 #include "preferences.h"
00036 #include "radiobutton.h"
00037 #include "synchtimer.h"
00038 #include "timeedit.h"
00039 #include "timespinbox.h"
00040 #include "timezonecombo.h"
00041 #include "alarmtimewidget.moc"
00042
00043 static const QTime time_23_59(23, 59);
00044
00045
00046 const int AlarmTimeWidget::maxDelayTime = 999*60 + 59;
00047
00048 QString AlarmTimeWidget::i18n_TimeAfterPeriod()
00049 {
00050 return i18nc("@info/plain", "Enter the length of time (in hours and minutes) after "
00051 "the current time to schedule the alarm.");
00052 }
00053
00054
00055
00056
00057
00058 AlarmTimeWidget::AlarmTimeWidget(const QString& groupBoxTitle, int mode, QWidget* parent, QWidget* custom)
00059 : QFrame(parent),
00060 mMinDateTimeIsNow(false),
00061 mPastMax(false),
00062 mMinMaxTimeSet(false)
00063 {
00064 init(mode, custom, groupBoxTitle);
00065 }
00066
00067
00068
00069
00070 AlarmTimeWidget::AlarmTimeWidget(int mode, QWidget* parent, QWidget* custom)
00071 : QFrame(parent),
00072 mMinDateTimeIsNow(false),
00073 mPastMax(false),
00074 mMinMaxTimeSet(false)
00075 {
00076 init(mode, custom);
00077 }
00078
00079 void AlarmTimeWidget::init(int mode, QWidget* custom, const QString& title)
00080 {
00081 static const QString recurText = i18nc("@info/plain",
00082 "If a recurrence is configured, the start date/time will be adjusted "
00083 "to the first recurrence on or after the entered date/time.");
00084 static const QString tzText = i18nc("@info/plain",
00085 "This uses KAlarm's default time zone, set in the Preferences dialog.");
00086
00087 QWidget* topWidget;
00088 if (title.isEmpty())
00089 topWidget = this;
00090 else
00091 {
00092 QBoxLayout* layout = new QVBoxLayout(this);
00093 layout->setMargin(0);
00094 layout->setSpacing(0);
00095 topWidget = new QGroupBox(title, this);
00096 layout->addWidget(topWidget);
00097 }
00098 mDeferring = mode & DEFER_TIME;
00099 mButtonGroup = new ButtonGroup(this);
00100 connect(mButtonGroup, SIGNAL(buttonSet(QAbstractButton*)), SLOT(slotButtonSet(QAbstractButton*)));
00101 QVBoxLayout* topLayout = new QVBoxLayout(topWidget);
00102 topLayout->setSpacing(KDialog::spacingHint());
00103 topLayout->setMargin(title.isEmpty() ? 0 : KDialog::marginHint());
00104
00105
00106 mAtTimeRadio = new RadioButton((mDeferring ? i18nc("@option:radio", "Defer to date/time:") : i18nc("@option:radio", "At date/time:")), topWidget);
00107 mAtTimeRadio->setFixedSize(mAtTimeRadio->sizeHint());
00108 mAtTimeRadio->setWhatsThis(mDeferring ? i18nc("@info:whatsthis", "Reschedule the alarm to the specified date and time.")
00109 : i18nc("@info:whatsthis", "Specify the date, or date and time, to schedule the alarm."));
00110 mButtonGroup->addButton(mAtTimeRadio);
00111
00112
00113 mDateEdit = new DateEdit(topWidget);
00114 connect(mDateEdit, SIGNAL(dateEntered(const QDate&)), SLOT(dateTimeChanged()));
00115 mDateEdit->setWhatsThis(i18nc("@info:whatsthis",
00116 "<para>Enter the date to schedule the alarm.</para>"
00117 "<para>%1</para>", (mDeferring ? tzText : recurText)));
00118 mAtTimeRadio->setFocusWidget(mDateEdit);
00119
00120
00121 KHBox* timeBox = new KHBox(topWidget);
00122 timeBox->setSpacing(2*KDialog::spacingHint());
00123 mTimeEdit = new TimeEdit(timeBox);
00124 mTimeEdit->setFixedSize(mTimeEdit->sizeHint());
00125 connect(mTimeEdit, SIGNAL(valueChanged(int)), SLOT(dateTimeChanged()));
00126 mTimeEdit->setWhatsThis(i18nc("@info:whatsthis",
00127 "<para>Enter the time to schedule the alarm.</para>"
00128 "<para>%1</para>"
00129 "<para>%2</para>", (mDeferring ? tzText : recurText), TimeSpinBox::shiftWhatsThis()));
00130
00131 mAnyTime = -1;
00132 if (mDeferring)
00133 {
00134 mAnyTimeAllowed = false;
00135 mAnyTimeCheckBox = 0;
00136 }
00137 else
00138 {
00139 mAnyTimeAllowed = true;
00140 mAnyTimeCheckBox = new CheckBox(i18nc("@option:check", "Any time"), timeBox);
00141 mAnyTimeCheckBox->setFixedSize(mAnyTimeCheckBox->sizeHint());
00142 connect(mAnyTimeCheckBox, SIGNAL(toggled(bool)), SLOT(slotAnyTimeToggled(bool)));
00143 mAnyTimeCheckBox->setWhatsThis(i18nc("@info:whatsthis",
00144 "Check to specify only a date (without a time) for the alarm. The alarm will trigger at the first opportunity on the selected date."));
00145 }
00146
00147
00148 mAfterTimeRadio = new RadioButton((mDeferring ? i18nc("@option:radio", "Defer for time interval:") : i18nc("@option:radio", "Time from now:")), topWidget);
00149 mAfterTimeRadio->setFixedSize(mAfterTimeRadio->sizeHint());
00150 mAfterTimeRadio->setWhatsThis(mDeferring ? i18nc("@info:whatsthis", "Reschedule the alarm for the specified time interval after now.")
00151 : i18nc("@info:whatsthis", "Schedule the alarm after the specified time interval from now."));
00152 mButtonGroup->addButton(mAfterTimeRadio);
00153
00154
00155 mDelayTimeEdit = new TimeSpinBox(1, maxDelayTime, topWidget);
00156 mDelayTimeEdit->setValue(1439);
00157 mDelayTimeEdit->setFixedSize(mDelayTimeEdit->sizeHint());
00158 connect(mDelayTimeEdit, SIGNAL(valueChanged(int)), SLOT(delayTimeChanged(int)));
00159 mDelayTimeEdit->setWhatsThis(mDeferring ? i18nc("@info:whatsthis", "<para>%1</para><para>%2</para>", i18n_TimeAfterPeriod(), TimeSpinBox::shiftWhatsThis())
00160 : i18nc("@info:whatsthis", "<para>%1</para><para>%2</para><para>%3</para>", i18n_TimeAfterPeriod(), recurText, TimeSpinBox::shiftWhatsThis()));
00161 mAfterTimeRadio->setFocusWidget(mDelayTimeEdit);
00162
00163
00164 QGridLayout* grid = new QGridLayout();
00165 grid->setMargin(0);
00166 topLayout->addLayout(grid);
00167 if (mDeferring)
00168 {
00169 grid->addWidget(mAtTimeRadio, 0, 0);
00170 grid->addWidget(mDateEdit, 0, 1, Qt::AlignLeft);
00171 grid->addWidget(timeBox, 1, 1, Qt::AlignLeft);
00172 grid->setColumnStretch(2, 1);
00173 topLayout->addStretch();
00174 QHBoxLayout* layout = new QHBoxLayout();
00175 topLayout->addLayout(layout);
00176 layout->addWidget(mAfterTimeRadio);
00177 layout->addWidget(mDelayTimeEdit);
00178 layout->addStretch();
00179 }
00180 else
00181 {
00182 grid->addWidget(mAtTimeRadio, 0, 0, Qt::AlignLeft);
00183 grid->addWidget(mDateEdit, 0, 1, Qt::AlignLeft);
00184 grid->addWidget(timeBox, 0, 2, Qt::AlignLeft);
00185 grid->setRowStretch(1, 1);
00186 grid->addWidget(mAfterTimeRadio, 2, 0, Qt::AlignLeft);
00187 grid->addWidget(mDelayTimeEdit, 2, 1, Qt::AlignLeft);
00188 if (custom)
00189 {
00190 custom->setParent(this);
00191 grid->addWidget(custom, 2, 2, Qt::AlignRight);
00192 }
00193 grid->setColumnStretch(3, 1);
00194 topLayout->addStretch();
00195 }
00196
00197 if (!mDeferring)
00198 {
00199 QHBoxLayout* layout = new QHBoxLayout();
00200 topLayout->addLayout(layout);
00201 layout->setSpacing(2*KDialog::spacingHint());
00202
00203
00204 KHBox* box = new KHBox(topWidget);
00205 box->setMargin(0);
00206 box->setSpacing(KDialog::spacingHint());
00207 QLabel* label = new QLabel(i18nc("@label:listbox", "Time zone:"), box);
00208 mTimeZone = new TimeZoneCombo(box);
00209 mTimeZone->setMaxVisibleItems(15);
00210 connect(mTimeZone, SIGNAL(activated(int)), SLOT(slotTimeZoneChanged()));
00211 box->setWhatsThis(i18nc("@info:whatsthis", "Select the time zone to use for this alarm."));
00212 label->setBuddy(mTimeZone);
00213 layout->addWidget(box);
00214
00215
00216 mNoTimeZone = new CheckBox(i18nc("@option:check", "Ignore time zone"), topWidget);
00217 connect(mNoTimeZone, SIGNAL(toggled(bool)), SLOT(slotTimeZoneToggled(bool)));
00218 mNoTimeZone->setWhatsThis(i18nc("@info:whatsthis",
00219 "<para>Check to use the local computer time, ignoring time zones.</para>"
00220 "<para>You are recommended not to use this option if the alarm has a "
00221 "recurrence specified in hours/minutes. If you do, the alarm may "
00222 "occur at unexpected times after daylight saving time shifts.</para>"));
00223 layout->addWidget(mNoTimeZone);
00224 layout->addStretch();
00225 }
00226
00227
00228 mAtTimeRadio->setChecked(true);
00229 slotButtonSet(mAtTimeRadio);
00230
00231
00232 MinuteTimer::connect(this, SLOT(updateTimes()));
00233 }
00234
00235
00236
00237
00238 void AlarmTimeWidget::setReadOnly(bool ro)
00239 {
00240 mAtTimeRadio->setReadOnly(ro);
00241 mDateEdit->setReadOnly(ro);
00242 mTimeEdit->setReadOnly(ro);
00243 if (mAnyTimeCheckBox)
00244 mAnyTimeCheckBox->setReadOnly(ro);
00245 mAfterTimeRadio->setReadOnly(ro);
00246 if (!mDeferring)
00247 {
00248 mTimeZone->setReadOnly(ro);
00249 mNoTimeZone->setReadOnly(ro);
00250 }
00251 mDelayTimeEdit->setReadOnly(ro);
00252 }
00253
00254
00255
00256
00257 void AlarmTimeWidget::selectTimeFromNow(int minutes)
00258 {
00259 mAfterTimeRadio->setChecked(true);
00260 if (minutes > 0)
00261 mDelayTimeEdit->setValue(minutes);
00262 }
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273 KDateTime AlarmTimeWidget::getDateTime(int* minsFromNow, bool checkExpired, bool showErrorMessage, QWidget** errorWidget) const
00274 {
00275 if (minsFromNow)
00276 *minsFromNow = 0;
00277 if (errorWidget)
00278 *errorWidget = 0;
00279 KDateTime now = KDateTime::currentUtcDateTime();
00280 now.setTime(QTime(now.time().hour(), now.time().minute(), 0));
00281 if (!mAtTimeRadio->isChecked())
00282 {
00283 if (!mDelayTimeEdit->isValid())
00284 {
00285 if (showErrorMessage)
00286 KMessageBox::sorry(const_cast<AlarmTimeWidget*>(this), i18nc("@info", "Invalid time"));
00287 if (errorWidget)
00288 *errorWidget = mDelayTimeEdit;
00289 return KDateTime();
00290 }
00291 int delayMins = mDelayTimeEdit->value();
00292 if (minsFromNow)
00293 *minsFromNow = delayMins;
00294 return now.addSecs(delayMins * 60).toTimeSpec(mTimeSpec);
00295 }
00296 else
00297 {
00298 bool dateOnly = mAnyTimeAllowed && mAnyTimeCheckBox && mAnyTimeCheckBox->isChecked();
00299 if (!mDateEdit->isValid() || !mTimeEdit->isValid())
00300 {
00301
00302 if (!mDateEdit->isValid())
00303 {
00304 if (showErrorMessage)
00305 KMessageBox::sorry(const_cast<AlarmTimeWidget*>(this), i18nc("@info", "Invalid date"));
00306 if (errorWidget)
00307 *errorWidget = mDateEdit;
00308 }
00309 else
00310 {
00311 if (showErrorMessage)
00312 KMessageBox::sorry(const_cast<AlarmTimeWidget*>(this), i18nc("@info", "Invalid time"));
00313 if (errorWidget)
00314 *errorWidget = mTimeEdit;
00315 }
00316 return KDateTime();
00317 }
00318
00319 KDateTime result;
00320 if (dateOnly)
00321 {
00322 result = KDateTime(mDateEdit->date(), mTimeSpec);
00323 if (checkExpired && result.date() < now.date())
00324 {
00325 if (showErrorMessage)
00326 KMessageBox::sorry(const_cast<AlarmTimeWidget*>(this), i18nc("@info", "Alarm date has already expired"));
00327 if (errorWidget)
00328 *errorWidget = mDateEdit;
00329 return KDateTime();
00330 }
00331 }
00332 else
00333 {
00334 result = KDateTime(mDateEdit->date(), mTimeEdit->time(), mTimeSpec);
00335 if (checkExpired && result <= now.addSecs(1))
00336 {
00337 if (showErrorMessage)
00338 KMessageBox::sorry(const_cast<AlarmTimeWidget*>(this), i18nc("@info", "Alarm time has already expired"));
00339 if (errorWidget)
00340 *errorWidget = mTimeEdit;
00341 return KDateTime();
00342 }
00343 }
00344 return result;
00345 }
00346 }
00347
00348
00349
00350
00351 void AlarmTimeWidget::setDateTime(const DateTime& dt)
00352 {
00353
00354 if (mDeferring)
00355 mTimeSpec = dt.timeSpec().isValid() ? dt.timeSpec() : KDateTime::LocalZone;
00356 else
00357 {
00358 KTimeZone tz = dt.timeZone();
00359 mNoTimeZone->setChecked(!tz.isValid());
00360 mTimeZone->setTimeZone(tz.isValid() ? tz : Preferences::timeZone());
00361 slotTimeZoneChanged();
00362 }
00363
00364 if (dt.date().isValid())
00365 {
00366 mTimeEdit->setValue(dt.effectiveTime());
00367 mDateEdit->setDate(dt.date());
00368 dateTimeChanged();
00369 }
00370 else
00371 {
00372 mTimeEdit->setValid(false);
00373 mDateEdit->setInvalid();
00374 mDelayTimeEdit->setValid(false);
00375 }
00376 if (mAnyTimeCheckBox)
00377 {
00378 bool dateOnly = dt.isDateOnly();
00379 if (dateOnly)
00380 mAnyTimeAllowed = true;
00381 mAnyTimeCheckBox->setChecked(dateOnly);
00382 setAnyTime();
00383 }
00384 }
00385
00386
00387
00388
00389 void AlarmTimeWidget::setMinDateTimeIsCurrent()
00390 {
00391 mMinDateTimeIsNow = true;
00392 mMinDateTime = KDateTime();
00393 KDateTime now = KDateTime::currentDateTime(mTimeSpec);
00394 mDateEdit->setMinDate(now.date());
00395 setMaxMinTimeIf(now);
00396 }
00397
00398
00399
00400
00401
00402 void AlarmTimeWidget::setMinDateTime(const KDateTime& dt)
00403 {
00404 mMinDateTimeIsNow = false;
00405 mMinDateTime = dt.toTimeSpec(mTimeSpec);
00406 mDateEdit->setMinDate(mMinDateTime.date());
00407 setMaxMinTimeIf(KDateTime::currentDateTime(mTimeSpec));
00408 }
00409
00410
00411
00412
00413
00414 void AlarmTimeWidget::setMaxDateTime(const DateTime& dt)
00415 {
00416 mPastMax = false;
00417 if (dt.isValid() && dt.isDateOnly())
00418 mMaxDateTime = dt.effectiveKDateTime().addSecs(24*3600 - 60).toTimeSpec(mTimeSpec);
00419 else
00420 mMaxDateTime = dt.kDateTime().toTimeSpec(mTimeSpec);
00421 mDateEdit->setMaxDate(mMaxDateTime.date());
00422 KDateTime now = KDateTime::currentDateTime(mTimeSpec);
00423 setMaxMinTimeIf(now);
00424 setMaxDelayTime(now);
00425 }
00426
00427
00428
00429
00430
00431 void AlarmTimeWidget::setMaxMinTimeIf(const KDateTime& now)
00432 {
00433 int mint = 0;
00434 QTime maxt = time_23_59;
00435 mMinMaxTimeSet = false;
00436 if (mMaxDateTime.isValid())
00437 {
00438 bool set = true;
00439 KDateTime minDT;
00440 if (mMinDateTimeIsNow)
00441 minDT = now.addSecs(60);
00442 else if (mMinDateTime.isValid())
00443 minDT = mMinDateTime;
00444 else
00445 set = false;
00446 if (set && mMaxDateTime.date() == minDT.date())
00447 {
00448
00449
00450 mint = minDT.time().hour()*60 + minDT.time().minute();
00451 maxt = mMaxDateTime.time();
00452 mMinMaxTimeSet = true;
00453 }
00454 }
00455 mTimeEdit->setMinimum(mint);
00456 mTimeEdit->setMaximum(maxt);
00457 mTimeEdit->setWrapping(!mint && maxt == time_23_59);
00458 }
00459
00460
00461
00462
00463
00464 void AlarmTimeWidget::setMaxDelayTime(const KDateTime& now)
00465 {
00466 int maxVal = maxDelayTime;
00467 if (mMaxDateTime.isValid())
00468 {
00469 if (now.date().daysTo(mMaxDateTime.date()) < 100)
00470 {
00471 KDateTime dt(now);
00472 dt.setTime(QTime(now.time().hour(), now.time().minute(), 0));
00473 maxVal = dt.secsTo(mMaxDateTime) / 60;
00474 if (maxVal > maxDelayTime)
00475 maxVal = maxDelayTime;
00476 }
00477 }
00478 mDelayTimeEdit->setMaximum(maxVal);
00479 }
00480
00481
00482
00483
00484 void AlarmTimeWidget::setAnyTime()
00485 {
00486 int old = mAnyTime;
00487 mAnyTime = (mAtTimeRadio->isChecked() && mAnyTimeAllowed && mAnyTimeCheckBox && mAnyTimeCheckBox->isChecked()) ? 1 : 0;
00488 if (mAnyTime != old)
00489 emit dateOnlyToggled(mAnyTime);
00490 }
00491
00492
00493
00494
00495 void AlarmTimeWidget::enableAnyTime(bool enable)
00496 {
00497 if (mAnyTimeCheckBox)
00498 {
00499 mAnyTimeAllowed = enable;
00500 bool at = mAtTimeRadio->isChecked();
00501 mAnyTimeCheckBox->setEnabled(enable && at);
00502 if (at)
00503 mTimeEdit->setEnabled(!enable || !mAnyTimeCheckBox->isChecked());
00504 setAnyTime();
00505 }
00506 }
00507
00508
00509
00510
00511
00512 void AlarmTimeWidget::updateTimes()
00513 {
00514 KDateTime now;
00515 if (mMinDateTimeIsNow)
00516 {
00517
00518 now = KDateTime::currentDateTime(mTimeSpec);
00519 mDateEdit->setMinDate(now.date());
00520 }
00521 if (mMaxDateTime.isValid())
00522 {
00523 if (!now.isValid())
00524 now = KDateTime::currentDateTime(mTimeSpec);
00525 if (!mPastMax)
00526 {
00527
00528 if (now.date() >= mMaxDateTime.date())
00529 {
00530
00531 if (now.date() > mMaxDateTime.date()
00532 || (!mAnyTime && now.time() > mTimeEdit->maxTime()))
00533 {
00534 mPastMax = true;
00535 emit pastMax();
00536 }
00537 else if (mMinDateTimeIsNow && !mMinMaxTimeSet)
00538 {
00539
00540
00541 setMaxMinTimeIf(now);
00542 }
00543 }
00544 }
00545 setMaxDelayTime(now);
00546 }
00547
00548 if (mAtTimeRadio->isChecked())
00549 dateTimeChanged();
00550 else
00551 delayTimeChanged(mDelayTimeEdit->value());
00552 }
00553
00554
00555
00556
00557
00558
00559 void AlarmTimeWidget::slotButtonSet(QAbstractButton*)
00560 {
00561 bool at = mAtTimeRadio->isChecked();
00562 mDateEdit->setEnabled(at);
00563 mTimeEdit->setEnabled(at && (!mAnyTimeAllowed || !mAnyTimeCheckBox || !mAnyTimeCheckBox->isChecked()));
00564 if (mAnyTimeCheckBox)
00565 mAnyTimeCheckBox->setEnabled(at && mAnyTimeAllowed);
00566
00567 KDateTime att(mDateEdit->date(), mTimeEdit->time(), mTimeSpec);
00568 int minutes = (KDateTime::currentUtcDateTime().secsTo(att) + 59) / 60;
00569 if (minutes <= 0)
00570 mDelayTimeEdit->setValid(true);
00571 mDelayTimeEdit->setEnabled(!at);
00572 setAnyTime();
00573 }
00574
00575
00576
00577
00578 void AlarmTimeWidget::slotAnyTimeToggled(bool on)
00579 {
00580 mTimeEdit->setEnabled((!mAnyTimeAllowed || !on) && mAtTimeRadio->isChecked());
00581 setAnyTime();
00582 }
00583
00584
00585
00586
00587
00588 void AlarmTimeWidget::slotTimeZoneChanged()
00589 {
00590 if (mNoTimeZone->isChecked())
00591 mTimeSpec = KDateTime::ClockTime;
00592 else
00593 {
00594 KTimeZone tz = mTimeZone->timeZone();
00595 mTimeSpec = tz.isValid() ? KDateTime::Spec(tz) : KDateTime::LocalZone;
00596 }
00597 mMinDateTime = mMinDateTime.toTimeSpec(mTimeSpec);
00598 mMaxDateTime = mMaxDateTime.toTimeSpec(mTimeSpec);
00599 updateTimes();
00600 }
00601
00602
00603
00604
00605 void AlarmTimeWidget::slotTimeZoneToggled(bool on)
00606 {
00607 mTimeZone->setEnabled(!on);
00608 slotTimeZoneChanged();
00609 }
00610
00611
00612
00613
00614
00615 void AlarmTimeWidget::dateTimeChanged()
00616 {
00617 KDateTime dt(mDateEdit->date(), mTimeEdit->time(), mTimeSpec);
00618 int minutes = (KDateTime::currentUtcDateTime().secsTo(dt) + 59) / 60;
00619 bool blocked = mDelayTimeEdit->signalsBlocked();
00620 mDelayTimeEdit->blockSignals(true);
00621 if (minutes <= 0 || minutes > mDelayTimeEdit->maximum())
00622 mDelayTimeEdit->setValid(false);
00623 else
00624 mDelayTimeEdit->setValue(minutes);
00625 mDelayTimeEdit->blockSignals(blocked);
00626 }
00627
00628
00629
00630
00631
00632 void AlarmTimeWidget::delayTimeChanged(int minutes)
00633 {
00634 if (mDelayTimeEdit->isValid())
00635 {
00636 QDateTime dt = KDateTime::currentUtcDateTime().addSecs(minutes * 60).toTimeSpec(mTimeSpec).dateTime();
00637 bool blockedT = mTimeEdit->signalsBlocked();
00638 bool blockedD = mDateEdit->signalsBlocked();
00639 mTimeEdit->blockSignals(true);
00640 mDateEdit->blockSignals(true);
00641 mTimeEdit->setValue(dt.time());
00642 mDateEdit->setDate(dt.date());
00643 mTimeEdit->blockSignals(blockedT);
00644 mDateEdit->blockSignals(blockedD);
00645 }
00646 }