Skip to content

Fix #35279, #35280: Move tuplets correctly when Insert adds time or time is removed - #35282

Open
davidstephengrant wants to merge 2 commits into
musescore:mainfrom
davidstephengrant:dsg-tuplet-remove-time
Open

davidstephengrant wants to merge 2 commits into
musescore:mainfrom
davidstephengrant:dsg-tuplet-remove-time

Conversation

@davidstephengrant

Copy link
Copy Markdown
Contributor

Resolves: #35279
Resolves: #35280

Follow-up to #35261, which made Insert move the tuplets after the insertion point.

Both now change the tuplets' ticks directly, without propagation. Unit tests cover Insert and remove time with stave sharing, remove time before a tuplet, and removing inserted time before a nested tuplet.

Screen.Recording.2026-10-18.at.11.19.41.mov

Assisted by Claude Code 2.1.290 (Claude Opus 5.5)

@davidstephengrant
davidstephengrant marked this pull request as ready for review October 19, 2026 08:34
@coderabbitai

coderabbitai Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: musescore/MuseScore/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: d16900f0-21de-4c44-b8ed-68883c6ae646
📥 Commits

Reviewing files that changed from the base of the PR and between 4457125 and 34a3017.

📒 Files selected for processing: 2
  • src/engraving/editing/edit.cpp
  • src/engraving/editing/noteinput.cpp

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.

📝 Walkthrough

Time insertion now independently shifts only tuplets without origin items. Time deletion collects later tuplets, including nested tuplets without origin items, and shifts their ticks after segment movement. New fixtures and tests cover shared-staff, triplet, and nested-tuplet edits, including undo and redo.

Priority: ➖ Normal

Severity of issue fixed: Medium

Merge Risk: ⚪ Minimal · up to 34a30

The reviewed time-edit paths have no established issue requiring a fix before merge.

Pre-merge checks: Passed 3 · Failed 2

Failed Failed checks: 2 warnings

Check name Status Explanation Resolution
Description check Warning The description explains both issues, the root causes, the fix, and the test coverage. However, it omits the required checklist and does not mark the AI-assistance checkbox or list the tool used in th… Complete the template checklist accurately. Mark applicable items, including the unit-test and AI-assistance items, and list Claude Code 2.1.290 in the AI tools section. Confirm the remaining checklist items before submission.
Docstring Coverage Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 4 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 3 passed
Check name Status Explanation
Title check Passed The title clearly identifies the two resolved issues and the main change: moving tuplets correctly when time is inserted or removed.
Linked Issues check Passed The changes address both active linked issues. For #35279, insertChordByInsertingTime excludes tuplets with shared origins from independent shifting, so shared and origin copies do not move twice. T…
Out of Scope Changes check Passed The source changes are limited to tuplet tick handling during time insertion and time deletion. The fixture and test changes support the linked regression cases. No unrelated product behavior or unrel…
Full details: Linked Issues check

Explanation

The changes address both active linked issues. For #35279, insertChordByInsertingTime excludes tuplets with shared origins from independent shifting, so shared and origin copies do not move twice. The stave-sharing test covers insertion, undo, redo, removal, and measure validity. For #35280, Score::doTimeDeleteForMeasure collects affected nested tuplets and shifts their ticks with the later segments. Tests cover direct removal, removal of inserted time, nested tuplets, tuplet deletion, undo/redo, and score sanity.

Full details: Out of Scope Changes check

Explanation

The source changes are limited to tuplet tick handling during time insertion and time deletion. The fixture and test changes support the linked regression cases. No unrelated product behavior or unrelated file changes are demonstrated.

Full details: Description check

Explanation

The description explains both issues, the root causes, the fix, and the test coverage. However, it omits the required checklist and does not mark the AI-assistance checkbox or list the tool used in the required section.

Resolution

Complete the template checklist accurately. Mark applicable items, including the unit-test and AI-assistance items, and list Claude Code 2.1.290 in the AI tools section. Confirm the remaining checklist items before submission.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Warning

Linked repositories: Public OSS repositories can only analyze public repositories installed in this organization. No linked repositories were analyzed; skipped musescore/muse_framework.git.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Comment thread src/engraving/editing/edit.cpp Outdated

// shared and origin tuplets are both in the set: don't propagate
for (Tuplet* t : tuplets) {
undo(new ChangeProperty(t, Pid::TICK, t->tick() - len));

@miiizen miiizen Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer it if we filtered the set so it only contained main and origin items and continued to use undoChangeProperty. Same in noteinput

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in both places: shared tuplets are now filtered out and the rest use undoChangeProperty again.

With stave sharing on, Insert collected the tuplets of both the origin staves and the shared staff, and undoChangeProperty(Pid::TICK) also propagated each change to the shared or origin copy, so tuplets moved by twice the inserted length. Deleting one of them later corrupted the measure.

Leave shared tuplets out of the set: they follow their origin.

Assisted-by: Claude Code 2.1.290 (Claude Opus 5.5)
Score::doTimeDeleteForMeasure() moved the measure's later segments back but not the ticks that tuplets store, so a tuplet after the removed time kept its old tick. Deleting that tuplet then put its rest at the old position, corrupting the measure. Since Insert moves tuplets forward, removing inserted time always left this state.

Move those tuplets back with their segments, leaving shared tuplets to follow their origin, as Insert does.

Assisted-by: Claude Code 2.1.290 (Claude Opus 5.5)

This branch has not been deployed

No deployments
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.

Corruption when deleting a tuplet after removing time before it Corruption when deleting a tuplet of a shared instrument after inserting a note

2 participants