1 /*
2  *  timeperiod.cpp  -  time period data entry widget
3  *  Program:  kalarm
4  *  SPDX-FileCopyrightText: 2003-2019 David Jarvie <djarvie@kde.org>
5  *
6  *  SPDX-License-Identifier: GPL-2.0-or-later
7  */
8 
9 #pragma once
10 
11 #include <KCalendarCore/Duration>
12 #include <QWidget>
13 #include <QString>
14 
15 class StackedWidget;
16 class ComboBox;
17 class SpinBox;
18 class TimeSpinBox;
19 
20 
21 /**
22  *  @short Time period entry widget.
23  *
24  *  The TimePeriod class provides a widget for entering a time period as a number of
25  *  weeks, days, hours and minutes, or minutes.
26  *
27  *  It displays a combo box to select the time units (weeks, days, hours and minutes, or
28  *  minutes) alongside a spin box to enter the number of units. The type of spin box
29  *  displayed alters according to the units selection: day, week and minute values are
30  *  entered in a normal spin box, while hours and minutes are entered in a time spin box
31  *  (with two pairs of spin buttons, one for hours and one for minutes).
32  *
33  *  The widget may be set as read-only. This has the same effect as disabling it, except
34  *  that its appearance is unchanged.
35  *
36  *  @author David Jarvie <djarvie@kde.org>
37  */
38 class TimePeriod : public QWidget
39 {
40         Q_OBJECT
41     public:
42         /** Units for the time period.
43          *  @li Minutes - the time period is entered as a number of minutes.
44          *  @li HoursMinutes - the time period is entered as an hours/minutes value.
45          *  @li Days - the time period is entered as a number of days.
46          *  @li Weeks - the time period is entered as a number of weeks.
47          */
48         enum Units { Minutes, HoursMinutes, Days, Weeks };
49 
50         /** Constructor.
51          *  @param allowMinute Set false to prevent hours/minutes or minutes from
52          *         being allowed as units; only days and weeks can ever be used,
53          *         regardless of other method calls. Set true to allow minutes,
54          *         hours/minutes, days or weeks as units.
55          *  @param parent The parent object of this widget.
56          */
57         TimePeriod(bool allowMinute, QWidget* parent);
58         /** Returns true if the widget is read only. */
isReadOnly()59         bool          isReadOnly() const             { return mReadOnly; }
60         /** Sets whether the widget is read-only for the user. If read-only,
61          *  the time period cannot be edited and the units combo box is inactive.
62          *  @param readOnly True to set the widget read-only, false to set it read-write.
63          */
64         virtual void  setReadOnly(bool readOnly);
65         /** Gets the currently selected time units. */
66         Units         units() const;
67         /** Sets the time units.
68          *  Note that this changes the value.
69          */
70         void          setUnits(Units units);
71         /** Gets the entered time period. */
72         KCalendarCore::Duration period() const;
73         /** Initialises the time period value.
74          *  @param period The value of the time period to set. If zero, the time period
75          *                is left unchanged.
76          *  @param dateOnly True to restrict the units available in the combo box to days or weeks.
77          *  @param defaultUnits The units to display initially in the combo box.
78          */
79         void          setPeriod(const KCalendarCore::Duration& period, bool dateOnly, Units defaultUnits);
80         /** Returns true if minutes and hours/minutes units are disabled. */
isDateOnly()81         bool          isDateOnly() const             { return mDateOnlyOffset; }
82         /** Enables or disables minutes and hours/minutes units in the combo box. To
83          *  disable minutes and hours/minutes, set @p dateOnly true; to enable minutes
84          *  and hours/minutes, set @p dateOnly false. But note that minutes and
85          *  hours/minutes cannot be enabled if it was disallowed in the constructor.
86          */
setDateOnly(bool dateOnly)87         void          setDateOnly(bool dateOnly)     { setDateOnly(period(), dateOnly, true); }
88         /** Sets the maximum values for the minutes and hours/minutes, and days/weeks
89          *  spin boxes.
90          *  Set @p hourmin = 0 to leave the minutes and hours/minutes maximum unchanged.
91          */
92         void          setMaximum(int hourmin, int days);
93         /** Sets whether the editor text is to be selected whenever spin buttons are
94          *  clicked. The default is to select it.
95          */
96         void          setSelectOnStep(bool select);
97         /** Sets the input focus to the count field. */
98         void          setFocusOnCount();
99         /** Sets separate WhatsThis texts for the count spin boxes and the units combo box.
100          *  If @p hourMin is omitted, both spin boxes are set to the same WhatsThis text.
101          */
102         void          setWhatsThises(const QString& units, const QString& dayWeek, const QString& hourMin = QString());
103 
104     Q_SIGNALS:
105         /** This signal is emitted whenever the value held in the widget changes.
106          *  @param period The current value of the time period.
107          */
108         void            valueChanged(const KCalendarCore::Duration& period);
109 
110     private Q_SLOTS:
111         void            slotUnitsSelected(int index);
112         void            slotDaysChanged(int);
113         void            slotTimeChanged(int minutes);
114 
115     private:
116         Units           setDateOnly(const KCalendarCore::Duration&, bool dateOnly, bool signal);
117         void            setUnitRange();
118         void            showHourMin(bool hourMin);
119         void            adjustDayWeekShown();
120 
121         static QString i18n_minutes();       // text of 'minutes' units, lower case
122         static QString i18n_hours_mins();    // text of 'hours/minutes' units
123         static QString i18n_days();          // text of 'days' units
124         static QString i18n_weeks();         // text of 'weeks' units
125 
126         StackedWidget*  mSpinStack;          // displays either the days/weeks or hours:minutes spinbox
127         SpinBox*        mSpinBox;            // the minutes/days/weeks value spinbox
128         TimeSpinBox*    mTimeSpinBox;        // the hours:minutes value spinbox
129         ComboBox*       mUnitsCombo;
130         int             mMaxDays {9999};     // maximum day count
131         int             mDateOnlyOffset;     // for mUnitsCombo: 2 if minutes & hours/minutes is disabled, else 0
132         Units           mMaxUnitShown;       // for mUnitsCombo: maximum units shown
133         bool            mNoHourMinute;       // hours/minutes cannot be displayed, ever
134         bool            mReadOnly {false};   // the widget is read only
135         bool            mHourMinuteRaised;   // hours:minutes spinbox is currently displayed
136 };
137 
138 
139 // vim: et sw=4:
140