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)
QAccessibleAbstractSpinBox(QWidget * w)71 QAccessibleAbstractSpinBox::QAccessibleAbstractSpinBox(QWidget *w)
72 : QAccessibleWidget(w, QAccessible::SpinBox), lineEdit(nullptr)
73 {
74 Q_ASSERT(abstractSpinBox());
75 }
76
~QAccessibleAbstractSpinBox()77 QAccessibleAbstractSpinBox::~QAccessibleAbstractSpinBox()
78 {
79 delete lineEdit;
80 }
81
82 /*!
83 Returns the underlying QAbstractSpinBox.
84 */
abstractSpinBox() const85 QAbstractSpinBox *QAccessibleAbstractSpinBox::abstractSpinBox() const
86 {
87 return qobject_cast<QAbstractSpinBox*>(object());
88 }
89
lineEditIface() const90 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
text(QAccessible::Text t) const102 QString QAccessibleAbstractSpinBox::text(QAccessible::Text t) const
103 {
104 if (t == QAccessible::Value)
105 return abstractSpinBox()->text();
106 return QAccessibleWidget::text(t);
107 }
108
interface_cast(QAccessible::InterfaceType t)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
currentValue() const120 QVariant QAccessibleAbstractSpinBox::currentValue() const
121 {
122 return abstractSpinBox()->property("value");
123 }
124
setCurrentValue(const QVariant & value)125 void QAccessibleAbstractSpinBox::setCurrentValue(const QVariant &value)
126 {
127 abstractSpinBox()->setProperty("value", value);
128 }
129
maximumValue() const130 QVariant QAccessibleAbstractSpinBox::maximumValue() const
131 {
132 return abstractSpinBox()->property("maximum");
133 }
134
minimumValue() const135 QVariant QAccessibleAbstractSpinBox::minimumValue() const
136 {
137 return abstractSpinBox()->property("minimum");
138 }
139
minimumStepSize() const140 QVariant QAccessibleAbstractSpinBox::minimumStepSize() const
141 {
142 return abstractSpinBox()->property("stepSize");
143 }
144
addSelection(int startOffset,int endOffset)145 void QAccessibleAbstractSpinBox::addSelection(int startOffset, int endOffset)
146 {
147 lineEditIface()->textInterface()->addSelection(startOffset, endOffset);
148 }
149
attributes(int offset,int * startOffset,int * endOffset) const150 QString QAccessibleAbstractSpinBox::attributes(int offset, int *startOffset, int *endOffset) const
151 {
152 return lineEditIface()->textInterface()->attributes(offset, startOffset, endOffset);
153 }
154
cursorPosition() const155 int QAccessibleAbstractSpinBox::cursorPosition() const
156 {
157 return lineEditIface()->textInterface()->cursorPosition();
158 }
159
characterRect(int offset) const160 QRect QAccessibleAbstractSpinBox::characterRect(int offset) const
161 {
162 return lineEditIface()->textInterface()->characterRect(offset);
163 }
164
selectionCount() const165 int QAccessibleAbstractSpinBox::selectionCount() const
166 {
167 return lineEditIface()->textInterface()->selectionCount();
168 }
169
offsetAtPoint(const QPoint & point) const170 int QAccessibleAbstractSpinBox::offsetAtPoint(const QPoint &point) const
171 {
172 return lineEditIface()->textInterface()->offsetAtPoint(point);
173 }
174
selection(int selectionIndex,int * startOffset,int * endOffset) const175 void QAccessibleAbstractSpinBox::selection(int selectionIndex, int *startOffset, int *endOffset) const
176 {
177 lineEditIface()->textInterface()->selection(selectionIndex, startOffset, endOffset);
178 }
179
text(int startOffset,int endOffset) const180 QString QAccessibleAbstractSpinBox::text(int startOffset, int endOffset) const
181 {
182 return lineEditIface()->textInterface()->text(startOffset, endOffset);
183 }
184
textBeforeOffset(int offset,QAccessible::TextBoundaryType boundaryType,int * startOffset,int * endOffset) const185 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
textAfterOffset(int offset,QAccessible::TextBoundaryType boundaryType,int * startOffset,int * endOffset) const190 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
textAtOffset(int offset,QAccessible::TextBoundaryType boundaryType,int * startOffset,int * endOffset) const195 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
removeSelection(int selectionIndex)200 void QAccessibleAbstractSpinBox::removeSelection(int selectionIndex)
201 {
202 lineEditIface()->textInterface()->removeSelection(selectionIndex);
203 }
204
setCursorPosition(int position)205 void QAccessibleAbstractSpinBox::setCursorPosition(int position)
206 {
207 lineEditIface()->textInterface()->setCursorPosition(position);
208 }
209
setSelection(int selectionIndex,int startOffset,int endOffset)210 void QAccessibleAbstractSpinBox::setSelection(int selectionIndex, int startOffset, int endOffset)
211 {
212 lineEditIface()->textInterface()->setSelection(selectionIndex, startOffset, endOffset);
213 }
214
characterCount() const215 int QAccessibleAbstractSpinBox::characterCount() const
216 {
217 return lineEditIface()->textInterface()->characterCount();
218 }
219
scrollToSubstring(int startIndex,int endIndex)220 void QAccessibleAbstractSpinBox::scrollToSubstring(int startIndex, int endIndex)
221 {
222 lineEditIface()->textInterface()->scrollToSubstring(startIndex, endIndex);
223 }
224
deleteText(int startOffset,int endOffset)225 void QAccessibleAbstractSpinBox::deleteText(int startOffset, int endOffset)
226 {
227 lineEditIface()->editableTextInterface()->deleteText(startOffset, endOffset);
228 }
229
insertText(int offset,const QString & text)230 void QAccessibleAbstractSpinBox::insertText(int offset, const QString &text)
231 {
232 lineEditIface()->editableTextInterface()->insertText(offset, text);
233 }
234
replaceText(int startOffset,int endOffset,const QString & text)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 */
QAccessibleSpinBox(QWidget * w)252 QAccessibleSpinBox::QAccessibleSpinBox(QWidget *w)
253 : QAccessibleAbstractSpinBox(w)
254 {
255 Q_ASSERT(spinBox());
256 addControllingSignal(QLatin1String("valueChanged(int)"));
257 addControllingSignal(QLatin1String("valueChanged(QString)"));
258 }
259
260 /*!
261 Returns the underlying QSpinBox.
262 */
spinBox() const263 QSpinBox *QAccessibleSpinBox::spinBox() const
264 {
265 return qobject_cast<QSpinBox*>(object());
266 }
267
268
269 // ================================== QAccessibleDoubleSpinBox ==================================
QAccessibleDoubleSpinBox(QWidget * widget)270 QAccessibleDoubleSpinBox::QAccessibleDoubleSpinBox(QWidget *widget)
271 : QAccessibleAbstractSpinBox(widget)
272 {
273 Q_ASSERT(qobject_cast<QDoubleSpinBox *>(widget));
274 addControllingSignal(QLatin1String("valueChanged(double)"));
275 addControllingSignal(QLatin1String("valueChanged(QString)"));
276 }
277
278 /*!
279 Returns the underlying QDoubleSpinBox.
280 */
doubleSpinBox() const281 QDoubleSpinBox *QAccessibleDoubleSpinBox::doubleSpinBox() const
282 {
283 return static_cast<QDoubleSpinBox*>(object());
284 }
285
text(QAccessible::Text textType) const286 QString QAccessibleDoubleSpinBox::text(QAccessible::Text textType) const
287 {
288 if (textType == QAccessible::Value)
289 return doubleSpinBox()->textFromValue(doubleSpinBox()->value());
290 return QAccessibleWidget::text(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 */
QAccessibleScrollBar(QWidget * w)308 QAccessibleScrollBar::QAccessibleScrollBar(QWidget *w)
309 : QAccessibleAbstractSlider(w, QAccessible::ScrollBar)
310 {
311 Q_ASSERT(scrollBar());
312 addControllingSignal(QLatin1String("valueChanged(int)"));
313 }
314
315 /*! Returns the scroll bar. */
scrollBar() const316 QScrollBar *QAccessibleScrollBar::scrollBar() const
317 {
318 return qobject_cast<QScrollBar*>(object());
319 }
320
text(QAccessible::Text t) const321 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 */
QAccessibleSlider(QWidget * w)343 QAccessibleSlider::QAccessibleSlider(QWidget *w)
344 : QAccessibleAbstractSlider(w)
345 {
346 Q_ASSERT(slider());
347 addControllingSignal(QLatin1String("valueChanged(int)"));
348 }
349
350 /*! Returns the slider. */
slider() const351 QSlider *QAccessibleSlider::slider() const
352 {
353 return qobject_cast<QSlider*>(object());
354 }
355
text(QAccessible::Text t) const356 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
QAccessibleAbstractSlider(QWidget * w,QAccessible::Role r)364 QAccessibleAbstractSlider::QAccessibleAbstractSlider(QWidget *w, QAccessible::Role r)
365 : QAccessibleWidget(w, r)
366 {
367 Q_ASSERT(qobject_cast<QAbstractSlider *>(w));
368 }
369
interface_cast(QAccessible::InterfaceType t)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
currentValue() const377 QVariant QAccessibleAbstractSlider::currentValue() const
378 {
379 return abstractSlider()->value();
380 }
381
setCurrentValue(const QVariant & value)382 void QAccessibleAbstractSlider::setCurrentValue(const QVariant &value)
383 {
384 abstractSlider()->setValue(value.toInt());
385 }
386
maximumValue() const387 QVariant QAccessibleAbstractSlider::maximumValue() const
388 {
389 return abstractSlider()->maximum();
390 }
391
minimumValue() const392 QVariant QAccessibleAbstractSlider::minimumValue() const
393 {
394 return abstractSlider()->minimum();
395 }
396
minimumStepSize() const397 QVariant QAccessibleAbstractSlider::minimumStepSize() const
398 {
399 return abstractSlider()->singleStep();
400 }
401
abstractSlider() const402 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 ======================================
QAccessibleDial(QWidget * widget)411 QAccessibleDial::QAccessibleDial(QWidget *widget)
412 : QAccessibleAbstractSlider(widget, QAccessible::Dial)
413 {
414 Q_ASSERT(qobject_cast<QDial *>(widget));
415 addControllingSignal(QLatin1String("valueChanged(int)"));
416 }
417
text(QAccessible::Text textType) const418 QString QAccessibleDial::text(QAccessible::Text textType) const
419 {
420 if (textType == QAccessible::Value)
421 return QString::number(dial()->value());
422
423 return QAccessibleAbstractSlider::text(textType);
424 }
425
dial() const426 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