• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • kdepim
  • Sitemap
  • Contact Us
 

kalarm

repetition.cpp

Go to the documentation of this file.
00001 /*
00002  *  repetition.cpp  -  pushbutton and dialog to specify alarm repetition
00003  *  Program:  kalarm
00004  *  Copyright © 2004-2008 by David Jarvie <djarvie@kde.org>
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License along
00017  *  with this program; if not, write to the Free Software Foundation, Inc.,
00018  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
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 = Class RepetitionButton
00042 = Button to display the Simple Alarm Repetition dialog.
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 *  Set the data for the dialog.
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 *  Create the alarm repetition dialog.
00081 *  If 'waitForInitialisation' is true, the dialog won't be displayed until set()
00082 *  is called to initialise its data.
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();     // request dialog initialisation
00091     else
00092         displayDialog();    // display the dialog now
00093 }
00094 
00095 /******************************************************************************
00096 *  Set the data for the dialog and display it.
00097 *  To be called only after needsInitialisation() has been emitted.
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();    // display the dialog now
00111     }
00112     else
00113         setChecked(mInterval && mCount);
00114 }
00115 
00116 /******************************************************************************
00117 *  Display the simple alarm repetition dialog.
00118 *  Alarm repetition has the following restrictions:
00119 *  1) Not allowed for a repeat-at-login alarm
00120 *  2) For a date-only alarm, the repeat interval must be a whole number of days.
00121 *  3) The overall repeat duration must be less than the recurrence interval.
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();   // delete dialog first, or initialise() will redisplay dialog
00142 }
00143 
00144 
00145 /*=============================================================================
00146 = Class RepetitionDlg
00147 = Simple alarm repetition dialog.
00148 =============================================================================*/
00149 
00150 static const int MAX_COUNT = 9999;    // maximum range for count spinbox
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 *  Set the state of all controls to reflect the data in the specified alarm.
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     // Set the units - needed later if the control is unchecked initially.
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);    // enable/disable controls
00258         if (on)
00259             intervalChanged(inter);    // ensure mCount range is set
00260         mCount->setValue(count);
00261         mDuration->setPeriod(inter * count, mDateOnly, units);
00262         mCountButton->setChecked(true);
00263     }
00264     mTimeSelector->setEnabled(mMaxDuration);
00265 }
00266 
00267 /******************************************************************************
00268 *  Set the read-only status.
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 *  Get the period between repetitions in minutes.
00282 */
00283 Duration RepetitionDlg::interval() const
00284 {
00285     return mTimeSelector->period();
00286 }
00287 
00288 /******************************************************************************
00289 *  Set the entered repeat count.
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;    // no repetition
00302 }
00303 
00304 /******************************************************************************
00305 *  Called when the time interval widget has changed value.
00306 *  Adjust the maximum repetition count accordingly.
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 *  Called when the count spinbox has changed value.
00322 *  Adjust the duration accordingly.
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 *  Called when the duration widget has changed value.
00339 *  Adjust the count accordingly.
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 *  Called when the time period widget is toggled on or off.
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 *  Called when one of the count or duration radio buttons is toggled.
00367 */
00368 void RepetitionDlg::typeClicked()
00369 {
00370     if (mTimeSelector->isChecked())
00371     {
00372         mCount->setEnabled(mCountButton->isChecked());
00373         mDuration->setEnabled(mDurationButton->isChecked());
00374     }
00375 }

kalarm

Skip menu "kalarm"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members

kdepim

Skip menu "kdepim"
  • akonadi
  •   clients
  •   kabc
  •   kcal
  •   kcm
  • akregator
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt
  • kdgantt1
  • kjots
  • kleopatra
  • kmail
  • kmobiletools
  • knode
  • knotes
  • kontact
  • kontactinterfaces
  • korganizer
  •   korgac
  • kpilot
  • ktimetracker
  • libkdepim
  • libkholidays
  • libkleo
  • libkpgp
  • maildir
Generated for kdepim by doxygen 1.5.7
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal