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: 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(name: "value" ); |
123 | } |
124 | |
125 | void QAccessibleAbstractSpinBox::setCurrentValue(const QVariant &value) |
126 | { |
127 | abstractSpinBox()->setProperty(name: "value" , value); |
128 | } |
129 | |
130 | QVariant QAccessibleAbstractSpinBox::maximumValue() const |
131 | { |
132 | return abstractSpinBox()->property(name: "maximum" ); |
133 | } |
134 | |
135 | QVariant QAccessibleAbstractSpinBox::minimumValue() const |
136 | { |
137 | return abstractSpinBox()->property(name: "minimum" ); |
138 | } |
139 | |
140 | QVariant QAccessibleAbstractSpinBox::minimumStepSize() const |
141 | { |
142 | return abstractSpinBox()->property(name: "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(signal: QLatin1String("valueChanged(int)" )); |
257 | addControllingSignal(signal: QLatin1String("valueChanged(QString)" )); |
258 | } |
259 | |
260 | /*! |
261 | Returns the underlying QSpinBox. |
262 | */ |
263 | QSpinBox *QAccessibleSpinBox::spinBox() const |
264 | { |
265 | return qobject_cast<QSpinBox*>(object: object()); |
266 | } |
267 | |
268 | |
269 | // ================================== QAccessibleDoubleSpinBox ================================== |
270 | QAccessibleDoubleSpinBox::QAccessibleDoubleSpinBox(QWidget *widget) |
271 | : QAccessibleAbstractSpinBox(widget) |
272 | { |
273 | Q_ASSERT(qobject_cast<QDoubleSpinBox *>(widget)); |
274 | addControllingSignal(signal: QLatin1String("valueChanged(double)" )); |
275 | addControllingSignal(signal: QLatin1String("valueChanged(QString)" )); |
276 | } |
277 | |
278 | /*! |
279 | Returns the underlying QDoubleSpinBox. |
280 | */ |
281 | QDoubleSpinBox *QAccessibleDoubleSpinBox::doubleSpinBox() const |
282 | { |
283 | return static_cast<QDoubleSpinBox*>(object()); |
284 | } |
285 | |
286 | QString QAccessibleDoubleSpinBox::text(QAccessible::Text textType) const |
287 | { |
288 | if (textType == QAccessible::Value) |
289 | return doubleSpinBox()->textFromValue(val: doubleSpinBox()->value()); |
290 | return QAccessibleWidget::text(t: textType); |
291 | } |
292 | |
293 | #endif // QT_CONFIG(spinbox) |
294 | |
295 | #if QT_CONFIG(scrollbar) |
296 | /*! |
297 | \class QAccessibleScrollBar |
298 | \brief The QAccessibleScrollBar class implements the QAccessibleInterface for scroll bars. |
299 | \internal |
300 | |
301 | \ingroup accessibility |
302 | */ |
303 | |
304 | /*! |
305 | Constructs a QAccessibleScrollBar object for \a w. |
306 | \a name is propagated to the QAccessibleWidget constructor. |
307 | */ |
308 | QAccessibleScrollBar::QAccessibleScrollBar(QWidget *w) |
309 | : QAccessibleAbstractSlider(w, QAccessible::ScrollBar) |
310 | { |
311 | Q_ASSERT(scrollBar()); |
312 | addControllingSignal(signal: QLatin1String("valueChanged(int)" )); |
313 | } |
314 | |
315 | /*! Returns the scroll bar. */ |
316 | QScrollBar *QAccessibleScrollBar::scrollBar() const |
317 | { |
318 | return qobject_cast<QScrollBar*>(object: object()); |
319 | } |
320 | |
321 | QString QAccessibleScrollBar::text(QAccessible::Text t) const |
322 | { |
323 | if (t == QAccessible::Value) |
324 | return QString::number(scrollBar()->value()); |
325 | return QAccessibleAbstractSlider::text(t); |
326 | } |
327 | |
328 | #endif // QT_CONFIG(scrollbar) |
329 | |
330 | #if QT_CONFIG(slider) |
331 | /*! |
332 | \class QAccessibleSlider |
333 | \brief The QAccessibleSlider class implements the QAccessibleInterface for sliders. |
334 | \internal |
335 | |
336 | \ingroup accessibility |
337 | */ |
338 | |
339 | /*! |
340 | Constructs a QAccessibleScrollBar object for \a w. |
341 | \a name is propagated to the QAccessibleWidget constructor. |
342 | */ |
343 | QAccessibleSlider::QAccessibleSlider(QWidget *w) |
344 | : QAccessibleAbstractSlider(w) |
345 | { |
346 | Q_ASSERT(slider()); |
347 | addControllingSignal(signal: QLatin1String("valueChanged(int)" )); |
348 | } |
349 | |
350 | /*! Returns the slider. */ |
351 | QSlider *QAccessibleSlider::slider() const |
352 | { |
353 | return qobject_cast<QSlider*>(object: object()); |
354 | } |
355 | |
356 | QString QAccessibleSlider::text(QAccessible::Text t) const |
357 | { |
358 | if (t == QAccessible::Value) |
359 | return QString::number(slider()->value()); |
360 | |
361 | return QAccessibleAbstractSlider::text(t); |
362 | } |
363 | |
364 | QAccessibleAbstractSlider::QAccessibleAbstractSlider(QWidget *w, QAccessible::Role r) |
365 | : QAccessibleWidget(w, r) |
366 | { |
367 | Q_ASSERT(qobject_cast<QAbstractSlider *>(w)); |
368 | } |
369 | |
370 | void *QAccessibleAbstractSlider::interface_cast(QAccessible::InterfaceType t) |
371 | { |
372 | if (t == QAccessible::ValueInterface) |
373 | return static_cast<QAccessibleValueInterface*>(this); |
374 | return QAccessibleWidget::interface_cast(t); |
375 | } |
376 | |
377 | QVariant QAccessibleAbstractSlider::currentValue() const |
378 | { |
379 | return abstractSlider()->value(); |
380 | } |
381 | |
382 | void QAccessibleAbstractSlider::setCurrentValue(const QVariant &value) |
383 | { |
384 | abstractSlider()->setValue(value.toInt()); |
385 | } |
386 | |
387 | QVariant QAccessibleAbstractSlider::maximumValue() const |
388 | { |
389 | return abstractSlider()->maximum(); |
390 | } |
391 | |
392 | QVariant QAccessibleAbstractSlider::minimumValue() const |
393 | { |
394 | return abstractSlider()->minimum(); |
395 | } |
396 | |
397 | QVariant QAccessibleAbstractSlider::minimumStepSize() const |
398 | { |
399 | return abstractSlider()->singleStep(); |
400 | } |
401 | |
402 | QAbstractSlider *QAccessibleAbstractSlider::abstractSlider() const |
403 | { |
404 | return static_cast<QAbstractSlider *>(object()); |
405 | } |
406 | |
407 | #endif // QT_CONFIG(slider) |
408 | |
409 | #if QT_CONFIG(dial) |
410 | // ======================================= QAccessibleDial ====================================== |
411 | QAccessibleDial::QAccessibleDial(QWidget *widget) |
412 | : QAccessibleAbstractSlider(widget, QAccessible::Dial) |
413 | { |
414 | Q_ASSERT(qobject_cast<QDial *>(widget)); |
415 | addControllingSignal(signal: QLatin1String("valueChanged(int)" )); |
416 | } |
417 | |
418 | QString QAccessibleDial::text(QAccessible::Text textType) const |
419 | { |
420 | if (textType == QAccessible::Value) |
421 | return QString::number(dial()->value()); |
422 | |
423 | return QAccessibleAbstractSlider::text(t: textType); |
424 | } |
425 | |
426 | QDial *QAccessibleDial::dial() const |
427 | { |
428 | return static_cast<QDial*>(object()); |
429 | } |
430 | #endif // QT_CONFIG(dial) |
431 | |
432 | #endif // QT_NO_ACCESSIBILITY |
433 | |
434 | QT_END_NAMESPACE |
435 | |