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