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