Fem: Fix CalculiX preferences file chooser

This commit is contained in:
marioalexis
2025-09-06 12:39:51 -03:00
parent dc22fb4b9b
commit 344f93c2da
6 changed files with 36 additions and 136 deletions

View File

@@ -34,34 +34,8 @@
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout" columnstretch="2,3">
<item row="2" column="0">
<widget class="QLabel" name="l_ccx_binary_std">
<property name="text">
<string>CalculiX binary</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="Gui::PrefCheckBox" name="cb_ccx_binary_std">
<property name="text">
<string>Search in known binary directories</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="prefEntry" stdset="0">
<cstring>UseStandardCcxLocation</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Fem/Ccx</cstring>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="l_ccx_binary_path">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>100</width>
@@ -69,15 +43,12 @@
</size>
</property>
<property name="text">
<string>CCX binary path</string>
<string>CalculiX path</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="Gui::PrefFileChooser" name="fc_ccx_binary_path">
<property name="enabled">
<bool>false</bool>
</property>
<widget class="Gui::PrefFileChooser" name="fc_ccx_binary_path" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
@@ -968,37 +939,5 @@ Only takes effect if 'Pipeline only' is enabled</string>
</hint>
</hints>
</connection>
<connection>
<sender>cb_ccx_binary_std</sender>
<signal>toggled(bool)</signal>
<receiver>l_ccx_binary_path</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>406</x>
<y>45</y>
</hint>
<hint type="destinationlabel">
<x>148</x>
<y>68</y>
</hint>
</hints>
</connection>
<connection>
<sender>cb_ccx_binary_std</sender>
<signal>toggled(bool)</signal>
<receiver>fc_ccx_binary_path</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>406</x>
<y>45</y>
</hint>
<hint type="destinationlabel">
<x>406</x>
<y>68</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -26,6 +26,7 @@
#include "PreCompiled.h"
#ifndef _PreComp_
#include <QMessageBox>
#include <QStandardPaths>
#include <QThread>
#endif
@@ -47,9 +48,9 @@ DlgSettingsFemCcxImp::DlgSettingsFemCcxImp(QWidget* parent)
ui->dsb_ccx_initial_time_increment->setMaximum(std::numeric_limits<float>::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));
}
}

View File

@@ -42,7 +42,7 @@ public:
~DlgSettingsFemCcxImp() override;
protected Q_SLOTS:
void onfileNameChanged(QString FileName);
void onfileNameSelected(const QString& fileName);
protected:
void saveSettings() override;

View File

@@ -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",
),
}

View File

@@ -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()

View File

@@ -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: