diff --git a/src/Mod/Fem/Gui/DlgSettingsFemCcx.ui b/src/Mod/Fem/Gui/DlgSettingsFemCcx.ui index 9288fc4351..ac0346f146 100644 --- a/src/Mod/Fem/Gui/DlgSettingsFemCcx.ui +++ b/src/Mod/Fem/Gui/DlgSettingsFemCcx.ui @@ -34,34 +34,8 @@ - - - - CalculiX binary - - - - - - - Search in known binary directories - - - true - - - UseStandardCcxLocation - - - Mod/Fem/Ccx - - - - - false - 100 @@ -69,15 +43,12 @@ - CCX binary path + CalculiX path - - - false - + 0 @@ -968,37 +939,5 @@ Only takes effect if 'Pipeline only' is enabled - - cb_ccx_binary_std - toggled(bool) - l_ccx_binary_path - setDisabled(bool) - - - 406 - 45 - - - 148 - 68 - - - - - cb_ccx_binary_std - toggled(bool) - fc_ccx_binary_path - setDisabled(bool) - - - 406 - 45 - - - 406 - 68 - - - diff --git a/src/Mod/Fem/Gui/DlgSettingsFemCcxImp.cpp b/src/Mod/Fem/Gui/DlgSettingsFemCcxImp.cpp index e668dce16b..8ef54f9c31 100644 --- a/src/Mod/Fem/Gui/DlgSettingsFemCcxImp.cpp +++ b/src/Mod/Fem/Gui/DlgSettingsFemCcxImp.cpp @@ -26,6 +26,7 @@ #include "PreCompiled.h" #ifndef _PreComp_ #include +#include #include #endif @@ -47,9 +48,9 @@ DlgSettingsFemCcxImp::DlgSettingsFemCcxImp(QWidget* parent) ui->dsb_ccx_initial_time_increment->setMaximum(std::numeric_limits::max()); connect(ui->fc_ccx_binary_path, - &Gui::PrefFileChooser::fileNameChanged, + &Gui::PrefFileChooser::fileNameSelected, this, - &DlgSettingsFemCcxImp::onfileNameChanged); + &DlgSettingsFemCcxImp::onfileNameSelected); } DlgSettingsFemCcxImp::~DlgSettingsFemCcxImp() = default; @@ -83,7 +84,6 @@ void DlgSettingsFemCcxImp::saveSettings() ui->cb_int_editor->onSave(); ui->fc_ext_editor->onSave(); - ui->cb_ccx_binary_std->onSave(); ui->fc_ccx_binary_path->onSave(); ui->cb_split_inp_writer->onSave(); } @@ -112,7 +112,6 @@ void DlgSettingsFemCcxImp::loadSettings() ui->cb_int_editor->onRestore(); ui->fc_ext_editor->onRestore(); - ui->cb_ccx_binary_std->onRestore(); ui->fc_ccx_binary_path->onRestore(); ui->cb_split_inp_writer->onRestore(); @@ -148,14 +147,10 @@ void DlgSettingsFemCcxImp::changeEvent(QEvent* e) } } -void DlgSettingsFemCcxImp::onfileNameChanged(QString FileName) +void DlgSettingsFemCcxImp::onfileNameSelected(const QString& fileName) { - if (!QFileInfo::exists(FileName)) { - QMessageBox::critical(this, - tr("File does not exist"), - tr("The specified executable\n'%1'\n does not exist!\n" - "Specify another file.") - .arg(FileName)); + if (!fileName.isEmpty() && QStandardPaths::findExecutable(fileName).isEmpty()) { + QMessageBox::critical(this, tr("CalculiX"), tr("Executable '%1' not found").arg(fileName)); } } diff --git a/src/Mod/Fem/Gui/DlgSettingsFemCcxImp.h b/src/Mod/Fem/Gui/DlgSettingsFemCcxImp.h index 792602a75a..048183c4eb 100644 --- a/src/Mod/Fem/Gui/DlgSettingsFemCcxImp.h +++ b/src/Mod/Fem/Gui/DlgSettingsFemCcxImp.h @@ -42,7 +42,7 @@ public: ~DlgSettingsFemCcxImp() override; protected Q_SLOTS: - void onfileNameChanged(QString FileName); + void onfileNameSelected(const QString& fileName); protected: void saveSettings() override; diff --git a/src/Mod/Fem/femsolver/settings.py b/src/Mod/Fem/femsolver/settings.py index 90d3bd5292..ff1a520b2f 100644 --- a/src/Mod/Fem/femsolver/settings.py +++ b/src/Mod/Fem/femsolver/settings.py @@ -214,10 +214,9 @@ class _SolverDlg: WRITE_COMMENTS_PARAM = "writeCommentsToInputFile" - def __init__(self, default, param_path, use_default, custom_path): + def __init__(self, default, param_path, custom_path): self.default = default self.param_path = param_path - self.use_default = use_default self.custom_path = custom_path self.param_group = FreeCAD.ParamGet(self.param_path) @@ -229,15 +228,11 @@ class _SolverDlg: # TODO the binaries provided with the FreeCAD distribution should be found # without any additional user input # see ccxttols, it works for Windows and Linux there - binary = self.default + binary = self.param_group.GetString(self.custom_path) + if not binary: + binary = self.default FreeCAD.Console.PrintLog(f"Solver binary path default: {binary} \n") - # check if use_default is set to True - # if True the standard binary path will be overwritten with a user binary path - if self.param_group.GetBool(self.use_default, True) is False: - binary = self.param_group.GetString(self.custom_path) - FreeCAD.Console.PrintLog(f"Solver binary path user setting: {binary} \n") - # get the whole binary path name for the given command or binary path and return it # None is returned if the binary has not been found # The user does not know what exactly has going wrong. @@ -264,31 +259,26 @@ _SOLVER_PARAM = { "Calculix": _SolverDlg( default="ccx", param_path=_PARAM_PATH + "Ccx", - use_default="UseStandardCcxLocation", custom_path="ccxBinaryPath", ), "ElmerSolver": _SolverDlg( default="ElmerSolver", param_path=_PARAM_PATH + "Elmer", - use_default="UseStandardElmerLocation", custom_path="elmerBinaryPath", ), "ElmerGrid": _SolverDlg( default="ElmerGrid", param_path=_PARAM_PATH + "Elmer", - use_default="UseStandardGridLocation", custom_path="gridBinaryPath", ), "Mystran": _SolverDlg( default="mystran", param_path=_PARAM_PATH + "Mystran", - use_default="UseStandardMystranLocation", custom_path="mystranBinaryPath", ), "Z88": _SolverDlg( default="z88r", param_path=_PARAM_PATH + "Z88", - use_default="UseStandardZ88Location", custom_path="z88BinaryPath", ), } diff --git a/src/Mod/Fem/femtaskpanels/task_solver_ccxtools.py b/src/Mod/Fem/femtaskpanels/task_solver_ccxtools.py index 91143c5dbc..d1909a0067 100644 --- a/src/Mod/Fem/femtaskpanels/task_solver_ccxtools.py +++ b/src/Mod/Fem/femtaskpanels/task_solver_ccxtools.py @@ -68,7 +68,10 @@ class _TaskPanel: # task panel, may be deactivate write and run button. self.fea = ccx(solver_object) self.fea.setup_working_dir() - self.fea.setup_ccx() + try: + self.fea.setup_ccx() + except FileNotFoundError as e: + FreeCAD.Console.PrintWarning(e.args[0]) self.Calculix = QtCore.QProcess() self.Timer = QtCore.QTimer() diff --git a/src/Mod/Fem/femtools/ccxtools.py b/src/Mod/Fem/femtools/ccxtools.py index 311ae865a6..058269658b 100644 --- a/src/Mod/Fem/femtools/ccxtools.py +++ b/src/Mod/Fem/femtools/ccxtools.py @@ -32,6 +32,7 @@ __url__ = "https://www.freecad.org" import os import sys import subprocess +import shutil import FreeCAD @@ -400,52 +401,24 @@ class FemToolsCcx(QtCore.QRunnable, QtCore.QObject): Defaults to 'CalculiX'. Expected output from `ccx` when run empty. """ - error_title = "No or wrong CalculiX binary ccx" - error_message = "" - from platform import system + self.ccx_binary = ccx_binary + if self.ccx_binary is None: + self.ccx_binary = FreeCAD.ParamGet( + "User parameter:BaseApp/Preferences/Mod/Fem/Ccx" + ).GetString("ccxBinaryPath", "") - ccx_std_location = FreeCAD.ParamGet( - "User parameter:BaseApp/Preferences/Mod/Fem/Ccx" - ).GetBool("UseStandardCcxLocation", True) - if ccx_std_location: - if system() == "Windows": - ccx_path = FreeCAD.getHomePath() + "bin/ccx.exe" - FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/Ccx").SetString( - "ccxBinaryPath", ccx_path - ) - self.ccx_binary = ccx_path - elif system() in ("Linux", "Darwin"): - p1 = subprocess.Popen(["which", "ccx"], stdout=subprocess.PIPE) - if p1.wait() == 0: - ccx_path = p1.stdout.read().decode("utf8").split("\n")[0] - elif p1.wait() == 1: - error_message = ( - "FEM: CalculiX binary ccx not found in " - "standard system binary path. " - "Please install ccx or set path to binary " - "in FEM preferences tab CalculiX.\n" - ) - if FreeCAD.GuiUp: - QtGui.QMessageBox.critical(None, error_title, error_message) - raise Exception(error_message) - self.ccx_binary = ccx_path + if not self.ccx_binary: + # search in system + self.ccx_binary = shutil.which("ccx") else: - if not ccx_binary: - self.ccx_prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/Ccx") - ccx_binary = self.ccx_prefs.GetString("ccxBinaryPath", "") - if not ccx_binary: - FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/Ccx").SetBool( - "UseStandardCcxLocation", True - ) - error_message = ( - "FEM: CalculiX binary ccx path not set at all. " - "The use of standard path was activated in " - "FEM preferences tab CalculiX. Please try again!\n" - ) - if FreeCAD.GuiUp: - QtGui.QMessageBox.critical(None, error_title, error_message) - FreeCAD.Console.PrintError(error_message) - self.ccx_binary = ccx_binary + # check user defined path + self.ccx_binary = shutil.which(self.ccx_binary) + + if self.ccx_binary is None: + raise FileNotFoundError( + "CalculiX binary not found\n" + "Install CalculiX or set path to binary in FEM user preferences" + ) ccx_stdout = None ccx_stderr = None @@ -474,7 +447,7 @@ class FemToolsCcx(QtCore.QRunnable, QtCore.QObject): error_message = ( "FEM: CalculiX binary ccx '{}' not found. " "Please set the CalculiX binary ccx path in " - "FEM preferences tab CalculiX.\n".format(ccx_binary) + "FEM preferences tab CalculiX.\n".format(self.ccx_binary) ) if FreeCAD.GuiUp: QtGui.QMessageBox.critical(None, error_title, error_message) @@ -487,7 +460,7 @@ class FemToolsCcx(QtCore.QRunnable, QtCore.QObject): "contain expected phrase '{}'. " "There are some problems when running the ccx binary. " "Check if ccx runs standalone without FreeCAD.\n".format( - ccx_binary, ccx_stdout, ccx_binary_sig + self.ccx_binary, ccx_stdout, ccx_binary_sig ) ) if FreeCAD.GuiUp: