1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the plugins of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 3 requirements |
23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
24 | ** |
25 | ** GNU General Public License Usage |
26 | ** Alternatively, this file may be used under the terms of the GNU |
27 | ** General Public License version 2.0 or (at your option) the GNU General |
28 | ** Public license version 3 or any later version approved by the KDE Free |
29 | ** Qt Foundation. The licenses are as published by the Free Software |
30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
31 | ** included in the packaging of this file. Please review the following |
32 | ** information to ensure the GNU General Public License requirements will |
33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
34 | ** https://www.gnu.org/licenses/gpl-3.0.html. |
35 | ** |
36 | ** $QT_END_LICENSE$ |
37 | ** |
38 | ****************************************************************************/ |
39 | |
40 | #include "rangecontrols_p.h" |
41 | |
42 | #if QT_CONFIG(slider) |
43 | #include <qslider.h> |
44 | #endif |
45 | #if QT_CONFIG(dial) |
46 | #include <qdial.h> |
47 | #endif |
48 | #if QT_CONFIG(spinbox) |
49 | #include <qspinbox.h> |
50 | #endif |
51 | #if QT_CONFIG(scrollbar) |
52 | #include <qscrollbar.h> |
53 | #endif |
54 | #include <qstyle.h> |
55 | #include <qstyleoption.h> |
56 | #include <qdebug.h> |
57 | #include <qglobal.h> |
58 | #if QT_CONFIG(lineedit) |
59 | #include <QtWidgets/qlineedit.h> |
60 | #endif |
61 | #include <qmath.h> |
62 | #include <private/qmath_p.h> |
63 | |
64 | #include "simplewidgets_p.h" // let spinbox use line edit's interface |
65 | |
66 | QT_BEGIN_NAMESPACE |
67 | |
68 | #ifndef QT_NO_ACCESSIBILITY |
69 | |
70 | #if QT_CONFIG(spinbox) |
71 | QAccessibleAbstractSpinBox::QAccessibleAbstractSpinBox(QWidget *w) |
72 | : QAccessibleWidget(w, QAccessible::SpinBox), lineEdit(nullptr) |
73 | { |
74 | Q_ASSERT(abstractSpinBox()); |
75 | } |
76 | |
77 | QAccessibleAbstractSpinBox::~QAccessibleAbstractSpinBox() |
78 | { |
79 | delete lineEdit; |
80 | } |
81 | |
82 | /*! |
83 | Returns the underlying QAbstractSpinBox. |
84 | */ |
85 | QAbstractSpinBox *QAccessibleAbstractSpinBox::abstractSpinBox() const |
86 | { |
87 | return qobject_cast<QAbstractSpinBox*>(object()); |
88 | } |
89 | |
90 | QAccessibleInterface *QAccessibleAbstractSpinBox::lineEditIface() const |
91 | { |
92 | #if QT_CONFIG(lineedit) |
93 | // QAccessibleLineEdit is only used to forward the text functions |
94 | if (!lineEdit) |
95 | lineEdit = new QAccessibleLineEdit(abstractSpinBox()->lineEdit()); |
96 | return lineEdit; |
97 | #else |
98 | return nullptr; |
99 | #endif |
100 | } |
101 | |
102 | QString QAccessibleAbstractSpinBox::text(QAccessible::Text t) const |
103 | { |
104 | if (t == QAccessible::Value) |
105 | return abstractSpinBox()->text(); |
106 | return QAccessibleWidget::text(t); |
107 | } |
108 | |
109 | void *QAccessibleAbstractSpinBox::interface_cast(QAccessible::InterfaceType t) |
110 | { |
111 | if (t == QAccessible::ValueInterface) |
112 | return static_cast<QAccessibleValueInterface*>(this); |
113 | if (t == QAccessible::TextInterface) |
114 | return static_cast<QAccessibleTextInterface*>(this); |
115 | if (t == QAccessible::EditableTextInterface) |
116 | return static_cast<QAccessibleEditableTextInterface*>(this); |
117 | return QAccessibleWidget::interface_cast(t); |
118 | } |
119 | |
120 | QVariant QAccessibleAbstractSpinBox::currentValue() const |
121 | { |
122 | return abstractSpinBox()->property("value" ); |
123 | } |
124 | |
125 | void QAccessibleAbstractSpinBox::setCurrentValue(const QVariant &value) |
126 | { |
127 | abstractSpinBox()->setProperty("value" , value); |
128 | } |
129 | |
130 | QVariant QAccessibleAbstractSpinBox::maximumValue() const |
131 | { |
132 | return abstractSpinBox()->property("maximum" ); |
133 | } |
134 | |
135 | QVariant QAccessibleAbstractSpinBox::minimumValue() const |
136 | { |
137 | return abstractSpinBox()->property("minimum" ); |
138 | } |
139 | |
140 | QVariant QAccessibleAbstractSpinBox::minimumStepSize() const |
141 | { |
142 | return abstractSpinBox()->property("stepSize" ); |
143 | } |
144 | |
145 | void QAccessibleAbstractSpinBox::addSelection(int startOffset, int endOffset) |
146 | { |
147 | lineEditIface()->textInterface()->addSelection(startOffset, endOffset); |
148 | } |
149 | |
150 | QString QAccessibleAbstractSpinBox::attributes(int offset, int *startOffset, int *endOffset) const |
151 | { |
152 | return lineEditIface()->textInterface()->attributes(offset, startOffset, endOffset); |
153 | } |
154 | |
155 | int QAccessibleAbstractSpinBox::cursorPosition() const |
156 | { |
157 | return lineEditIface()->textInterface()->cursorPosition(); |
158 | } |
159 | |
160 | QRect QAccessibleAbstractSpinBox::characterRect(int offset) const |
161 | { |
162 | return lineEditIface()->textInterface()->characterRect(offset); |
163 | } |
164 | |
165 | int QAccessibleAbstractSpinBox::selectionCount() const |
166 | { |
167 | return lineEditIface()->textInterface()->selectionCount(); |
168 | } |
169 | |
170 | int QAccessibleAbstractSpinBox::offsetAtPoint(const QPoint &point) const |
171 | { |
172 | return lineEditIface()->textInterface()->offsetAtPoint(point); |
173 | } |
174 | |
175 | void QAccessibleAbstractSpinBox::selection(int selectionIndex, int *startOffset, int *endOffset) const |
176 | { |
177 | lineEditIface()->textInterface()->selection(selectionIndex, startOffset, endOffset); |
178 | } |
179 | |
180 | QString QAccessibleAbstractSpinBox::text(int startOffset, int endOffset) const |
181 | { |
182 | return lineEditIface()->textInterface()->text(startOffset, endOffset); |
183 | } |
184 | |
185 | QString QAccessibleAbstractSpinBox::textBeforeOffset(int offset, QAccessible::TextBoundaryType boundaryType, int *startOffset, int *endOffset) const |
186 | { |
187 | return lineEditIface()->textInterface()->textBeforeOffset(offset, boundaryType, startOffset, endOffset); |
188 | } |
189 | |
190 | QString QAccessibleAbstractSpinBox::textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType, int *startOffset, int *endOffset) const |
191 | { |
192 | return lineEditIface()->textInterface()->textAfterOffset(offset, boundaryType, startOffset, endOffset); |
193 | } |
194 | |
195 | QString QAccessibleAbstractSpinBox::textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType, int *startOffset, int *endOffset) const |
196 | { |
197 | return lineEditIface()->textInterface()->textAtOffset(offset, boundaryType, startOffset, endOffset); |
198 | } |
199 | |
200 | void QAccessibleAbstractSpinBox::removeSelection(int selectionIndex) |
201 | { |
202 | lineEditIface()->textInterface()->removeSelection(selectionIndex); |
203 | } |
204 | |
205 | void QAccessibleAbstractSpinBox::setCursorPosition(int position) |
206 | { |
207 | lineEditIface()->textInterface()->setCursorPosition(position); |
208 | } |
209 | |
210 | void QAccessibleAbstractSpinBox::setSelection(int selectionIndex, int startOffset, int endOffset) |
211 | { |
212 | lineEditIface()->textInterface()->setSelection(selectionIndex, startOffset, endOffset); |
213 | } |
214 | |
215 | int QAccessibleAbstractSpinBox::characterCount() const |
216 | { |
217 | return lineEditIface()->textInterface()->characterCount(); |
218 | } |
219 | |
220 | void QAccessibleAbstractSpinBox::scrollToSubstring(int startIndex, int endIndex) |
221 | { |
222 | lineEditIface()->textInterface()->scrollToSubstring(startIndex, endIndex); |
223 | } |
224 | |
225 | void QAccessibleAbstractSpinBox::deleteText(int startOffset, int endOffset) |
226 | { |
227 | lineEditIface()->editableTextInterface()->deleteText(startOffset, endOffset); |
228 | } |
229 | |
230 | void QAccessibleAbstractSpinBox::insertText(int offset, const QString &text) |
231 | { |
232 | lineEditIface()->editableTextInterface()->insertText(offset, text); |
233 | } |
234 | |
235 | void QAccessibleAbstractSpinBox::replaceText(int startOffset, int endOffset, const QString &text) |
236 | { |
237 | lineEditIface()->editableTextInterface()->replaceText(startOffset, endOffset, text); |
238 | } |
239 | |
240 | |
241 | /*! |
242 | \class QAccessibleSpinBox |
243 | \brief The QAccessibleSpinBox class implements the QAccessibleInterface for spinbox widgets. |
244 | \internal |
245 | |
246 | \ingroup accessibility |
247 | */ |
248 | |
249 | /*! |
250 | Constructs a QAccessibleSpinWidget object for \a w. |
251 | */ |
252 | QAccessibleSpinBox::QAccessibleSpinBox(QWidget *w) |
253 | : QAccessibleAbstractSpinBox(w) |
254 | { |
255 | Q_ASSERT(spinBox()); |
256 | addControllingSignal(QLatin1String("valueChanged(int)" )); |
257 | } |
258 | |
259 | /*! |
260 | Returns the underlying QSpinBox. |
261 | */ |
262 | QSpinBox *QAccessibleSpinBox::spinBox() const |
263 | { |
264 | return qobject_cast<QSpinBox*>(object()); |
265 | } |
266 | |
267 | |
268 | // ================================== QAccessibleDoubleSpinBox ================================== |
269 | QAccessibleDoubleSpinBox::QAccessibleDoubleSpinBox(QWidget *widget) |
270 | : QAccessibleAbstractSpinBox(widget) |
271 | { |
272 | Q_ASSERT(qobject_cast<QDoubleSpinBox *>(widget)); |
273 | addControllingSignal(QLatin1String("valueChanged(double)" )); |
274 | } |
275 | |
276 | /*! |
277 | Returns the underlying QDoubleSpinBox. |
278 | */ |
279 | QDoubleSpinBox *QAccessibleDoubleSpinBox::doubleSpinBox() const |
280 | { |
281 | return static_cast<QDoubleSpinBox*>(object()); |
282 | } |
283 | |
284 | QString QAccessibleDoubleSpinBox::text(QAccessible::Text textType) const |
285 | { |
286 | if (textType == QAccessible::Value) |
287 | return doubleSpinBox()->textFromValue(doubleSpinBox()->value()); |
288 | return QAccessibleWidget::text(textType); |
289 | } |
290 | |
291 | #endif // QT_CONFIG(spinbox) |
292 | |
293 | #if QT_CONFIG(scrollbar) |
294 | /*! |
295 | \class QAccessibleScrollBar |
296 | \brief The QAccessibleScrollBar class implements the QAccessibleInterface for scroll bars. |
297 | \internal |
298 | |
299 | \ingroup accessibility |
300 | */ |
301 | |
302 | /*! |
303 | Constructs a QAccessibleScrollBar object for \a w. |
304 | \a name is propagated to the QAccessibleWidget constructor. |
305 | */ |
306 | QAccessibleScrollBar::QAccessibleScrollBar(QWidget *w) |
307 | : QAccessibleAbstractSlider(w, QAccessible::ScrollBar) |
308 | { |
309 | Q_ASSERT(scrollBar()); |
310 | addControllingSignal(QLatin1String("valueChanged(int)" )); |
311 | } |
312 | |
313 | /*! Returns the scroll bar. */ |
314 | QScrollBar *QAccessibleScrollBar::scrollBar() const |
315 | { |
316 | return qobject_cast<QScrollBar*>(object()); |
317 | } |
318 | |
319 | QString QAccessibleScrollBar::text(QAccessible::Text t) const |
320 | { |
321 | if (t == QAccessible::Value) |
322 | return QString::number(scrollBar()->value()); |
323 | return QAccessibleAbstractSlider::text(t); |
324 | } |
325 | |
326 | #endif // QT_CONFIG(scrollbar) |
327 | |
328 | #if QT_CONFIG(slider) |
329 | /*! |
330 | \class QAccessibleSlider |
331 | \brief The QAccessibleSlider class implements the QAccessibleInterface for sliders. |
332 | \internal |
333 | |
334 | \ingroup accessibility |
335 | */ |
336 | |
337 | /*! |
338 | Constructs a QAccessibleScrollBar object for \a w. |
339 | \a name is propagated to the QAccessibleWidget constructor. |
340 | */ |
341 | QAccessibleSlider::QAccessibleSlider(QWidget *w) |
342 | : QAccessibleAbstractSlider(w) |
343 | { |
344 | Q_ASSERT(slider()); |
345 | addControllingSignal(QLatin1String("valueChanged(int)" )); |
346 | } |
347 | |
348 | /*! Returns the slider. */ |
349 | QSlider *QAccessibleSlider::slider() const |
350 | { |
351 | return qobject_cast<QSlider*>(object()); |
352 | } |
353 | |
354 | QString QAccessibleSlider::text(QAccessible::Text t) const |
355 | { |
356 | if (t == QAccessible::Value) |
357 | return QString::number(slider()->value()); |
358 | |
359 | return QAccessibleAbstractSlider::text(t); |
360 | } |
361 | |
362 | QAccessibleAbstractSlider::QAccessibleAbstractSlider(QWidget *w, QAccessible::Role r) |
363 | : QAccessibleWidget(w, r) |
364 | { |
365 | Q_ASSERT(qobject_cast<QAbstractSlider *>(w)); |
366 | } |
367 | |
368 | void *QAccessibleAbstractSlider::interface_cast(QAccessible::InterfaceType t) |
369 | { |
370 | if (t == QAccessible::ValueInterface) |
371 | return static_cast<QAccessibleValueInterface*>(this); |
372 | return QAccessibleWidget::interface_cast(t); |
373 | } |
374 | |
375 | QVariant QAccessibleAbstractSlider::currentValue() const |
376 | { |
377 | return abstractSlider()->value(); |
378 | } |
379 | |
380 | void QAccessibleAbstractSlider::setCurrentValue(const QVariant &value) |
381 | { |
382 | abstractSlider()->setValue(value.toInt()); |
383 | } |
384 | |
385 | QVariant QAccessibleAbstractSlider::maximumValue() const |
386 | { |
387 | return abstractSlider()->maximum(); |
388 | } |
389 | |
390 | QVariant QAccessibleAbstractSlider::minimumValue() const |
391 | { |
392 | return abstractSlider()->minimum(); |
393 | } |
394 | |
395 | QVariant QAccessibleAbstractSlider::minimumStepSize() const |
396 | { |
397 | return abstractSlider()->singleStep(); |
398 | } |
399 | |
400 | QAbstractSlider *QAccessibleAbstractSlider::abstractSlider() const |
401 | { |
402 | return static_cast<QAbstractSlider *>(object()); |
403 | } |
404 | |
405 | #endif // QT_CONFIG(slider) |
406 | |
407 | #if QT_CONFIG(dial) |
408 | // ======================================= QAccessibleDial ====================================== |
409 | QAccessibleDial::QAccessibleDial(QWidget *widget) |
410 | : QAccessibleAbstractSlider(widget, QAccessible::Dial) |
411 | { |
412 | Q_ASSERT(qobject_cast<QDial *>(widget)); |
413 | addControllingSignal(QLatin1String("valueChanged(int)" )); |
414 | } |
415 | |
416 | QString QAccessibleDial::text(QAccessible::Text textType) const |
417 | { |
418 | if (textType == QAccessible::Value) |
419 | return QString::number(dial()->value()); |
420 | |
421 | return QAccessibleAbstractSlider::text(textType); |
422 | } |
423 | |
424 | QDial *QAccessibleDial::dial() const |
425 | { |
426 | return static_cast<QDial*>(object()); |
427 | } |
428 | #endif // QT_CONFIG(dial) |
429 | |
430 | #endif // QT_NO_ACCESSIBILITY |
431 | |
432 | QT_END_NAMESPACE |
433 | |