File indexing completed on 2024-06-02 05:19:18

0001 /*
0002  *  timeperiod.cpp  -  time period data entry widget
0003  *  Program:  kalarm
0004  *  SPDX-FileCopyrightText: 2003-2023 David Jarvie <djarvie@kde.org>
0005  *
0006  *  SPDX-License-Identifier: GPL-2.0-or-later
0007  */
0008 
0009 #pragma once
0010 
0011 #include <KCalendarCore/Duration>
0012 #include <QWidget>
0013 #include <QString>
0014 
0015 class StackedWidget;
0016 class ComboBox;
0017 class SpinBox;
0018 class TimeSpinBox;
0019 
0020 
0021 /**
0022  *  @short Time period entry widget.
0023  *
0024  *  The TimePeriod class provides a widget for entering a time period as a number of
0025  *  weeks, days, hours and minutes, or minutes.
0026  *
0027  *  It displays a combo box to select the time units (weeks, days, hours and minutes, or
0028  *  minutes) alongside a spin box to enter the number of units. The type of spin box
0029  *  displayed alters according to the units selection: day, week and minute values are
0030  *  entered in a normal spin box, while hours and minutes are entered in a time spin box
0031  *  (with two pairs of spin buttons, one for hours and one for minutes).
0032  *
0033  *  The widget may be set as read-only. This has the same effect as disabling it, except
0034  *  that its appearance is unchanged.
0035  *
0036  *  @author David Jarvie <djarvie@kde.org>
0037  */
0038 class TimePeriod : public QWidget
0039 {
0040     Q_OBJECT
0041 public:
0042     /** Mode values for constructor. */
0043     enum Mode
0044     {
0045         NoMinutes     = 0x00,  // do not show minutes or hours/minutes options
0046         ShowMinutes   = 0x01   // show minutes and hours/minutes options
0047     };
0048 
0049     /** Units for the time period.
0050      *  @li Minutes - the time period is entered as a number of minutes.
0051      *  @li HoursMinutes - the time period is entered as an hours/minutes value.
0052      *  @li Days - the time period is entered as a number of days.
0053      *  @li Weeks - the time period is entered as a number of weeks.
0054      */
0055     enum Units { Minutes, HoursMinutes, Days, Weeks };
0056 
0057     /** Constructor.
0058      *  @param mode Set false to prevent hours/minutes or minutes from
0059      *         being allowed as units; only days and weeks can ever be used,
0060      *         regardless of other method calls. Set true to allow minutes,
0061      *         hours/minutes, days or weeks as units.
0062      *  @param parent The parent object of this widget.
0063      */
0064     TimePeriod(Mode mode, QWidget* parent);
0065 
0066     /** Returns true if the widget holds a valid value.
0067      *  An invalid value is displayed as asterisks.
0068      */
0069     bool isValid() const;
0070 
0071     /** Sets the spin box as holding a valid or invalid value.
0072      *  If newly invalid, the value is displayed as asterisks.
0073      *  If newly valid, the value is set to the minimum value.
0074      */
0075     void setValid(bool);
0076 
0077     /** Returns true if the widget is read only. */
0078     bool isReadOnly() const             { return mReadOnly; }
0079 
0080     /** Sets whether the widget is read-only for the user. If read-only,
0081      *  the time period cannot be edited and the units combo box is inactive.
0082      *  @param readOnly True to set the widget read-only, false to set it read-write.
0083      */
0084     virtual void  setReadOnly(bool readOnly);
0085 
0086     /** Gets the currently selected time units. */
0087     Units units() const;
0088 
0089     /** Sets the time units.
0090      *  Note that this changes the value.
0091      */
0092     void setUnits(Units units);
0093 
0094     /** Gets the entered time period. */
0095     KCalendarCore::Duration period() const;
0096 
0097     /** Initialises the time period value.
0098      *  @param period The value of the time period to set. If zero, the time period
0099      *                is left unchanged.
0100      *  @param dateOnly True to restrict the units available in the combo box to days or weeks.
0101      *  @param defaultUnits The units to display initially in the combo box.
0102      */
0103     void setPeriod(const KCalendarCore::Duration& period, bool dateOnly, Units defaultUnits);
0104 
0105     /** Gets the entered time period in minutes. */
0106     int minutes() const;
0107 
0108     /** Changes the already initialised time period value.
0109      *  @param minutes The value of the time period to set, in minutes
0110      */
0111     void setMinutes(int minutes);
0112 
0113     /** Changes the already initialised time period value, and sets the units.
0114      *  @param minutes The value of the time period to set, in minutes
0115      */
0116     void setMinutes(int minutes, Units units);
0117 
0118     /** Returns true if minutes and hours/minutes units are disabled. */
0119     bool isDateOnly() const             { return mDateOnlyOffset; }
0120 
0121     /** Enables or disables minutes and hours/minutes units in the combo box. To
0122      *  disable minutes and hours/minutes, set @p dateOnly true; to enable minutes
0123      *  and hours/minutes, set @p dateOnly false. But note that minutes and
0124      *  hours/minutes cannot be enabled if it was disallowed in the constructor.
0125      */
0126     void setDateOnly(bool dateOnly)     { setDateOnly(period(), dateOnly, true); }
0127 
0128     /** Sets the maximum values for the minutes and hours/minutes, and days/weeks
0129      *  spin boxes.
0130      *  Set @p hourmin = 0 to leave the minutes and hours/minutes maximum unchanged.
0131      */
0132     void setMaximum(int hourmin, int days);
0133 
0134     /** Returns the maximum of the maximum values of the minutes and hours/minutes,
0135      *  and days/weeks spin boxes.
0136      */
0137     int maxMinutes() const;
0138 
0139     /** Sets the maximum values for the minutes and hours/minutes, and days/weeks
0140      *  spin boxes.
0141      */
0142     void setMaxMinutes(int minutes);
0143 
0144     /** Sets whether the editor text is to be selected whenever spin buttons are
0145      *  clicked. The default is to select it.
0146      */
0147     void setSelectOnStep(bool select);
0148 
0149     /** Sets the input focus to the count field. */
0150     void setFocusOnCount();
0151 
0152     /** Sets separate WhatsThis texts for the count spin boxes and the units combo box.
0153      *  If @p hourMin is omitted, both spin boxes are set to the same WhatsThis text.
0154      */
0155     void setWhatsThises(const QString& units, const QString& dayWeek, const QString& hourMin = QString());
0156 
0157 Q_SIGNALS:
0158     /** This signal is emitted whenever the value held in the widget changes.
0159      *  @param period The current value of the time period.
0160      */
0161     void valueChanged(const KCalendarCore::Duration& period);
0162 
0163 private Q_SLOTS:
0164     void  slotUnitsSelected(int index);
0165     void  slotDaysChanged(int);
0166     void  slotTimeChanged(int minutes);
0167 
0168 private:
0169     Units setDateOnly(const KCalendarCore::Duration&, bool dateOnly, bool signal);
0170     void  setUnitRange();
0171     void  showHourMin(bool hourMin);
0172     void  adjustDayWeekShown();
0173 
0174     static QString i18n_minutes();       // text of 'minutes' units, lower case
0175     static QString i18n_hours_mins();    // text of 'hours/minutes' units
0176     static QString i18n_days();          // text of 'days' units
0177     static QString i18n_weeks();         // text of 'weeks' units
0178 
0179     StackedWidget*  mSpinStack;          // displays either the days/weeks or hours:minutes spinbox
0180     SpinBox*        mSpinBox;            // the minutes/days/weeks value spinbox
0181     TimeSpinBox*    mTimeSpinBox;        // the hours:minutes value spinbox
0182     ComboBox*       mUnitsCombo;
0183     int             mMaxDays {9999};     // maximum day count
0184     int             mDateOnlyOffset;     // for mUnitsCombo: 2 if minutes & hours/minutes is disabled, else 0
0185     Units           mMaxUnitShown;       // for mUnitsCombo: maximum units shown
0186     Units           mUnitShown;          // units currently shown in mUnitsCombo
0187     bool            mNoHourMinute;       // hours/minutes cannot be displayed, ever
0188     bool            mReadOnly {false};   // the widget is read only
0189     bool            mHourMinuteRaised;   // hours:minutes spinbox is currently displayed
0190 };
0191 
0192 // vim: et sw=4: