LCOV - code coverage report
Current view: top level - muse/framework/accessibility/internal - accessibleiteminterface.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 1.9 % 314 6
Test Date: 2026-11-05 04:07:02

            Line data    Source code
       1              : /*
       2              :  * SPDX-License-Identifier: GPL-3.0-only
       3              :  * MuseScore-CLA-applies
       4              :  *
       5              :  * MuseScore Studio
       6              :  * Music Composition & Notation
       7              :  *
       8              :  * Copyright (C) 2021 MuseScore Limited and others
       9              :  *
      10              :  * This program is free software: you can redistribute it and/or modify
      11              :  * it under the terms of the GNU General Public License version 3 as
      12              :  * published by the Free Software Foundation.
      13              :  *
      14              :  * This program is distributed in the hope that it will be useful,
      15              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      16              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17              :  * GNU General Public License for more details.
      18              :  *
      19              :  * You should have received a copy of the GNU General Public License
      20              :  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
      21              :  */
      22              : #include "accessibleiteminterface.h"
      23              : 
      24              : #include <QWindow>
      25              : 
      26              : #include "global/translation.h"
      27              : 
      28              : #include "accessibilitycontroller.h"
      29              : 
      30              : #include "log.h"
      31              : 
      32              : //#define MUSE_ACCESSIBILITY_TRACE
      33              : 
      34              : #undef MYLOG
      35              : #ifdef MUSE_ACCESSIBILITY_TRACE
      36              : #define MYLOG() LOGI()
      37              : #else
      38              : #define MYLOG() LOGN()
      39              : #endif
      40              : 
      41              : using namespace muse;
      42              : using namespace muse::accessibility;
      43              : 
      44           10 : AccessibleItemInterface::AccessibleItemInterface(AccessibleObject* object)
      45           10 :     : muse::Contextable(object->item()->iocContext())
      46              : {
      47           10 :     m_object = object;
      48           10 : }
      49              : 
      50            0 : bool AccessibleItemInterface::isValid() const
      51              : {
      52            0 :     return m_object != nullptr;
      53              : }
      54              : 
      55           20 : QObject* AccessibleItemInterface::object() const
      56              : {
      57           20 :     return m_object;
      58              : }
      59              : 
      60            0 : QWindow* AccessibleItemInterface::window() const
      61              : {
      62            0 :     QWindow* window = m_object->item()->accessibleWindow();
      63            0 :     if (window) {
      64            0 :         return window;
      65              :     }
      66              : 
      67            0 :     return interactive()->topWindow();
      68              : }
      69              : 
      70            0 : QRect AccessibleItemInterface::rect() const
      71              : {
      72            0 :     return m_object->item()->accessibleRect();
      73              : }
      74              : 
      75            0 : QAccessibleInterface* AccessibleItemInterface::parent() const
      76              : {
      77            0 :     QAccessibleInterface* iface = m_object->controller().lock()->parentIface(m_object->item());
      78              :     MYLOG() << "item: " << m_object->item()->accessibleName() << ", parent: " << (iface ? iface->text(QAccessible::Name) : "null");
      79            0 :     return iface;
      80              : }
      81              : 
      82            0 : int AccessibleItemInterface::childCount() const
      83              : {
      84            0 :     int count = m_object->controller().lock()->childCount(m_object->item());
      85              :     MYLOG() << "item: " << m_object->item()->accessibleName() << ", childCount: " << count;
      86            0 :     return count;
      87              : }
      88              : 
      89            0 : QAccessibleInterface* AccessibleItemInterface::child(int index) const
      90              : {
      91            0 :     QAccessibleInterface* iface = m_object->controller().lock()->child(m_object->item(), index);
      92              :     MYLOG() << "item: " << m_object->item()->accessibleName() << ", child: " << index << " " << iface->text(QAccessible::Name);
      93            0 :     return iface;
      94              : }
      95              : 
      96            0 : int AccessibleItemInterface::indexOfChild(const QAccessibleInterface* iface) const
      97              : {
      98            0 :     int idx = m_object->controller().lock()->indexOfChild(m_object->item(), iface);
      99              :     MYLOG() << "item: " << m_object->item()->accessibleName() << ", indexOfChild: " << iface->text(QAccessible::Name) << " = " << idx;
     100            0 :     return idx;
     101              : }
     102              : 
     103            0 : QAccessibleInterface* AccessibleItemInterface::childAt(int, int) const
     104              : {
     105            0 :     NOT_IMPLEMENTED;
     106            0 :     return nullptr;
     107              : }
     108              : 
     109            0 : QAccessibleInterface* AccessibleItemInterface::focusChild() const
     110              : {
     111            0 :     QAccessibleInterface* child = m_object->controller().lock()->focusedChild(m_object->item());
     112              :     MYLOG() << "item: " << m_object->item()->accessibleName() << ", focused child: " << (child ? child->text(QAccessible::Name) : "null");
     113            0 :     return child;
     114              : }
     115              : 
     116            0 : QAccessible::State AccessibleItemInterface::state() const
     117              : {
     118            0 :     IAccessible* item = m_object->item();
     119            0 :     QAccessible::State state;
     120            0 :     state.invalid = false;
     121            0 :     state.disabled = !item->accessibleState(IAccessible::State::Enabled);
     122            0 :     state.invisible = state.disabled;
     123              : 
     124            0 :     if (state.disabled) {
     125            0 :         return state;
     126              :     }
     127              : 
     128            0 :     IAccessible::Role r = item->accessibleRole();
     129            0 :     switch (r) {
     130            0 :     case IAccessible::Role::NoRole: break;
     131            0 :     case IAccessible::Role::Application: {
     132            0 :         state.active = true;
     133            0 :     } break;
     134            0 :     case IAccessible::Role::Dialog: {
     135            0 :         state.active = item->accessibleState(IAccessible::State::Active);
     136            0 :     } break;
     137            0 :     case IAccessible::Role::Panel: {
     138            0 :         state.active = item->accessibleState(IAccessible::State::Active);
     139            0 :     } break;
     140            0 :     case IAccessible::Role::Button: {
     141            0 :         state.focusable = true;
     142            0 :         state.focused = item->accessibleState(IAccessible::State::Focused);
     143            0 :     } break;
     144            0 :     case IAccessible::Role::RadioButton: {
     145            0 :         state.focusable = true;
     146            0 :         state.focused = item->accessibleState(IAccessible::State::Focused);
     147              : 
     148            0 :         state.checkable = true;
     149            0 :         state.checked = item->accessibleState(IAccessible::State::Checked);
     150            0 :     } break;
     151            0 :     case IAccessible::Role::EditableText: {
     152            0 :         state.focusable = true;
     153            0 :         state.focused = item->accessibleState(IAccessible::State::Focused);
     154            0 :     } break;
     155            0 :     case IAccessible::Role::StaticText: {
     156            0 :         state.focusable = true;
     157            0 :         state.focused = item->accessibleState(IAccessible::State::Focused);
     158            0 :     } break;
     159            0 :     case IAccessible::Role::SilentRole: {
     160            0 :         state.focusable = true;
     161            0 :         state.focused = item->accessibleState(IAccessible::State::Focused);
     162            0 :     } break;
     163            0 :     case IAccessible::Role::List: {
     164            0 :         state.active = item->accessibleState(IAccessible::State::Active);
     165            0 :     } break;
     166            0 :     case IAccessible::Role::ListItem: {
     167            0 :         state.focusable = true;
     168            0 :         state.focused = item->accessibleState(IAccessible::State::Focused);
     169              : 
     170            0 :         state.selectable = true;
     171            0 :         state.selected = item->accessibleState(IAccessible::State::Selected);
     172            0 :     } break;
     173            0 :     case IAccessible::Role::Information: {
     174            0 :         state.focusable = true;
     175            0 :         state.focused = item->accessibleState(IAccessible::State::Focused);
     176            0 :     } break;
     177            0 :     case IAccessible::Role::ElementOnScore: {
     178            0 :         state.focusable = true;
     179            0 :         state.focused = item->accessibleState(IAccessible::State::Focused);
     180              : 
     181              : //        state.checkable = true;
     182              : //        state.checked = item->accessibleState(IAccessible::State::Selected);
     183            0 :     } break;
     184            0 :     case IAccessible::Role::CheckBox: {
     185            0 :         state.focusable = true;
     186            0 :         state.focused = item->accessibleState(IAccessible::State::Focused);
     187              : 
     188            0 :         state.checkable = true;
     189            0 :         state.checked = item->accessibleState(IAccessible::State::Checked);
     190            0 :     } break;
     191            0 :     case IAccessible::Role::ComboBox: {
     192            0 :         state.focusable = true;
     193            0 :         state.focused = item->accessibleState(IAccessible::State::Focused);
     194            0 :     } break;
     195            0 :     case IAccessible::Role::MenuItem: {
     196            0 :         state.focusable = true;
     197            0 :         state.focused = item->accessibleState(IAccessible::State::Focused);
     198            0 :     } break;
     199            0 :     case IAccessible::Role::SpinBox: {
     200            0 :         state.focusable = true;
     201            0 :         state.focused = item->accessibleState(IAccessible::State::Focused);
     202            0 :     } break;
     203            0 :     case IAccessible::Role::Range: {
     204            0 :         state.focusable = true;
     205            0 :         state.focused = item->accessibleState(IAccessible::State::Focused);
     206            0 :     } break;
     207            0 :     case IAccessible::Role::Group: {
     208            0 :         state.focusable = true;
     209            0 :         state.focused = item->accessibleState(IAccessible::State::Focused);
     210            0 :     } break;
     211            0 :     case IAccessible::Role::Table: {
     212            0 :         state.focusable = true;
     213            0 :         state.focused = item->accessibleState(IAccessible::State::Focused);
     214            0 :     } break;
     215            0 :     case IAccessible::Role::ColumnHeader: {
     216            0 :         state.focusable = true;
     217            0 :         state.focused = item->accessibleState(IAccessible::State::Focused);
     218            0 :     } break;
     219            0 :     case IAccessible::Role::RowHeader: {
     220            0 :         state.focusable = true;
     221            0 :         state.focused = item->accessibleState(IAccessible::State::Focused);
     222            0 :     } break;
     223            0 :     case IAccessible::Role::Column: {
     224            0 :         state.focusable = true;
     225            0 :         state.focused = item->accessibleState(IAccessible::State::Focused);
     226            0 :     } break;
     227            0 :     case IAccessible::Role::Row: {
     228            0 :         state.focusable = true;
     229            0 :         state.focused = item->accessibleState(IAccessible::State::Focused);
     230            0 :     } break;
     231            0 :     case IAccessible::Role::Cell: {
     232            0 :         state.focusable = true;
     233            0 :         state.focused = item->accessibleState(IAccessible::State::Focused);
     234            0 :     } break;
     235            0 :     default: {
     236            0 :         LOGW() << "not handled role: " << static_cast<int>(r);
     237            0 :     } break;
     238              :     }
     239              : 
     240            0 :     if (IAccessible* pretendFocus = m_object->controller().lock()->pretendFocus()) {
     241            0 :         if (item == pretendFocus) {
     242              :             // Pretend to have focus.
     243            0 :             state.focusable = true;
     244            0 :             state.focused = true;
     245              :         } else {
     246              :             // Pretend to not have focus.
     247            0 :             state.focused = false;
     248              :         }
     249              :     }
     250              : 
     251            0 :     return state;
     252              : }
     253              : 
     254            0 : QAccessible::Role AccessibleItemInterface::role() const
     255              : {
     256            0 :     IAccessible::Role r = m_object->item()->accessibleRole();
     257            0 :     switch (r) {
     258            0 :     case IAccessible::Role::NoRole: return QAccessible::NoRole;
     259            0 :     case IAccessible::Role::Application: return QAccessible::Application;
     260            0 :     case IAccessible::Role::Dialog: return QAccessible::Dialog;
     261            0 :     case IAccessible::Role::Panel:
     262              : #if defined(Q_OS_WIN)
     263              :         // Narrator: Don't say the panel name twice when changing panels.
     264              :         return QAccessible::StaticText;
     265              : #else
     266            0 :         return QAccessible::Pane;
     267              : #endif
     268            0 :     case IAccessible::Role::StaticText: return QAccessible::StaticText;
     269            0 :     case IAccessible::Role::SilentRole: {
     270              :         // See https://doc.qt.io/qt-5/qaccessible.html#Role-enum
     271              :         // We want the screen reader to say the name of the current item and
     272              :         // nothing else (i.e. not the name followed by "button" or "text").
     273              : #if defined(Q_OS_MACOS)
     274              :         // Good on macOS with VoiceOver.
     275              :         return QAccessible::StaticText;
     276              :         // VoiceOver gives unwanted additional output if ListItem is used, and it
     277              :         // doesn't work at all if the role is TreeItem or Cell.
     278              : #else
     279              :         // Good on Windows with Narrator, NVDA, or JAWS; and on Linux with Orca.
     280            0 :         return QAccessible::ListItem;
     281              :         // Orca is equally happy with the roles TreeItem or Cell, but these cause
     282              :         // unwanted additional ouput on Windows. StaticText causes unwanted
     283              :         // additional output on both Linux and Windows.
     284              : #endif
     285              :     }
     286            0 :     case IAccessible::Role::EditableText: return QAccessible::EditableText;
     287            0 :     case IAccessible::Role::Button: return QAccessible::Button;
     288            0 :     case IAccessible::Role::CheckBox: return QAccessible::CheckBox;
     289            0 :     case IAccessible::Role::RadioButton: return QAccessible::RadioButton;
     290            0 :     case IAccessible::Role::ComboBox: return QAccessible::ComboBox;
     291            0 :     case IAccessible::Role::List: return QAccessible::List;
     292            0 :     case IAccessible::Role::ListItem: return QAccessible::ListItem;
     293            0 :     case IAccessible::Role::MenuItem: return QAccessible::MenuItem;
     294            0 :     case IAccessible::Role::SpinBox: return QAccessible::SpinBox;
     295            0 :     case IAccessible::Role::Range: return QAccessible::Slider;
     296            0 :     case IAccessible::Role::Table: return QAccessible::Table;
     297            0 :     case IAccessible::Role::ColumnHeader: return QAccessible::ColumnHeader;
     298            0 :     case IAccessible::Role::RowHeader: return QAccessible::RowHeader;
     299            0 :     case IAccessible::Role::Column: return QAccessible::Column;
     300            0 :     case IAccessible::Role::Row: return QAccessible::Row;
     301            0 :     case IAccessible::Role::Cell: return QAccessible::Cell;
     302            0 :     case IAccessible::Role::Group:
     303              :     case IAccessible::Role::Information:
     304              :     case IAccessible::Role::ElementOnScore: {
     305              : #ifdef Q_OS_WIN
     306              :         return QAccessible::StaticText;
     307              : #else
     308            0 :         return QAccessible::UserRole;
     309              : #endif
     310              :     }
     311              :     }
     312              : 
     313            0 :     LOGE() << "not handled role: " << static_cast<int>(r);
     314            0 :     return QAccessible::NoRole;
     315              : }
     316              : 
     317            0 : QString AccessibleItemInterface::text(QAccessible::Text textType) const
     318              : {
     319              :     // NOTE: Handling of text types must match AccessibilityController::propertyChanged().
     320            0 :     switch (textType) {
     321            0 :     case QAccessible::Name: {
     322            0 :         QString ann = announcement();
     323            0 :         if (!ann.isEmpty()) {
     324            0 :             return ann;
     325              :         }
     326            0 :         QString name = m_object->item()->accessibleName();
     327              : #if defined(Q_OS_MACOS)
     328              :         // VoiceOver doesn't speak descriptions so add it to name instead.
     329              :         QString desc = description();
     330              :         if (!desc.isEmpty()) {
     331              :             name += ", " + desc;
     332              :         }
     333              : #endif
     334            0 :         if (auto controller = m_object->controller().lock()) {
     335            0 :             if (m_object->item() == controller->lastFocused() && controller->needToVoicePanelInfo()) {
     336            0 :                 QString panelName = controller->currentPanelAccessibleName();
     337            0 :                 if (!panelName.isEmpty()) {
     338            0 :                     name.prepend(muse::qtrc("accessibility", "%1 panel").arg(panelName) + ", ");
     339              :                 }
     340            0 :             }
     341            0 :         }
     342            0 :         return name;
     343            0 :     }
     344              : #if !defined(Q_OS_MACOS) // Give description separately to name.
     345              : #if defined(Q_OS_WINDOWS)
     346              :     // Narrator doesn't read descriptions but it does read accelerators.
     347              :     // NVDA reads both so it should be safe to give just an accelerator.
     348              :     case QAccessible::Accelerator: {
     349              : #else
     350              :     //  Orca on Linux does read descriptions.
     351            0 :     case QAccessible::Description: {
     352              : #endif
     353            0 :         if (!announcement().isEmpty()) {
     354            0 :             break; // Don't say description after an announcement.
     355              :         }
     356            0 :         return description();
     357              :     }
     358              : #endif
     359            0 :     default: break;
     360              :     }
     361              : 
     362            0 :     return QString();
     363              : }
     364              : 
     365            0 : void AccessibleItemInterface::setText(QAccessible::Text, const QString&)
     366              : {
     367            0 :     NOT_IMPLEMENTED;
     368            0 : }
     369              : 
     370            0 : QVariant AccessibleItemInterface::currentValue() const
     371              : {
     372            0 :     return m_object->item()->accessibleValue();
     373              : }
     374              : 
     375            0 : void AccessibleItemInterface::setCurrentValue(const QVariant&)
     376              : {
     377            0 :     NOT_IMPLEMENTED;
     378            0 : }
     379              : 
     380            0 : QVariant AccessibleItemInterface::maximumValue() const
     381              : {
     382            0 :     return m_object->item()->accessibleMaximumValue();
     383              : }
     384              : 
     385            0 : QVariant AccessibleItemInterface::minimumValue() const
     386              : {
     387            0 :     return m_object->item()->accessibleMinimumValue();
     388              : }
     389              : 
     390            0 : QVariant AccessibleItemInterface::minimumStepSize() const
     391              : {
     392            0 :     return m_object->item()->accessibleValueStepSize();
     393              : }
     394              : 
     395            0 : void AccessibleItemInterface::selection(int selectionIndex, int* startOffset, int* endOffset) const
     396              : {
     397            0 :     m_object->item()->accessibleSelection(selectionIndex, startOffset, endOffset);
     398            0 : }
     399              : 
     400            0 : int AccessibleItemInterface::selectionCount() const
     401              : {
     402            0 :     return m_object->item()->accessibleSelectionCount();
     403              : }
     404              : 
     405            0 : void AccessibleItemInterface::addSelection(int, int)
     406              : {
     407            0 :     NOT_IMPLEMENTED;
     408            0 : }
     409              : 
     410            0 : void AccessibleItemInterface::removeSelection(int)
     411              : {
     412            0 :     NOT_IMPLEMENTED;
     413            0 : }
     414              : 
     415            0 : void AccessibleItemInterface::setSelection(int, int, int)
     416              : {
     417            0 :     NOT_IMPLEMENTED;
     418            0 : }
     419              : 
     420            0 : int AccessibleItemInterface::cursorPosition() const
     421              : {
     422            0 :     return m_object->item()->accessibleCursorPosition();
     423              : }
     424              : 
     425            0 : void AccessibleItemInterface::setCursorPosition(int)
     426              : {
     427            0 :     NOT_IMPLEMENTED;
     428            0 : }
     429              : 
     430            0 : QString AccessibleItemInterface::text(int startOffset, int endOffset) const
     431              : {
     432            0 :     return m_object->item()->accessibleText(startOffset, endOffset);
     433              : }
     434              : 
     435            0 : QString AccessibleItemInterface::textBeforeOffset(int offset, QAccessible::TextBoundaryType boundaryType, int* startOffset,
     436              :                                                   int* endOffset) const
     437              : {
     438            0 :     return m_object->item()->accessibleTextBeforeOffset(offset, muBoundaryType(boundaryType), startOffset, endOffset);
     439              : }
     440              : 
     441            0 : QString AccessibleItemInterface::textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType, int* startOffset,
     442              :                                                  int* endOffset) const
     443              : {
     444            0 :     return m_object->item()->accessibleTextAfterOffset(offset, muBoundaryType(boundaryType), startOffset, endOffset);
     445              : }
     446              : 
     447            0 : QString AccessibleItemInterface::textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType, int* startOffset,
     448              :                                               int* endOffset) const
     449              : {
     450            0 :     return m_object->item()->accessibleTextAtOffset(offset, muBoundaryType(boundaryType), startOffset, endOffset);
     451              : }
     452              : 
     453            0 : int AccessibleItemInterface::characterCount() const
     454              : {
     455            0 :     return m_object->item()->accessibleCharacterCount();
     456              : }
     457              : 
     458            0 : QRect AccessibleItemInterface::characterRect(int) const
     459              : {
     460            0 :     NOT_IMPLEMENTED;
     461              : 
     462            0 :     return QRect();
     463              : }
     464              : 
     465            0 : int AccessibleItemInterface::offsetAtPoint(const QPoint&) const
     466              : {
     467            0 :     NOT_IMPLEMENTED;
     468              : 
     469            0 :     return -1;
     470              : }
     471              : 
     472            0 : void AccessibleItemInterface::scrollToSubstring(int, int)
     473              : {
     474            0 :     NOT_IMPLEMENTED;
     475            0 : }
     476              : 
     477            0 : QString AccessibleItemInterface::attributes(int, int* startOffset, int* endOffset) const
     478              : {
     479            0 :     NOT_IMPLEMENTED;
     480              : 
     481            0 :     *startOffset = -1;
     482            0 :     *endOffset = -1;
     483            0 :     return QString();
     484              : }
     485              : 
     486            0 : bool AccessibleItemInterface::isSelected() const
     487              : {
     488            0 :     return m_object->item()->accessibleState(IAccessible::State::Selected);
     489              : }
     490              : 
     491            0 : QList<QAccessibleInterface*> AccessibleItemInterface::columnHeaderCells() const
     492              : {
     493            0 :     NOT_IMPLEMENTED;
     494            0 :     return QList<QAccessibleInterface*>();
     495              : }
     496              : 
     497            0 : QList<QAccessibleInterface*> AccessibleItemInterface::rowHeaderCells() const
     498              : {
     499            0 :     NOT_IMPLEMENTED;
     500            0 :     return QList<QAccessibleInterface*>();
     501              : }
     502              : 
     503            0 : int AccessibleItemInterface::columnIndex() const
     504              : {
     505            0 :     NOT_IMPLEMENTED;
     506            0 :     return 0;
     507              : }
     508              : 
     509            0 : int AccessibleItemInterface::rowIndex() const
     510              : {
     511            0 :     return m_object->item()->accessibleRowIndex();
     512              : }
     513              : 
     514            0 : int AccessibleItemInterface::columnExtent() const
     515              : {
     516            0 :     NOT_IMPLEMENTED;
     517            0 :     return 1;
     518              : }
     519              : 
     520            0 : int AccessibleItemInterface::rowExtent() const
     521              : {
     522            0 :     NOT_IMPLEMENTED;
     523            0 :     return 1;
     524              : }
     525              : 
     526            0 : QAccessibleInterface* AccessibleItemInterface::table() const
     527              : {
     528            0 :     return parent();
     529              : }
     530              : 
     531            0 : void* AccessibleItemInterface::interface_cast(QAccessible::InterfaceType type)
     532              : {
     533            0 :     QAccessible::Role itemRole = role();
     534            0 :     if (type == QAccessible::InterfaceType::ValueInterface && itemRole == QAccessible::Slider) {
     535            0 :         return static_cast<QAccessibleValueInterface*>(this);
     536            0 :     } else if (type == QAccessible::InterfaceType::TextInterface) {
     537            0 :         return static_cast<QAccessibleTextInterface*>(this);
     538              :     }
     539              : 
     540            0 :     bool isTableType = type == QAccessible::InterfaceType::TableCellInterface;
     541              : #ifdef Q_OS_WIN
     542              :     //! NOTE: Without Action and Text interfaces NVDA doesn't work
     543              :     isTableType |= type == QAccessible::InterfaceType::ActionInterface;
     544              : #endif
     545              : 
     546            0 :     if (isTableType && itemRole == QAccessible::ListItem) {
     547              :         //! NOTE: Without Action and Text interfaces NVDA doesn't work
     548            0 :         return static_cast<QAccessibleTableCellInterface*>(this);
     549              :     }
     550              : 
     551              :     //! NOTE Not implemented
     552            0 :     return nullptr;
     553              : }
     554              : 
     555            0 : IAccessible::TextBoundaryType AccessibleItemInterface::muBoundaryType(QAccessible::TextBoundaryType qtBoundaryType) const
     556              : {
     557            0 :     switch (qtBoundaryType) {
     558            0 :     case QAccessible::TextBoundaryType::CharBoundary: return IAccessible::CharBoundary;
     559            0 :     case QAccessible::TextBoundaryType::WordBoundary: return IAccessible::WordBoundary;
     560            0 :     case QAccessible::TextBoundaryType::SentenceBoundary: return IAccessible::SentenceBoundary;
     561            0 :     case QAccessible::TextBoundaryType::ParagraphBoundary: return IAccessible::ParagraphBoundary;
     562            0 :     case QAccessible::TextBoundaryType::LineBoundary: return IAccessible::LineBoundary;
     563            0 :     case QAccessible::TextBoundaryType::NoBoundary: return IAccessible::NoBoundary;
     564              :     }
     565              : 
     566            0 :     return IAccessible::NoBoundary;
     567              : }
     568              : 
     569            0 : QString AccessibleItemInterface::announcement() const
     570              : {
     571            0 :     if (auto controller = m_object->controller().lock()) {
     572              :         // Announcements override the current item's accessible name.
     573            0 :         if (m_object->item() == controller->lastFocused()) {
     574            0 :             return controller->announcement(); // Can be empty/null.
     575              :         }
     576            0 :     }
     577              : 
     578            0 :     return QString(); // Don't override the names of any other items.
     579              : }
     580              : 
     581            0 : QString AccessibleItemInterface::description() const
     582              : {
     583            0 :     IAccessible* item = m_object->item();
     584            0 :     QString desc = item->accessibleDescription(); // Can be empty/null.
     585              : 
     586            0 :     if (desc.isEmpty() || item->accessibleName().contains(desc, Qt::CaseInsensitive)) {
     587            0 :         return QString();
     588              :     }
     589              : 
     590            0 :     return desc;
     591            0 : }
        

Generated by: LCOV version 2.0-1