Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 8 additions & 9 deletions src/engraving/rendering/score/headerfooterlayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ TextBlock HeaderFooterLayout::replaceTextMacros(LayoutContext& ctx, const Page*
}

for (size_t i = 0, n = s.size(); i < n; ++i) {
const auto dateFormat = muse::DateFormat::LocaleShortFormat;

@Jojo-Schmitz Jojo-Schmitz Jun 12, 2026

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.

@coderabbitai: Is there a way to find out at compile time whether a build is for the backend on musescore.com?
I'd want MuseScore Studio to use the current locale`s format, but would want to keep ISO format on musescore.com rather than having it show the (IMHO sick, for sure confusing) US format (MM/DD/YYYY)

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.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for backend-related preprocessor defines or CMake options
rg -rn --type=cpp --type=cmake -i 'backend|musescore\.com|server.build|cloud.build|MUSECORE_COM' -C2 | head -80

# Also check top-level CMakeLists for any backend/server options
grep -n -i 'backend\|server\|cloud\|MUSE_APP' CMakeLists.txt 2>/dev/null | head -40

# Check for any build type defines
rg -rn 'MUSE_APP\|BUILD_TYPE\|APP_TYPE\|BACKEND' --include='*.h' --include='*.cmake' --include='CMakeLists.txt' -C2 | head -80

Length of output: 8984


🏁 Script executed:

#!/bin/bash
# Look at MUSE_APP_BUILD_MODE definition and its possible values
sed -n '70,120p' CMakeLists.txt

# Search for all usages of MUSE_APP_BUILD_MODE
rg -rn 'MUSE_APP_BUILD_MODE' -C2 | head -100

# Also look for any "backend" or "server" string in CMakeLists
rg -rn -i 'backend\|BUILD_FOR_SERVER\|HEADLESS\|NO_GUI' CMakeLists.txt | head -40

Length of output: 8279


🏁 Script executed:

#!/bin/bash
# Look at the full backend build script
cat buildscripts/ci/backend/build.sh

# Look at SetupConfigure.cmake to see how build config becomes C++ defines
cat SetupConfigure.cmake 2>/dev/null || fd -i 'SetupConfigure.cmake' --exec cat {}

# Check if BUILD_CONFIGURATION or similar ends up as a C++ preprocessor define
rg -rn 'add_compile_definitions\|add_definitions\|target_compile_definitions' --type=cmake | grep -i 'BUILD_CONFIGURATION\|BUILD_MODE\|APP_WEB\|BACKEND' | head -30

Length of output: 16155


🏁 Script executed:

#!/bin/bash
# Check app_config.h.in for compile-time defines
fd -i 'app_config.h.in' --exec cat {}

# Also check if backend CI script passes any special CMake flags
grep -n 'MUSESCORE_BUILD_CONFIGURATION\|BUILD_CONFIGURATION\|BACKEND\|configure' buildscripts/ci/backend/build.sh

Length of output: 3065



@Jojo-Schmitz — there is no existing compile-time flag that distinguishes a backend/musescore.com build from a regular Studio build. The buildscripts/ci/backend/build.sh script does not set a special MUSESCORE_BUILD_CONFIGURATION; it falls through to the default "app" configuration, so backend builds are currently indistinguishable from desktop builds at compile time.

However, the codebase has a well-established pattern for adding exactly this kind of flag:

  1. SetupConfigure.cmake — add a new MUSESCORE_BUILD_CONFIGURATION value (e.g. app-backend) or a standalone CMake option (e.g. MUE_BUILD_FOR_BACKEND):

    if(BUILD_CONFIGURATION STREQUAL "APP-BACKEND")
        set(MUE_CONFIGURATION_IS_BACKEND ON)
    endif()
  2. src/app/app_config.h.in — expose it as a C++ preprocessor define (alongside the existing MUE_CONFIGURATION_IS_APPWEB etc.):

    `#cmakedefine` MUE_CONFIGURATION_IS_BACKEND 1
  3. buildscripts/ci/backend/build.sh — pass the flag when building for musescore.com:

    MUSESCORE_BUILD_CONFIGURATION=app-backend \
    bash ./ninja_build.sh -t appimage
  4. headerfooterlayout.cpp — then conditionally select the format:

    `#ifdef` MUE_CONFIGURATION_IS_BACKEND
        const auto dateFormat = muse::DateFormat::ISODate;
    `#else`
        const auto dateFormat = muse::DateFormat::LocaleShortFormat;
    `#endif`

This would need to land as a coordinated change across those files (plus the muse_framework PR #79 you already have). Since this touches the build infrastructure, it might be worth coordinating with the MuseScore infrastructure/build team to confirm the backend CI actually uses that script and what the right hook point is.


🧠 Learnings used
Learnt from: igorkorsukov
Repo: musescore/MuseScore PR: 32874
File: src/appshell/widgets/splashscreen/loadingscreenview.cpp:32-32
Timestamp: 2026-04-01T07:34:44.168Z
Learning: In the MuseScore C++ codebase, `IApplication::fullVersion()` (non-static virtual instance method in `src/framework/global/iapplication.h`) must only be called after application/services initialization. Do not use it in code paths that run before services are ready (e.g., splash/loading screens). If you need the app version via service-free static access in early UI/boot code, call `muse::BaseApplication::appFullVersion()` instead (static method declared in `src/framework/global/internal/baseapplication.h`), which reads compile-time constants.

Learnt from: igorkorsukov
Repo: musescore/MuseScore PR: 32950
File: src/framework/testing/environment.cpp:65-65
Timestamp: 2026-04-09T08:32:46.263Z
Learning: When using MuseScore’s IoC container (e.g., `muse::modularity::globalIoc()->registerExport<T>(name, impl)`), treat the `name` argument as the *registering module* identifier used for informational/tracing purposes. It does not have to match the key that consumers use to resolve the service later. In reviews, do not flag cases where the registration key (module name) differs from the resolution/lookup key as a bug, as this mismatch can be intentional (e.g., `IApplication` registered under `"testing"` in `src/framework/testing/environment.cpp`).

Learnt from: igorkorsukov
Repo: musescore/MuseScore PR: 33000
File: src/framework/audio/main/audiomodule.cpp:154-154
Timestamp: 2026-04-14T09:30:22.267Z
Learning: When registering exports via MuseScore’s IoC container (`muse::modularity`), it is acceptable to pass a raw pointer created with `new` to `ioc()->registerExport<T>(name, ...)`. The container will wrap it internally into a `std::shared_ptr`, so calls like `ioc()->registerExport<T>(name, new Impl(...))` are not a bug and should not be flagged for ownership/style issues. Prefer clarity, but do not treat raw `new` in `registerExport` arguments as an error; `ioc()->registerExport<T>(name, std::make_shared<Impl>(...))` is also valid.

Learnt from: Jojo-Schmitz
Repo: musescore/MuseScore PR: 33028
File: src/project/internal/opensaveprojectscenario.cpp:477-477
Timestamp: 2026-04-16T10:04:41.682Z
Learning: In the MuseScore C++ codebase, `configuration()->supportForumUrl()` intentionally returns a MuseScore Studio/app support URL on `musescore.org` (e.g., `/forum/...`, language-specific). When adding user-facing help text or help-button links for cloud-related errors (issues involving saving/uploading via `musescore.com`), ensure the help URL points to `musescore.com` (not `musescore.org`). Use `musescore.org` for Studio/app support problems and `musescore.com` for cloud-saving/upload issues.

Learnt from: saintmatthieu
Repo: musescore/MuseScore PR: 33036
File: src/framework/uicomponents/qml/Muse/UiComponents/tablesortfilterproxymodel.cpp:101-105
Timestamp: 2026-04-21T09:36:52.350Z
Learning: This repository guarantees Qt 6.10 as the minimum supported version. Therefore, when reviewing C++ code, do not require compatibility guards (e.g., QT_VERSION_CHECK) or fallback paths for Qt 6.10+ APIs/classes/enums. For example, do not flag uses of QSortFilterProxyModel::endFilterChange or QSortFilterProxyModel::Direction::Rows as needing guards for older Qt versions; such guards are unnecessary in this codebase.

Learnt from: Jojo-Schmitz
Repo: musescore/MuseScore PR: 33499
File: src/engraving/rendering/single/singledraw.cpp:1167-1169
Timestamp: 2026-05-20T11:29:20.381Z
Learning: When reviewing MSVC compiler warning fixes (notably warning C5054) in the engraving rendering C++ code, only flag `drawText`/painter call sites that bitwise-OR (`operator|`) `muse::draw` flags coming from *different* enum types unless the combination uses an explicit `static_cast<int>`. If the OR’d enumerators are all from the *same* enum type, they do not trigger C5054, so don’t require preemptive consistency casts—limit changes/flags to patterns that actually generate the compiler warning.

Char c = s.at(i);
if (c == '$' && (i < (n - 1))) {
Char nc = s.at(i + 1);
Expand Down Expand Up @@ -306,35 +307,33 @@ TextBlock HeaderFooterLayout::replaceTextMacros(LayoutContext& ctx, const Page*
newFragments.back().text += page->score()->masterScore()->fileInfo()->path().toString();
break;
case 'd':
newFragments.back().text += muse::Date::currentDate().toString(muse::DateFormat::ISODate);
newFragments.back().text += muse::Date::currentDate().toString(dateFormat);
break;
case 'D':
{
String creationDate = page->score()->metaTag(u"creationDate");
if (creationDate.isEmpty()) {
newFragments.back().text += page->score()->masterScore()->fileInfo()->birthTime().date().toString(
muse::DateFormat::ISODate);
newFragments.back().text += page->score()->masterScore()->fileInfo()->birthTime().date().toString(dateFormat);
} else {
newFragments.back().text += muse::Date::fromStringISOFormat(creationDate).toString(
muse::DateFormat::ISODate);
newFragments.back().text += muse::Date::fromStringISOFormat(creationDate).toString(dateFormat);
}
}
break;
case 'm': {
IFileInfoProviderPtr fileInfo = page->score()->masterScore()->fileInfo();
if (fileInfo->isNewlyCreated()) {
newFragments.back().text += String(u"HH:mm:ss");
newFragments.back().text += muse::Time::currentTime().toString(dateFormat);
} else {
newFragments.back().text += fileInfo->lastModified().time().toString(muse::DateFormat::ISODate);
newFragments.back().text += fileInfo->lastModified().time().toString(dateFormat);
}
}
break;
case 'M': {
IFileInfoProviderPtr fileInfo = page->score()->masterScore()->fileInfo();
if (fileInfo->isNewlyCreated()) {
newFragments.back().text += String(u"YYYY-MM-DD");
newFragments.back().text += muse::Date::currentDate().toString(dateFormat);
} else {
newFragments.back().text += fileInfo->lastModified().date().toString(muse::DateFormat::ISODate);
newFragments.back().text += fileInfo->lastModified().date().toString(dateFormat);
}
}
break;
Expand Down
Loading