Fix bugtracker #270: Save As on Snap produces file with no .qet extension

ProjectView::askUserForFilePath() only appended the .qet extension when
FLATPAK_ID/SNAP_NAME were NOT set, on the assumption that the
xdg-desktop-portal file dialog used by sandboxed Snap/Flatpak builds
always appends the selected filter's extension itself (avoiding a
double ".qet.qet"). In practice, on the reporter's Snap/Ubuntu 22.04
setup the portal dialog does not append it, so the environment-based
skip left Save As producing a file with no extension at all.

Portal behavior isn't something QET controls or can reliably detect via
environment variables -- it depends on the desktop's actual portal
implementation/version. Rather than guessing per-environment, normalize
unconditionally: strip any existing .qet suffix (case-insensitive) and
re-append exactly one. This produces the correct single extension
whether or not the dialog already added it, on every environment.

Verified: clean rebuild, only the intended object file recompiled and
linked successfully. Wrote a standalone test of the normalization logic
covering no-extension, already-has-extension, uppercase-extension, and
a literal dot in the base filename -- all four produced exactly one
correct ".qet" suffix with no double-extension and no missing extension.

Not verified: the actual Snap-sandboxed portal dialog behavior itself,
since building/running the Snap package and testing its file-save
dialog under a portal is outside what's practical to set up in this
sandbox. Confidence rests on the fix removing the environment-guessing
entirely in favor of unconditional, dialog-implementation-agnostic
normalization, which is correct regardless of what the underlying
dialog does.
This commit is contained in:
ispyisail
2026-08-11 12:01:24 +12:00
parent 13e245b104
commit 55250a6de9
+13 -5
View File
@@ -345,11 +345,19 @@ QString ProjectView::askUserForFilePath(bool assign) {
// if no filepath is provided, return an empty string // if no filepath is provided, return an empty string
if (filepath.isEmpty()) return(filepath); if (filepath.isEmpty()) return(filepath);
// if the name does not end with the .qet extension and we're _not_ using xdg-desktop-portal, append it // Ensure the path ends with exactly one .qet extension, regardless of
bool usesPortal = // whether the active file dialog already appended one. Whether it does
qEnvironmentVariableIsSet("FLATPAK_ID") || // depends on which backend actually shows the dialog (Qt's own vs. the
qEnvironmentVariableIsSet("SNAP_NAME"); // xdg-desktop-portal used by sandboxed Snap/Flatpak builds), and that
if (!filepath.endsWith(".qet", Qt::CaseInsensitive) && !usesPortal) filepath += ".qet"; // isn't reliably predictable from environment variables alone -- an
// earlier attempt at that (only appending when *not* Snap/Flatpak,
// assuming the portal always appends it) left Snap saves with no
// extension at all whenever the portal didn't (bugtracker #270).
// Stripping any existing suffix first and re-appending it once is
// correct either way.
if (filepath.endsWith(".qet", Qt::CaseInsensitive))
filepath.chop(4);
filepath += ".qet";
if (assign) { if (assign) {
// assign the provided filepath to the currently edited project // assign the provided filepath to the currently edited project