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

kalarm/lib

timeperiod.cpp

Go to the documentation of this file.
00001 /*
00002  *  timeperiod.h  -  time period data entry widget
00003  *  Program:  kalarm
00004  *  Copyright © 2003-2005,2007,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 <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 // Collect these widget labels together to ensure consistent wording and
00036 // translations across different modules.
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;   // absolute maximum value for hours:minutes = 999H59M
00043 
00044 /*=============================================================================
00045 = Class TimePeriod
00046 = Contains a time unit combo box, plus a time spinbox, to select a time period.
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);    // max 999H59M
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 *  Set whether the editor text is to be selected whenever spin buttons are
00107 *  clicked. Default is to select them.
00108 */
00109 void TimePeriod::setSelectOnStep(bool sel)
00110 {
00111     mSpinBox->setSelectOnStep(sel);
00112     mTimeSpinBox->setSelectOnStep(sel);
00113 }
00114 
00115 /******************************************************************************
00116 *  Set the input focus on the count field.
00117 */
00118 void TimePeriod::setFocusOnCount()
00119 {
00120     mSpinStack->setFocus();
00121 }
00122 
00123 /******************************************************************************
00124 *  Set the maximum values for the hours:minutes and days/weeks spinboxes.
00125 *  If 'hourmin' = 0, the hours:minutes maximum is left unchanged.
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  * Get the specified time period.
00146  * Reply = 0 if error.
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             // fall through to DAYS
00160         case Days:
00161             return Duration(mSpinBox->value() * factor, Duration::Days);
00162     }
00163     return 0;
00164 }
00165 
00166 /******************************************************************************
00167 *  Initialise the controls with a specified time period.
00168 *  The time unit combo-box is initialised to 'defaultUnits', but if 'dateOnly'
00169 *  is true, it will never be initialised to minutes or hours/minutes.
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;   // minutes
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 *  Enable/disable hours/minutes units (if hours/minutes were permitted in the
00226 *  constructor).
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             // Change from date-only to allow hours/minutes
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             // Change from allowing hours/minutes to date-only
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                 // Set units to days and round up the warning period
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 *  Adjust the days/weeks units shown to suit the maximum days limit.
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 *  Set the maximum value which may be entered into the day/week count field,
00303 *  depending on the current unit selection.
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             // fall through to Days
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 *  Called when a new item is made current in the time units combo box.
00331 */
00332 void TimePeriod::slotUnitsSelected(int index)
00333 {
00334     setUnitRange();
00335     showHourMin(index + mDateOnlyOffset == HoursMinutes);
00336     emit valueChanged(period());
00337 }
00338 
00339 /******************************************************************************
00340 *  Called when the value of the days/weeks spin box changes.
00341 */
00342 void TimePeriod::slotDaysChanged(int)
00343 {
00344     if (!mHourMinuteRaised)
00345         emit valueChanged(period());
00346 }
00347 
00348 /******************************************************************************
00349 *  Called when the value of the time spin box changes.
00350 */
00351 void TimePeriod::slotTimeChanged(int)
00352 {
00353     if (mHourMinuteRaised)
00354         emit valueChanged(period());
00355 }
00356 
00357 /******************************************************************************
00358  * Set the currently displayed count widget.
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  * Set separate WhatsThis texts for the count spinboxes and the units combobox.
00380  * If the hours:minutes text is omitted, both spinboxes are set to the same
00381  * WhatsThis text.
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 }

kalarm/lib

Skip menu "kalarm/lib"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • 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.4
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