summaryrefslogtreecommitdiffstats
path: root/kalarm/lib/spinbox2.h
blob: 06a48d1afc9f0b7ad674db0621e0fc2e1bddf9a8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
/*
 *  spinbox2.h  -  spin box with extra pair of spin buttons (for Qt 3)
 *  Program:  kalarm
 *  Copyright © 2001-2007 by David Jarvie <software@astrojar.org.uk>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#ifndef SPINBOX2_H
#define SPINBOX2_H

#include <tqglobal.h>
#include <tqlineedit.h>

class SpinMirror;
class ExtraSpinBox;
#include "spinbox.h"


/**
 *  @short Spin box with a pair of spin buttons on either side.
 *
 *  The SpinBox2 class provides a spin box with two pairs of spin buttons, one on either side.
 *
 *  It is designed as a base class for implementing such facilities as time spin boxes, where
 *  the hours and minutes values are separately displayed in the edit field. When the
 *  appropriate step increments are configured, the left spin arrows can then be used to
 *  change the hours value, while the right spin arrows can be used to change the minutes
 *  value.
 *
 *  Rather than using SpinBox2 directly for time entry, use in preference TimeSpinBox or
 *  TimeEdit classes which are tailored from SpinBox2 for this purpose.
 *
 *  Separate step increments may optionally be specified for use when the shift key is
 *  held down. Typically these would be larger than the normal steps. Then, when the user
 *  clicks the spin buttons, he/she can increment or decrement the value faster by holding
 *  the shift key down.
 *
 *  The widget may be set as read-only. This has the same effect as disabling it, except
 *  that its appearance is unchanged.
 *
 *  @author David Jarvie <software@astrojar.org.uk>
 */
class SpinBox2 : public QFrame
{
		Q_OBJECT
	public:
		/** Constructor.
		 *  @param parent The parent object of this widget.
		 *  @param name The name of this widget.
		 */
		explicit SpinBox2(TQWidget* parent = 0, const char* name = 0);
		/** Constructor.
		 *  @param minValue The minimum value which the spin box can have.
		 *  @param maxValue The maximum value which the spin box can have.
		 *  @param step The (unshifted) step interval for the right-hand spin buttons.
		 *  @param step2 The (unshifted) step interval for the left-hand spin buttons.
		 *  @param parent The parent object of this widget.
		 *  @param name The name of this widget.
		 */
		SpinBox2(int minValue, int maxValue, int step = 1, int step2 = 1,
		         TQWidget* parent = 0, const char* name = 0);
		/** Sets whether the spin box can be changed by the user.
		 *  @param readOnly True to set the widget read-only, false to set it read-write.
		 */
		virtual void        setReadOnly(bool readOnly);
		/** Returns true if the widget is read only. */
		bool                isReadOnly() const          { return mSpinbox->isReadOnly(); }
		/** Sets whether the spin box value text should be selected when its value is stepped. */
		void                setSelectOnStep(bool sel)   { mSpinbox->setSelectOnStep(sel); }
		/** Sets whether the spin button pairs should be reversed for a right-to-left language.
		 *  The default is for them to be reversed.
		 */
		void                setReverseWithLayout(bool reverse);
		/** Returns whether the spin button pairs will be reversed for a right-to-left language. */
		bool                reverseButtons() const      { return mReverseLayout  &&  !mReverseWithLayout; }

		/** Returns the spin box's text, including any prefix() and suffix(). */
		TQString             text() const                { return mSpinbox->text(); }
		/** Returns the prefix for the spin box's text. */
		virtual TQString     prefix() const              { return mSpinbox->prefix(); }
		/** Returns the suffix for the spin box's text. */
		virtual TQString     suffix() const              { return mSpinbox->suffix(); }
		/** Returns the spin box's text with no prefix(), suffix() or leading or trailing whitespace. */
		virtual TQString     cleanText() const           { return mSpinbox->cleanText(); }

		/** Sets the special-value text which, if non-null, is displayed instead of a numeric
		 *  value when the current value is equal to minValue().
		 */
		virtual void        setSpecialValueText(const TQString& text)  { mSpinbox->setSpecialValueText(text); }
		/** Returns the special-value text which, if non-null, is displayed instead of a numeric
		 *  value when the current value is equal to minValue().
		 */
		TQString             specialValueText() const    { return mSpinbox->specialValueText(); }

		/** Sets whether it is possible to step the value from the highest value to the
		 *  lowest value and vice versa.
		 */
		virtual void        setWrapping(bool on);
		/** Returns whether it is possible to step the value from the highest value to the
		 *  lowest value and vice versa.
		 */
		bool                wrapping() const            { return mSpinbox->wrapping(); }

