Never leave a collection folder without a name, and say when it is broken

Fixes https://qelectrotech.org/bugtracker/view.php?id=332

localName() set a non-root folder's label only inside the success path of
loading its qet_directory file. If that load failed -- file missing,
malformed, or unopenable because of the Windows path-encoding problem with
accented characters that plc-user diagnosed on the tracker -- nothing was
set at all, and since a fresh item's text() is null the folder rendered
with a completely blank label. That is the reported symptom.

Resolve the name into a local and always fall back to the folder's own
directory name, so the label is never empty whatever went wrong.

The fallback is applied *after* NamesList::name() rather than passed into
it. This matters: name() returns a caller-supplied fallback before it
reaches its "first available translation" step, so passing m_path in would
replace a perfectly good name in some other language with the raw
directory name. A folder named only in French, viewed under an English
locale, previously showed "Accentué" and must keep doing so.

Falling back on its own would then hide the broken file -- the user sees a
plausible name and never learns there is anything to repair. So a folder
whose qet_directory could not be read now says so in its tooltip, naming
the file, above the collection path that tooltip already carried.
Suggested by plc-user on PR #622. The flag is recorded in localName() and
consumed in setUpData(), because setUpData() assigns the tooltip after
localName() runs and would otherwise discard it.

Only a file-level failure is flagged. A readable qet-directory with no
entry for the current language is not an error; NamesList::name() resolves
that itself and no warning is shown.

Verified on a fixture collection of four folders -- valid, malformed,
missing, and one named only in French:

                  master        this patch
  fr-only         Accentué      Accentué        (no warning)
  malformed       <blank>       malformed       (warning)
  no qet_directory <blank>      no_file         (warning)
  valid           Valid Folder  Valid Folder    (no warning)
This commit is contained in:
ispyisail
2026-08-02 01:36:11 +12:00
parent ec70bdc0a3
commit 87a010eb75
2 changed files with 45 additions and 3 deletions
@@ -136,18 +136,41 @@ QString FileElementCollectionItem::localName()
} }
else else
{ {
// Fall back to the raw directory name (m_path) whenever the
// translated name can't be obtained -- qet_directory missing,
// unreadable (e.g. a Windows path-encoding issue with special
// characters, see bugtracker #332), malformed, or present but
// without a usable name entry -- rather than leaving the item
// blank.
QString display_name;
bool readable = false;
QString str(fileSystemPath() % "/qet_directory"); QString str(fileSystemPath() % "/qet_directory");
pugi::xml_document docu; pugi::xml_document docu;
if(docu.load_file(str.toStdWString().c_str())) if (docu.load_file(str.toStdWString().c_str()))
{ {
if (QString(docu.document_element().name()) if (QString(docu.document_element().name())
== "qet-directory") == "qet-directory")
{ {
readable = true;
NamesList nl; NamesList nl;
nl.fromXml(docu.document_element()); nl.fromXml(docu.document_element());
setText(nl.name()); // Deliberately no fallback argument: a non-empty one
// is returned *before* NamesList::name() reaches its
// "first available translation" step, so passing
// m_path here would replace a perfectly good name in
// some other language with the raw directory name.
// The fallback belongs after the chain, not inside it.
display_name = nl.name();
} }
} }
setText(display_name.isEmpty() ? m_path : display_name);
// Only a file-level failure counts: a readable qet-directory
// with no entry for the current language is not an error,
// NamesList::name() resolves that on its own. Recorded here
// and reported by setUpData(), which sets the tooltip after
// this runs.
m_qet_directory_unreadable = !readable;
} }
} }
else if (isElement()) { else if (isElement()) {
@@ -350,7 +373,21 @@ void FileElementCollectionItem::setUpData()
} }
} }
setToolTip(collectionPath()); // Falling back to the raw directory name keeps the folder usable, but
// on its own it hides the fact that a file is broken: the user sees a
// plausible name and never learns there is anything to repair. Say so
// above the collection path, which stays as the last line the way the
// element tooltip above builds it.
QStringList tip;
if (isDir() && m_qet_directory_unreadable)
{
tip << QObject::tr("Le fichier « %1 » est absent ou illisible : "
"le nom traduit de ce dossier n'a pas pu être lu, "
"son nom de dossier est affiché à la place.")
.arg(fileSystemPath() % "/qet_directory");
}
tip << collectionPath();
setToolTip(tip.join(QLatin1Char('\n')));
} }
/** /**
@@ -64,6 +64,11 @@ class FileElementCollectionItem : public ElementCollectionItem
private: private:
QString m_path; QString m_path;
/// True when this directory's qet_directory file is missing or
/// unreadable, so setUpData() can say so in the tooltip. Recorded
/// rather than acted on in localName(), because setUpData() resets
/// the tooltip afterwards and would otherwise discard it.
bool m_qet_directory_unreadable = false;
}; };
#endif // FILEELEMENTCOLLECTIONITEM2_H #endif // FILEELEMENTCOLLECTIONITEM2_H