Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
simplewidgets.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5
6#if QT_CONFIG(abstractbutton)
7#include <qabstractbutton.h>
8#endif
9#if QT_CONFIG(checkbox)
10#include <qcheckbox.h>
11#endif
12#if QT_CONFIG(pushbutton)
13#include <qpushbutton.h>
14#endif
15#if QT_CONFIG(progressbar)
16#include <qprogressbar.h>
17#endif
18#if QT_CONFIG(statusbar)
19#include <qstatusbar.h>
20#endif
21#if QT_CONFIG(radiobutton)
22#include <qradiobutton.h>
23#endif
24#if QT_CONFIG(toolbutton)
25#include <qtoolbutton.h>
26#endif
27#if QT_CONFIG(menu)
28#include <qmenu.h>
29#endif
30#if QT_CONFIG(label)
31#include <qlabel.h>
32#endif
33#if QT_CONFIG(groupbox)
34#include <qgroupbox.h>
35#endif
36#if QT_CONFIG(lcdnumber)
37#include <qlcdnumber.h>
38#endif
39#if QT_CONFIG(lineedit)
40#include <qlineedit.h>
41#include <private/qlineedit_p.h>
42#endif
43#ifndef QT_NO_PICTURE
44#include <QtGui/qpicture.h>
45#endif
46#if QT_CONFIG(messagebox)
47#include <qmessagebox.h>
48#endif
49#include <qstyle.h>
50#include <qstyleoption.h>
51#include <qtextdocument.h>
52#include <qwindow.h>
53#include <private/qwindowcontainer_p.h>
54#include <QtCore/qvarlengtharray.h>
55#if QT_CONFIG(accessibility)
56#include <QtGui/private/qaccessiblehelper_p.h>
57#endif
58#include <QtGui/qvalidator.h>
59
60#ifdef Q_OS_MAC
61#include <qfocusframe.h>
62#endif
63
65
66using namespace Qt::StringLiterals;
67
68#if QT_CONFIG(accessibility)
69
70QWidgetList _q_ac_childWidgets(const QWidget *widget);
71
72QString qt_accHotKey(const QString &text);
73
74#if QT_CONFIG(abstractbutton)
75/*!
76 \class QAccessibleButton
77 \brief The QAccessibleButton class implements the QAccessibleInterface for button type widgets.
78 \internal
79
80 \ingroup accessibility
81*/
82
83/*!
84 Creates a QAccessibleButton object for \a w.
85*/
86QAccessibleButton::QAccessibleButton(QWidget *w)
87: QAccessibleWidgetV2(w)
88{
89 Q_ASSERT(button());
90
91 // FIXME: The checkable state of the button is dynamic,
92 // while we only update the controlling signal once :(
93 if (button()->isCheckable())
94 addControllingSignal("toggled(bool)"_L1);
95 else
96 addControllingSignal("clicked()"_L1);
97}
98
99/*! Returns the button. */
100QAbstractButton *QAccessibleButton::button() const
101{
102 return qobject_cast<QAbstractButton*>(object());
103}
104
105/*! \reimp */
106QString QAccessibleButton::text(QAccessible::Text t) const
107{
108 QString str;
109 switch (t) {
110 case QAccessible::Accelerator:
111 {
112#if QT_CONFIG(shortcut) && QT_CONFIG(pushbutton)
113 QPushButton *pb = qobject_cast<QPushButton*>(object());
114 if (pb && pb->isDefault())
115 str = QKeySequence(Qt::Key_Enter).toString(QKeySequence::NativeText);
116#endif
117 if (str.isEmpty())
118 str = qt_accHotKey(button()->text());
119 }
120 break;
121 case QAccessible::Name:
122 str = widget()->accessibleName();
123 if (str.isEmpty())
124 str = qt_accStripAmp(button()->text());
125 break;
126 default:
127 break;
128 }
129 if (str.isEmpty())
130 str = QAccessibleWidgetV2::text(t);
131 return str;
132}
133
134QAccessible::State QAccessibleButton::state() const
135{
136 QAccessible::State state = QAccessibleWidgetV2::state();
137
138 QAbstractButton *b = button();
139#if QT_CONFIG(checkbox)
140 QCheckBox *cb = qobject_cast<QCheckBox *>(b);
141#endif
142 if (b->isCheckable())
143 state.checkable = true;
144 if (b->isChecked())
145 state.checked = true;
146#if QT_CONFIG(checkbox)
147 if (cb && cb->checkState() == Qt::PartiallyChecked)
148 state.checkStateMixed = true;
149#endif
150 if (b->isDown())
151 state.pressed = true;
152#if QT_CONFIG(pushbutton)
153 QPushButton *pb = qobject_cast<QPushButton*>(b);
154 if (pb) {
155 if (pb->isDefault())
156 state.defaultButton = true;
157#if QT_CONFIG(menu)
158 if (pb->menu())
159 state.hasPopup = true;
160#endif
161 }
162#endif
163
164 return state;
165}
166
167QRect QAccessibleButton::rect() const
168{
169 QAbstractButton *ab = button();
170 if (!ab->isVisible())
171 return QRect();
172
173#if QT_CONFIG(checkbox)
174 if (QCheckBox *cb = qobject_cast<QCheckBox *>(ab)) {
175 QPoint wpos = cb->mapToGlobal(QPoint(0, 0));
176 QStyleOptionButton opt;
177 cb->initStyleOption(&opt);
178 return cb->style()->subElementRect(QStyle::SE_CheckBoxClickRect, &opt, cb).translated(wpos);
179 }
180#endif
181#if QT_CONFIG(radiobutton)
182 else if (QRadioButton *rb = qobject_cast<QRadioButton *>(ab)) {
183 QPoint wpos = rb->mapToGlobal(QPoint(0, 0));
184 QStyleOptionButton opt;
185 rb->initStyleOption(&opt);
186 return rb->style()->subElementRect(QStyle::SE_RadioButtonClickRect, &opt, rb).translated(wpos);
187 }
188#endif
189 return QAccessibleWidgetV2::rect();
190}
191
192QAccessible::Role QAccessibleButton::role() const
193{
194 QAbstractButton *ab = button();
195
196#if QT_CONFIG(menu)
197 if (QPushButton *pb = qobject_cast<QPushButton*>(ab)) {
198 if (pb->menu())
199 return QAccessible::ButtonMenu;
200 }
201#endif
202
203 if (ab->isCheckable())
204 return ab->autoExclusive() ? QAccessible::RadioButton : QAccessible::CheckBox;
205
206 return QAccessible::Button;
207}
208
209QStringList QAccessibleButton::actionNames() const
210{
211 QStringList names;
212 if (widget()->isEnabled()) {
213 switch (role()) {
214 case QAccessible::ButtonMenu:
215 names << showMenuAction();
216 break;
217 case QAccessible::RadioButton:
218 names << toggleAction();
219 break;
220 default:
221 if (button()->isCheckable())
222 names << toggleAction();
223 names << pressAction();
224 break;
225 }
226 }
227 names << QAccessibleWidgetV2::actionNames();
228 return names;
229}
230
231void QAccessibleButton::doAction(const QString &actionName)
232{
233 if (!widget()->isEnabled())
234 return;
235 if (actionName == pressAction() ||
236 actionName == showMenuAction()) {
237#if QT_CONFIG(menu)
238 QPushButton *pb = qobject_cast<QPushButton*>(object());
239 if (pb && pb->menu())
240 pb->showMenu();
241 else
242#endif
243 button()->animateClick();
244 } else if (actionName == toggleAction()) {
245 button()->toggle();
246 } else {
247 QAccessibleWidgetV2::doAction(actionName);
248 }
249}
250
251QStringList QAccessibleButton::keyBindingsForAction(const QString &actionName) const
252{
253 if (actionName == pressAction()) {
254#ifndef QT_NO_SHORTCUT
255 return QStringList() << button()->shortcut().toString();
256#endif
257 }
258 return QStringList();
259}
260#endif // QT_CONFIG(abstractbutton)
261
262#if QT_CONFIG(toolbutton)
263/*!
264 \class QAccessibleToolButton
265 \brief The QAccessibleToolButton class implements the QAccessibleInterface for tool buttons.
266 \internal
267
268 \ingroup accessibility
269*/
270
271/*!
272 Creates a QAccessibleToolButton object for \a w.
273*/
274QAccessibleToolButton::QAccessibleToolButton(QWidget *w)
275: QAccessibleButton(w)
276{
277 Q_ASSERT(toolButton());
278}
279
280/*! Returns the button. */
281QToolButton *QAccessibleToolButton::toolButton() const
282{
283 return qobject_cast<QToolButton*>(object());
284}
285
286/*!
287 Returns \c true if this tool button is a split button.
288*/
289bool QAccessibleToolButton::isSplitButton() const
290{
291#if QT_CONFIG(menu)
292 return menu() && toolButton()->popupMode() == QToolButton::MenuButtonPopup;
293#else
294 return false;
295#endif
296}
297
298#if QT_CONFIG(menu)
299QMenu *QAccessibleToolButton::menu() const
300{
301 if (QMenu *menu = toolButton()->menu())
302 return menu;
303
304 if (QAction *defaultAction = toolButton()->defaultAction())
305 return defaultAction->menu();
306
307 return nullptr;
308}
309#endif
310
311QAccessible::State QAccessibleToolButton::state() const
312{
313 QAccessible::State st = QAccessibleButton::state();
314 if (toolButton()->autoRaise())
315 st.hotTracked = true;
316#if QT_CONFIG(menu)
317 if (menu())
318 st.hasPopup = true;
319#endif
320 return st;
321}
322
323int QAccessibleToolButton::childCount() const
324{
325 return isSplitButton() ? 1 : 0;
326}
327
328QAccessible::Role QAccessibleToolButton::role() const
329{
330#if QT_CONFIG(menu)
331 QToolButton *tb = toolButton();
332 if (!menu())
333 return tb->isCheckable() ? QAccessible::CheckBox : QAccessible::PushButton;
334 else if (tb->popupMode() == QToolButton::DelayedPopup)
335 return QAccessible::ButtonDropDown;
336#endif
337
338 return QAccessible::ButtonMenu;
339}
340
341QAccessibleInterface *QAccessibleToolButton::child(int index) const
342{
343#if QT_CONFIG(menu)
344 if (index == 0 && menu())
345 return QAccessible::queryAccessibleInterface(menu());
346#else
347 Q_UNUSED(index);
348#endif
349 return nullptr;
350}
351
352/*
353 The three different tool button types can have the following actions:
354| DelayedPopup | ShowMenuAction + (PressedAction || CheckedAction) |
355| MenuButtonPopup | ShowMenuAction + (PressedAction || CheckedAction) |
356| InstantPopup | ShowMenuAction |
357*/
358QStringList QAccessibleToolButton::actionNames() const
359{
360 QStringList names;
361 if (widget()->isEnabled()) {
362#if QT_CONFIG(menu)
363 if (toolButton()->menu())
364 names << showMenuAction();
365 if (toolButton()->popupMode() != QToolButton::InstantPopup)
366 names << QAccessibleButton::actionNames();
367#endif
368 }
369 return names;
370}
371
372void QAccessibleToolButton::doAction(const QString &actionName)
373{
374 if (!widget()->isEnabled())
375 return;
376
377 if (actionName == pressAction()) {
378 button()->click();
379 } else if (actionName == showMenuAction()) {
380#if QT_CONFIG(menu)
381 if (toolButton()->popupMode() != QToolButton::InstantPopup) {
382 toolButton()->setDown(true);
383 toolButton()->showMenu();
384 }
385#endif
386 } else {
387 QAccessibleButton::doAction(actionName);
388 }
389
390}
391
392#endif // QT_CONFIG(toolbutton)
393
394/*!
395 \class QAccessibleDisplay
396 \brief The QAccessibleDisplay class implements the QAccessibleInterface for widgets that display information.
397 \internal
398
399 \ingroup accessibility
400*/
401
402/*!
403 Constructs a QAccessibleDisplay object for \a w.
404 \a role is propagated to the QAccessibleWidget constructor.
405*/
406QAccessibleDisplay::QAccessibleDisplay(QWidget *w, QAccessible::Role role)
407: QAccessibleWidgetV2(w, role)
408{
409}
410
411QAccessible::Role QAccessibleDisplay::role() const
412{
413#if QT_CONFIG(label)
414 QLabel *l = qobject_cast<QLabel*>(object());
415 if (l) {
416 if (!l->pixmap().isNull())
417 return QAccessible::Graphic;
418#ifndef QT_NO_PICTURE
419 if (!l->picture().isNull())
420 return QAccessible::Graphic;
421#endif
422#if QT_CONFIG(movie)
423 if (l->movie())
424 return QAccessible::Animation;
425#endif
426#if QT_CONFIG(progressbar)
427 } else if (qobject_cast<QProgressBar*>(object())) {
428 return QAccessible::ProgressBar;
429#endif
430#if QT_CONFIG(statusbar)
431 } else if (qobject_cast<QStatusBar*>(object())) {
432 return QAccessible::StatusBar;
433#endif
434 }
435#endif
436 return QAccessibleWidgetV2::role();
437}
438
439QAccessible::State QAccessibleDisplay::state() const
440{
441 QAccessible::State s = QAccessibleWidgetV2::state();
442 s.readOnly = true;
443 return s;
444}
445
446QString QAccessibleDisplay::text(QAccessible::Text t) const
447{
448 QString str;
449 switch (t) {
450 case QAccessible::Name:
451 str = widget()->accessibleName();
452 if (str.isEmpty()) {
453 if (false) {
454#if QT_CONFIG(label)
455 } else if (qobject_cast<QLabel*>(object())) {
456 QLabel *label = qobject_cast<QLabel*>(object());
457 str = label->text();
458#ifndef QT_NO_TEXTHTMLPARSER
459 if (label->textFormat() == Qt::RichText
460 || (label->textFormat() == Qt::AutoText && Qt::mightBeRichText(str))) {
461 QTextDocument doc;
462 doc.setHtml(str);
463 str = doc.toPlainText();
464 }
465#endif
466#ifndef QT_NO_SHORTCUT
467 if (label->buddy())
468 str = qt_accStripAmp(str);
469#endif
470#endif // QT_CONFIG(label)
471#if QT_CONFIG(lcdnumber)
472 } else if (qobject_cast<QLCDNumber*>(object())) {
473 QLCDNumber *l = qobject_cast<QLCDNumber*>(object());
474 if (l->digitCount())
475 str = QString::number(l->value());
476 else
477 str = QString::number(l->intValue());
478#endif
479#if QT_CONFIG(statusbar)
480 } else if (qobject_cast<QStatusBar*>(object())) {
481 return qobject_cast<QStatusBar*>(object())->currentMessage();
482#endif
483 }
484 }
485 break;
486 case QAccessible::Value:
487#if QT_CONFIG(progressbar)
488 if (qobject_cast<QProgressBar*>(object()))
489 str = QString::number(qobject_cast<QProgressBar*>(object())->value());
490#endif
491 break;
492 default:
493 break;
494 }
495 if (str.isEmpty())
496 str = QAccessibleWidgetV2::text(t);
497 return str;
498}
499
500/*! \reimp */
501QList<std::pair<QAccessibleInterface *, QAccessible::Relation>>
502QAccessibleDisplay::relations(QAccessible::Relation match /* = QAccessible::AllRelations */) const
503{
504 QList<std::pair<QAccessibleInterface *, QAccessible::Relation>> rels =
505 QAccessibleWidgetV2::relations(match);
506# if QT_CONFIG(shortcut) && QT_CONFIG(label)
507 if (match & QAccessible::Labelled) {
508 if (QLabel *label = qobject_cast<QLabel*>(object())) {
509 const QAccessible::Relation rel = QAccessible::Labelled;
510 if (QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(label->buddy()))
511 rels.emplace_back(iface, rel);
512 }
513 }
514#endif
515 return rels;
516}
517
518void *QAccessibleDisplay::interface_cast(QAccessible::InterfaceType t)
519{
520 if (t == QAccessible::ImageInterface)
521 return static_cast<QAccessibleImageInterface*>(this);
522 return QAccessibleWidgetV2::interface_cast(t);
523}
524
525/*! \internal */
526QString QAccessibleDisplay::imageDescription() const
527{
528#if QT_CONFIG(tooltip)
529 return widget()->toolTip();
530#else
531 return QString();
532#endif
533}
534
535/*! \internal */
536QSize QAccessibleDisplay::imageSize() const
537{
538#if QT_CONFIG(label)
539 QLabel *label = qobject_cast<QLabel *>(widget());
540 if (!label)
541#endif
542 return QSize();
543#if QT_CONFIG(label)
544 return label->pixmap().size();
545#endif
546}
547
548/*! \internal */
549QPoint QAccessibleDisplay::imagePosition() const
550{
551#if QT_CONFIG(label)
552 QLabel *label = qobject_cast<QLabel *>(widget());
553 if (!label)
554#endif
555 return QPoint();
556#if QT_CONFIG(label)
557 if (label->pixmap().isNull())
558 return QPoint();
559
560 return QPoint(label->mapToGlobal(label->pos()));
561#endif
562}
563
564#if QT_CONFIG(groupbox)
565QAccessibleGroupBox::QAccessibleGroupBox(QWidget *w)
566: QAccessibleWidgetV2(w)
567{
568}
569
570QGroupBox* QAccessibleGroupBox::groupBox() const
571{
572 return static_cast<QGroupBox *>(widget());
573}
574
575QString QAccessibleGroupBox::text(QAccessible::Text t) const
576{
577 QString txt = QAccessibleWidgetV2::text(t);
578
579 if (txt.isEmpty()) {
580 switch (t) {
581 case QAccessible::Name:
582 txt = qt_accStripAmp(groupBox()->title());
583 break;
584#if QT_CONFIG(tooltip)
585 case QAccessible::Description:
586 txt = groupBox()->toolTip();
587 break;
588#endif
589 case QAccessible::Accelerator:
590 txt = qt_accHotKey(groupBox()->title());
591 break;
592 default:
593 break;
594 }
595 }
596
597 return txt;
598}
599
600QAccessible::State QAccessibleGroupBox::state() const
601{
602 QAccessible::State st = QAccessibleWidgetV2::state();
603 st.checkable = groupBox()->isCheckable();
604 st.checked = groupBox()->isChecked();
605 return st;
606}
607
608QAccessible::Role QAccessibleGroupBox::role() const
609{
610 return groupBox()->isCheckable() ? QAccessible::CheckBox : QAccessible::Grouping;
611}
612
613QList<std::pair<QAccessibleInterface *, QAccessible::Relation>>
614QAccessibleGroupBox::relations(QAccessible::Relation match /* = QAccessible::AllRelations */) const
615{
616 QList<std::pair<QAccessibleInterface *, QAccessible::Relation>> rels =
617 QAccessibleWidgetV2::relations(match);
618
619 if ((match & QAccessible::Labelled) && (!groupBox()->title().isEmpty())) {
620 const QList<QWidget*> kids = _q_ac_childWidgets(widget());
621 for (QWidget *kid : kids) {
622 QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(kid);
623 if (iface)
624 rels.emplace_back(iface, QAccessible::Relation(QAccessible::Labelled));
625 }
626 }
627 return rels;
628}
629
630QStringList QAccessibleGroupBox::actionNames() const
631{
632 QStringList actions = QAccessibleWidgetV2::actionNames();
633
634 if (groupBox()->isCheckable()) {
635 actions.prepend(QAccessibleActionInterface::toggleAction());
636 }
637 return actions;
638}
639
640void QAccessibleGroupBox::doAction(const QString &actionName)
641{
642 if (actionName == QAccessibleActionInterface::toggleAction())
643 groupBox()->setChecked(!groupBox()->isChecked());
644}
645
646QStringList QAccessibleGroupBox::keyBindingsForAction(const QString &) const
647{
648 return QStringList();
649}
650
651#endif
652
653#if QT_CONFIG(lineedit)
654/*!
655 \class QAccessibleLineEdit
656 \brief The QAccessibleLineEdit class implements the QAccessibleInterface for widgets with editable text
657 \internal
658
659 \ingroup accessibility
660*/
661
662/*!
663 Constructs a QAccessibleLineEdit object for \a w.
664 \a name is propagated to the QAccessibleWidget constructor.
665*/
666QAccessibleLineEdit::QAccessibleLineEdit(QWidget *w, const QString &name)
667: QAccessibleWidgetV2(w, QAccessible::EditableText, name)
668{
669 addControllingSignal("textChanged(const QString&)"_L1);
670 addControllingSignal("returnPressed()"_L1);
671}
672
673/*! Returns the line edit. */
674QLineEdit *QAccessibleLineEdit::lineEdit() const
675{
676 return qobject_cast<QLineEdit*>(object());
677}
678
679QString QAccessibleLineEdit::text(QAccessible::Text t) const
680{
681 QString str;
682 switch (t) {
683 case QAccessible::Value:
684 str = lineEdit()->displayText();
685 break;
686 default:
687 break;
688 }
689 if (str.isEmpty())
690 str = QAccessibleWidgetV2::text(t);
691 if (str.isEmpty() && t == QAccessible::Description)
692 str = lineEdit()->placeholderText();
693 return str;
694}
695
696void QAccessibleLineEdit::setText(QAccessible::Text t, const QString &text)
697{
698 if (t != QAccessible::Value) {
699 QAccessibleWidgetV2::setText(t, text);
700 return;
701 }
702
703 QString newText = text;
704#if QT_CONFIG(validator)
705 if (lineEdit()->validator()) {
706 int pos = 0;
707 if (lineEdit()->validator()->validate(newText, pos) != QValidator::Acceptable)
708 return;
709 }
710#endif
711 lineEdit()->setText(newText);
712}
713
714QAccessible::State QAccessibleLineEdit::state() const
715{
716 QAccessible::State state = QAccessibleWidgetV2::state();
717
718 QLineEdit *l = lineEdit();
719 state.editable = true;
720 if (l->isReadOnly())
721 state.readOnly = true;
722
723 if (l->echoMode() != QLineEdit::Normal)
724 state.passwordEdit = true;
725
726 state.selectableText = true;
727 return state;
728}
729
730void *QAccessibleLineEdit::interface_cast(QAccessible::InterfaceType t)
731{
732 if (t == QAccessible::TextInterface)
733 return static_cast<QAccessibleTextInterface*>(this);
734 if (t == QAccessible::EditableTextInterface)
735 return static_cast<QAccessibleEditableTextInterface*>(this);
736 return QAccessibleWidgetV2::interface_cast(t);
737}
738
739void QAccessibleLineEdit::addSelection(int startOffset, int endOffset)
740{
741 setSelection(0, startOffset, endOffset);
742}
743
744QString QAccessibleLineEdit::attributes(int offset, int *startOffset, int *endOffset) const
745{
746 // QLineEdit doesn't have text attributes
747 *startOffset = *endOffset = offset;
748 return QString();
749}
750
751int QAccessibleLineEdit::cursorPosition() const
752{
753 return lineEdit()->cursorPosition();
754}
755
756QRect QAccessibleLineEdit::characterRect(int offset) const
757{
758 int x = lineEdit()->d_func()->control->cursorToX(offset);
759 int y = lineEdit()->textMargins().top();
760 QFontMetrics fm(lineEdit()->font());
761 const QString ch = text(offset, offset + 1);
762 if (ch.isEmpty())
763 return QRect();
764 int w = fm.horizontalAdvance(ch);
765 int h = fm.height();
766 QRect r(x, y, w, h);
767 r.moveTo(lineEdit()->mapToGlobal(r.topLeft()));
768 return r;
769}
770
771int QAccessibleLineEdit::selectionCount() const
772{
773 return lineEdit()->hasSelectedText() ? 1 : 0;
774}
775
776int QAccessibleLineEdit::offsetAtPoint(const QPoint &point) const
777{
778 QPoint p = lineEdit()->mapFromGlobal(point);
779
780 return lineEdit()->cursorPositionAt(p);
781}
782
783void QAccessibleLineEdit::selection(int selectionIndex, int *startOffset, int *endOffset) const
784{
785 *startOffset = *endOffset = 0;
786 if (selectionIndex != 0)
787 return;
788
789 *startOffset = lineEdit()->selectionStart();
790 *endOffset = *startOffset + lineEdit()->selectedText().size();
791}
792
793QString QAccessibleLineEdit::text(int startOffset, int endOffset) const
794{
795 if (startOffset > endOffset)
796 return QString();
797
798 return lineEdit()->displayText().mid(startOffset, endOffset - startOffset);
799}
800
801QString QAccessibleLineEdit::textBeforeOffset(int offset, QAccessible::TextBoundaryType boundaryType,
802 int *startOffset, int *endOffset) const
803{
804 if (offset == -2)
805 offset = cursorPosition();
806 return QAccessibleTextInterface::textBeforeOffset(offset, boundaryType, startOffset, endOffset);
807}
808
809QString QAccessibleLineEdit::textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType,
810 int *startOffset, int *endOffset) const
811{
812 if (offset == -2)
813 offset = cursorPosition();
814 return QAccessibleTextInterface::textAfterOffset(offset, boundaryType, startOffset, endOffset);
815}
816
817QString QAccessibleLineEdit::textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType,
818 int *startOffset, int *endOffset) const
819{
820 if (offset == -2)
821 offset = cursorPosition();
822 return QAccessibleTextInterface::textAtOffset(offset, boundaryType, startOffset, endOffset);
823}
824
825void QAccessibleLineEdit::removeSelection(int selectionIndex)
826{
827 if (selectionIndex != 0)
828 return;
829
830 lineEdit()->deselect();
831}
832
833void QAccessibleLineEdit::setCursorPosition(int position)
834{
835 lineEdit()->setCursorPosition(position);
836}
837
838void QAccessibleLineEdit::setSelection(int selectionIndex, int startOffset, int endOffset)
839{
840 if (selectionIndex != 0)
841 return;
842
843 lineEdit()->setSelection(startOffset, endOffset - startOffset);
844}
845
846int QAccessibleLineEdit::characterCount() const
847{
848 return lineEdit()->displayText().size();
849}
850
851void QAccessibleLineEdit::scrollToSubstring(int startIndex, int endIndex)
852{
853 lineEdit()->setCursorPosition(endIndex);
854 lineEdit()->setCursorPosition(startIndex);
855}
856
857void QAccessibleLineEdit::deleteText(int startOffset, int endOffset)
858{
859 lineEdit()->setText(lineEdit()->text().remove(startOffset, endOffset - startOffset));
860}
861
862void QAccessibleLineEdit::insertText(int offset, const QString &text)
863{
864 lineEdit()->setText(lineEdit()->text().insert(offset, text));
865}
866
867void QAccessibleLineEdit::replaceText(int startOffset, int endOffset, const QString &text)
868{
869 lineEdit()->setText(lineEdit()->text().replace(startOffset, endOffset - startOffset, text));
870}
871
872#endif // QT_CONFIG(lineedit)
873
874#if QT_CONFIG(progressbar)
875QAccessibleProgressBar::QAccessibleProgressBar(QWidget *o)
876 : QAccessibleDisplay(o)
877{
878 Q_ASSERT(progressBar());
879}
880
881void *QAccessibleProgressBar::interface_cast(QAccessible::InterfaceType t)
882{
883 if (t == QAccessible::ValueInterface)
884 return static_cast<QAccessibleValueInterface*>(this);
885 return QAccessibleDisplay::interface_cast(t);
886}
887
888QVariant QAccessibleProgressBar::currentValue() const
889{
890 return progressBar()->value();
891}
892
893QVariant QAccessibleProgressBar::maximumValue() const
894{
895 return progressBar()->maximum();
896}
897
898QVariant QAccessibleProgressBar::minimumValue() const
899{
900 return progressBar()->minimum();
901}
902
903QVariant QAccessibleProgressBar::minimumStepSize() const
904{
905 // This is arbitrary since any value between min and max is valid.
906 // Some screen readers (orca use it to calculate how many digits to display though,
907 // so it makes sense to return a "sensible" value. Providing 100 increments seems ok.
908 return (progressBar()->maximum() - progressBar()->minimum()) / 100.0;
909}
910
911QProgressBar *QAccessibleProgressBar::progressBar() const
912{
913 return qobject_cast<QProgressBar *>(object());
914}
915#endif
916
917
918QAccessibleWindowContainer::QAccessibleWindowContainer(QWidget *w)
919 : QAccessibleWidgetV2(w)
920{
921}
922
923int QAccessibleWindowContainer::childCount() const
924{
925 if (container()->containedWindow() && QAccessible::queryAccessibleInterface(container()->containedWindow()))
926 return 1;
927 return 0;
928}
929
930int QAccessibleWindowContainer::indexOfChild(const QAccessibleInterface *child) const
931{
932 if (child->object() == container()->containedWindow())
933 return 0;
934 return -1;
935}
936
937QAccessibleInterface *QAccessibleWindowContainer::child(int i) const
938{
939 if (i == 0)
940 return QAccessible::queryAccessibleInterface(container()->containedWindow());
941 return nullptr;
942}
943
944QWindowContainer *QAccessibleWindowContainer::container() const
945{
946 return static_cast<QWindowContainer *>(widget());
947}
948
949#if QT_CONFIG(messagebox)
950/*!
951 \internal
952 Implements QAccessibleWidget for QMessageBox
953*/
954QAccessibleMessageBox::QAccessibleMessageBox(QWidget *widget)
955 : QAccessibleWidgetV2(widget, QAccessible::AlertMessage)
956{
957 Q_ASSERT(qobject_cast<QMessageBox *>(widget));
958}
959
960QMessageBox *QAccessibleMessageBox::messageBox() const
961{
962 return static_cast<QMessageBox *>(widget());
963}
964
965QString QAccessibleMessageBox::text(QAccessible::Text t) const
966{
967 QString str;
968
969 switch (t) {
970 case QAccessible::Name:
971 str = QAccessibleWidgetV2::text(t);
972 if (str.isEmpty()) // implies no title text is set
973 str = messageBox()->text();
974 break;
975 case QAccessible::Value:
976 str = messageBox()->text();
977 break;
978 case QAccessible::Help:
979 str = messageBox()->informativeText();
980 break;
981 default:
982 str = QAccessibleWidgetV2::text(t);
983 break;
984 }
985
986 return str;
987}
988#endif
989
990#endif // QT_CONFIG(accessibility)
991
992QT_END_NAMESPACE