diff --git a/src/Mod/Fem/Gui/DlgSettingsFemGmsh.ui b/src/Mod/Fem/Gui/DlgSettingsFemGmsh.ui index d86711d295..1549fbe5cd 100644 --- a/src/Mod/Fem/Gui/DlgSettingsFemGmsh.ui +++ b/src/Mod/Fem/Gui/DlgSettingsFemGmsh.ui @@ -35,48 +35,7 @@ - - - Search in known binary directories - - - true - - - UseStandardGmshLocation - - - Mod/Fem/Gmsh - - - - - - - false - - - - 0 - 0 - - - - - 100 - 0 - - - - Gmsh binary path - - - - - - - false - + 0 @@ -112,6 +71,25 @@ + + + + + 0 + 0 + + + + + 100 + 0 + + + + Gmsh binary path + + + @@ -209,11 +187,6 @@ Gui::FileChooser
Gui/PrefWidgets.h
- - Gui::PrefCheckBox - QCheckBox -
Gui/PrefWidgets.h
-
Gui::PrefComboBox QComboBox @@ -228,70 +201,5 @@ - - - cb_gmsh_binary_std - toggled(bool) - l_gmsh_binary_path - setEnabled(bool) - - - 406 - 45 - - - 148 - 68 - - - - - cb_gmsh_binary_std - toggled(bool) - fc_gmsh_binary_path - setEnabled(bool) - - - 406 - 45 - - - 406 - 68 - - - - - cb_gmsh_binary_std - toggled(bool) - l_gmsh_binary_path - setDisabled(bool) - - - 406 - 45 - - - 148 - 68 - - - - - cb_gmsh_binary_std - toggled(bool) - fc_gmsh_binary_path - setDisabled(bool) - - - 406 - 45 - - - 406 - 68 - - - - + diff --git a/src/Mod/Fem/Gui/DlgSettingsFemGmshImp.cpp b/src/Mod/Fem/Gui/DlgSettingsFemGmshImp.cpp index eecdd566d3..aa51594c4a 100644 --- a/src/Mod/Fem/Gui/DlgSettingsFemGmshImp.cpp +++ b/src/Mod/Fem/Gui/DlgSettingsFemGmshImp.cpp @@ -25,6 +25,7 @@ #include "PreCompiled.h" #ifndef _PreComp_ #include +#include #include #endif @@ -42,16 +43,15 @@ DlgSettingsFemGmshImp::DlgSettingsFemGmshImp(QWidget* parent) ui->setupUi(this); connect(ui->fc_gmsh_binary_path, - &Gui::PrefFileChooser::fileNameChanged, + &Gui::PrefFileChooser::fileNameSelected, this, - &DlgSettingsFemGmshImp::onfileNameChanged); + &DlgSettingsFemGmshImp::onfileNameSelected); } DlgSettingsFemGmshImp::~DlgSettingsFemGmshImp() = default; void DlgSettingsFemGmshImp::saveSettings() { - ui->cb_gmsh_binary_std->onSave(); ui->fc_gmsh_binary_path->onSave(); ui->cb_log_verbosity->onSave(); ui->sb_threads->onSave(); @@ -59,7 +59,6 @@ void DlgSettingsFemGmshImp::saveSettings() void DlgSettingsFemGmshImp::loadSettings() { - ui->cb_gmsh_binary_std->onRestore(); ui->fc_gmsh_binary_path->onRestore(); ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath( @@ -84,14 +83,15 @@ void DlgSettingsFemGmshImp::changeEvent(QEvent* e) } } -void DlgSettingsFemGmshImp::onfileNameChanged(QString FileName) +void DlgSettingsFemGmshImp::onfileNameSelected(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("Not an executable binary"), + tr("The specified file \n'%1'\n does not exist or is not executable.\n" + "Specify another file.") + .arg(FileName)); } } diff --git a/src/Mod/Fem/Gui/DlgSettingsFemGmshImp.h b/src/Mod/Fem/Gui/DlgSettingsFemGmshImp.h index 66f77c4a22..aeb5737b4b 100644 --- a/src/Mod/Fem/Gui/DlgSettingsFemGmshImp.h +++ b/src/Mod/Fem/Gui/DlgSettingsFemGmshImp.h @@ -41,7 +41,7 @@ public: ~DlgSettingsFemGmshImp() override; protected Q_SLOTS: - void onfileNameChanged(QString FileName); + void onfileNameSelected(QString FileName); protected: void saveSettings() override; diff --git a/src/Mod/Fem/Gui/PreCompiled.h b/src/Mod/Fem/Gui/PreCompiled.h index cee7332325..97824d7f34 100644 --- a/src/Mod/Fem/Gui/PreCompiled.h +++ b/src/Mod/Fem/Gui/PreCompiled.h @@ -81,6 +81,7 @@ #include #include #include +#include #include #include #include diff --git a/src/Mod/Fem/femmesh/gmshtools.py b/src/Mod/Fem/femmesh/gmshtools.py index 6c284dc81a..a7ddf539f7 100644 --- a/src/Mod/Fem/femmesh/gmshtools.py +++ b/src/Mod/Fem/femmesh/gmshtools.py @@ -29,6 +29,7 @@ __url__ = "https://www.freecad.org" import os import re +import shutil import subprocess from PySide.QtCore import QProcess, QThread @@ -337,59 +338,33 @@ class GmshTools: Console.PrintMessage(" " + self.temp_file_geo + "\n") def get_gmsh_command(self): - from platform import system - - gmsh_std_location = FreeCAD.ParamGet( + self.gmsh_bin = FreeCAD.ParamGet( "User parameter:BaseApp/Preferences/Mod/Fem/Gmsh" - ).GetBool("UseStandardGmshLocation") - if gmsh_std_location: - if system() == "Windows": - gmsh_path = FreeCAD.getHomePath() + "bin/gmsh.exe" - FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/Gmsh").SetString( - "gmshBinaryPath", gmsh_path - ) - self.gmsh_bin = gmsh_path - elif system() == "Linux": - p1 = subprocess.Popen(["which", "gmsh"], stdout=subprocess.PIPE) - if p1.wait() == 0: - output = p1.stdout.read() - output = output.decode("utf-8") - gmsh_path = output.split("\n")[0] - elif p1.wait() == 1: - error_message = ( - "Gmsh binary gmsh not found in standard system binary path. " - "Please install Gmsh or set path to binary " - "in FEM preferences tab Gmsh.\n" - ) - Console.PrintError(error_message) - raise GmshError(error_message) - self.gmsh_bin = gmsh_path - elif system() == "Darwin": - # https://forum.freecad.org/viewtopic.php?f=13&t=73041&p=642026#p642022 - gmsh_path = "/Applications/Gmsh.app/Contents/MacOS/gmsh" - FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/Gmsh").SetString( - "gmshBinaryPath", gmsh_path - ) - self.gmsh_bin = gmsh_path - else: + ).GetString("gmshBinaryPath", "") + + if self.gmsh_bin and not shutil.which(self.gmsh_bin): + error_message = ( + f"Configured Gmsh binary '${self.gmsh_bin}' not found. Please set path to " + "binary in FEM's Gmsh preferences page or leave blank to use default binary.\n" + ) + Console.PrintError(error_message) + raise GmshError(error_message) + + if not self.gmsh_bin: + from platform import system + + gmsh_path = shutil.which("gmsh") + if system() == "Darwin" and not gmsh_path: + gmsh_path = shutil.which("/Applications/Gmsh.app/Contents/MacOS/gmsh") + + if not gmsh_path: error_message = ( - "No standard location implemented for your operating system. " - "Set GMHS binary path in FEM preferences.\n" + "Gmsh binary not found. Please install Gmsh or set path to binary " + "in FEM's Gmsh preferences page.\n" ) Console.PrintError(error_message) raise GmshError(error_message) - else: - if not self.gmsh_bin: - self.gmsh_bin = FreeCAD.ParamGet( - "User parameter:BaseApp/Preferences/Mod/Fem/Gmsh" - ).GetString("gmshBinaryPath", "") - if not self.gmsh_bin: # in prefs not set, we will try to use something reasonable - if system() == "Linux": - self.gmsh_bin = "gmsh" - elif system() == "Windows": - self.gmsh_bin = FreeCAD.getHomePath() + "bin/gmsh.exe" - else: - self.gmsh_bin = "gmsh" + self.gmsh_bin = gmsh_path Console.PrintMessage(" " + self.gmsh_bin + "\n") def get_group_data(self): @@ -433,7 +408,7 @@ class GmshTools: def version(self): self.get_gmsh_command() - if os.path.exists(self.gmsh_bin): + if shutil.which(self.gmsh_bin): found_message = "file found: " + self.gmsh_bin Console.PrintMessage(found_message + "\n") else: @@ -949,10 +924,10 @@ class GmshTools: # print(output) # print(error) except Exception: - if os.path.exists(self.gmsh_bin): + if shutil.which(self.gmsh_bin): error = "Error executing: {}\n".format(" ".join(command_list)) else: - error = f"Gmsh executable not found: {self.gmsh_bin}\n" + error = f"Gmsh executable not found: '{self.gmsh_bin}'\n" Console.PrintError(error) self.error = True