LCOV - code coverage report
Current view: top level - src/notation/internal - notationaccessibility.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 0.0 % 92 0
Test Date: 2026-11-05 04:07:02

            Line data    Source code
       1              : /*
       2              :  * SPDX-License-Identifier: GPL-3.0-only
       3              :  * MuseScore-Studio-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              : #include "notationaccessibility.h"
      24              : 
      25              : #include "translation.h"
      26              : 
      27              : #include "engraving/accessibility/accessibleroot.h"
      28              : #include "engraving/dom/masterscore.h"
      29              : #include "engraving/dom/measure.h"
      30              : #include "engraving/dom/part.h"
      31              : #include "engraving/dom/segment.h"
      32              : #include "engraving/dom/staff.h"
      33              : 
      34              : #include "igetscore.h"
      35              : #include "inotationinteraction.h" // IWYU pragma: keep
      36              : #include "notation.h"
      37              : 
      38              : using namespace mu::notation;
      39              : using namespace muse::async;
      40              : using namespace mu::engraving;
      41              : using namespace muse::accessibility;
      42              : 
      43            0 : NotationAccessibility::NotationAccessibility(const Notation* notation)
      44            0 :     : m_getScore(notation)
      45              : {
      46            0 :     notation->interaction()->selectionChanged().onNotify(this, [this]() {
      47            0 :         updateAccessibilityInfo();
      48            0 :     });
      49              : 
      50            0 :     notation->notationChanged().onReceive(this, [this](const muse::RectF&) {
      51            0 :         updateAccessibilityInfo();
      52            0 :     });
      53            0 : }
      54              : 
      55            0 : const mu::engraving::Score* NotationAccessibility::score() const
      56              : {
      57            0 :     return m_getScore->score();
      58              : }
      59              : 
      60            0 : const mu::engraving::Selection* NotationAccessibility::selection() const
      61              : {
      62            0 :     return &score()->selection();
      63              : }
      64              : 
      65            0 : muse::ValCh<std::string> NotationAccessibility::accessibilityInfo() const
      66              : {
      67            0 :     return m_accessibilityInfo;
      68              : }
      69              : 
      70            0 : void NotationAccessibility::setMapToScreenFunc(const AccessibleMapToScreenFunc& func)
      71              : {
      72              : #ifndef ENGRAVING_NO_ACCESSIBILITY
      73            0 :     score()->rootItem()->accessible()->accessibleRoot()->setMapToScreenFunc(func);
      74            0 :     score()->dummy()->rootItem()->accessible()->accessibleRoot()->setMapToScreenFunc(func);
      75              : #else
      76              :     UNUSED(func)
      77              : #endif
      78            0 : }
      79              : 
      80            0 : void NotationAccessibility::setEnabled(bool enabled)
      81              : {
      82              : #ifndef ENGRAVING_NO_ACCESSIBILITY
      83              :     std::vector<AccessibleRoot*> roots {
      84            0 :         score()->rootItem()->accessible()->accessibleRoot(),
      85            0 :         score()->dummy()->rootItem()->accessible()->accessibleRoot()
      86            0 :     };
      87              : 
      88            0 :     EngravingItem* selectedElement = selection()->element();
      89            0 :     AccessibleItemPtr selectedElementAccItem = selectedElement ? selectedElement->accessible() : nullptr;
      90              : 
      91            0 :     for (AccessibleRoot* root : roots) {
      92            0 :         root->setEnabled(enabled);
      93              : 
      94            0 :         if (!enabled) {
      95            0 :             root->setFocusedElement(nullptr);
      96            0 :             continue;
      97              :         }
      98              : 
      99            0 :         if (!selectedElementAccItem) {
     100            0 :             continue;
     101              :         }
     102              : 
     103            0 :         if (selectedElementAccItem->accessibleRoot() == root) {
     104            0 :             root->setFocusedElement(selectedElementAccItem);
     105              :         }
     106              :     }
     107              : #else
     108              :     UNUSED(enabled)
     109              : #endif
     110            0 : }
     111              : 
     112            0 : void NotationAccessibility::updateAccessibilityInfo()
     113              : {
     114            0 :     if (!score()) {
     115            0 :         return;
     116              :     }
     117              : 
     118            0 :     QString newAccessibilityInfo;
     119              : 
     120            0 :     if (selection()->isSingle()) {
     121            0 :         newAccessibilityInfo = singleElementAccessibilityInfo();
     122            0 :     } else if (selection()->isRange()) {
     123            0 :         newAccessibilityInfo = rangeAccessibilityInfo();
     124            0 :     } else if (selection()->isList()) {
     125            0 :         newAccessibilityInfo = muse::qtrc("notation", "List selection");
     126              :     }
     127              : 
     128              :     // Simplify whitespace and remove newlines
     129            0 :     newAccessibilityInfo = newAccessibilityInfo.simplified();
     130              : 
     131            0 :     setAccessibilityInfo(newAccessibilityInfo);
     132            0 : }
     133              : 
     134            0 : void NotationAccessibility::setAccessibilityInfo(const QString& info)
     135              : {
     136            0 :     std::string infoStd = info.toStdString();
     137              : 
     138            0 :     if (m_accessibilityInfo.val == infoStd) {
     139            0 :         return;
     140              :     }
     141              : 
     142            0 :     m_accessibilityInfo.set(infoStd);
     143            0 : }
     144              : 
     145            0 : QString NotationAccessibility::rangeAccessibilityInfo() const
     146              : {
     147            0 :     const mu::engraving::Segment* endSegment = selection()->endSegment();
     148              : 
     149            0 :     if (!endSegment) {
     150            0 :         endSegment = score()->lastSegment();
     151              :     } else {
     152            0 :         endSegment = endSegment->prev1MM();
     153              :     }
     154              : 
     155            0 :     EngravingItem::BarBeat startBarbeat = selection()->startSegment()->barbeat();
     156              : 
     157            0 :     QString start = muse::qtrc("engraving", "Start measure: %1").arg(String::number(startBarbeat.bar));
     158            0 :     if (startBarbeat.displayedBar != startBarbeat.bar) {
     159            0 :         start += "; " + muse::qtrc("engraving", "Start displayed measure: %1").arg(startBarbeat.displayedBar);
     160              :     }
     161            0 :     start += "; " + muse::qtrc("engraving", "Start beat: %1").arg(startBarbeat.beat);
     162              : 
     163            0 :     EngravingItem::BarBeat endBarbeat = endSegment->barbeat();
     164            0 :     QString end = muse::qtrc("engraving", "End measure: %1").arg(String::number(endBarbeat.bar));
     165            0 :     if (endBarbeat.displayedBar != endBarbeat.bar) {
     166            0 :         end += "; " + muse::qtrc("engraving", "End displayed measure: %1").arg(endBarbeat.displayedBar);
     167              :     }
     168            0 :     end += "; " + muse::qtrc("engraving", "End beat: %1").arg(endBarbeat.beat);
     169              : 
     170            0 :     return muse::qtrc("notation", "Range selection; %1; %2")
     171            0 :            .arg(start)
     172            0 :            .arg(end);
     173            0 : }
     174              : 
     175            0 : QString NotationAccessibility::singleElementAccessibilityInfo() const
     176              : {
     177            0 :     const EngravingItem* element = selection()->element();
     178            0 :     if (!element) {
     179            0 :         return QString();
     180              :     }
     181              : 
     182            0 :     QString accessibilityInfo = element->accessibleInfo();
     183            0 :     QString barsAndBeats = element->formatBarsAndBeats();
     184              : 
     185            0 :     if (!barsAndBeats.isEmpty()) {
     186            0 :         accessibilityInfo += "; " + barsAndBeats;
     187              :     }
     188              : 
     189            0 :     if (element->hasStaff()) {
     190            0 :         QString staff = muse::qtrc("notation", "Staff %1").arg(QString::number(element->staffIdx() + 1));
     191              : 
     192            0 :         QString staffName = element->originPart()->longName(element->tick());
     193            0 :         if (staffName.isEmpty()) {
     194            0 :             staffName = element->originPart()->partName();
     195              :         }
     196              : 
     197            0 :         if (staffName.isEmpty()) {
     198            0 :             accessibilityInfo = QString("%1; %2").arg(accessibilityInfo).arg(staff);
     199              :         } else {
     200            0 :             accessibilityInfo = QString("%1; %2 (%3)").arg(accessibilityInfo).arg(staff).arg(staffName);
     201              :         }
     202            0 :     }
     203              : 
     204            0 :     return accessibilityInfo;
     205            0 : }
        

Generated by: LCOV version 2.0-1