From 5ed5eb82ee86b53e586b0b81aec1b44fc2040052 Mon Sep 17 00:00:00 2001 From: ispyisail Date: Sat, 3 Oct 2026 09:33:24 +1300 Subject: [PATCH] Honour --common-elements-dir and the other folder options in headless runs Reported on #1178. Two things kept --common-elements-dir from working for --run and the command-line export: - main() runs both before QETApp exists, and only QETApp::parseArguments() applied the folder options, so they were ignored. The application of those options is now QETApp::applyDirectoryArguments(), static, and the two headless branches call it too. They also drop the options from the arguments they pass on: the export reads its project and output by position, so "--export-pdf --common-elements-dir=X p.qet out.pdf" took the option for the project ("Project not found"). - commonElementsDir() read the saved collection path before the command-line one, so a user's own setting beat a folder given for this run. The command line now comes first, in the GUI too. Tested with a --run script adding a symbol that exists only in a given folder: master fails with or without a saved collection path; this resolves it, before or after --run, and over a saved path to another folder. Without the option it still fails, and a saved path to the folder still works. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01ELKpbGxqJd7EFiTUypBtVe --- sources/main.cpp | 28 +++++++++++++++-- sources/qetapp.cpp | 78 +++++++++++++++++++++++++++------------------- sources/qetapp.h | 1 + 3 files changed, 73 insertions(+), 34 deletions(-) diff --git a/sources/main.cpp b/sources/main.cpp index 5c8f78ab8..a0d0a9aa5 100644 --- a/sources/main.cpp +++ b/sources/main.cpp @@ -93,6 +93,30 @@ void qetLogMessageHandler(QtMsgType type, \~French paramètres \~ @return exit code */ +/** + @brief headlessArguments + For the headless export and --run, which return before QETApp parses + the command line: apply the folder options (--common-elements-dir= and + the others QETArguments knows) and return the arguments without them, + so they are not read as the project or output path (issue #1178). +*/ +static QStringList headlessArguments(const QStringList &args) +{ + QETApp::applyDirectoryArguments(QETArguments(args.mid(1))); + static const QStringList folder_options { + QStringLiteral("--common-elements-dir="), QStringLiteral("--common-tbt-dir="), + QStringLiteral("--config-dir="), QStringLiteral("--data-dir="), + QStringLiteral("--lang-dir=")}; + QStringList kept; + for (const QString &arg : args) { + bool folder = false; + for (const QString &option : folder_options) + folder = folder || arg.startsWith(option); + if (!folder) kept << arg; + } + return kept; +} + int main(int argc, char **argv) { // before creating Application: @@ -159,7 +183,7 @@ int main(int argc, char **argv) // QETProject::readProjectXml(), and with nobody able to dismiss it // QDialog::exec() would spin its event loop forever. QET::QetMessageBox::setNonInteractive(true); - return CLIExport::run(export_app.arguments()); + return CLIExport::run(headlessArguments(export_app.arguments())); } #ifdef QET_HAS_SCRIPTING // Headless scripting: --run (bugtracker @@ -169,7 +193,7 @@ int main(int argc, char **argv) QApplication script_app(argc, argv); QETProject::setBackupEnabled(false); QET::QetMessageBox::setNonInteractive(true); - return QetScripting::run(script_app.arguments()); + return QetScripting::run(headlessArguments(script_app.arguments())); } #endif } diff --git a/sources/qetapp.cpp b/sources/qetapp.cpp index 615428f07..67ba6ab23 100644 --- a/sources/qetapp.cpp +++ b/sources/qetapp.cpp @@ -658,6 +658,15 @@ QString QETApp::commonElementsDir() { m_common_element_dir_is_set = true; +#ifdef QET_ALLOW_OVERRIDE_CED_OPTION + //A folder given on the command line, for this run, comes + //before the one saved in the settings. + if (m_overrided_common_elements_dir != QString()) { + m_common_element_dir = m_overrided_common_elements_dir; + return(m_common_element_dir); + } +#endif + //Check if user define a custom path //for the common collection QSettings settings; @@ -674,12 +683,6 @@ QString QETApp::commonElementsDir() } } -#ifdef QET_ALLOW_OVERRIDE_CED_OPTION - if (m_overrided_common_elements_dir != QString()) { - m_common_element_dir = m_overrided_common_elements_dir; - return(m_common_element_dir); - } -#endif #ifndef QET_COMMON_COLLECTION_PATH /* in the absence of a compilation option, * we use the elements folder, located next to the executable binary @@ -2389,6 +2392,42 @@ QList QETApp::floatingToolbarsAndDocksForMainWindow( } +/** + @brief QETApp::applyDirectoryArguments + Apply the folder options (--common-elements-dir=, --common-tbt-dir=, + --config-dir=, --data-dir=, --lang-dir=) of @p arguments. Static, so + the headless export and --run in main() can apply them too: they + return before a QETApp exists. +*/ +void QETApp::applyDirectoryArguments(const QETArguments &arguments) +{ +#ifdef QET_ALLOW_OVERRIDE_CED_OPTION + if (arguments.commonElementsDirSpecified()) { + overrideCommonElementsDir(arguments.commonElementsDir()); + } +#endif +#ifdef QET_ALLOW_OVERRIDE_CTBTD_OPTION + if (arguments.commonTitleBlockTemplatesDirSpecified()) { + overrideCommonTitleBlockTemplatesDir( + arguments.commonTitleBlockTemplatesDir()); + } +#endif +#ifdef QET_ALLOW_OVERRIDE_CD_OPTION + if (arguments.configDirSpecified()) { + overrideConfigDir(arguments.configDir()); + } +#endif +#ifdef QET_ALLOW_OVERRIDE_DD_OPTION + if (arguments.dataDirSpecified()) { + overrideDataDir(arguments.dataDir()); + } +#endif + + if (arguments.langDirSpecified()) { + overrideLangDir(arguments.langDir()); + } +} + /** @brief QETApp::parseArguments Parse the following arguments: @@ -2430,32 +2469,7 @@ void QETApp::parseArguments() // analyze the arguments // analyse les arguments qet_arguments_ = QETArguments(arguments_list); - -#ifdef QET_ALLOW_OVERRIDE_CED_OPTION - if (qet_arguments_.commonElementsDirSpecified()) { - overrideCommonElementsDir(qet_arguments_.commonElementsDir()); - } -#endif -#ifdef QET_ALLOW_OVERRIDE_CTBTD_OPTION - if (qet_arguments_.commonTitleBlockTemplatesDirSpecified()) { - overrideCommonTitleBlockTemplatesDir( - qet_arguments_.commonTitleBlockTemplatesDir()); - } -#endif -#ifdef QET_ALLOW_OVERRIDE_CD_OPTION - if (qet_arguments_.configDirSpecified()) { - overrideConfigDir(qet_arguments_.configDir()); - } -#endif -#ifdef QET_ALLOW_OVERRIDE_DD_OPTION - if (qet_arguments_.dataDirSpecified()) { - overrideDataDir(qet_arguments_.dataDir()); - } -#endif - - if (qet_arguments_.langDirSpecified()) { - overrideLangDir(qet_arguments_.langDir()); - } + applyDirectoryArguments(qet_arguments_); if (qet_arguments_.printLicenseRequested()) { printLicense(); diff --git a/sources/qetapp.h b/sources/qetapp.h index 2c2fa1d3e..309002808 100644 --- a/sources/qetapp.h +++ b/sources/qetapp.h @@ -115,6 +115,7 @@ class QETApp : public QObject static QStringList handledFiles(const QList &); static RecentFiles *projectsRecentFiles(); static RecentFiles *elementsRecentFiles(); + static void applyDirectoryArguments(const QETArguments &); #ifdef QET_ALLOW_OVERRIDE_CED_OPTION public: