1 | /****************************************************************************
|
---|
2 | **
|
---|
3 | ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
---|
4 | ** All rights reserved.
|
---|
5 | ** Contact: Nokia Corporation ([email protected])
|
---|
6 | **
|
---|
7 | ** This file is part of the plugins of the Qt Toolkit.
|
---|
8 | **
|
---|
9 | ** $QT_BEGIN_LICENSE:LGPL$
|
---|
10 | ** Commercial Usage
|
---|
11 | ** Licensees holding valid Qt Commercial licenses may use this file in
|
---|
12 | ** accordance with the Qt Commercial License Agreement provided with the
|
---|
13 | ** Software or, alternatively, in accordance with the terms contained in
|
---|
14 | ** a written agreement between you and Nokia.
|
---|
15 | **
|
---|
16 | ** GNU Lesser General Public License Usage
|
---|
17 | ** Alternatively, this file may be used under the terms of the GNU Lesser
|
---|
18 | ** General Public License version 2.1 as published by the Free Software
|
---|
19 | ** Foundation and appearing in the file LICENSE.LGPL included in the
|
---|
20 | ** packaging of this file. Please review the following information to
|
---|
21 | ** ensure the GNU Lesser General Public License version 2.1 requirements
|
---|
22 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
---|
23 | **
|
---|
24 | ** In addition, as a special exception, Nokia gives you certain additional
|
---|
25 | ** rights. These rights are described in the Nokia Qt LGPL Exception
|
---|
26 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
---|
27 | **
|
---|
28 | ** GNU General Public License Usage
|
---|
29 | ** Alternatively, this file may be used under the terms of the GNU
|
---|
30 | ** General Public License version 3.0 as published by the Free Software
|
---|
31 | ** Foundation and appearing in the file LICENSE.GPL included in the
|
---|
32 | ** packaging of this file. Please review the following information to
|
---|
33 | ** ensure the GNU General Public License version 3.0 requirements will be
|
---|
34 | ** met: http://www.gnu.org/copyleft/gpl.html.
|
---|
35 | **
|
---|
36 | ** If you have questions regarding the use of this file, please contact
|
---|
37 | ** Nokia at [email protected].
|
---|
38 | ** $QT_END_LICENSE$
|
---|
39 | **
|
---|
40 | ****************************************************************************/
|
---|
41 |
|
---|
42 | #include "rangecontrols.h"
|
---|
43 |
|
---|
44 | #include <qslider.h>
|
---|
45 | #include <qdial.h>
|
---|
46 | #include <qspinbox.h>
|
---|
47 | #include <qscrollbar.h>
|
---|
48 | #include <qstyle.h>
|
---|
49 | #include <qstyleoption.h>
|
---|
50 | #include <qdebug.h>
|
---|
51 | #include <qglobal.h>
|
---|
52 | #include <QDoubleSpinBox>
|
---|
53 | #include <QDial>
|
---|
54 | #include <qmath.h>
|
---|
55 | #include <private/qmath_p.h>
|
---|
56 |
|
---|
57 | QT_BEGIN_NAMESPACE
|
---|
58 |
|
---|
59 | #ifndef QT_NO_ACCESSIBILITY
|
---|
60 | extern QString Q_GUI_EXPORT qt_accStripAmp(const QString &text);
|
---|
61 | #ifndef QT_NO_SCROLLBAR
|
---|
62 | extern QStyleOptionSlider Q_GUI_EXPORT qt_qscrollbarStyleOption(QScrollBar *scrollBar);
|
---|
63 | #endif
|
---|
64 | #ifndef QT_NO_SLIDER
|
---|
65 | extern QStyleOptionSlider Q_GUI_EXPORT qt_qsliderStyleOption(QSlider *slider);
|
---|
66 | #endif
|
---|
67 |
|
---|
68 | #ifndef QT_NO_SPINBOX
|
---|
69 | QAccessibleAbstractSpinBox::QAccessibleAbstractSpinBox(QWidget *w)
|
---|
70 | : QAccessibleWidgetEx(w, SpinBox)
|
---|
71 | {
|
---|
72 | Q_ASSERT(abstractSpinBox());
|
---|
73 | }
|
---|
74 |
|
---|
75 | /*!
|
---|
76 | Returns the underlying QAbstractSpinBox.
|
---|
77 | */
|
---|
78 | QAbstractSpinBox *QAccessibleAbstractSpinBox::abstractSpinBox() const
|
---|
79 | {
|
---|
80 | return qobject_cast<QAbstractSpinBox*>(object());
|
---|
81 | }
|
---|
82 |
|
---|
83 | /*! \reimp */
|
---|
84 | int QAccessibleAbstractSpinBox::childCount() const
|
---|
85 | {
|
---|
86 | if (!abstractSpinBox()->isVisible())
|
---|
87 | return 0;
|
---|
88 | return ValueDown;
|
---|
89 | }
|
---|
90 |
|
---|
91 | /*! \reimp */
|
---|
92 | QRect QAccessibleAbstractSpinBox::rect(int child) const
|
---|
93 | {
|
---|
94 | QRect rect;
|
---|
95 | if (!abstractSpinBox()->isVisible())
|
---|
96 | return rect;
|
---|
97 | QStyleOptionSpinBox so;
|
---|
98 | so.rect = widget()->rect();
|
---|
99 | switch(child) {
|
---|
100 | case Editor:
|
---|
101 | rect = widget()->style()->subControlRect(QStyle::CC_SpinBox, &so,
|
---|
102 | QStyle::SC_SpinBoxEditField, widget());
|
---|
103 | break;
|
---|
104 | case ValueUp:
|
---|
105 | rect = widget()->style()->subControlRect(QStyle::CC_SpinBox, &so,
|
---|
106 | QStyle::SC_SpinBoxUp, widget());
|
---|
107 | break;
|
---|
108 | case ValueDown:
|
---|
109 | rect = widget()->style()->subControlRect(QStyle::CC_SpinBox, &so,
|
---|
110 | QStyle::SC_SpinBoxDown, widget());
|
---|
111 | break;
|
---|
112 | default:
|
---|
113 | rect = so.rect;
|
---|
114 | break;
|
---|
115 | }
|
---|
116 | QPoint tl = widget()->mapToGlobal(QPoint(0, 0));
|
---|
117 | return QRect(tl.x() + rect.x(), tl.y() + rect.y(), rect.width(), rect.height());
|
---|
118 | }
|
---|
119 |
|
---|
120 | /*! \reimp */
|
---|
121 | int QAccessibleAbstractSpinBox::navigate(RelationFlag rel, int entry, QAccessibleInterface **target) const
|
---|
122 | {
|
---|
123 | *target = 0;
|
---|
124 |
|
---|
125 | if (entry) switch (rel) {
|
---|
126 | case Child:
|
---|
127 | return entry <= childCount() ? entry : -1;
|
---|
128 | case QAccessible::Left:
|
---|
129 | return (entry == ValueUp || entry == ValueDown) ? Editor : -1;
|
---|
130 | case QAccessible::Right:
|
---|
131 | return entry == Editor ? ValueUp : -1;
|
---|
132 | case QAccessible::Up:
|
---|
133 | return entry == ValueDown ? ValueUp : -1;
|
---|
134 | case QAccessible::Down:
|
---|
135 | return entry == ValueUp ? ValueDown : -1;
|
---|
136 | default:
|
---|
137 | break;
|
---|
138 | }
|
---|
139 | return QAccessibleWidgetEx::navigate(rel, entry, target);
|
---|
140 | }
|
---|
141 |
|
---|
142 | /*! \reimp */
|
---|
143 | QString QAccessibleAbstractSpinBox::text(Text t, int child) const
|
---|
144 | {
|
---|
145 | if (!abstractSpinBox()->isVisible())
|
---|
146 | return QString();
|
---|
147 | switch (t) {
|
---|
148 | case Name:
|
---|
149 | switch (child) {
|
---|
150 | case ValueUp:
|
---|
151 | return QSpinBox::tr("More");
|
---|
152 | case ValueDown:
|
---|
153 | return QSpinBox::tr("Less");
|
---|
154 | }
|
---|
155 | break;
|
---|
156 | case Value:
|
---|
157 | if (child == Editor || child == SpinBoxSelf)
|
---|
158 | return abstractSpinBox()->text();
|
---|
159 | break;
|
---|
160 | default:
|
---|
161 | break;
|
---|
162 | }
|
---|
163 | return QAccessibleWidgetEx::text(t, 0);
|
---|
164 | }
|
---|
165 |
|
---|
166 | /*! \reimp */
|
---|
167 | QAccessible::Role QAccessibleAbstractSpinBox::role(int child) const
|
---|
168 | {
|
---|
169 | switch(child) {
|
---|
170 | case Editor:
|
---|
171 | return EditableText;
|
---|
172 | case ValueUp:
|
---|
173 | case ValueDown:
|
---|
174 | return PushButton;
|
---|
175 | default:
|
---|
176 | break;
|
---|
177 | }
|
---|
178 | return QAccessibleWidgetEx::role(child);
|
---|
179 | }
|
---|
180 |
|
---|
181 | /*! \reimp */
|
---|
182 | bool QAccessibleAbstractSpinBox::doAction(int action, int child, const QVariantList ¶ms)
|
---|
183 | {
|
---|
184 | if (!widget()->isEnabled())
|
---|
185 | return false;
|
---|
186 |
|
---|
187 | if (action == Press) {
|
---|
188 | switch(child) {
|
---|
189 | case ValueUp:
|
---|
190 | abstractSpinBox()->stepUp();
|
---|
191 | return true;
|
---|
192 | case ValueDown:
|
---|
193 | abstractSpinBox()->stepDown();
|
---|
194 | return true;
|
---|
195 | default:
|
---|
196 | break;
|
---|
197 | }
|
---|
198 | }
|
---|
199 | return QAccessibleWidgetEx::doAction(action, 0, params);
|
---|
200 | }
|
---|
201 |
|
---|
202 | QVariant QAccessibleAbstractSpinBox::currentValue()
|
---|
203 | {
|
---|
204 | QVariant result = abstractSpinBox()->property("value");
|
---|
205 | QVariant::Type type = result.type();
|
---|
206 |
|
---|
207 | // IA2 only allows numeric types
|
---|
208 | if (type == QVariant::Int || type == QVariant::UInt || type == QVariant::LongLong
|
---|
209 | || type == QVariant::ULongLong || type == QVariant::Double)
|
---|
210 | return result;
|
---|
211 |
|
---|
212 | return QVariant();
|
---|
213 | }
|
---|
214 |
|
---|
215 | void QAccessibleAbstractSpinBox::setCurrentValue(const QVariant &value)
|
---|
216 | {
|
---|
217 | abstractSpinBox()->setProperty("setValue", value);
|
---|
218 | }
|
---|
219 |
|
---|
220 | QVariant QAccessibleAbstractSpinBox::maximumValue()
|
---|
221 | {
|
---|
222 | return abstractSpinBox()->property("maximum");
|
---|
223 | }
|
---|
224 |
|
---|
225 | QVariant QAccessibleAbstractSpinBox::minimumValue()
|
---|
226 | {
|
---|
227 | return abstractSpinBox()->property("minimum");
|
---|
228 | }
|
---|
229 |
|
---|
230 | QVariant QAccessibleAbstractSpinBox::invokeMethodEx(Method method, int child, const QVariantList ¶ms)
|
---|
231 | {
|
---|
232 | switch (method) {
|
---|
233 | case ListSupportedMethods: {
|
---|
234 | QSet<QAccessible::Method> set;
|
---|
235 | set << ListSupportedMethods;
|
---|
236 | return qVariantFromValue(set | qvariant_cast<QSet<QAccessible::Method> >(
|
---|
237 | QAccessibleWidgetEx::invokeMethodEx(method, child, params)));
|
---|
238 | }
|
---|
239 | default:
|
---|
240 | return QAccessibleWidgetEx::invokeMethodEx(method, child, params);
|
---|
241 | }
|
---|
242 | }
|
---|
243 |
|
---|
244 |
|
---|
245 | /*!
|
---|
246 | \class QAccessibleSpinBox
|
---|
247 | \brief The QAccessibleSpinBox class implements the QAccessibleInterface for spinbox widgets.
|
---|
248 | \internal
|
---|
249 |
|
---|
250 | \ingroup accessibility
|
---|
251 | */
|
---|
252 |
|
---|
253 | /*!
|
---|
254 | \enum QAccessibleAbstractSpinBox::SpinBoxElements
|
---|
255 |
|
---|
256 | This enum identifies the components of the spin box.
|
---|
257 |
|
---|
258 | \value SpinBoxSelf The spin box as a whole
|
---|
259 | \value Editor The line edit sub-widget.
|
---|
260 | \value ValueUp The up sub-widget (i.e. the up arrow or + button)
|
---|
261 | \value ValueDown The down sub-widget (i.e. the down arrow or - button)
|
---|
262 | */
|
---|
263 |
|
---|
264 | /*!
|
---|
265 | Constructs a QAccessibleSpinWidget object for \a w.
|
---|
266 | */
|
---|
267 | QAccessibleSpinBox::QAccessibleSpinBox(QWidget *w)
|
---|
268 | : QAccessibleAbstractSpinBox(w)
|
---|
269 | {
|
---|
270 | Q_ASSERT(spinBox());
|
---|
271 | addControllingSignal(QLatin1String("valueChanged(int)"));
|
---|
272 | addControllingSignal(QLatin1String("valueChanged(QString)"));
|
---|
273 | }
|
---|
274 |
|
---|
275 | /*!
|
---|
276 | Returns the underlying QSpinBox.
|
---|
277 | */
|
---|
278 | QSpinBox *QAccessibleSpinBox::spinBox() const
|
---|
279 | {
|
---|
280 | return qobject_cast<QSpinBox*>(object());
|
---|
281 | }
|
---|
282 |
|
---|
283 | /*! \reimp */
|
---|
284 | QAccessible::State QAccessibleSpinBox::state(int child) const
|
---|
285 | {
|
---|
286 | State state = QAccessibleAbstractSpinBox::state(child);
|
---|
287 | switch(child) {
|
---|
288 | case ValueUp:
|
---|
289 | if (spinBox()->value() >= spinBox()->maximum())
|
---|
290 | state |= Unavailable;
|
---|
291 | return state;
|
---|
292 | case ValueDown:
|
---|
293 | if (spinBox()->value() <= spinBox()->minimum())
|
---|
294 | state |= Unavailable;
|
---|
295 | return state;
|
---|
296 | default:
|
---|
297 | break;
|
---|
298 | }
|
---|
299 | return state;
|
---|
300 | }
|
---|
301 |
|
---|
302 | /*! \reimp */
|
---|
303 | bool QAccessibleSpinBox::doAction(int action, int child, const QVariantList ¶ms)
|
---|
304 | {
|
---|
305 | if (!widget()->isEnabled())
|
---|
306 | return false;
|
---|
307 |
|
---|
308 | if (action == Press) {
|
---|
309 | switch(child) {
|
---|
310 | case ValueUp:
|
---|
311 | if (spinBox()->value() >= spinBox()->maximum())
|
---|
312 | return false;
|
---|
313 | spinBox()->stepUp();
|
---|
314 | return true;
|
---|
315 | case ValueDown:
|
---|
316 | if (spinBox()->value() <= spinBox()->minimum())
|
---|
317 | return false;
|
---|
318 | spinBox()->stepDown();
|
---|
319 | return true;
|
---|
320 | default:
|
---|
321 | break;
|
---|
322 | }
|
---|
323 | }
|
---|
324 | return QAccessibleAbstractSpinBox::doAction(action, 0, params);
|
---|
325 | }
|
---|
326 |
|
---|
327 | // ================================== QAccessibleDoubleSpinBox ==================================
|
---|
328 | QAccessibleDoubleSpinBox::QAccessibleDoubleSpinBox(QWidget *widget)
|
---|
329 | : QAccessibleWidgetEx(widget, SpinBox)
|
---|
330 | {
|
---|
331 | Q_ASSERT(qobject_cast<QDoubleSpinBox *>(widget));
|
---|
332 | addControllingSignal(QLatin1String("valueChanged(double)"));
|
---|
333 | addControllingSignal(QLatin1String("valueChanged(QString)"));
|
---|
334 | }
|
---|
335 |
|
---|
336 | /*!
|
---|
337 | Returns the underlying QDoubleSpinBox.
|
---|
338 | */
|
---|
339 | QDoubleSpinBox *QAccessibleDoubleSpinBox::doubleSpinBox() const
|
---|
340 | {
|
---|
341 | return static_cast<QDoubleSpinBox*>(object());
|
---|
342 | }
|
---|
343 |
|
---|
344 | /*! \reimp */
|
---|
345 | int QAccessibleDoubleSpinBox::childCount() const
|
---|
346 | {
|
---|
347 | if (!doubleSpinBox()->isVisible())
|
---|
348 | return 0;
|
---|
349 | return ValueDown;
|
---|
350 | }
|
---|
351 |
|
---|
352 | /*! \reimp */
|
---|
353 | QRect QAccessibleDoubleSpinBox::rect(int child) const
|
---|
354 | {
|
---|
355 | QRect rect;
|
---|
356 | if (!doubleSpinBox()->isVisible())
|
---|
357 | return rect;
|
---|
358 | QStyleOptionSpinBox spinBoxOption;
|
---|
359 | spinBoxOption.initFrom(doubleSpinBox());
|
---|
360 | switch (child) {
|
---|
361 | case Editor:
|
---|
362 | rect = doubleSpinBox()->style()->subControlRect(QStyle::CC_SpinBox, &spinBoxOption,
|
---|
363 | QStyle::SC_SpinBoxEditField, doubleSpinBox());
|
---|
364 | break;
|
---|
365 | case ValueUp:
|
---|
366 | rect = doubleSpinBox()->style()->subControlRect(QStyle::CC_SpinBox, &spinBoxOption,
|
---|
367 | QStyle::SC_SpinBoxUp, doubleSpinBox());
|
---|
368 | break;
|
---|
369 | case ValueDown:
|
---|
370 | rect = doubleSpinBox()->style()->subControlRect(QStyle::CC_SpinBox, &spinBoxOption,
|
---|
371 | QStyle::SC_SpinBoxDown, doubleSpinBox());
|
---|
372 | break;
|
---|
373 | default:
|
---|
374 | rect = spinBoxOption.rect;
|
---|
375 | break;
|
---|
376 | }
|
---|
377 | const QPoint globalPos = doubleSpinBox()->mapToGlobal(QPoint(0, 0));
|
---|
378 | return QRect(globalPos.x() + rect.x(), globalPos.y() + rect.y(), rect.width(), rect.height());
|
---|
379 | }
|
---|
380 |
|
---|
381 | /*! \reimp */
|
---|
382 | int QAccessibleDoubleSpinBox::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const
|
---|
383 | {
|
---|
384 | if (entry <= 0)
|
---|
385 | return QAccessibleWidgetEx::navigate(relation, entry, target);
|
---|
386 |
|
---|
387 | *target = 0;
|
---|
388 | switch (relation) {
|
---|
389 | case Child:
|
---|
390 | return entry <= childCount() ? entry : -1;
|
---|
391 | case QAccessible::Left:
|
---|
392 | return (entry == ValueUp || entry == ValueDown) ? Editor : -1;
|
---|
393 | case QAccessible::Right:
|
---|
394 | return entry == Editor ? ValueUp : -1;
|
---|
395 | case QAccessible::Up:
|
---|
396 | return entry == ValueDown ? ValueUp : -1;
|
---|
397 | case QAccessible::Down:
|
---|
398 | return entry == ValueUp ? ValueDown : -1;
|
---|
399 | default:
|
---|
400 | break;
|
---|
401 | }
|
---|
402 | return QAccessibleWidgetEx::navigate(relation, entry, target);
|
---|
403 | }
|
---|
404 |
|
---|
405 | QVariant QAccessibleDoubleSpinBox::invokeMethodEx(QAccessible::Method, int, const QVariantList &)
|
---|
406 | {
|
---|
407 | return QVariant();
|
---|
408 | }
|
---|
409 |
|
---|
410 | /*! \reimp */
|
---|
411 | QString QAccessibleDoubleSpinBox::text(Text textType, int child) const
|
---|
412 | {
|
---|
413 | if (!doubleSpinBox()->isVisible())
|
---|
414 | return QString();
|
---|
415 | switch (textType) {
|
---|
416 | case Name:
|
---|
417 | if (child == ValueUp)
|
---|
418 | return QDoubleSpinBox::tr("More");
|
---|
419 | else if (child == ValueDown)
|
---|
420 | return QDoubleSpinBox::tr("Less");
|
---|
421 | break;
|
---|
422 | case Value:
|
---|
423 | if (child == Editor || child == SpinBoxSelf)
|
---|
424 | return doubleSpinBox()->textFromValue(doubleSpinBox()->value());
|
---|
425 | break;
|
---|
426 | default:
|
---|
427 | break;
|
---|
428 | }
|
---|
429 | return QAccessibleWidgetEx::text(textType, 0);
|
---|
430 | }
|
---|
431 |
|
---|
432 | /*! \reimp */
|
---|
433 | QAccessible::Role QAccessibleDoubleSpinBox::role(int child) const
|
---|
434 | {
|
---|
435 | switch (child) {
|
---|
436 | case Editor:
|
---|
437 | return EditableText;
|
---|
438 | case ValueUp:
|
---|
439 | case ValueDown:
|
---|
440 | return PushButton;
|
---|
441 | default:
|
---|
442 | break;
|
---|
443 | }
|
---|
444 | return QAccessibleWidgetEx::role(child);
|
---|
445 | }
|
---|
446 |
|
---|
447 | /*! \reimp */
|
---|
448 | QAccessible::State QAccessibleDoubleSpinBox::state(int child) const
|
---|
449 | {
|
---|
450 | State state = QAccessibleWidgetEx::state(child);
|
---|
451 | switch (child) {
|
---|
452 | case ValueUp:
|
---|
453 | if (doubleSpinBox()->value() >= doubleSpinBox()->maximum())
|
---|
454 | state |= Unavailable;
|
---|
455 | break;
|
---|
456 | case ValueDown:
|
---|
457 | if (doubleSpinBox()->value() <= doubleSpinBox()->minimum())
|
---|
458 | state |= Unavailable;
|
---|
459 | break;
|
---|
460 | default:
|
---|
461 | break;
|
---|
462 | }
|
---|
463 | return state;
|
---|
464 | }
|
---|
465 | #endif // QT_NO_SPINBOX
|
---|
466 |
|
---|
467 | #ifndef QT_NO_SCROLLBAR
|
---|
468 | /*!
|
---|
469 | \class QAccessibleScrollBar
|
---|
470 | \brief The QAccessibleScrollBar class implements the QAccessibleInterface for scroll bars.
|
---|
471 | \internal
|
---|
472 |
|
---|
473 | \ingroup accessibility
|
---|
474 | */
|
---|
475 |
|
---|
476 | /*!
|
---|
477 | \enum QAccessibleScrollBar::ScrollBarElements
|
---|
478 |
|
---|
479 | This enum identifies the components of the scroll bar.
|
---|
480 |
|
---|
481 | \value ScrollBarSelf The scroll bar as a whole.
|
---|
482 | \value LineUp The up arrow button.
|
---|
483 | \value PageUp The area between the position and the up arrow button.
|
---|
484 | \value Position The position marking rectangle.
|
---|
485 | \value PageDown The area between the position and the down arrow button.
|
---|
486 | \value LineDown The down arrow button.
|
---|
487 | */
|
---|
488 |
|
---|
489 | /*!
|
---|
490 | Constructs a QAccessibleScrollBar object for \a w.
|
---|
491 | \a name is propagated to the QAccessibleWidgetEx constructor.
|
---|
492 | */
|
---|
493 | QAccessibleScrollBar::QAccessibleScrollBar(QWidget *w)
|
---|
494 | : QAccessibleAbstractSlider(w, ScrollBar)
|
---|
495 | {
|
---|
496 | Q_ASSERT(scrollBar());
|
---|
497 | addControllingSignal(QLatin1String("valueChanged(int)"));
|
---|
498 | }
|
---|
499 |
|
---|
500 | /*! Returns the scroll bar. */
|
---|
501 | QScrollBar *QAccessibleScrollBar::scrollBar() const
|
---|
502 | {
|
---|
503 | return qobject_cast<QScrollBar*>(object());
|
---|
504 | }
|
---|
505 |
|
---|
506 | /*! \reimp */
|
---|
507 | QRect QAccessibleScrollBar::rect(int child) const
|
---|
508 | {
|
---|
509 | if (!scrollBar()->isVisible())
|
---|
510 | return QRect();
|
---|
511 |
|
---|
512 | QStyle::SubControl subControl;
|
---|
513 | switch (child) {
|
---|
514 | case LineUp:
|
---|
515 | subControl = QStyle ::SC_ScrollBarSubLine;
|
---|
516 | break;
|
---|
517 | case PageUp:
|
---|
518 | subControl = QStyle::SC_ScrollBarSubPage;
|
---|
519 | break;
|
---|
520 | case Position:
|
---|
521 | subControl = QStyle::SC_ScrollBarSlider;
|
---|
522 | break;
|
---|
523 | case PageDown:
|
---|
524 | subControl = QStyle::SC_ScrollBarAddPage;
|
---|
525 | break;
|
---|
526 | case LineDown:
|
---|
527 | subControl = QStyle::SC_ScrollBarAddLine;
|
---|
528 | break;
|
---|
529 | default:
|
---|
530 | return QAccessibleAbstractSlider::rect(child);
|
---|
531 | }
|
---|
532 |
|
---|
533 | const QStyleOptionSlider option = qt_qscrollbarStyleOption(scrollBar());
|
---|
534 | const QRect rect = scrollBar()->style()->subControlRect(QStyle::CC_ScrollBar, &option,
|
---|
535 | subControl, scrollBar());
|
---|
536 | const QPoint tp = scrollBar()->mapToGlobal(QPoint(0,0));
|
---|
537 | return QRect(tp.x() + rect.x(), tp.y() + rect.y(), rect.width(), rect.height());
|
---|
538 | }
|
---|
539 |
|
---|
540 | /*! \reimp */
|
---|
541 | int QAccessibleScrollBar::childCount() const
|
---|
542 | {
|
---|
543 | if (!scrollBar()->isVisible())
|
---|
544 | return 0;
|
---|
545 | return LineDown;
|
---|
546 | }
|
---|
547 |
|
---|
548 | /*! \reimp */
|
---|
549 | QString QAccessibleScrollBar::text(Text t, int child) const
|
---|
550 | {
|
---|
551 | if (!scrollBar()->isVisible())
|
---|
552 | return QString();
|
---|
553 | switch (t) {
|
---|
554 | case Value:
|
---|
555 | if (!child || child == Position)
|
---|
556 | return QString::number(scrollBar()->value());
|
---|
557 | return QString();
|
---|
558 | case Name:
|
---|
559 | switch (child) {
|
---|
560 | case LineUp:
|
---|
561 | return QScrollBar::tr("Line up");
|
---|
562 | case PageUp:
|
---|
563 | return QScrollBar::tr("Page up");
|
---|
564 | case Position:
|
---|
565 | return QScrollBar::tr("Position");
|
---|
566 | case PageDown:
|
---|
567 | return QScrollBar::tr("Page down");
|
---|
568 | case LineDown:
|
---|
569 | return QScrollBar::tr("Line down");
|
---|
570 | }
|
---|
571 | break;
|
---|
572 | default:
|
---|
573 | break;
|
---|
574 | }
|
---|
575 | return QAccessibleAbstractSlider::text(t, child);
|
---|
576 | }
|
---|
577 |
|
---|
578 | /*! \reimp */
|
---|
579 | QAccessible::Role QAccessibleScrollBar::role(int child) const
|
---|
580 | {
|
---|
581 | switch (child) {
|
---|
582 | case LineUp:
|
---|
583 | case PageUp:
|
---|
584 | case PageDown:
|
---|
585 | case LineDown:
|
---|
586 | return PushButton;
|
---|
587 | case Position:
|
---|
588 | return Indicator;
|
---|
589 | default:
|
---|
590 | return ScrollBar;
|
---|
591 | }
|
---|
592 | }
|
---|
593 |
|
---|
594 | /*! \reimp */
|
---|
595 | QAccessible::State QAccessibleScrollBar::state(int child) const
|
---|
596 | {
|
---|
597 | const State parentState = QAccessibleAbstractSlider::state(0);
|
---|
598 |
|
---|
599 | if (child == 0)
|
---|
600 | return parentState;
|
---|
601 |
|
---|
602 | // Inherit the Invisible state from parent.
|
---|
603 | State state = parentState & QAccessible::Invisible;
|
---|
604 |
|
---|
605 | // Disable left/right if we are at the minimum/maximum.
|
---|
606 | const QScrollBar * const scrollBar = QAccessibleScrollBar::scrollBar();
|
---|
607 | switch (child) {
|
---|
608 | case LineUp:
|
---|
609 | case PageUp:
|
---|
610 | if (scrollBar->value() <= scrollBar->minimum())
|
---|
611 | state |= Unavailable;
|
---|
612 | break;
|
---|
613 | case LineDown:
|
---|
614 | case PageDown:
|
---|
615 | if (scrollBar->value() >= scrollBar->maximum())
|
---|
616 | state |= Unavailable;
|
---|
617 | break;
|
---|
618 | case Position:
|
---|
619 | default:
|
---|
620 | break;
|
---|
621 | }
|
---|
622 |
|
---|
623 | return state;
|
---|
624 | }
|
---|
625 | #endif // QT_NO_SCROLLBAR
|
---|
626 |
|
---|
627 | #ifndef QT_NO_SLIDER
|
---|
628 | /*!
|
---|
629 | \class QAccessibleSlider
|
---|
630 | \brief The QAccessibleSlider class implements the QAccessibleInterface for sliders.
|
---|
631 | \internal
|
---|
632 |
|
---|
633 | \ingroup accessibility
|
---|
634 | */
|
---|
635 |
|
---|
636 | /*!
|
---|
637 | \enum QAccessibleSlider::SliderElements
|
---|
638 |
|
---|
639 | This enum identifies the components of the slider.
|
---|
640 |
|
---|
641 | \value SliderSelf The slider as a whole.
|
---|
642 | \value PageLeft The area to the left of the position.
|
---|
643 | \value Position The position indicator.
|
---|
644 | \value PageRight The area to the right of the position.
|
---|
645 | */
|
---|
646 |
|
---|
647 | /*!
|
---|
648 | Constructs a QAccessibleScrollBar object for \a w.
|
---|
649 | \a name is propagated to the QAccessibleWidgetEx constructor.
|
---|
650 | */
|
---|
651 | QAccessibleSlider::QAccessibleSlider(QWidget *w)
|
---|
652 | : QAccessibleAbstractSlider(w)
|
---|
653 | {
|
---|
654 | Q_ASSERT(slider());
|
---|
655 | addControllingSignal(QLatin1String("valueChanged(int)"));
|
---|
656 | }
|
---|
657 |
|
---|
658 | /*! Returns the slider. */
|
---|
659 | QSlider *QAccessibleSlider::slider() const
|
---|
660 | {
|
---|
661 | return qobject_cast<QSlider*>(object());
|
---|
662 | }
|
---|
663 |
|
---|
664 | /*! \reimp */
|
---|
665 | QRect QAccessibleSlider::rect(int child) const
|
---|
666 | {
|
---|
667 | QRect rect;
|
---|
668 | if (!slider()->isVisible())
|
---|
669 | return rect;
|
---|
670 | const QStyleOptionSlider option = qt_qsliderStyleOption(slider());
|
---|
671 | QRect srect = slider()->style()->subControlRect(QStyle::CC_Slider, &option,
|
---|
672 | QStyle::SC_SliderHandle, slider());
|
---|
673 |
|
---|
674 | switch (child) {
|
---|
675 | case PageLeft:
|
---|
676 | if (slider()->orientation() == Qt::Vertical)
|
---|
677 | rect = QRect(0, 0, slider()->width(), srect.y());
|
---|
678 | else
|
---|
679 | rect = QRect(0, 0, srect.x(), slider()->height());
|
---|
680 | break;
|
---|
681 | case Position:
|
---|
682 | rect = srect;
|
---|
683 | break;
|
---|
684 | case PageRight:
|
---|
685 | if (slider()->orientation() == Qt::Vertical)
|
---|
686 | rect = QRect(0, srect.y() + srect.height(), slider()->width(), slider()->height()- srect.y() - srect.height());
|
---|
687 | else
|
---|
688 | rect = QRect(srect.x() + srect.width(), 0, slider()->width() - srect.x() - srect.width(), slider()->height());
|
---|
689 | break;
|
---|
690 | default:
|
---|
691 | return QAccessibleAbstractSlider::rect(child);
|
---|
692 | }
|
---|
693 |
|
---|
694 | QPoint tp = slider()->mapToGlobal(QPoint(0,0));
|
---|
695 | return QRect(tp.x() + rect.x(), tp.y() + rect.y(), rect.width(), rect.height());
|
---|
696 | }
|
---|
697 |
|
---|
698 | /*! \reimp */
|
---|
699 | int QAccessibleSlider::childCount() const
|
---|
700 | {
|
---|
701 | if (!slider()->isVisible())
|
---|
702 | return 0;
|
---|
703 | return PageRight;
|
---|
704 | }
|
---|
705 |
|
---|
706 | /*! \reimp */
|
---|
707 | QString QAccessibleSlider::text(Text t, int child) const
|
---|
708 | {
|
---|
709 | if (!slider()->isVisible())
|
---|
710 | return QString();
|
---|
711 | switch (t) {
|
---|
712 | case Value:
|
---|
713 | if (!child || child == 2)
|
---|
714 | return QString::number(slider()->value());
|
---|
715 | return QString();
|
---|
716 | case Name:
|
---|
717 | switch (child) {
|
---|
718 | case PageLeft:
|
---|
719 | return slider()->orientation() == Qt::Horizontal ?
|
---|
720 | QSlider::tr("Page left") : QSlider::tr("Page up");
|
---|
721 | case Position:
|
---|
722 | return QSlider::tr("Position");
|
---|
723 | case PageRight:
|
---|
724 | return slider()->orientation() == Qt::Horizontal ?
|
---|
725 | QSlider::tr("Page right") : QSlider::tr("Page down");
|
---|
726 | }
|
---|
727 | break;
|
---|
728 | default:
|
---|
729 | break;
|
---|
730 | }
|
---|
731 | return QAccessibleAbstractSlider::text(t, child);
|
---|
732 | }
|
---|
733 |
|
---|
734 | /*! \reimp */
|
---|
735 | QAccessible::Role QAccessibleSlider::role(int child) const
|
---|
736 | {
|
---|
737 | switch (child) {
|
---|
738 | case PageLeft:
|
---|
739 | case PageRight:
|
---|
740 | return PushButton;
|
---|
741 | case Position:
|
---|
742 | return Indicator;
|
---|
743 | default:
|
---|
744 | return Slider;
|
---|
745 | }
|
---|
746 | }
|
---|
747 |
|
---|
748 | /*! \reimp */
|
---|
749 | QAccessible::State QAccessibleSlider::state(int child) const
|
---|
750 | {
|
---|
751 | const State parentState = QAccessibleAbstractSlider::state(0);
|
---|
752 |
|
---|
753 | if (child == 0)
|
---|
754 | return parentState;
|
---|
755 |
|
---|
756 | // Inherit the Invisible state from parent.
|
---|
757 | State state = parentState & QAccessible::Invisible;
|
---|
758 |
|
---|
759 | // Disable left/right if we are at the minimum/maximum.
|
---|
760 | const QSlider * const slider = QAccessibleSlider::slider();
|
---|
761 | switch (child) {
|
---|
762 | case PageLeft:
|
---|
763 | if (slider->value() <= slider->minimum())
|
---|
764 | state |= Unavailable;
|
---|
765 | break;
|
---|
766 | case PageRight:
|
---|
767 | if (slider->value() >= slider->maximum())
|
---|
768 | state |= Unavailable;
|
---|
769 | break;
|
---|
770 | case Position:
|
---|
771 | default:
|
---|
772 | break;
|
---|
773 | }
|
---|
774 |
|
---|
775 | return state;
|
---|
776 | }
|
---|
777 |
|
---|
778 | /*!
|
---|
779 | \fn int QAccessibleSlider::defaultAction(int child) const
|
---|
780 |
|
---|
781 | Returns the default action for the given \a child. The base class
|
---|
782 | implementation returns 0.
|
---|
783 | */
|
---|
784 | int QAccessibleSlider::defaultAction(int /*child*/) const
|
---|
785 | {
|
---|
786 | /*
|
---|
787 | switch (child) {
|
---|
788 | case SliderSelf:
|
---|
789 | return SetFocus;
|
---|
790 | case PageLeft:
|
---|
791 | return Press;
|
---|
792 | case PageRight:
|
---|
793 | return Press;
|
---|
794 | }
|
---|
795 | */
|
---|
796 | return 0;
|
---|
797 | }
|
---|
798 |
|
---|
799 | /*! \internal */
|
---|
800 | QString QAccessibleSlider::actionText(int /*action*/, Text /*t*/, int /*child*/) const
|
---|
801 | {
|
---|
802 | return QLatin1String("");
|
---|
803 | }
|
---|
804 |
|
---|
805 | QAccessibleAbstractSlider::QAccessibleAbstractSlider(QWidget *w, Role r)
|
---|
806 | : QAccessibleWidgetEx(w, r)
|
---|
807 | {
|
---|
808 | Q_ASSERT(qobject_cast<QAbstractSlider *>(w));
|
---|
809 | }
|
---|
810 |
|
---|
811 | QVariant QAccessibleAbstractSlider::invokeMethodEx(Method method, int child, const QVariantList ¶ms)
|
---|
812 | {
|
---|
813 | switch (method) {
|
---|
814 | case ListSupportedMethods: {
|
---|
815 | QSet<QAccessible::Method> set;
|
---|
816 | set << ListSupportedMethods;
|
---|
817 | return qVariantFromValue(set | qvariant_cast<QSet<QAccessible::Method> >(
|
---|
818 | QAccessibleWidgetEx::invokeMethodEx(method, child, params)));
|
---|
819 | }
|
---|
820 | default:
|
---|
821 | return QAccessibleWidgetEx::invokeMethodEx(method, child, params);
|
---|
822 | }
|
---|
823 | }
|
---|
824 |
|
---|
825 | QVariant QAccessibleAbstractSlider::currentValue()
|
---|
826 | {
|
---|
827 | return abstractSlider()->value();
|
---|
828 | }
|
---|
829 |
|
---|
830 | void QAccessibleAbstractSlider::setCurrentValue(const QVariant &value)
|
---|
831 | {
|
---|
832 | abstractSlider()->setValue(value.toInt());
|
---|
833 | }
|
---|
834 |
|
---|
835 | QVariant QAccessibleAbstractSlider::maximumValue()
|
---|
836 | {
|
---|
837 | return abstractSlider()->maximum();
|
---|
838 | }
|
---|
839 |
|
---|
840 | QVariant QAccessibleAbstractSlider::minimumValue()
|
---|
841 | {
|
---|
842 | return abstractSlider()->minimum();
|
---|
843 | }
|
---|
844 |
|
---|
845 | QAbstractSlider *QAccessibleAbstractSlider::abstractSlider() const
|
---|
846 | {
|
---|
847 | return static_cast<QAbstractSlider *>(object());
|
---|
848 | }
|
---|
849 |
|
---|
850 | #endif // QT_NO_SLIDER
|
---|
851 |
|
---|
852 | #ifndef QT_NO_DIAL
|
---|
853 | // ======================================= QAccessibleDial ======================================
|
---|
854 | QAccessibleDial::QAccessibleDial(QWidget *widget)
|
---|
855 | : QAccessibleWidgetEx(widget, Dial)
|
---|
856 | {
|
---|
857 | Q_ASSERT(qobject_cast<QDial *>(widget));
|
---|
858 | addControllingSignal(QLatin1String("valueChanged(int)"));
|
---|
859 | }
|
---|
860 |
|
---|
861 | QRect QAccessibleDial::rect(int child) const
|
---|
862 | {
|
---|
863 | QRect rect;
|
---|
864 | if (!dial()->isVisible())
|
---|
865 | return rect;
|
---|
866 | switch (child) {
|
---|
867 | case Self:
|
---|
868 | return QAccessibleWidgetEx::rect(child);
|
---|
869 | case SpeedoMeter: {
|
---|
870 | // Mixture from qcommonstyle.cpp (focus rect).
|
---|
871 | int width = dial()->width();
|
---|
872 | int height = dial()->height();
|
---|
873 | qreal radius = qMin(width, height) / 2.0;
|
---|
874 | qreal delta = radius / 6.0;
|
---|
875 | qreal dx = delta + (width - 2 * radius) / 2.0;
|
---|
876 | qreal dy = delta + (height - 2 * radius) / 2.0;
|
---|
877 | rect = QRect(int(dx), int(dy), int(radius * 2 - 2 * delta), int(radius * 2 - 2 * delta));
|
---|
878 | if (dial()->notchesVisible()) {
|
---|
879 | rect.translate(int(-radius / 6), int(-radius / 6));
|
---|
880 | rect.setWidth(rect.width() + int(radius / 3));
|
---|
881 | rect.setHeight(rect.height() + int(radius / 3));
|
---|
882 | }
|
---|
883 | break;
|
---|
884 | }
|
---|
885 | case SliderHandle: {
|
---|
886 | // Mixture from qcommonstyle.cpp and qdial.cpp.
|
---|
887 | int sliderValue = !dial()->invertedAppearance() ? dial()->value()
|
---|
888 | : (dial()->maximum() - dial()->value());
|
---|
889 | qreal angle = 0;
|
---|
890 | if (dial()->maximum() == dial()->minimum()) {
|
---|
891 | angle = Q_PI / 2;
|
---|
892 | } else if (dial()->wrapping()) {
|
---|
893 | angle = Q_PI * 3 / 2 - (sliderValue - dial()->minimum()) * 2 * Q_PI
|
---|
894 | / (dial()->maximum() - dial()->minimum());
|
---|
895 | } else {
|
---|
896 | angle = (Q_PI * 8 - (sliderValue - dial()->minimum()) * 10 * Q_PI
|
---|
897 | / (dial()->maximum() - dial()->minimum())) / 6;
|
---|
898 | }
|
---|
899 |
|
---|
900 | int width = dial()->rect().width();
|
---|
901 | int height = dial()->rect().height();
|
---|
902 | int radius = qMin(width, height) / 2;
|
---|
903 | int xc = width / 2;
|
---|
904 | int yc = height / 2;
|
---|
905 | int bigLineSize = radius / 6;
|
---|
906 | if (bigLineSize < 4)
|
---|
907 | bigLineSize = 4;
|
---|
908 | if (bigLineSize > radius / 2)
|
---|
909 | bigLineSize = radius / 2;
|
---|
910 | int len = radius - bigLineSize - 5;
|
---|
911 | if (len < 5)
|
---|
912 | len = 5;
|
---|
913 | int back = len / 2;
|
---|
914 |
|
---|
915 | QPolygonF arrow(3);
|
---|
916 | arrow[0] = QPointF(0.5 + xc + len * qCos(angle),
|
---|
917 | 0.5 + yc - len * qSin(angle));
|
---|
918 | arrow[1] = QPointF(0.5 + xc + back * qCos(angle + Q_PI * 5 / 6),
|
---|
919 | 0.5 + yc - back * qSin(angle + Q_PI * 5 / 6));
|
---|
920 | arrow[2] = QPointF(0.5 + xc + back * qCos(angle - Q_PI * 5 / 6),
|
---|
921 | 0.5 + yc - back * qSin(angle - Q_PI * 5 / 6));
|
---|
922 | rect = arrow.boundingRect().toRect();
|
---|
923 | break;
|
---|
924 | }
|
---|
925 | default:
|
---|
926 | return QRect();
|
---|
927 | }
|
---|
928 |
|
---|
929 | QPoint globalPos = dial()->mapToGlobal(QPoint(0,0));
|
---|
930 | return QRect(globalPos.x() + rect.x(), globalPos.y() + rect.y(), rect.width(), rect.height());
|
---|
931 | }
|
---|
932 |
|
---|
933 | int QAccessibleDial::childCount() const
|
---|
934 | {
|
---|
935 | if (!dial()->isVisible())
|
---|
936 | return 0;
|
---|
937 | return SliderHandle;
|
---|
938 | }
|
---|
939 |
|
---|
940 | QString QAccessibleDial::text(Text textType, int child) const
|
---|
941 | {
|
---|
942 | if (!dial()->isVisible())
|
---|
943 | return QString();
|
---|
944 | if (textType == Value && child >= Self && child <= SliderHandle)
|
---|
945 | return QString::number(dial()->value());
|
---|
946 | if (textType == Name) {
|
---|
947 | switch (child) {
|
---|
948 | case Self:
|
---|
949 | if (!widget()->accessibleName().isEmpty())
|
---|
950 | return widget()->accessibleName();
|
---|
951 | return QDial::tr("QDial");
|
---|
952 | case SpeedoMeter:
|
---|
953 | return QDial::tr("SpeedoMeter");
|
---|
954 | case SliderHandle:
|
---|
955 | return QDial::tr("SliderHandle");
|
---|
956 | }
|
---|
957 | }
|
---|
958 | return QAccessibleWidgetEx::text(textType, child);
|
---|
959 | }
|
---|
960 |
|
---|
961 | QAccessible::Role QAccessibleDial::role(int child) const
|
---|
962 | {
|
---|
963 | if (child == SpeedoMeter)
|
---|
964 | return Slider;
|
---|
965 | else if (child == SliderHandle)
|
---|
966 | return Indicator;
|
---|
967 | return QAccessibleWidgetEx::role(child);
|
---|
968 | }
|
---|
969 |
|
---|
970 | QAccessible::State QAccessibleDial::state(int child) const
|
---|
971 | {
|
---|
972 | const State parentState = QAccessibleWidgetEx::state(0);
|
---|
973 | if (child == SliderHandle)
|
---|
974 | return parentState | HotTracked;
|
---|
975 | return parentState;
|
---|
976 | }
|
---|
977 |
|
---|
978 | QVariant QAccessibleDial::invokeMethodEx(Method, int, const QVariantList &)
|
---|
979 | {
|
---|
980 | return QVariant();
|
---|
981 | }
|
---|
982 |
|
---|
983 | QDial *QAccessibleDial::dial() const
|
---|
984 | {
|
---|
985 | return static_cast<QDial*>(object());
|
---|
986 | }
|
---|
987 | #endif // QT_NO_DIAL
|
---|
988 |
|
---|
989 | #endif // QT_NO_ACCESSIBILITY
|
---|
990 |
|
---|
991 | QT_END_NAMESPACE
|
---|