Implement QAccessibleLineEdit::characterRect()
[qt:qtbase.git] / src / plugins / accessible / widgets / simplewidgets.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the plugins of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.  For licensing terms and
14 ** conditions see http://qt.digia.com/licensing.  For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights.  These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file.  Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "simplewidgets.h"
43
44 #include <qabstractbutton.h>
45 #include <qcheckbox.h>
46 #include <qpushbutton.h>
47 #include <qprogressbar.h>
48 #include <qstatusbar.h>
49 #include <qradiobutton.h>
50 #include <qtoolbutton.h>
51 #include <qmenu.h>
52 #include <qlabel.h>
53 #include <qgroupbox.h>
54 #include <qlcdnumber.h>
55 #include <qlineedit.h>
56 #include <private/qlineedit_p.h>
57 #include <qstyle.h>
58 #include <qstyleoption.h>
59 #include <qtextdocument.h>
60 #include <QtCore/qvarlengtharray.h>
61
62 #ifdef Q_OS_MAC
63 #include <qfocusframe.h>
64 #endif
65
66 QT_BEGIN_NAMESPACE
67
68 #ifndef QT_NO_ACCESSIBILITY
69
70 using namespace QAccessible2;
71 extern QList<QWidget*> childWidgets(const QWidget *widget, bool includeTopLevel = false);
72
73 QString Q_GUI_EXPORT qt_accStripAmp(const QString &text);
74 QString Q_GUI_EXPORT qt_accHotKey(const QString &text);
75
76 /*!
77   \class QAccessibleButton
78   \brief The QAccessibleButton class implements the QAccessibleInterface for button type widgets.
79   \internal
80
81   \ingroup accessibility
82 */
83
84 /*!
85   Creates a QAccessibleButton object for \a w.
86   \a role is propagated to the QAccessibleWidget constructor.
87 */
88 QAccessibleButton::QAccessibleButton(QWidget *w, QAccessible::Role role)
89 : QAccessibleWidget(w, role)
90 {
91     Q_ASSERT(button());
92     if (button()->isCheckable())
93         addControllingSignal(QLatin1String("toggled(bool)"));
94     else
95         addControllingSignal(QLatin1String("clicked()"));
96 }
97
98 /*! Returns the button. */
99 QAbstractButton *QAccessibleButton::button() const
100 {
101     return qobject_cast<QAbstractButton*>(object());
102 }
103
104 /*! \reimp */
105 QString QAccessibleButton::text(QAccessible::Text t) const
106 {
107     QString str;
108     switch (t) {
109     case QAccessible::Accelerator:
110     {
111 #ifndef QT_NO_SHORTCUT
112         QPushButton *pb = qobject_cast<QPushButton*>(object());
113         if (pb && pb->isDefault())
114             str = QKeySequence(Qt::Key_Enter).toString(QKeySequence::NativeText);
115 #endif
116         if (str.isEmpty())
117             str = qt_accHotKey(button()->text());
118     }
119          break;
120     case QAccessible::Name:
121         str = widget()->accessibleName();
122         if (str.isEmpty())
123             str = button()->text();
124         break;
125     default:
126         break;
127     }
128     if (str.isEmpty())
129         str = QAccessibleWidget::text(t);
130     return qt_accStripAmp(str);
131 }
132
133 QAccessible::State QAccessibleButton::state() const
134 {
135     QAccessible::State state = QAccessibleWidget::state();
136
137     QAbstractButton *b = button();
138     QCheckBox *cb = qobject_cast<QCheckBox *>(b);
139     if (b->isChecked())
140         state.checked = true;
141     else if (cb && cb->checkState() == Qt::PartiallyChecked)
142         state.checkStateMixed = true;
143     if (b->isDown())
144         state.pressed = true;
145     QPushButton *pb = qobject_cast<QPushButton*>(b);
146     if (pb) {
147         if (pb->isDefault())
148             state.defaultButton = true;
149 #ifndef QT_NO_MENU
150         if (pb->menu())
151             state.hasPopup = true;
152 #endif
153     }
154
155     return state;
156 }
157
158 QStringList QAccessibleButton::actionNames() const
159 {
160     QStringList names;
161     if (widget()->isEnabled()) {
162         switch (role()) {
163         case QAccessible::ButtonMenu:
164             names << showMenuAction();
165             break;
166         case QAccessible::RadioButton:
167             names << toggleAction();
168             break;
169         default:
170             if (button()->isCheckable()) {
171                 names <<  toggleAction();
172             } else {
173                 names << pressAction();
174             }
175             break;
176         }
177     }
178     names << QAccessibleWidget::actionNames();
179     return names;
180 }
181
182 void QAccessibleButton::doAction(const QString &actionName)
183 {
184     if (!widget()->isEnabled())
185         return;
186     if (actionName == pressAction() ||
187         actionName == showMenuAction()) {
188 #ifndef QT_NO_MENU
189         QPushButton *pb = qobject_cast<QPushButton*>(object());
190         if (pb && pb->menu())
191             pb->showMenu();
192         else
193 #endif
194             button()->animateClick();
195     } else if (actionName == toggleAction()) {
196         button()->toggle();
197     } else {
198         QAccessibleWidget::doAction(actionName);
199     }
200 }
201
202 QStringList QAccessibleButton::keyBindingsForAction(const QString &actionName) const
203 {
204     if (actionName == pressAction()) {
205 #ifndef QT_NO_SHORTCUT
206         return QStringList() << button()->shortcut().toString();
207 #endif
208     }
209     return QStringList();
210 }
211
212
213 #ifndef QT_NO_TOOLBUTTON
214 /*!
215   \class QAccessibleToolButton
216   \brief The QAccessibleToolButton class implements the QAccessibleInterface for tool buttons.
217   \internal
218
219   \ingroup accessibility
220 */
221
222 /*!
223   Creates a QAccessibleToolButton object for \a w.
224   \a role is propagated to the QAccessibleWidget constructor.
225 */
226 QAccessibleToolButton::QAccessibleToolButton(QWidget *w, QAccessible::Role role)
227 : QAccessibleButton(w, role)
228 {
229     Q_ASSERT(toolButton());
230 }
231
232 /*! Returns the button. */
233 QToolButton *QAccessibleToolButton::toolButton() const
234 {
235     return qobject_cast<QToolButton*>(object());
236 }
237
238 /*!
239     Returns true if this tool button is a split button.
240 */
241 bool QAccessibleToolButton::isSplitButton() const
242 {
243 #ifndef QT_NO_MENU
244     return toolButton()->menu() && toolButton()->popupMode() == QToolButton::MenuButtonPopup;
245 #else
246     return false;
247 #endif
248 }
249
250 QAccessible::State QAccessibleToolButton::state() const
251 {
252     QAccessible::State st = QAccessibleButton::state();
253     if (toolButton()->autoRaise())
254         st.hotTracked = true;
255 #ifndef QT_NO_MENU
256     if (toolButton()->menu())
257         st.hasPopup = true;
258 #endif
259     return st;
260 }
261
262 int QAccessibleToolButton::childCount() const
263 {
264     return isSplitButton() ? 1 : 0;
265 }
266
267 QAccessibleInterface *QAccessibleToolButton::child(int index) const
268 {
269 #ifndef QT_NO_MENU
270     if (index == 0 && toolButton()->menu())
271     {
272         return QAccessible::queryAccessibleInterface(toolButton()->menu());
273     }
274 #endif
275     return 0;
276 }
277
278 /*!
279     \internal
280
281     Returns the button's text label, depending on the text \a t, and
282     the \a child.
283 */
284 QString QAccessibleToolButton::text(QAccessible::Text t) const
285 {
286     QString str;
287     switch (t) {
288     case QAccessible::Name:
289         str = toolButton()->accessibleName();
290         if (str.isEmpty())
291             str = toolButton()->text();
292         break;
293     default:
294         break;
295     }
296     if (str.isEmpty())
297         str = QAccessibleButton::text(t);
298     return qt_accStripAmp(str);
299 }
300
301 /*
302    The three different tool button types can have the following actions:
303 | DelayedPopup    | ShowMenuAction + (PressedAction || CheckedAction) |
304 | MenuButtonPopup | ShowMenuAction + (PressedAction || CheckedAction) |
305 | InstantPopup    | ShowMenuAction |
306 */
307 QStringList QAccessibleToolButton::actionNames() const
308 {
309     QStringList names;
310     if (widget()->isEnabled()) {
311         if (toolButton()->menu())
312             names << showMenuAction();
313         if (toolButton()->popupMode() != QToolButton::InstantPopup)
314             names << QAccessibleButton::actionNames();
315     }
316     return names;
317 }
318
319 void QAccessibleToolButton::doAction(const QString &actionName)
320 {
321     if (!widget()->isEnabled())
322         return;
323
324     if (actionName == pressAction()) {
325         button()->click();
326     } else if (actionName == showMenuAction()) {
327         if (toolButton()->popupMode() != QToolButton::InstantPopup) {
328             toolButton()->setDown(true);
329 #ifndef QT_NO_MENU
330             toolButton()->showMenu();
331 #endif
332         }
333     } else {
334         QAccessibleButton::doAction(actionName);
335     }
336
337 }
338
339 #endif // QT_NO_TOOLBUTTON
340
341 /*!
342   \class QAccessibleDisplay
343   \brief The QAccessibleDisplay class implements the QAccessibleInterface for widgets that display information.
344   \internal
345
346   \ingroup accessibility
347 */
348
349 /*!
350   Constructs a QAccessibleDisplay object for \a w.
351   \a role is propagated to the QAccessibleWidget constructor.
352 */
353 QAccessibleDisplay::QAccessibleDisplay(QWidget *w, QAccessible::Role role)
354 : QAccessibleWidget(w, role)
355 {
356 }
357
358 QAccessible::Role QAccessibleDisplay::role() const
359 {
360     QLabel *l = qobject_cast<QLabel*>(object());
361     if (l) {
362         if (l->pixmap())
363             return QAccessible::Graphic;
364 #ifndef QT_NO_PICTURE
365         if (l->picture())
366             return QAccessible::Graphic;
367 #endif
368 #ifndef QT_NO_MOVIE
369         if (l->movie())
370             return QAccessible::Animation;
371 #endif
372 #ifndef QT_NO_PROGRESSBAR
373     } else if (qobject_cast<QProgressBar*>(object())) {
374         return QAccessible::ProgressBar;
375 #endif
376     } else if (qobject_cast<QStatusBar*>(object())) {
377         return QAccessible::StatusBar;
378     }
379     return QAccessibleWidget::role();
380 }
381
382 QString QAccessibleDisplay::text(QAccessible::Text t) const
383 {
384     QString str;
385     switch (t) {
386     case QAccessible::Name:
387         str = widget()->accessibleName();
388         if (str.isEmpty()) {
389             if (qobject_cast<QLabel*>(object())) {
390                 QLabel *label = qobject_cast<QLabel*>(object());
391                 str = label->text();
392                 if (label->textFormat() == Qt::RichText
393                     || (label->textFormat() == Qt::AutoText && Qt::mightBeRichText(str))) {
394                     QTextDocument doc;
395                     doc.setHtml(str);
396                     str = doc.toPlainText();
397                 }
398 #ifndef QT_NO_LCDNUMBER
399             } else if (qobject_cast<QLCDNumber*>(object())) {
400                 QLCDNumber *l = qobject_cast<QLCDNumber*>(object());
401                 if (l->digitCount())
402                     str = QString::number(l->value());
403                 else
404                     str = QString::number(l->intValue());
405 #endif
406             } else if (qobject_cast<QStatusBar*>(object())) {
407                 return qobject_cast<QStatusBar*>(object())->currentMessage();
408             }
409         }
410         break;
411     case QAccessible::Value:
412 #ifndef QT_NO_PROGRESSBAR
413         if (qobject_cast<QProgressBar*>(object()))
414             str = QString::number(qobject_cast<QProgressBar*>(object())->value());
415 #endif
416         break;
417     default:
418         break;
419     }
420     if (str.isEmpty())
421         str = QAccessibleWidget::text(t);
422     return qt_accStripAmp(str);
423 }
424
425 /*! \reimp */
426 QVector<QPair<QAccessibleInterface*, QAccessible::Relation> >
427 QAccessibleDisplay::relations(QAccessible::Relation match /*= QAccessible::AllRelations*/) const
428 {
429     QVector<QPair<QAccessibleInterface*, QAccessible::Relation> > rels = QAccessibleWidget::relations(match);
430     if (match & QAccessible::Labelled) {
431         QVarLengthArray<QObject *, 4> relatedObjects;
432
433 #ifndef QT_NO_SHORTCUT
434         if (QLabel *label = qobject_cast<QLabel*>(object())) {
435             relatedObjects.append(label->buddy());
436 #endif
437         }
438         for (int i = 0; i < relatedObjects.count(); ++i) {
439             const QAccessible::Relation rel = QAccessible::Labelled;
440             QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(relatedObjects.at(i));
441             if (iface)
442                 rels.append(qMakePair(iface, rel));
443         }
444     }
445     return rels;
446 }
447
448 void *QAccessibleDisplay::interface_cast(QAccessible::InterfaceType t)
449 {
450     if (t == QAccessible::ImageInterface)
451         return static_cast<QAccessibleImageInterface*>(this);
452     return QAccessibleWidget::interface_cast(t);
453 }
454
455 /*! \internal */
456 QString QAccessibleDisplay::imageDescription() const
457 {
458 #ifndef QT_NO_TOOLTIP
459     return widget()->toolTip();
460 #else
461     return QString::null;
462 #endif
463 }
464
465 /*! \internal */
466 QSize QAccessibleDisplay::imageSize() const
467 {
468     QLabel *label = qobject_cast<QLabel *>(widget());
469     if (!label)
470         return QSize();
471     const QPixmap *pixmap = label->pixmap();
472     if (!pixmap)
473         return QSize();
474     return pixmap->size();
475 }
476
477 /*! \internal */
478 QRect QAccessibleDisplay::imagePosition() const
479 {
480     QLabel *label = qobject_cast<QLabel *>(widget());
481     if (!label)
482         return QRect();
483     const QPixmap *pixmap = label->pixmap();
484     if (!pixmap)
485         return QRect();
486
487     return QRect(label->mapToGlobal(label->pos()), label->size());
488 }
489
490 #ifndef QT_NO_GROUPBOX
491 QAccessibleGroupBox::QAccessibleGroupBox(QWidget *w)
492 : QAccessibleWidget(w)
493 {
494 }
495
496 QGroupBox* QAccessibleGroupBox::groupBox() const
497 {
498     return static_cast<QGroupBox *>(widget());
499 }
500
501 QString QAccessibleGroupBox::text(QAccessible::Text t) const
502 {
503     QString txt = QAccessibleWidget::text(t);
504
505     if (txt.isEmpty()) {
506         switch (t) {
507         case QAccessible::Name:
508             txt = qt_accStripAmp(groupBox()->title());
509         case QAccessible::Description:
510             txt = qt_accStripAmp(groupBox()->title());
511         default:
512             break;
513         }
514     }
515
516     return txt;
517 }
518
519 QAccessible::State QAccessibleGroupBox::state() const
520 {
521     QAccessible::State st = QAccessibleWidget::state();
522     st.checkable = groupBox()->isCheckable();
523     st.checked = groupBox()->isChecked();
524     return st;
525 }
526
527 QAccessible::Role QAccessibleGroupBox::role() const
528 {
529     return groupBox()->isCheckable() ? QAccessible::CheckBox : QAccessible::Grouping;
530 }
531
532 QVector<QPair<QAccessibleInterface*, QAccessible::Relation> >
533 QAccessibleGroupBox::relations(QAccessible::Relation match /*= QAccessible::AllRelations*/) const
534 {
535     QVector<QPair<QAccessibleInterface*, QAccessible::Relation> > rels = QAccessibleWidget::relations(match);
536
537     if ((match & QAccessible::Labelled) && (!groupBox()->title().isEmpty())) {
538         const QList<QWidget*> kids = childWidgets(widget());
539         for (int i = 0; i < kids.count(); ++i) {
540             QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(kids.at(i));
541             if (iface)
542                 rels.append(qMakePair(iface, QAccessible::Relation(QAccessible::Labelled)));
543         }
544     }
545     return rels;
546 }
547
548 QStringList QAccessibleGroupBox::actionNames() const
549 {
550     QStringList actions = QAccessibleWidget::actionNames();
551
552     if (groupBox()->isCheckable()) {
553         actions.prepend(QAccessibleActionInterface::toggleAction());
554     }
555     return actions;
556 }
557
558 void QAccessibleGroupBox::doAction(const QString &actionName)
559 {
560     if (actionName == QAccessibleActionInterface::toggleAction())
561         groupBox()->setChecked(!groupBox()->isChecked());
562 }
563
564 QStringList QAccessibleGroupBox::keyBindingsForAction(const QString &) const
565 {
566     return QStringList();
567 }
568
569 #endif
570
571 #ifndef QT_NO_LINEEDIT
572 /*!
573   \class QAccessibleLineEdit
574   \brief The QAccessibleLineEdit class implements the QAccessibleInterface for widgets with editable text
575   \internal
576
577   \ingroup accessibility
578 */
579
580 /*!
581   Constructs a QAccessibleLineEdit object for \a w.
582   \a name is propagated to the QAccessibleWidget constructor.
583 */
584 QAccessibleLineEdit::QAccessibleLineEdit(QWidget *w, const QString &name)
585 : QAccessibleWidget(w, QAccessible::EditableText, name)
586 {
587     addControllingSignal(QLatin1String("textChanged(const QString&)"));
588     addControllingSignal(QLatin1String("returnPressed()"));
589 }
590
591 /*! Returns the line edit. */
592 QLineEdit *QAccessibleLineEdit::lineEdit() const
593 {
594     return qobject_cast<QLineEdit*>(object());
595 }
596
597 QString QAccessibleLineEdit::text(QAccessible::Text t) const
598 {
599     QString str;
600     switch (t) {
601     case QAccessible::Value:
602         if (lineEdit()->echoMode() == QLineEdit::Normal)
603             str = lineEdit()->text();
604         break;
605     default:
606         break;
607     }
608     if (str.isEmpty())
609         str = QAccessibleWidget::text(t);;
610     return qt_accStripAmp(str);
611 }
612
613 void QAccessibleLineEdit::setText(QAccessible::Text t, const QString &text)
614 {
615     if (t != QAccessible::Value) {
616         QAccessibleWidget::setText(t, text);
617         return;
618     }
619
620     QString newText = text;
621     if (lineEdit()->validator()) {
622         int pos = 0;
623         if (lineEdit()->validator()->validate(newText, pos) != QValidator::Acceptable)
624             return;
625     }
626     lineEdit()->setText(newText);
627 }
628
629 QAccessible::State QAccessibleLineEdit::state() const
630 {
631     QAccessible::State state = QAccessibleWidget::state();
632
633     QLineEdit *l = lineEdit();
634     if (l->isReadOnly())
635         state.readOnly = true;
636     else
637         state.editable = true;
638
639     if (l->echoMode() != QLineEdit::Normal)
640         state.passwordEdit = true;
641     state.selectable = true;
642     if (l->hasSelectedText())
643         state.selected = true;
644
645     if (l->contextMenuPolicy() != Qt::NoContextMenu
646         && l->contextMenuPolicy() != Qt::PreventContextMenu)
647         state.hasPopup = true;
648
649     return state;
650 }
651
652 void *QAccessibleLineEdit::interface_cast(QAccessible::InterfaceType t)
653 {
654     if (t == QAccessible::TextInterface)
655         return static_cast<QAccessibleTextInterface*>(this);
656     return QAccessibleWidget::interface_cast(t);
657 }
658
659 void QAccessibleLineEdit::addSelection(int startOffset, int endOffset)
660 {
661     setSelection(0, startOffset, endOffset);
662 }
663
664 QString QAccessibleLineEdit::attributes(int offset, int *startOffset, int *endOffset) const
665 {
666     // QLineEdit doesn't have text attributes
667     *startOffset = *endOffset = offset;
668     return QString();
669 }
670
671 int QAccessibleLineEdit::cursorPosition() const
672 {
673     return lineEdit()->cursorPosition();
674 }
675
676 QRect QAccessibleLineEdit::characterRect(int offset) const
677 {
678     int x = lineEdit()->d_func()->control->cursorToX(offset);
679     int y;
680     lineEdit()->getTextMargins(0, &y, 0, 0);
681     QFontMetrics fm(lineEdit()->font());
682     const QString ch = text(offset, offset + 1);
683     if (ch.isEmpty())
684         return QRect();
685     int w = fm.width(ch);
686     int h = fm.height();
687     QRect r(x, y, w, h);
688     r.moveTo(lineEdit()->mapToGlobal(r.topLeft()));
689     return r;
690 }
691
692 int QAccessibleLineEdit::selectionCount() const
693 {
694     return lineEdit()->hasSelectedText() ? 1 : 0;
695 }
696
697 int QAccessibleLineEdit::offsetAtPoint(const QPoint &point) const
698 {
699     QPoint p = lineEdit()->mapFromGlobal(point);
700
701     return lineEdit()->cursorPositionAt(p);
702 }
703
704 void QAccessibleLineEdit::selection(int selectionIndex, int *startOffset, int *endOffset) const
705 {
706     *startOffset = *endOffset = 0;
707     if (selectionIndex != 0)
708         return;
709
710     *startOffset = lineEdit()->selectionStart();
711     *endOffset = *startOffset + lineEdit()->selectedText().count();
712 }
713
714 QString QAccessibleLineEdit::text(int startOffset, int endOffset) const
715 {
716     if (startOffset > endOffset)
717         return QString();
718
719     if (lineEdit()->echoMode() != QLineEdit::Normal)
720         return QString();
721
722     return lineEdit()->text().mid(startOffset, endOffset - startOffset);
723 }
724
725 QString QAccessibleLineEdit::textBeforeOffset(int offset, BoundaryType boundaryType,
726         int *startOffset, int *endOffset) const
727 {
728     if (lineEdit()->echoMode() != QLineEdit::Normal) {
729         *startOffset = *endOffset = -1;
730         return QString();
731     }
732     return QAccessibleTextInterface::textBeforeOffset(offset, boundaryType, startOffset, endOffset);
733 }
734
735 QString QAccessibleLineEdit::textAfterOffset(int offset, BoundaryType boundaryType,
736         int *startOffset, int *endOffset) const
737 {
738     if (lineEdit()->echoMode() != QLineEdit::Normal) {
739         *startOffset = *endOffset = -1;
740         return QString();
741     }
742     return QAccessibleTextInterface::textAfterOffset(offset, boundaryType, startOffset, endOffset);
743 }
744
745 QString QAccessibleLineEdit::textAtOffset(int offset, BoundaryType boundaryType,
746         int *startOffset, int *endOffset) const
747 {
748     if (lineEdit()->echoMode() != QLineEdit::Normal) {
749         *startOffset = *endOffset = -1;
750         return QString();
751     }
752     return QAccessibleTextInterface::textAtOffset(offset, boundaryType, startOffset, endOffset);
753 }
754
755 void QAccessibleLineEdit::removeSelection(int selectionIndex)
756 {
757     if (selectionIndex != 0)
758         return;
759
760     lineEdit()->deselect();
761 }
762
763 void QAccessibleLineEdit::setCursorPosition(int position)
764 {
765     lineEdit()->setCursorPosition(position);
766 }
767
768 void QAccessibleLineEdit::setSelection(int selectionIndex, int startOffset, int endOffset)
769 {
770     if (selectionIndex != 0)
771         return;
772
773     lineEdit()->setSelection(startOffset, endOffset - startOffset);
774 }
775
776 int QAccessibleLineEdit::characterCount() const
777 {
778     return lineEdit()->text().count();
779 }
780
781 void QAccessibleLineEdit::scrollToSubstring(int startIndex, int endIndex)
782 {
783     lineEdit()->setCursorPosition(endIndex);
784     lineEdit()->setCursorPosition(startIndex);
785 }
786
787 #endif // QT_NO_LINEEDIT
788
789 #ifndef QT_NO_PROGRESSBAR
790 QAccessibleProgressBar::QAccessibleProgressBar(QWidget *o)
791     : QAccessibleDisplay(o)
792 {
793     Q_ASSERT(progressBar());
794 }
795
796 void *QAccessibleProgressBar::interface_cast(QAccessible::InterfaceType t)
797 {
798     if (t == QAccessible::ValueInterface)
799         return static_cast<QAccessibleValueInterface*>(this);
800     return QAccessibleDisplay::interface_cast(t);
801 }
802
803 QVariant QAccessibleProgressBar::currentValue() const
804 {
805     return progressBar()->value();
806 }
807
808 QVariant QAccessibleProgressBar::maximumValue() const
809 {
810     return progressBar()->maximum();
811 }
812
813 QVariant QAccessibleProgressBar::minimumValue() const
814 {
815     return progressBar()->minimum();
816 }
817
818 QProgressBar *QAccessibleProgressBar::progressBar() const
819 {
820     return qobject_cast<QProgressBar *>(object());
821 }
822 #endif
823
824 #endif // QT_NO_ACCESSIBILITY
825
826 QT_END_NAMESPACE
827