Skip to content

Fuzzy text search, part 0: Allow subclassing filters and sorters of SortFilterProxyModel#14

Open
juli27 wants to merge 6 commits into
musescore:mainfrom
juli27:refactorSFPM
Open

Fuzzy text search, part 0: Allow subclassing filters and sorters of SortFilterProxyModel#14
juli27 wants to merge 6 commits into
musescore:mainfrom
juli27:refactorSFPM

Conversation

@juli27
Copy link
Copy Markdown
Contributor

@juli27 juli27 commented May 9, 2026

This is a prerequisite part for my effort to implement fuzzy search in MSS. (musescore/MuseScore#15983)
This aligns our SortFilterProxyModel a bit closer to Qt's new-ish Qml SortFilterProxyModel, while allowing custom filters and sorters.
MuseScore Studio builds over at the previous home of these changes: musescore/MuseScore#33052.

Also used GitHub code search in the Audacity repo to check for uses of the removed methods. The changes shouldn't be breaking.

  • I signed the CLA
  • The title of the PR describes the problem it addresses
  • Each commit's message describes its purpose and effects, and references the issue it resolves
  • If changes are extensive, there is a sequence of easily reviewable commits
  • The code in the PR follows the coding rules
  • There are no unnecessary changes
  • The code compiles and runs on my machine, preferably after each commit individually
  • I created a unit test or vtest to verify the changes I made (if applicable)

Build configuration

audacity: audacity/audacity/master
audacity platforms: linux_x64
musescore: musescore/MuseScore/master
musescore platforms: linux_x64 windows_x64 macos

juli27 added 3 commits May 20, 2026 23:08
- Remove unused private method `reset()`
- Remove unused invokable method `refresh()`
- Remove unused signal `filtersChanged`
  - it is never emitted
- expose roleIdFromName (formerly roleKey)
  - this is needed by later commits
This prevented multiple filters from using the same role.
Also, filter subclasses won't necessarily operate on a single role.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 20, 2026

Review Change Stack

Warning

Rate limit exceeded

@juli27 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 25 minutes and 37 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 918460ce-5c07-4ab0-b2c1-f45051becc2e

📥 Commits

Reviewing files that changed from the base of the PR and between 27c25fc and 0449568.

📒 Files selected for processing (14)
  • framework/uicomponents/qml/Muse/UiComponents/CMakeLists.txt
  • framework/uicomponents/qml/Muse/UiComponents/ValueList.qml
  • framework/uicomponents/qml/Muse/UiComponents/filter.cpp
  • framework/uicomponents/qml/Muse/UiComponents/filter.h
  • framework/uicomponents/qml/Muse/UiComponents/filtervalue.cpp
  • framework/uicomponents/qml/Muse/UiComponents/filtervalue.h
  • framework/uicomponents/qml/Muse/UiComponents/sorter.cpp
  • framework/uicomponents/qml/Muse/UiComponents/sorter.h
  • framework/uicomponents/qml/Muse/UiComponents/sortervalue.cpp
  • framework/uicomponents/qml/Muse/UiComponents/sortervalue.h
  • framework/uicomponents/qml/Muse/UiComponents/sortfilterproxymodel.cpp
  • framework/uicomponents/qml/Muse/UiComponents/sortfilterproxymodel.h
  • framework/uicomponents/qml/Muse/UiComponents/tests/CMakeLists.txt
  • framework/uicomponents/qml/Muse/UiComponents/tests/sortfilterproxymodel_tests.cpp
📝 Walkthrough

Walkthrough

This pull request refactors the UI components filtering and sorting architecture from concrete FilterValue and SorterValue types to abstract Filter and Sorter base classes. Two new base classes introduce enabled, async (for filters) and sortOrder, enabled (for sorters) properties, with pure virtual methods acceptsRow(...) and lessThan(...) respectively. FilterValue and SorterValue are refactored to inherit from these bases, removing duplicate property declarations. SortFilterProxyModel is updated to operate polymorphically on the base types, delegating filtering and sorting logic to filter and sorter instances. Role ID mapping is changed from an int-based hash to a QByteArray-keyed storage. QML and build configuration are updated to integrate the new classes, and comprehensive tests validate filtering across multiple compare modes and sorting with proper ordering.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: allowing subclassing of filters and sorters in SortFilterProxyModel, which is the core purpose of this refactoring PR.
Description check ✅ Passed The PR description comprehensively covers the motivation, context, and validation performed. All checklist items are marked complete, including CLA signing, descriptive commits, coding standards compliance, and unit tests.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@framework/uicomponents/qml/Muse/UiComponents/filtervalue.cpp`:
- Around line 42-44: The code dereferences proxyModel.sourceModel() without a
null check; modify the logic around the call that gets sourceModel (the const
QAbstractItemModel* sourceModel = proxyModel.sourceModel() line) to test for
nullptr before using it (e.g., if sourceModel is null, bail out early or return
the appropriate default/false), so subsequent calls to sourceModel->index(...)
and sourceModel->data(...) are only executed when sourceModel is valid; update
the surrounding function (where index and data are used) to handle the null-case
consistently.

In `@framework/uicomponents/qml/Muse/UiComponents/sortervalue.cpp`:
- Around line 42-44: The code calls proxyModel.sourceModel() in sortervalue.cpp
and immediately dereferences it; add a null check for the returned
QAbstractItemModel* (e.g., store into a local const QAbstractItemModel*
sourceModel and if sourceModel is nullptr) before calling sourceModel->data(...)
to avoid dereferencing null (mirror the guard used in FilterValue::acceptsRow);
if null, handle appropriately (return a safe default/abort the comparison)
inside the SorterValue comparison logic so subsequent lines using sourceModel,
sourceLeft, and sourceRight are only executed when sourceModel is valid.

In `@framework/uicomponents/qml/Muse/UiComponents/sortfilterproxymodel.cpp`:
- Around line 44-51: The code uses inconsistent enum qualification for the
filter change direction: inside the invalidateRows lambda (function
invalidateRows) it calls endFilterChange(Direction::Rows) while elsewhere (e.g.,
where endFilterChange is called around line 120) the fully qualified
QSortFilterProxyModel::Direction::Rows is used; update the lambda to use the
same fully qualified enum (QSortFilterProxyModel::Direction::Rows) so enum
references are consistent across beginFilterChange/endFilterChange and the
invalidateRows lambda.

In
`@framework/uicomponents/qml/Muse/UiComponents/tests/sortfilterproxymodel_tests.cpp`:
- Around line 61-157: Add a regression test that verifies SortFilterProxyModel
dispatches to subclasses of Filter and Sorter by creating minimal test-double
subclasses (e.g., class TestFilter : public Filter and class TestSorter : public
Sorter) that override the base virtual methods (match/filter and compare/sort),
instantiate them, append them to proxyModel->filters() and
proxyModel->sorters(), and assert the proxyModel behavior changes according to
those overrides; place this alongside the existing tests (e.g.,
testFilterValue/testSorterValue) and use the same helper listModel(),
QQmlListProperty append pattern to attach the test doubles so you confirm
subclass polymorphism works through the Filter/Sorter contracts.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4f2118b7-4a6a-4f45-aef3-23870cbc2234

📥 Commits

Reviewing files that changed from the base of the PR and between 0fc3b4e and 27c25fc.

📒 Files selected for processing (16)
  • framework/ui/internal/uiconfiguration.cpp
  • framework/ui/internal/uicontextconfiguration.cpp
  • framework/uicomponents/qml/Muse/UiComponents/CMakeLists.txt
  • framework/uicomponents/qml/Muse/UiComponents/ValueList.qml
  • framework/uicomponents/qml/Muse/UiComponents/filter.cpp
  • framework/uicomponents/qml/Muse/UiComponents/filter.h
  • framework/uicomponents/qml/Muse/UiComponents/filtervalue.cpp
  • framework/uicomponents/qml/Muse/UiComponents/filtervalue.h
  • framework/uicomponents/qml/Muse/UiComponents/sorter.cpp
  • framework/uicomponents/qml/Muse/UiComponents/sorter.h
  • framework/uicomponents/qml/Muse/UiComponents/sortervalue.cpp
  • framework/uicomponents/qml/Muse/UiComponents/sortervalue.h
  • framework/uicomponents/qml/Muse/UiComponents/sortfilterproxymodel.cpp
  • framework/uicomponents/qml/Muse/UiComponents/sortfilterproxymodel.h
  • framework/uicomponents/qml/Muse/UiComponents/tests/CMakeLists.txt
  • framework/uicomponents/qml/Muse/UiComponents/tests/sortfilterproxymodel_tests.cpp
💤 Files with no reviewable changes (1)
  • framework/ui/internal/uiconfiguration.cpp

Comment thread framework/uicomponents/qml/Muse/UiComponents/filtervalue.cpp
Comment thread framework/uicomponents/qml/Muse/UiComponents/sortervalue.cpp
@juli27 juli27 force-pushed the refactorSFPM branch 2 times, most recently from f19df01 to c4563a7 Compare May 20, 2026 21:28
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.

1 participant