		/** Set the text alignment of the widget */
		void                setAlignment(int a)         { mSpinbox->setAlignment(a); }
		/** Sets the button symbols to use (arrows or plus/minus). */
		virtual void        setButtonSymbols(TQSpinBox::ButtonSymbols);
		/** Returns the button symbols currently in use (arrows or plus/minus). */
		TQSpinBox::ButtonSymbols buttonSymbols() const   { return mSpinbox->buttonSymbols(); }

		/** Sets the validator to @p v. The validator controls what keyboard input is accepted
		 *  when the user is editing the value field.
		 */
		virtual void        setValidator(const TQValidator* v)  { mSpinbox->setValidator(v); }
		/** Returns the current validator. The validator controls what keyboard input is accepted
		 *  when the user is editing the value field.
		 */
		const TQValidator*   validator() const           { return mSpinbox->validator(); }

		virtual TQSize       sizeHint() const;
		virtual TQSize       minimumSizeHint() const;

		/** Returns the minimum value of the spin box. */
		int                 minValue() const            { return mMinValue; }
		/** Returns the maximum value of the spin box. */
		int                 maxValue() const            { return mMaxValue; }
		/** Sets the minimum value of the spin box. */
		virtual void        setMinValue(int val);
		/** Sets the maximum value of the spin box. */
		virtual void        setMaxValue(int val);
		/** Sets the minimum and maximum values of the spin box. */
		void                setRange(int minValue, int maxValue)   { setMinValue(minValue);  setMaxValue(maxValue); }
		/** Returns the current value of the spin box. */
		int                 value() const               { return mSpinbox->value(); }
		/** Returns the specified value clamped to the range of the spin box. */
		int                 bound(int val) const;

		/** Returns the geometry of the right-hand "up" button. */
		TQRect               upRect() const              { return mSpinbox->upRect(); }
		/** Returns the geometry of the right-hand "down" button. */
		TQRect               downRect() const            { return mSpinbox->downRect(); }
		/** Returns the geometry of the left-hand "up" button. */
		TQRect               up2Rect() const;
		/** Returns the geometry of the left-hand "down" button. */
		TQRect               down2Rect() const;

		/** Returns the unshifted step increment for the right-hand spin buttons,
		 *  i.e. the amount by which the spin box value changes when a right-hand
		 *  spin button is clicked without the shift key being pressed.
		 */
		int                 lineStep() const            { return mLineStep; }
		/** Returns the shifted step increment for the right-hand spin buttons,
		 *  i.e. the amount by which the spin box value changes when a right-hand
		 *  spin button is clicked while the shift key is pressed.
		 */
		int                 lineShiftStep() const       { return mLineShiftStep; }
		/** Returns the unshifted step increment for the left-hand spin buttons,
		 *  i.e. the amount by which the spin box value changes when a left-hand
		 *  spin button is clicked without the shift key being pressed.
		 */
		int                 pageStep() const            { return mPageStep; }
		/** Returns the shifted step increment for the left-hand spin buttons,
		 *  i.e. the amount by which the spin box value changes when a left-hand
		 *  spin button is clicked while the shift key is pressed.
		 */
		int                 pageShiftStep() const       { return mPageShiftStep; }
		/** Sets the unshifted step increment for the right-hand spin buttons,
		 *  i.e. the amount by which the spin box value changes when a right-hand
		 *  spin button is clicked without the shift key being pressed.
		 */
		void                setLineStep(int step);
		/** Sets the unshifted step increments for the two pairs of spin buttons,
		 *  i.e. the amount by which the spin box value changes when a spin button
		 *  is clicked without the shift key being pressed.
		 *  @param line The step increment for the right-hand spin buttons.
		 *  @param page The step increment for the left-hand spin buttons.
		 */
		void                setSteps(int line, int page);
		/** Sets the shifted step increments for the two pairs of spin buttons,
		 *  i.e. the amount by which the spin box value changes when a spin button
		 *  is clicked while the shift key is pressed.
		 *  @param line The shift step increment for the right-hand spin buttons.
		 *  @param page The shift step increment for the left-hand spin buttons.
		 */
		void                setShiftSteps(int line, int page);

		/** Increments the current value by adding the unshifted step increment for
		 *  the left-hand spin buttons.
		 */
		void                addPage()                   { addValue(mPageStep); }
		/** Decrements the current value by subtracting the unshifted step increment for
		 *  the left-hand spin buttons.
		 */
		void                subtractPage()              { addValue(-mPageStep); }
		/** Increments the current value by adding the unshifted step increment for
		 *  the right-hand spin buttons.
		 */
		void                addLine()                   { addValue(mLineStep); }
		/** Decrements the current value by subtracting the unshifted step increment for
		 *  the right-hand spin buttons.
		 */
		void                subtractLine()              { addValue(-mLineStep); }
		/** Adjusts the current value by adding @p change. */
		void                addValue(int change)        { mSpinbox->addValue(change); }

