src/plugins/accessible/widgets/rangecontrols.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the plugins of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    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 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    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 &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 
       
   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 &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 */
       
   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 &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 ==================================
       
   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 &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 
       
   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