LCOV - code coverage report
Current view: top level - muse/framework/accessibility/internal - accessibilitycontroller.h Coverage Total Hit
Test: filtered_coverage.info Lines: 50.0 % 2 1
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              : 
      23              : #pragma once
      24              : 
      25              : #include <memory>
      26              : #include <QObject>
      27              : #include <QList>
      28              : #include <QHash>
      29              : #include <QTimer>
      30              : 
      31              : #include "global/async/asyncable.h"
      32              : #include "global/async/channel.h"
      33              : #include "global/iapplication.h"
      34              : 
      35              : #include "modularity/ioc.h"
      36              : #include "../iaccessibleapprootobject.h"
      37              : #include "../iaccessibilitycontroller.h"
      38              : #include "accessibleobject.h"
      39              : #include "interactive/iinteractive.h"
      40              : #include "ui/imainwindow.h"
      41              : #include "ui/inavigationcontroller.h"
      42              : #include "rcommand/icommanddispatcher.h"
      43              : #include "rcommand/icommandsregister.h"
      44              : 
      45              : #include "muse_framework_config.h"
      46              : #ifdef MUSE_MODULE_ACTIONS_SUPPORT
      47              : #include "actions/iactionsdispatcher.h"
      48              : #include "ui/iuiactionsregister.h"
      49              : #endif
      50              : 
      51              : class QAccessibleInterface;
      52              : class QAccessibleEvent;
      53              : 
      54              : namespace muse::diagnostics {
      55              : class DiagnosticAccessibleModel;
      56              : }
      57              : 
      58              : namespace muse::accessibility {
      59              : class AccessibilityController : public IAccessibilityController, public IAccessible, public muse::Contextable, public async::Asyncable,
      60              :     public std::enable_shared_from_this<AccessibilityController>
      61              : {
      62              : public:
      63              :     GlobalInject<IApplication> application;
      64              :     GlobalInject<IAccessibleAppRootObject> appRootObject;
      65              :     GlobalInject<rcommand::ICommandsRegister> commandsRegister;
      66              :     ContextInject<IInteractive> interactive = { this };
      67              :     ContextInject<ui::IMainWindow> mainWindow = { this };
      68              :     ContextInject<ui::INavigationController> navigationController = { this };
      69              :     ContextInject<rcommand::ICommandDispatcher> commandDispatcher = { this };
      70              : 
      71              : #ifdef MUSE_MODULE_ACTIONS_SUPPORT
      72              :     ContextInject<actions::IActionsDispatcher> actionsDispatcher = { this };
      73              :     ContextInject<ui::IUiActionsRegister> actionsRegister = { this };
      74              : #endif
      75              : 
      76              : public:
      77              :     AccessibilityController(const muse::modularity::ContextPtr& iocCtx);
      78              :     ~AccessibilityController() override;
      79              : 
      80              :     static QAccessibleInterface* accessibleInterface(QObject* object);
      81              : 
      82              :     void setAccessibilityEnabled(bool enabled);
      83              :     void deinit();
      84              : 
      85              :     // IAccessibilityController
      86              :     void reg(IAccessible* item) override;
      87              :     void unreg(IAccessible* item) override;
      88              :     bool isReg(IAccessible* item) const override;
      89              : 
      90              :     void announce(const QString& announcement) override;
      91              :     QString announcement() const override;
      92              : 
      93              :     const IAccessible* accessibleRoot() const override;
      94              :     const IAccessible* lastFocused() const override;
      95              : 
      96              :     bool needToVoicePanelInfo() const override;
      97              :     QString currentPanelAccessibleName() const override;
      98              : 
      99              :     bool isEnabled() const override;
     100              : 
     101              :     void setIgnoreQtAccessibilityEvents(bool ignore) override;
     102              : 
     103              :     // -----
     104              : 
     105              :     // IAccessibility (root)
     106              :     IAccessible* accessibleParent() const override;
     107              : 
     108              :     size_t accessibleChildCount() const override;
     109              :     IAccessible* accessibleChild(size_t i) const override;
     110              : 
     111              :     QWindow* accessibleWindow() const override;
     112              :     muse::modularity::ContextPtr iocContext() const override;
     113              : 
     114              :     Role accessibleRole() const override;
     115              :     QString accessibleName() const override;
     116              :     QString accessibleDescription() const override;
     117              :     bool accessibleState(State st) const override;
     118              :     QRect accessibleRect() const override;
     119              :     bool accessibleIgnored() const override;
     120              : 
     121              :     // Value Interface
     122              :     QVariant accessibleValue() const override;
     123              :     QVariant accessibleMaximumValue() const override;
     124              :     QVariant accessibleMinimumValue() const override;
     125              :     QVariant accessibleValueStepSize() const override;
     126              : 
     127              :     // Text Interface
     128              :     void accessibleSelection(int selectionIndex, int* startOffset, int* endOffset) const override;
     129              :     int accessibleSelectionCount() const override;
     130              : 
     131              :     int accessibleCursorPosition() const override;
     132              : 
     133              :     QString accessibleText(int startOffset, int endOffset) const override;
     134              :     QString accessibleTextBeforeOffset(int offset, TextBoundaryType boundaryType, int* startOffset, int* endOffset) const override;
     135              :     QString accessibleTextAfterOffset(int offset, TextBoundaryType boundaryType, int* startOffset, int* endOffset) const override;
     136              :     QString accessibleTextAtOffset(int offset, TextBoundaryType boundaryType, int* startOffset, int* endOffset) const override;
     137              :     int accessibleCharacterCount() const override;
     138              : 
     139              :     // ListView item Interface
     140              :     int accessibleRowIndex() const override;
     141              : 
     142              :     async::Channel<Property, Val> accessiblePropertyChanged() const override;
     143              :     async::Channel<State, bool> accessibleStateChanged() const override;
     144              : 
     145              :     void setState(State state, bool arg) override;
     146              :     // -----
     147              : 
     148              :     QAccessibleInterface* parentIface(const IAccessible* item) const;
     149              :     int childCount(const IAccessible* item) const;
     150              :     QAccessibleInterface* child(const IAccessible* item, int i) const;
     151              :     int indexOfChild(const IAccessible* item, const QAccessibleInterface* iface) const;
     152              :     QAccessibleInterface* focusedChild(const IAccessible* item) const;
     153              : 
     154              :     IAccessible* pretendFocus() const;
     155              :     async::Channel<QAccessibleEvent*> eventSent() const;
     156              : 
     157              : private:
     158              : 
     159              :     friend class muse::diagnostics::DiagnosticAccessibleModel;
     160              : 
     161              :     struct Item
     162              :     {
     163              :         IAccessible* item = nullptr;
     164              :         AccessibleObject* object = nullptr;
     165              :         QAccessibleInterface* iface = nullptr;
     166              : 
     167           12 :         bool isValid() const { return item != nullptr; }
     168            0 :         bool isUsable() const { return item && iface && !item->accessibleIgnored(); }
     169              :     };
     170              : 
     171              :     void init();
     172              : 
     173              :     const Item& findItem(const IAccessible* aitem) const;
     174              : 
     175              :     void propertyChanged(IAccessible* item, IAccessible::Property property, const Val& value);
     176              :     void stateChanged(IAccessible* item, IAccessible::State state, bool arg);
     177              : 
     178              :     void sendEvent(QAccessibleEvent* ev);
     179              : 
     180              :     void cancelPreviousReading();
     181              :     void savePanelAccessibleName(const IAccessible* oldItem, const IAccessible* newItem);
     182              :     bool needsRevoicing(const QAccessibleInterface& iface, QAccessible::Event eventType) const;
     183              :     void triggerRevoicing(const Item& current);
     184              :     void restoreFocus();
     185              :     void setExternalFocus(const Item& other);
     186              : 
     187              :     const IAccessible* panel(const IAccessible* item) const;
     188              : 
     189              :     const Item& findSiblingItem(const Item& parent, const Item& current) const;
     190              : 
     191              :     QHash<const IAccessible*, Item> m_allItems;
     192              : 
     193              :     QList<IAccessible*> m_children;
     194              :     async::Channel<QAccessibleEvent*> m_eventSent;
     195              :     IAccessible* m_lastFocused = nullptr;
     196              :     IAccessible* m_pretendFocus = nullptr;
     197              :     QTimer m_pretendFocusTimer;
     198              :     QString m_announcement;
     199              : 
     200              :     IAccessible* m_preDispatchFocus = nullptr;
     201              :     QString m_preDispatchName;
     202              : 
     203              :     bool m_inited = false;
     204              :     bool m_enabled = false;
     205              :     bool m_treeConnected = false;
     206              : 
     207              :     bool m_ignorePanelChangingVoice = false;
     208              :     bool m_needToVoicePanelInfo = false;
     209              : };
     210              : }
        

Generated by: LCOV version 2.0-1