	public slots:
		/** Sets the current value to @p val. */
		virtual void        setValue(int val)           { mSpinbox->setValue(val); }
		/** Sets the prefix which is prepended to the start of the displayed text. */
		virtual void        setPrefix(const TQString& text)  { mSpinbox->setPrefix(text); }
		/** Sets the suffix which is prepended to the start of the displayed text. */
		virtual void        setSuffix(const TQString& text)  { mSpinbox->setSuffix(text); }
		/** Increments the current value by adding the unshifted step increment for
		 *  the right-hand spin buttons.
		 */
		virtual void        stepUp()                    { addValue(mLineStep); }
		/** Decrements the current value by subtracting the unshifted step increment for
		 *  the right-hand spin buttons.
		 */
		virtual void        stepDown()                  { addValue(-mLineStep); }
		/** Increments the current value by adding the unshifted step increment for
		 *  the left-hand spin buttons.
		 */
		virtual void        pageUp()                    { addValue(mPageStep); }
		/** Decrements the current value by subtracting the unshifted step increment for
		 *  the left-hand spin buttons.
		 */
		virtual void        pageDown()                  { addValue(-mPageStep); }
		/** Selects all the text in the spin box's editor. */
		virtual void        selectAll()                 { mSpinbox->selectAll(); }
		/** Sets whether the widget is enabled. */
		virtual void        setEnabled(bool enabled);

	signals:
		/** Signal which is emitted whenever the value of the spin box changes. */
		void                valueChanged(int value);
		/** Signal which is emitted whenever the value of the spin box changes. */
		void                valueChanged(const TQString& valueText);

	protected:
		virtual TQString     mapValueToText(int v)         { return mSpinbox->mapValToText(v); }
		virtual int         mapTextToValue(bool* ok)      { return mSpinbox->mapTextToVal(ok); }
		virtual void        resizeEvent(TQResizeEvent*)    { arrange(); }
		virtual void        showEvent(TQShowEvent*);
		virtual void        styleChange(TQStyle&);
		virtual void        getMetrics() const;

		mutable int      wUpdown2;        // width of second spin widget
		mutable int      xUpdown2;        // x offset of visible area in 'mUpdown2'
		mutable int      xSpinbox;        // x offset of visible area in 'mSpinbox'
		mutable int      wGap;            // gap between mUpdown2Frame and mSpinboxFrame

	protected slots:
		virtual void        valueChange();
		virtual void        stepPage(int);

	private slots:
		void                updateMirror();

	private:
		void                init();
		void                arrange();
		int                 whichButton(TQObject* spinWidget, const TQPoint&);
		void                setShiftStepping(bool on);

		// Visible spin box class.
		// Declared here to allow use of mSpinBox in inline methods.
		class MainSpinBox : public SpinBox
		{
			public:
				MainSpinBox(SpinBox2* sb2, TQWidget* parent, const char* name = 0)
				                : SpinBox(parent, name), owner(sb2) { }
				MainSpinBox(int minValue, int maxValue, int step, SpinBox2* sb2, TQWidget* parent, const char* name = 0)
				                : SpinBox(minValue, maxValue, step, parent, name), owner(sb2) { }
				void            setAlignment(int a)       { editor()->setAlignment(a); }
				virtual TQString mapValueToText(int v)     { return owner->mapValueToText(v); }
				virtual int     mapTextToValue(bool* ok)  { return owner->mapTextToValue(ok); }
				TQString         mapValToText(int v)       { return SpinBox::mapValueToText(v); }
				int             mapTextToVal(bool* ok)    { return SpinBox::mapTextToValue(ok); }
				virtual int     shiftStepAdjustment(int oldValue, int shiftStep);
			private:
				SpinBox2* owner;   // owner SpinBox2
		};

		enum { NO_BUTTON = -1, UP, DOWN, UP2, DOWN2 };

		static int       mReverseLayout;  // widgets are mirrored right to left
		TQFrame*          mUpdown2Frame;   // contains visible part of the extra pair of spin buttons
		TQFrame*          mSpinboxFrame;   // contains the main spin box
		ExtraSpinBox*    mUpdown2;        // the extra pair of spin buttons
		MainSpinBox*     mSpinbox;        // the visible spin box
		SpinMirror*      mSpinMirror;     // image of the extra pair of spin buttons
		int              mMinValue;
		int              mMaxValue;
		int              mLineStep;           // right button increment
		int              mLineShiftStep;      // right button increment with shift pressed
		int              mPageStep;           // left button increment
		int              mPageShiftStep;      // left button increment with shift pressed
		bool             mReverseWithLayout;  // reverse button positions if reverse layout (default = true)

	friend class MainSpinBox;
};

#endif // SPINBOX2_H