source: trunk/src/plugins/accessible/widgets/rangecontrols.cpp@ 846

Last change on this file since 846 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 27.7 KB
Line 
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
57QT_BEGIN_NAMESPACE
58
59#ifndef QT_NO_ACCESSIBILITY
60extern QString Q_GUI_EXPORT qt_accStripAmp(const QString &text);
61#ifndef QT_NO_SCROLLBAR
62extern QStyleOptionSlider Q_GUI_EXPORT qt_qscrollbarStyleOption(QScrollBar *scrollBar);
63#endif
64#ifndef QT_NO_SLIDER
65extern QStyleOptionSlider Q_GUI_EXPORT qt_qsliderStyleOption(QSlider *slider);
66#endif
67
68#ifndef QT_NO_SPINBOX
69QAccessibleAbstractSpinBox::QAccessibleAbstractSpinBox(QWidget *w)
70: QAccessibleWidgetEx(w, SpinBox)
71{
72 Q_ASSERT(abstractSpinBox());
73}
74
75/*!
76 Returns the underlying QAbstractSpinBox.
77*/
78QAbstractSpinBox *QAccessibleAbstractSpinBox::abstractSpinBox() const
79{
80 return qobject_cast<QAbstractSpinBox*>(object());
81}
82
83/*! \reimp */
84int QAccessibleAbstractSpinBox::childCount() const
85{
86 if (!abstractSpinBox()->isVisible())
87 return 0;
88 return ValueDown;
89}
90
91/*! \reimp */
92QRect 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 */
121int 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 */
143QString 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 */
167QAccessible::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 */
182bool QAccessibleAbstractSpinBox::doAction(int action, int child, const QVariantList &params)
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
202QVariant 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
215void QAccessibleAbstractSpinBox::setCurrentValue(const QVariant &value)
216{
217 abstractSpinBox()->setProperty("setValue", value);
218}
219
220QVariant QAccessibleAbstractSpinBox::maximumValue()
221{
222 return abstractSpinBox()->property("maximum");
223}
224
225QVariant QAccessibleAbstractSpinBox::minimumValue()
226{
227 return abstractSpinBox()->property("minimum");
228}
229
230QVariant QAccessibleAbstractSpinBox::invokeMethodEx(Method method, int child, const QVariantList &params)
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*/
267QAccessibleSpinBox::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*/
278QSpinBox *QAccessibleSpinBox::spinBox() const
279{
280 return qobject_cast<QSpinBox*>(object());
281}
282
283/*! \reimp */
284QAccessible::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 */
303bool QAccessibleSpinBox::doAction(int action, int child, const QVariantList &params)
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 ==================================
328QAccessibleDoubleSpinBox::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*/
339QDoubleSpinBox *QAccessibleDoubleSpinBox::doubleSpinBox() const
340{
341 return static_cast<QDoubleSpinBox*>(object());
342}
343
344/*! \reimp */
345int QAccessibleDoubleSpinBox::childCount() const
346{
347 if (!doubleSpinBox()->isVisible())
348 return 0;
349 return ValueDown;
350}
351
352/*! \reimp */
353QRect 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 */
382int 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
405QVariant QAccessibleDoubleSpinBox::invokeMethodEx(QAccessible::Method, int, const QVariantList &)
406{
407 return QVariant();
408}
409
410/*! \reimp */
411QString 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 */
433QAccessible::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 */
448QAccessible::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*/
493QAccessibleScrollBar::QAccessibleScrollBar(QWidget *w)
494: QAccessibleAbstractSlider(w, ScrollBar)
495{
496 Q_ASSERT(scrollBar());
497 addControllingSignal(QLatin1String("valueChanged(int)"));
498}
499
500/*! Returns the scroll bar. */
501QScrollBar *QAccessibleScrollBar::scrollBar() const
502{
503 return qobject_cast<QScrollBar*>(object());
504}
505
506/*! \reimp */
507QRect 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 */
541int QAccessibleScrollBar::childCount() const
542{
543 if (!scrollBar()->isVisible())
544 return 0;
545 return LineDown;
546}
547
548/*! \reimp */
549QString 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 */
579QAccessible::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 */
595QAccessible::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*/
651QAccessibleSlider::QAccessibleSlider(QWidget *w)
652: QAccessibleAbstractSlider(w)
653{
654 Q_ASSERT(slider());
655 addControllingSignal(QLatin1String("valueChanged(int)"));
656}
657
658/*! Returns the slider. */
659QSlider *QAccessibleSlider::slider() const
660{
661 return qobject_cast<QSlider*>(object());
662}
663
664/*! \reimp */
665QRect 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 */
699int QAccessibleSlider::childCount() const
700{
701 if (!slider()->isVisible())
702 return 0;
703 return PageRight;
704}
705
706/*! \reimp */
707QString 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 */
735QAccessible::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 */
749QAccessible::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*/
784int 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 */
800QString QAccessibleSlider::actionText(int /*action*/, Text /*t*/, int /*child*/) const
801{
802 return QLatin1String("");
803}
804
805QAccessibleAbstractSlider::QAccessibleAbstractSlider(QWidget *w, Role r)
806 : QAccessibleWidgetEx(w, r)
807{
808 Q_ASSERT(qobject_cast<QAbstractSlider *>(w));
809}
810
811QVariant QAccessibleAbstractSlider::invokeMethodEx(Method method, int child, const QVariantList &params)
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
825QVariant QAccessibleAbstractSlider::currentValue()
826{
827 return abstractSlider()->value();
828}
829
830void QAccessibleAbstractSlider::setCurrentValue(const QVariant &value)
831{
832 abstractSlider()->setValue(value.toInt());
833}
834
835QVariant QAccessibleAbstractSlider::maximumValue()
836{
837 return abstractSlider()->maximum();
838}
839
840QVariant QAccessibleAbstractSlider::minimumValue()
841{
842 return abstractSlider()->minimum();
843}
844
845QAbstractSlider *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 ======================================
854QAccessibleDial::QAccessibleDial(QWidget *widget)
855 : QAccessibleWidgetEx(widget, Dial)
856{
857 Q_ASSERT(qobject_cast<QDial *>(widget));
858 addControllingSignal(QLatin1String("valueChanged(int)"));
859}
860
861QRect 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
933int QAccessibleDial::childCount() const
934{
935 if (!dial()->isVisible())
936 return 0;
937 return SliderHandle;
938}
939
940QString 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
961QAccessible::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
970QAccessible::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
978QVariant QAccessibleDial::invokeMethodEx(Method, int, const QVariantList &)
979{
980 return QVariant();
981}
982
983QDial *QAccessibleDial::dial() const
984{
985 return static_cast<QDial*>(object());
986}
987#endif // QT_NO_DIAL
988
989#endif // QT_NO_ACCESSIBILITY
990
991QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.