src/gui/accessible/qaccessiblewidget.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.
00004 **
00005 ** This file is part of the QtGui module of the Qt Toolkit.
00006 **
00007 ** This file may be used under the terms of the GNU General Public
00008 ** License version 2.0 as published by the Free Software Foundation
00009 ** and appearing in the file LICENSE.GPL included in the packaging of
00010 ** this file.  Please review the following information to ensure GNU
00011 ** General Public Licensing requirements will be met:
00012 ** http://www.trolltech.com/products/qt/opensource.html
00013 **
00014 ** If you are unsure which license is appropriate for your use, please
00015 ** review the following information:
00016 ** http://www.trolltech.com/products/qt/licensing.html or contact the
00017 ** sales department at sales@trolltech.com.
00018 **
00019 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00020 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00021 **
00022 ****************************************************************************/
00023 
00024 #include "qaccessiblewidget.h"
00025 
00026 #ifndef QT_NO_ACCESSIBILITY
00027 
00028 #include "qapplication.h"
00029 #include "qgroupbox.h"
00030 #include "qlabel.h"
00031 #include "qtooltip.h"
00032 #include "qwhatsthis.h"
00033 #include "qwidget.h"
00034 
00035 #include <math.h>
00036 
00037 static QList<QWidget*> childWidgets(const QWidget *widget)
00038 {
00039     QList<QObject*> list = widget->children();
00040     QList<QWidget*> widgets;
00041     for (int i = 0; i < list.size(); ++i) {
00042         QWidget *w = qobject_cast<QWidget *>(list.at(i));
00043         if (w && !w->isWindow())
00044             widgets.append(w);
00045     }
00046     return widgets;
00047 }
00048 
00049 static QString buddyString(const QWidget *widget)
00050 {
00051     if (!widget)
00052         return QString();
00053     QWidget *parent = widget->parentWidget();
00054     if (!parent)
00055         return QString();
00056 #ifndef QT_NO_SHORTCUT
00057     QObjectList ol = parent->children();
00058     for (int i = 0; i < ol.size(); ++i) {
00059         QLabel *label = qobject_cast<QLabel*>(ol.at(i));
00060         if (label && label->buddy() == widget)
00061             return label->text();
00062     }
00063 #endif
00064 
00065 #ifndef QT_NO_GROUPBOX
00066     QGroupBox *groupbox = qobject_cast<QGroupBox*>(parent);
00067     if (groupbox)
00068         return groupbox->title();
00069 #endif
00070 
00071     return QString();
00072 }
00073 
00074 QString Q_GUI_EXPORT qt_accStripAmp(const QString &text)
00075 {
00076     if (text.isEmpty())
00077         return text;
00078 
00079     const QChar *ch = text.unicode();
00080     int length = text.length();
00081     QString str;
00082     while (length > 0) {
00083         if (*ch == QLatin1Char('&')) {
00084             ++ch;
00085             --length;
00086             if (!ch)
00087                 --ch;
00088         }
00089         str += *ch;
00090         ++ch;
00091         --length;
00092     }
00093     return str;
00094 }
00095 
00096 QString Q_GUI_EXPORT qt_accHotKey(const QString &text)
00097 {
00098 #ifndef QT_NO_SHORTCUT
00099     if (text.isEmpty())
00100         return text;
00101 
00102     int fa = 0;
00103     QChar ac;
00104     while ((fa = text.indexOf(QLatin1Char('&'), fa)) != -1) {
00105         if (fa == text.length() - 1 || text.at(fa+1) != QLatin1Char('&')) {
00106             ac = text.at(fa+1);
00107             break;
00108         }
00109     }
00110     if (ac.isNull())
00111         return QString();
00112     return (QString)QKeySequence(Qt::ALT) + ac.toUpper();
00113 #else
00114     Q_UNUSED(text);
00115     return QString();
00116 #endif
00117 }
00118 
00119 class QAccessibleWidgetPrivate : public QAccessible
00120 {
00121 public:
00122     QAccessibleWidgetPrivate()
00123         :role(Client)
00124     {}
00125 
00126     Role role;
00127     QString name;
00128     QString description;
00129     QString value;
00130     QString help;
00131     QString accelerator;
00132     QStringList primarySignals;
00133     const QAccessibleInterface *asking;
00134 };
00135 
00161 QAccessibleWidget::QAccessibleWidget(QWidget *w, Role role, const QString &name)
00162 : QAccessibleObject(w)
00163 {
00164     Q_ASSERT(widget());
00165     d = new QAccessibleWidgetPrivate();
00166     d->role = role;
00167     d->name = name;
00168     d->asking = 0;
00169 }
00170 
00174 QAccessibleWidget::~QAccessibleWidget()
00175 {
00176     delete d;
00177 }
00178 
00182 QWidget *QAccessibleWidget::widget() const
00183 {
00184     return qobject_cast<QWidget*>(object());
00185 }
00186 
00191 QObject *QAccessibleWidget::parentObject() const
00192 {
00193     QObject *parent = object()->parent();
00194     if (!parent)
00195         parent = qApp;
00196     return parent;
00197 }
00198 
00200 int QAccessibleWidget::childAt(int x, int y) const
00201 {
00202     QWidget *w = widget();
00203     QPoint gp = w->mapToGlobal(QPoint(0, 0));
00204     if (!QRect(gp.x(), gp.y(), w->width(), w->height()).contains(x, y))
00205         return -1;
00206 
00207     QWidgetList list = childWidgets(w);
00208     int ccount = childCount();
00209 
00210     // a complex child
00211     if (list.size() < ccount) {
00212         for (int i = 1; i <= ccount; ++i) {
00213             if (rect(i).contains(x, y))
00214                 return i;
00215         }
00216         return 0;
00217     }
00218 
00219     QPoint rp = w->mapFromGlobal(QPoint(x, y));
00220     for (int i = 0; i<list.size(); ++i) {
00221         QWidget *child = list.at(i);
00222         if (!child->isWindow() && !child->isHidden() && child->geometry().contains(rp)) {
00223             return i + 1;
00224         }
00225     }
00226     return -1;
00227 }
00228 
00230 QRect QAccessibleWidget::rect(int child) const
00231 {
00232     if (child)
00233         qWarning("QAccessibleWidget::rect: This implementation does not support subelements! (ID %d unknown for %s)", child, widget()->metaObject()->className());
00234 
00235     QWidget *w = widget();
00236     QPoint wpos = w->mapToGlobal(QPoint(0, 0));
00237 
00238     return QRect(wpos.x(), wpos.y(), w->width(), w->height());
00239 }
00240 
00241 #include <private/qobject_p.h>
00242 
00243 class QACConnectionObject : public QObject
00244 {
00245     Q_DECLARE_PRIVATE(QObject)
00246 public:
00247     inline bool isSender(const QObject *receiver, const char *signal) const
00248     { return d_func()->isSender(receiver, signal); }
00249     inline QObjectList receiverList(const char *signal) const
00250     { return d_func()->receiverList(signal); }
00251     inline QObjectList senderList() const
00252     { return d_func()->senderList(); }
00253 };
00254 
00261 void QAccessibleWidget::addControllingSignal(const QString &signal)
00262 {
00263     QByteArray s = QMetaObject::normalizedSignature(signal.toAscii());
00264     if (object()->metaObject()->indexOfSignal(s) < 0)
00265         qWarning("Signal %s unknown in %s", s.constData(), object()->metaObject()->className());
00266     d->primarySignals << QLatin1String(s);
00267 }
00268 
00277 void QAccessibleWidget::setValue(const QString &value)
00278 {
00279     d->value = value;
00280 }
00281 
00290 void QAccessibleWidget::setDescription(const QString &desc)
00291 {
00292     d->description = desc;
00293 }
00294 
00303 void QAccessibleWidget::setHelp(const QString &help)
00304 {
00305     d->help = help;
00306 }
00307 
00316 void QAccessibleWidget::setAccelerator(const QString &accel)
00317 {
00318     d->accelerator = accel;
00319 }
00320 
00321 static inline bool isAncestor(const QObject *obj, const QObject *child)
00322 {
00323     while (child) {
00324         if (child == obj)
00325             return true;
00326         child = child->parent();
00327     }
00328     return false;
00329 }
00330 
00331 
00333 QAccessible::Relation QAccessibleWidget::relationTo(int child,
00334             const QAccessibleInterface *other, int otherChild) const
00335 {
00336     Relation relation = Unrelated;
00337     if (d->asking == this) // recursive call
00338         return relation;
00339 
00340     QObject *o = other ? other->object() : 0;
00341     if (!o)
00342         return relation;
00343 
00344     QWidget *focus = widget()->focusWidget();
00345     if (object() == focus && isAncestor(o, focus))
00346         relation |= FocusChild;
00347 
00348     QACConnectionObject *connectionObject = (QACConnectionObject*)object();
00349     for (int sig = 0; sig < d->primarySignals.count(); ++sig) {
00350         if (connectionObject->isSender(o, d->primarySignals.at(sig).toAscii())) {
00351             relation |= Controller;
00352             break;
00353         }
00354     }
00355     // test for passive relationships.
00356     // d->asking protects from endless recursion.
00357     d->asking = this;
00358     int inverse = other->relationTo(otherChild, this, child);
00359     d->asking = 0;
00360 
00361     if (inverse & Controller)
00362         relation |= Controlled;
00363     if (inverse & Label)
00364         relation |= Labelled;
00365 
00366     if(o == object()) {
00367         if (child && !otherChild)
00368             return relation | Child;
00369         if (!child && otherChild)
00370             return relation | Ancestor;
00371         if (!child && !otherChild)
00372             return relation | Self;
00373     }
00374 
00375     QObject *parent = object()->parent();
00376     if (o == parent)
00377         return relation | Child;
00378 
00379     if (o->parent() == parent) {
00380         relation |= Sibling;
00381         QAccessibleInterface *sibIface = QAccessible::queryAccessibleInterface(o);
00382         Q_ASSERT(sibIface);
00383         QRect wg = rect(0);
00384         QRect sg = sibIface->rect(0);
00385         if (wg.intersects(sg)) {
00386             QAccessibleInterface *pIface = 0;
00387             sibIface->navigate(Ancestor, 1, &pIface);
00388             if (pIface && !((sibIface->state(0) | state(0)) & Invisible)) {
00389                 int wi = pIface->indexOfChild(this);
00390                 int si = pIface->indexOfChild(sibIface);
00391 
00392                 if (wi > si)
00393                     relation |= QAccessible::Covers;
00394                 else
00395                     relation |= QAccessible::Covered;
00396             }
00397             delete pIface;
00398         } else {
00399             QPoint wc = wg.center();
00400             QPoint sc = sg.center();
00401             if (wc.x() < sc.x())
00402                 relation |= QAccessible::Left;
00403             else if(wc.x() > sc.x())
00404                 relation |= QAccessible::Right;
00405             if (wc.y() < sc.y())
00406                 relation |= QAccessible::Up;
00407             else if (wc.y() > sc.y())
00408                 relation |= QAccessible::Down;
00409         }
00410         delete sibIface;
00411 
00412         return relation;
00413     }
00414 
00415     if (isAncestor(o, object()))
00416         return relation | Descendent;
00417     if (isAncestor(object(), o))
00418         return relation | Ancestor;
00419 
00420     return relation;
00421 }
00422 
00424 int QAccessibleWidget::navigate(RelationFlag relation, int entry,
00425                                 QAccessibleInterface **target) const
00426 {
00427     if (!target)
00428         return -1;
00429 
00430     *target = 0;
00431     QObject *targetObject = 0;
00432 
00433     QWidgetList childList = childWidgets(widget());
00434     bool complexWidget = childList.size() < childCount();
00435 
00436     switch (relation) {
00437     // Hierarchical
00438     case Self:
00439         targetObject = object();
00440         break;
00441     case Child:
00442         if (complexWidget) {
00443             if (entry > 0 && entry <= childCount())
00444                 return entry;
00445             return -1;
00446         }else {
00447             if (entry > 0 && childList.size() >= entry)
00448                 targetObject = childList.at(entry - 1);
00449         }
00450         break;
00451     case Ancestor:
00452         {
00453             if (entry <= 0)
00454                 return -1;
00455             targetObject = widget()->parentWidget();
00456             int i;
00457             for (i = entry; i > 1 && targetObject; --i)
00458                 targetObject = targetObject->parent();
00459             if (!targetObject && i == 1)
00460                 targetObject = qApp;
00461         }
00462         break;
00463     case Sibling:
00464         {
00465             QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(parentObject());
00466             if (!iface)
00467                 return -1;
00468 
00469             iface->navigate(Child, entry, target);
00470             delete iface;
00471             if (*target)
00472                 return 0;
00473         }
00474         break;
00475 
00476     // Geometrical
00477     case QAccessible::Left:
00478         if (complexWidget && entry) {
00479             if (entry < 2 || widget()->height() > widget()->width() + 20) // looks vertical
00480                 return -1;
00481             return entry - 1;
00482         }
00483         // fall through
00484     case QAccessible::Right:
00485         if (complexWidget && entry) {
00486             if (entry >= childCount() || widget()->height() > widget()->width() + 20) // looks vertical
00487                 return -1;
00488             return entry + 1;
00489         }
00490         // fall through
00491     case QAccessible::Up:
00492         if (complexWidget && entry) {
00493             if (entry < 2 || widget()->width() > widget()->height() + 20) // looks horizontal
00494                 return - 1;
00495             return entry - 1;
00496         }
00497         // fall through
00498     case QAccessible::Down:
00499         if (complexWidget && entry) {
00500             if (entry >= childCount() || widget()->width() > widget()->height()  + 20) // looks horizontal
00501                 return - 1;
00502             return entry + 1;
00503         } else {
00504             QAccessibleInterface *pIface = QAccessible::queryAccessibleInterface(parentObject());
00505             if (!pIface)
00506                 return -1;
00507 
00508             QRect startg = rect(0);
00509             QPoint startc = startg.center();
00510             QAccessibleInterface *candidate = 0;
00511             int mindist = 100000;
00512             int sibCount = pIface->childCount();
00513             for (int i = 0; i < sibCount; ++i) {
00514                 QAccessibleInterface *sibling = 0;
00515                 pIface->navigate(Child, i+1, &sibling);
00516                 Q_ASSERT(sibling);
00517                 if ((relationTo(0, sibling, 0) & Self) || (sibling->state(0) & QAccessible::Invisible)) {
00518                     //ignore ourself and invisible siblings
00519                     delete sibling;
00520                     continue;
00521                 }
00522 
00523                 QRect sibg = sibling->rect(0);
00524                 QPoint sibc = sibg.center();
00525                 QPoint sibp;
00526                 QPoint startp;
00527                 QPoint distp;
00528                 switch (relation) {
00529                 case QAccessible::Left:
00530                     startp = QPoint(startg.left(), startg.top() + startg.height() / 2);
00531                     sibp = QPoint(sibg.right(), sibg.top() + sibg.height() / 2);
00532                     if (QPoint(sibc - startc).x() >= 0) {
00533                         delete sibling;
00534                         continue;
00535                     }
00536                     distp = sibp - startp;
00537                     break;
00538                 case QAccessible::Right:
00539                     startp = QPoint(startg.right(), startg.top() + startg.height() / 2);
00540                     sibp = QPoint(sibg.left(), sibg.top() + sibg.height() / 2);
00541                     if (QPoint(sibc - startc).x() <= 0) {
00542                         delete sibling;
00543                         continue;
00544                     }
00545                     distp = sibp - startp;
00546                     break;
00547                 case QAccessible::Up:
00548                     startp = QPoint(startg.left() + startg.width() / 2, startg.top());
00549                     sibp = QPoint(sibg.left() + sibg.width() / 2, sibg.bottom());
00550                     if (QPoint(sibc - startc).y() >= 0) {
00551                         delete sibling;
00552                         continue;
00553                     }
00554                     distp = sibp - startp;
00555                     break;
00556                 case QAccessible::Down:
00557                     startp = QPoint(startg.left() + startg.width() / 2, startg.bottom());
00558                     sibp = QPoint(sibg.left() + sibg.width() / 2, sibg.top());
00559                     if (QPoint(sibc - startc).y() <= 0) {
00560                         delete sibling;
00561                         continue;
00562                     }
00563                     distp = sibp - startp;
00564                     break;
00565     default:
00566         break;
00567                 }
00568 
00569                 int dist = (int)sqrt((double)distp.x() * distp.x() + distp.y() * distp.y());
00570                 if (dist < mindist) {
00571                     delete candidate;
00572                     candidate = sibling;
00573                     mindist = dist;
00574                 } else {
00575                     delete sibling;
00576                 }
00577             }
00578             delete pIface;
00579             *target = candidate;
00580             if (*target)
00581                 return 0;
00582         }
00583         break;
00584     case Covers:
00585         if (entry > 0) {
00586             QAccessibleInterface *pIface = QAccessible::queryAccessibleInterface(parentObject());
00587             if (!pIface)
00588                 return -1;
00589 
00590             QRect r = rect(0);
00591             int sibCount = pIface->childCount();
00592             QAccessibleInterface *sibling = 0;
00593             for (int i = pIface->indexOfChild(this) + 1; i <= sibCount && entry; ++i) {
00594                 pIface->navigate(Child, i, &sibling);
00595                 Q_ASSERT(sibling);
00596                 if (!sibling || (sibling->state(0) & Invisible)) {
00597                     delete sibling;
00598                     sibling = 0;
00599                     continue;
00600                 }
00601                 if (sibling->rect(0).intersects(r))
00602                     --entry;
00603                 if (!entry)
00604                     break;
00605                 delete sibling;
00606                 sibling = 0;
00607             }
00608             delete pIface;
00609             *target = sibling;
00610             if (*target)
00611                 return 0;
00612         }
00613         break;
00614     case Covered:
00615         if (entry > 0) {
00616             QAccessibleInterface *pIface = QAccessible::queryAccessibleInterface(parentObject());
00617             if (!pIface)
00618                 return -1;
00619 
00620             QRect r = rect(0);
00621             int index = pIface->indexOfChild(this);
00622             QAccessibleInterface *sibling = 0;
00623             for (int i = 1; i < index && entry; ++i) {
00624                 pIface->navigate(Child, i, &sibling);
00625                 Q_ASSERT(sibling);
00626                 if (!sibling || (sibling->state(0) & Invisible)) {
00627                     delete sibling;
00628                     sibling = 0;
00629                     continue;
00630                 }
00631                 if (sibling->rect(0).intersects(r))
00632                     --entry;
00633                 if (!entry)
00634                     break;
00635                 delete sibling;
00636                 sibling = 0;
00637             }
00638             delete pIface;
00639             *target = sibling;
00640             if (*target)
00641                 return 0;
00642         }
00643         break;
00644 
00645     // Logical
00646     case FocusChild:
00647         {
00648             if (widget()->hasFocus())
00649                 return 0;
00650 
00651             QWidget *fw = widget()->focusWidget();
00652             if (!fw)
00653                 return -1;
00654 
00655             if (isAncestor(widget(), fw))
00656                 targetObject = fw;
00657             /* ###
00658             QWidget *parent = fw;
00659             while (parent && !targetObject) {
00660                 parent = parent->parentWidget();
00661                 if (parent == widget())
00662                     targetObject = fw;
00663             }
00664             */
00665         }
00666         break;
00667     case Label:
00668         if (entry > 0) {
00669             QAccessibleInterface *pIface = QAccessible::queryAccessibleInterface(parentObject());
00670             if (!pIface)
00671                 return -1;
00672 
00673             // first check for all siblings that are labels to us
00674             // ideally we would go through all objects and check, but that
00675             // will be too expensive
00676             int sibCount = pIface->childCount();
00677             QAccessibleInterface *candidate = 0;
00678             for (int i = 0; i < sibCount && entry; ++i) {
00679                 pIface->navigate(Child, i+1, &candidate);
00680                 Q_ASSERT(candidate);
00681                 if (candidate->relationTo(0, this, 0) & Label)
00682                     --entry;
00683                 if (!entry)
00684                     break;
00685                 delete candidate;
00686                 candidate = 0;
00687             }
00688             if (!candidate) {
00689                 if (pIface->relationTo(0, this, 0) & Label)
00690                     --entry;
00691                 if (!entry)
00692                     candidate = pIface;
00693             }
00694             if (pIface != candidate)
00695                 delete pIface;
00696 
00697             *target = candidate;
00698             if (*target)
00699                 return 0;
00700         }
00701         break;
00702     case Labelled: // only implemented in subclasses
00703         break;
00704     case Controller:
00705         if (entry > 0) {
00706             // check all senders we are connected to,
00707             // and figure out which one are controllers to us
00708             QACConnectionObject *connectionObject = (QACConnectionObject*)object();
00709             QObjectList allSenders = connectionObject->senderList();
00710             QObjectList senders;
00711             for (int s = 0; s < allSenders.size(); ++s) {
00712                 QObject *sender = allSenders.at(s);
00713                 QAccessibleInterface *candidate = QAccessible::queryAccessibleInterface(sender);
00714                 if (!candidate)
00715                     continue;
00716                 if (candidate->relationTo(0, this, 0)&Controller)
00717                     senders << sender;
00718                 delete candidate;
00719             }
00720             if (entry <= senders.size())
00721                 targetObject = senders.at(entry-1);
00722         }
00723         break;
00724     case Controlled:
00725         if (entry > 0) {
00726             QObjectList allReceivers;
00727             QACConnectionObject *connectionObject = (QACConnectionObject*)object();
00728             for (int sig = 0; sig < d->primarySignals.count(); ++sig) {
00729                 QObjectList receivers = connectionObject->receiverList(d->primarySignals.at(sig).toAscii());
00730                 allReceivers += receivers;
00731             }
00732             if (entry <= allReceivers.size())
00733                 targetObject = allReceivers.at(entry-1);
00734         }
00735         break;
00736     default:
00737         break;
00738     }
00739     *target = QAccessible::queryAccessibleInterface(targetObject);
00740     return *target ? 0 : -1;
00741 }
00742 
00744 int QAccessibleWidget::childCount() const
00745 {
00746     QWidgetList cl = childWidgets(widget());
00747     return cl.size();
00748 }
00749 
00751 int QAccessibleWidget::indexOfChild(const QAccessibleInterface *child) const
00752 {
00753     QWidgetList cl = childWidgets(widget());
00754     int index = cl.indexOf(qobject_cast<QWidget *>(child->object()));
00755     if (index != -1)
00756         ++index;
00757     return index;
00758 }
00759 
00760 // from qwidget.cpp
00761 extern QString qt_setWindowTitle_helperHelper(const QString &, QWidget*);
00762 
00764 QString QAccessibleWidget::text(Text t, int child) const
00765 {
00766     QString str;
00767 
00768     switch (t) {
00769     case Name:
00770         if (!d->name.isEmpty()) {
00771             str = d->name;
00772         } else if (!widget()->accessibleName().isEmpty()) {
00773             str = widget()->accessibleName();
00774         } else if (!child && widget()->isWindow()) {
00775             if (widget()->isMinimized())
00776                 str = qt_setWindowTitle_helperHelper(widget()->windowIconText(), widget());
00777             else
00778                 str = qt_setWindowTitle_helperHelper(widget()->windowTitle(), widget());
00779         } else {
00780             str = qt_accStripAmp(buddyString(widget()));
00781         }
00782         break;
00783     case Description:
00784         if (!d->description.isEmpty())
00785             str = d->description;
00786         else if (!widget()->accessibleDescription().isEmpty())
00787             str = widget()->accessibleDescription();
00788 #ifndef QT_NO_TOOLTIP
00789         else
00790             str = widget()->toolTip();
00791 #endif
00792         break;
00793     case Help:
00794         if (!d->help.isEmpty())
00795             str = d->help;
00796 #ifndef QT_NO_WHATSTHIS
00797         else
00798             str = widget()->whatsThis();
00799 #endif
00800         break;
00801     case Accelerator:
00802         if (!d->accelerator.isEmpty())
00803             str = d->accelerator;
00804         else
00805             str = qt_accHotKey(buddyString(widget()));
00806         break;
00807     case Value:
00808         str = d->value;
00809         break;
00810     default:
00811         break;
00812     }
00813     return str;
00814 }
00815 
00817 QString QAccessibleWidget::actionText(int action, Text t, int child) const
00818 {
00819     if (action == DefaultAction)
00820         action = SetFocus;
00821 
00822     return QAccessibleObject::actionText(action, t, child);
00823 }
00824 
00826 bool QAccessibleWidget::doAction(int action, int child, const QVariantList &params)
00827 {
00828     if (action == SetFocus || action == DefaultAction) {
00829         if (child || !widget()->isEnabled())
00830             return false;
00831         if (widget()->focusPolicy() != Qt::NoFocus)
00832             widget()->setFocus();
00833         else if (widget()->isWindow())
00834             widget()->activateWindow();
00835         else
00836             return false;
00837         return true;
00838     }
00839     return QAccessibleObject::doAction(action, child, params);
00840 }
00841 
00843 QAccessible::Role QAccessibleWidget::role(int child) const
00844 {
00845     if (!child)
00846         return d->role;
00847     return NoRole;
00848 }
00849 
00851 QAccessible::State QAccessibleWidget::state(int child) const
00852 {
00853     if (child)
00854         return Normal;
00855 
00856     QAccessible::State state = Normal;
00857 
00858     QWidget *w = widget();
00859     if (w->testAttribute(Qt::WA_WState_Visible) == false)
00860         state |= Invisible;
00861     if (w->focusPolicy() != Qt::NoFocus && w->isActiveWindow())
00862         state |= Focusable;
00863     if (w->hasFocus())
00864         state |= Focused;
00865     if (!w->isEnabled())
00866         state |= Unavailable;
00867     if (w->isWindow()) {
00868         if (w->windowFlags() & Qt::WindowSystemMenuHint)
00869             state |= Movable;
00870         if (w->minimumSize() != w->maximumSize())
00871             state |= Sizeable;
00872     }
00873 
00874     return state;
00875 }
00876 
00877 // ### Qt 5: remove me - binary compatibility hack
00878 QAccessibleWidgetEx::QAccessibleWidgetEx(QWidget *o, Role role, const QString& name)
00879     : QAccessibleObjectEx(o)
00880 {
00881     Q_ASSERT(widget());
00882     d = new QAccessibleWidgetPrivate();
00883     d->role = role;
00884     d->name = name;
00885     d->asking = 0;
00886 }
00887 
00888 int QAccessibleWidgetEx::childCount() const
00889 { return reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::childCount(); }
00890 int QAccessibleWidgetEx::indexOfChild(const QAccessibleInterface *child) const
00891 { return reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::indexOfChild(child); }
00892 QAccessible::Relation QAccessibleWidgetEx::relationTo(int child, const QAccessibleInterface *other, int otherChild) const
00893 { return reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::relationTo(child, other, otherChild); }
00894 
00895 int QAccessibleWidgetEx::childAt(int x, int y) const
00896 { return reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::childAt(x, y); }
00897 QRect QAccessibleWidgetEx::rect(int child) const
00898 { return reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::rect(child); }
00899 int QAccessibleWidgetEx::navigate(RelationFlag rel, int entry, QAccessibleInterface **target) const
00900 { return reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::navigate(rel, entry, target); }
00901 
00902 QString QAccessibleWidgetEx::text(Text t, int child) const
00903 { return reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::text(t, child); }
00904 QAccessible::Role QAccessibleWidgetEx::role(int child) const
00905 { return reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::role(child); }
00906 QAccessible::State QAccessibleWidgetEx::state(int child) const
00907 { return (reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::state(child))
00908     | HasInvokeExtension; }
00909 
00910 QString QAccessibleWidgetEx::actionText(int action, Text t, int child) const
00911 { return reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::actionText(action, t, child); }
00912 bool QAccessibleWidgetEx::doAction(int action, int child, const QVariantList &params)
00913 { return reinterpret_cast<QAccessibleWidget *>(this)->QAccessibleWidget::doAction(action, child, params); }
00914 
00915 QAccessibleWidgetEx::~QAccessibleWidgetEx()
00916 { delete d; }
00917 QWidget *QAccessibleWidgetEx::widget() const
00918 { return reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::widget(); }
00919 QObject *QAccessibleWidgetEx::parentObject() const
00920 { return reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::parentObject(); }
00921 
00922 void QAccessibleWidgetEx::addControllingSignal(const QString &signal)
00923 { reinterpret_cast<QAccessibleWidget *>(this)->QAccessibleWidget::addControllingSignal(signal); }
00924 void QAccessibleWidgetEx::setValue(const QString &value)
00925 { reinterpret_cast<QAccessibleWidget *>(this)->QAccessibleWidget::setValue(value); }
00926 void QAccessibleWidgetEx::setDescription(const QString &desc)
00927 { reinterpret_cast<QAccessibleWidget *>(this)->QAccessibleWidget::setDescription(desc); }
00928 void QAccessibleWidgetEx::setHelp(const QString &help)
00929 { reinterpret_cast<QAccessibleWidget *>(this)->QAccessibleWidget::setHelp(help); }
00930 void QAccessibleWidgetEx::setAccelerator(const QString &accel)
00931 { reinterpret_cast<QAccessibleWidget *>(this)->QAccessibleWidget::setAccelerator(accel); }
00932 
00933 #endif //QT_NO_ACCESSIBILITY

Generated on Thu Mar 15 11:54:19 2007 for Qt 4.2 User's Guide by  doxygen 1.5.1