Skip to content

Conversation

@Jojo-Schmitz
Copy link
Owner

@Jojo-Schmitz Jojo-Schmitz commented Aug 17, 2025

Backport of musescore#27244

Resolves: musescore#27204

@Jojo-Schmitz Jojo-Schmitz force-pushed the 3.x-spannerproperties branch 2 times, most recently from eedf96b to caff196 Compare August 17, 2025 09:50
Backport of musescore#27244

Cleanup other `propertyDelegate()`s (use `switch` and sort their `Pid`s alphabetical)
@Jojo-Schmitz Jojo-Schmitz force-pushed the 3.x-spannerproperties branch from caff196 to 46eb623 Compare August 17, 2025 12:18
@Jojo-Schmitz Jojo-Schmitz merged commit 79b8587 into 3.x Aug 19, 2025
manolo added a commit to manolo/MuseScore that referenced this pull request Nov 16, 2025
    Problem:
    --------
    While PR musescore#27204 (musescore#27204) and PR musescore#1006
    (Jojo-Schmitz#1006) fixed property delegation from
    SpannerSegment to parent Spanner objects, plugins still have no way
    to iterate through or access the spanners collection in a score
    preventing plugins from:

    - Finding hairpins to disable playback
    - Modifying slur properties across the score
    - Accessing other spanner types (ottavas, pedal lines, etc.)

    Currently, spanners cannot be accessed via:
    - note.spannerForward (only works for tied/slurred notes)
    - segment.annotations (only contains dynamics, expressions, etc.)
    - segment.elementAt() (doesn't return spanners)
    - system.spannerSegments (not exposed to Plugin API)

    Solution:
    ---------
    Expose the spanners collection as a QML property on Score, similar
    to existing collections (parts, staves, pages, systems).

    Changes:
    1. Implemented Score::spannerList() in dom/score.cpp to convert internal multimap to vector
    2. Declared spannerList() in dom/score.h (declaration already existed)
    3. Added Q_PROPERTY spanners to api/v1/score.h
    4. Implemented QML wrapper in api/v1/score.cpp
    5. Comprehensive test validating access and properties in spanners_tests.cpp

    Usage in plugins:
    -----------------
    // Iterate all spanners in the score
    for (var i = 0; i < curScore.spanners.length; i++) {
        var spanner = curScore.spanners[i];

        // Check spanner type
        if (spanner.type === Element.HAIRPIN) {
            spanner.play = false;  // Disable hairpin playback
        } else if (spanner.type === Element.SLUR) {
            // Modify slur properties
        }
    }

    Related:
    --------
    - Issue musescore#27204: Property delegation fix for SpannerSegment
    - PR musescore#1006: Added SPANNER_TICK/SPANNER_TICKS to propertyDelegate
manolo added a commit to manolo/MuseScore that referenced this pull request Nov 16, 2025
    Problem:
    --------
    While Issue [musescore#27204](musescore#27204) and
    PR [musescore#1006](Jojo-Schmitz#1006) fixed property delegation from
    SpannerSegment to parent Spanner objects, plugins still have no way
    to iterate through or access the spanners collection in a score
    preventing plugins from:

    - Finding hairpins to disable playback
    - Modifying slur properties across the score
    - Accessing other spanner types (ottavas, pedal lines, etc.)

    Currently, spanners cannot be accessed via:
    - note.spannerForward (only works for tied/slurred notes)
    - segment.annotations (only contains dynamics, expressions, etc.)
    - segment.elementAt() (doesn't return spanners)
    - system.spannerSegments (not exposed to Plugin API)

    Solution:
    ---------
    Expose the spanners collection as a QML property on Score, similar
    to existing collections (parts, staves, pages, systems).

    Changes:
    1. Implemented Score::spannerList() in dom/score.cpp to convert internal multimap to vector
    2. Declared spannerList() in dom/score.h (declaration already existed)
    3. Added Q_PROPERTY spanners to api/v1/score.h
    4. Implemented QML wrapper in api/v1/score.cpp
    5. Comprehensive test validating access and properties in spanners_tests.cpp

    Usage in plugins:
    -----------------
    // Remove slurs when adapting violin part to bandurria (bandurria is plucked, cannot do legato like violin)
    for (var i = 0; i < curScore.spanners.length; i++) {
        var spanner = curScore.spanners[i];
        if (spanner.type === Element.SLUR &&
            spanner.track >= bandurriaPart.startTrack &&
            spanner.track < bandurriaPart.endTrack) {
            removeElement(spanner);
        }
    }

    Related:
    --------
    - Issue [musescore#27204](musescore#27204): Property delegation fix for SpannerSegment
    - PR [#1006i](Jojo-Schmitz#1006): Added SPANNER_TICK/SPANNER_TICKS to propertyDelegate
manolo added a commit to manolo/MuseScore that referenced this pull request Nov 25, 2025
    Problem:
    --------
    While Issue [musescore#27204](musescore#27204) and
    PR [musescore#1006](Jojo-Schmitz#1006) fixed property delegation from
    SpannerSegment to parent Spanner objects, plugins still have no way
    to iterate through or access the spanners collection in a score
    preventing plugins from:

    - Finding hairpins to disable playback
    - Modifying slur properties across the score
    - Accessing other spanner types (ottavas, pedal lines, etc.)

    Currently, spanners cannot be accessed via:
    - note.spannerForward (only works for tied/slurred notes)
    - segment.annotations (only contains dynamics, expressions, etc.)
    - segment.elementAt() (doesn't return spanners)
    - system.spannerSegments (not exposed to Plugin API)

    Solution:
    ---------
    Expose the spanners collection as a QML property on Score, similar
    to existing collections (parts, staves, pages, systems).

    Changes:
    1. Implemented Score::spannerList() in dom/score.cpp to convert internal multimap to vector
    2. Declared spannerList() in dom/score.h (declaration already existed)
    3. Added Q_PROPERTY spanners to api/v1/score.h
    4. Implemented QML wrapper in api/v1/score.cpp
    5. Comprehensive test validating access and properties in spanners_tests.cpp

    Usage in plugins:
    -----------------
    // Remove slurs when adapting violin part to bandurria (bandurria is plucked, cannot do legato like violin)
    for (var i = 0; i < curScore.spanners.length; i++) {
        var spanner = curScore.spanners[i];
        if (spanner.type === Element.SLUR &&
            spanner.track >= bandurriaPart.startTrack &&
            spanner.track < bandurriaPart.endTrack) {
            removeElement(spanner);
        }
    }

    Related:
    --------
    - Issue [musescore#27204](musescore#27204): Property delegation fix for SpannerSegment
    - PR [#1006i](Jojo-Schmitz#1006): Added SPANNER_TICK/SPANNER_TICKS to propertyDelegate
igorkorsukov pushed a commit to musescore/MuseScore that referenced this pull request Nov 25, 2025
    Problem:
    --------
    While Issue [#27204](#27204) and
    PR [#1006](Jojo-Schmitz#1006) fixed property delegation from
    SpannerSegment to parent Spanner objects, plugins still have no way
    to iterate through or access the spanners collection in a score
    preventing plugins from:

    - Finding hairpins to disable playback
    - Modifying slur properties across the score
    - Accessing other spanner types (ottavas, pedal lines, etc.)

    Currently, spanners cannot be accessed via:
    - note.spannerForward (only works for tied/slurred notes)
    - segment.annotations (only contains dynamics, expressions, etc.)
    - segment.elementAt() (doesn't return spanners)
    - system.spannerSegments (not exposed to Plugin API)

    Solution:
    ---------
    Expose the spanners collection as a QML property on Score, similar
    to existing collections (parts, staves, pages, systems).

    Changes:
    1. Implemented Score::spannerList() in dom/score.cpp to convert internal multimap to vector
    2. Declared spannerList() in dom/score.h (declaration already existed)
    3. Added Q_PROPERTY spanners to api/v1/score.h
    4. Implemented QML wrapper in api/v1/score.cpp
    5. Comprehensive test validating access and properties in spanners_tests.cpp

    Usage in plugins:
    -----------------
    // Remove slurs when adapting violin part to bandurria (bandurria is plucked, cannot do legato like violin)
    for (var i = 0; i < curScore.spanners.length; i++) {
        var spanner = curScore.spanners[i];
        if (spanner.type === Element.SLUR &&
            spanner.track >= bandurriaPart.startTrack &&
            spanner.track < bandurriaPart.endTrack) {
            removeElement(spanner);
        }
    }

    Related:
    --------
    - Issue [#27204](#27204): Property delegation fix for SpannerSegment
    - PR [#1006i](Jojo-Schmitz#1006): Added SPANNER_TICK/SPANNER_TICKS to propertyDelegate
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants