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