Merge fix: prompt Save-As on Design View tag when project unsaved

This commit is contained in:
2026-07-23 14:45:18 -04:00
+40 -1
View File
@@ -34,6 +34,9 @@
#define REAPERAPI_MINIMAL
#define REAPERAPI_WANT_CountSelectedTracks
#define REAPERAPI_WANT_GetSelectedTrack
#define REAPERAPI_WANT_EnumProjects
#define REAPERAPI_WANT_Main_SaveProject
#define REAPERAPI_WANT_ShowConsoleMsg
#include "reaper_plugin_functions.h"
namespace reasampler {
@@ -115,8 +118,44 @@ void reapplyActiveMode() {
// state. Called after every state-changing Design View action so the view model
// is not lost across save/close/reopen. Marking the project dirty is correct —
// a Design View mutation is a project-level change the user should be prompted
// to save. Safe when there is no active/saved project (saveToActiveProject no-ops).
// to save.
//
// When the membership index is non-empty AND the project is unsaved, we prompt
// the user to Save-As before persisting — mirroring the flow capture uses.
// Gate: if membership is empty (no tracks tagged), skip the prompt entirely;
// saveToActiveProject will no-op for an unsaved project, which is correct.
//
// DAW-ONLY ASSUMPTION: Main_SaveProject(proj, true) opens a Save-As dialog and
// blocks until the user dismisses it. The blocking behaviour and dialog
// appearance can only be confirmed in a running REAPER (same caveat as capture).
void persistViewState() {
if (!g_session->view().membership().empty()) {
// At least one track is tagged — worth persisting. Check whether the
// project is saved and, if not, prompt Save-As so saveToActiveProject
// can write ext state. Mirrors capture's readRppPath idiom exactly.
ReaProject* proj = EnumProjects(-1, nullptr, 0);
if (proj) {
auto readRppPath = [&]() -> std::string {
std::vector<char> buf(4096, '\0');
EnumProjects(-1, buf.data(), static_cast<int>(buf.size()));
return std::string(buf.data());
};
if (readRppPath().empty()) {
// Project is unsaved — prompt Save-As.
Main_SaveProject(proj, true);
// Re-read: still empty means the user cancelled.
if (readRppPath().empty()) {
ShowConsoleMsg(
"ReaSampler: Design View state will not persist until "
"the project is saved.\n");
// The in-session tag state is left as-is — the mode change
// already applied and remains valid for this session.
return;
}
}
}
}
g_session->saveToActiveProject();
}