From 353085d7e3aeb8be1da6c23a4e7034f9a5d85c7b Mon Sep 17 00:00:00 2001 From: Alex Tran <56737137+xelathan@users.noreply.github.com> Date: Tue, 15 Apr 2025 23:29:07 -0700 Subject: [PATCH 01/20] App: Running FreeCAD in verbose mode information to reflect Gui -> Help -> About Dialog info (#20487) --- src/App/Application.cpp | 289 ++++++++++++++++++++++++++++++++--- src/App/Application.h | 11 ++ src/Gui/Application.cpp | 42 +++++ src/Gui/Application.h | 3 + src/Gui/Dialogs/DlgAbout.cpp | 278 +-------------------------------- src/Main/MainCmd.cpp | 13 ++ src/Main/MainGui.cpp | 11 ++ 7 files changed, 354 insertions(+), 293 deletions(-) diff --git a/src/App/Application.cpp b/src/App/Application.cpp index 8fdaf9f2d2..3acf6856ad 100644 --- a/src/App/Application.cpp +++ b/src/App/Application.cpp @@ -64,7 +64,9 @@ #include #include #include +#include #include +#include #include #include @@ -172,6 +174,7 @@ FC_LOG_LEVEL_INIT("App", true, true) using namespace App; namespace sp = std::placeholders; +namespace fs = std::filesystem; //========================================================================== // Application @@ -2384,28 +2387,10 @@ void parseProgramOptions(int ac, char ** av, const std::string& exe, boost::prog void processProgramOptions(const boost::program_options::variables_map& vm, std::map& mConfig) { - if (vm.count("version")) { + if (vm.count("version") && !vm.count("verbose")) { std::stringstream str; str << mConfig["ExeName"] << " " << mConfig["ExeVersion"] << " Revision: " << mConfig["BuildRevision"] << '\n'; - if (vm.count("verbose")) { - str << "\nLibrary versions:\n"; - str << "boost " << BOOST_LIB_VERSION << '\n'; - str << "Coin3D " << fcCoin3dVersion << '\n'; - str << "Eigen3 " << fcEigen3Version << '\n'; -#ifdef OCC_VERSION_STRING_EXT - str << "OCC " << OCC_VERSION_STRING_EXT << '\n'; -#endif - str << "Qt " << QT_VERSION_STR << '\n'; - str << "Python " << PY_VERSION << '\n'; - str << "PySide " << fcPysideVersion << '\n'; - str << "shiboken " << fcShibokenVersion << '\n'; -#ifdef SMESH_VERSION_STR - str << "SMESH " << SMESH_VERSION_STR << '\n'; -#endif - str << "VTK " << fcVtkVersion << '\n'; - str << "xerces-c " << fcXercescVersion << '\n'; - } throw Base::ProgramInformation(str.str()); } @@ -2535,6 +2520,7 @@ void processProgramOptions(const boost::program_options::variables_map& vm, std: } } } + } // clang-format on @@ -2670,7 +2656,7 @@ void Application::initConfig(int argc, char ** argv) _pConsoleObserverFile = nullptr; // Banner =========================================================== - if (mConfig["RunMode"] != "Cmd") { + if (mConfig["RunMode"] != "Cmd" && !(vm.count("verbose") && vm.count("version"))) { // Remove banner if FreeCAD is invoked via the -c command as regular // Python interpreter if (mConfig["Verbose"] != "Strict") @@ -2781,6 +2767,11 @@ void Application::initConfig(int argc, char ** argv) logStatus(); + + if (vm.count("verbose") && vm.count("version")) { + Application::_pcSingleton = new Application(mConfig); + throw Base::ProgramInformation(Application::verboseVersionEmitMessage); + } } void Application::SaveEnv(const char* s) @@ -3549,3 +3540,261 @@ std::string Application::FindHomePath(const char* sCall) #else # error "std::string Application::FindHomePath(const char*) not implemented" #endif + +QString Application::prettyProductInfoWrapper() +{ + auto productName = QSysInfo::prettyProductName(); +#if QT_VERSION < QT_VERSION_CHECK(6, 5, 0) +#ifdef FC_OS_MACOSX + auto macosVersionFile = + QStringLiteral("/System/Library/CoreServices/.SystemVersionPlatform.plist"); + auto fi = QFileInfo(macosVersionFile); + if (fi.exists() && fi.isReadable()) { + auto plistFile = QFile(macosVersionFile); + plistFile.open(QIODevice::ReadOnly); + while (!plistFile.atEnd()) { + auto line = plistFile.readLine(); + if (line.contains("ProductUserVisibleVersion")) { + auto nextLine = plistFile.readLine(); + if (nextLine.contains("")) { + QRegularExpression re(QStringLiteral("\\s*(.*)")); + auto matches = re.match(QString::fromUtf8(nextLine)); + if (matches.hasMatch()) { + productName = QStringLiteral("macOS ") + matches.captured(1); + break; + } + } + } + } + } +#endif +#endif +#ifdef FC_OS_WIN64 + QSettings regKey { + QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"), + QSettings::NativeFormat}; + if (regKey.contains(QStringLiteral("CurrentBuildNumber"))) { + auto buildNumber = regKey.value(QStringLiteral("CurrentBuildNumber")).toInt(); + if (buildNumber > 0) { + if (buildNumber < 9200) { + productName = QStringLiteral("Windows 7 build %1").arg(buildNumber); + } + else if (buildNumber < 10240) { + productName = QStringLiteral("Windows 8 build %1").arg(buildNumber); + } + else if (buildNumber < 22000) { + productName = QStringLiteral("Windows 10 build %1").arg(buildNumber); + } + else { + productName = QStringLiteral("Windows 11 build %1").arg(buildNumber); + } + } + } +#endif + return productName; +} + +void Application::addModuleInfo(QTextStream& str, const QString& modPath, bool& firstMod) +{ + QFileInfo mod(modPath); + if (mod.isHidden()) { // Ignore hidden directories + return; + } + if (firstMod) { + firstMod = false; + str << "Installed mods: \n"; + } + str << " * " << (mod.isDir() ? QDir(modPath).dirName() : mod.fileName()); + try { + auto metadataFile = + std::filesystem::path(mod.absoluteFilePath().toStdString()) / "package.xml"; + if (std::filesystem::exists(metadataFile)) { + App::Metadata metadata(metadataFile); + if (metadata.version() != App::Meta::Version()) { + str << QLatin1String(" ") + QString::fromStdString(metadata.version().str()); + } + } + } + catch (const Base::Exception& e) { + auto what = QString::fromUtf8(e.what()).trimmed().replace(QChar::fromLatin1('\n'), + QChar::fromLatin1(' ')); + str << " (Malformed metadata: " << what << ")"; + } + QFileInfo disablingFile(mod.absoluteFilePath(), QStringLiteral("ADDON_DISABLED")); + if (disablingFile.exists()) { + str << " (Disabled)"; + } + + str << "\n"; +} + +QString Application::getValueOrEmpty(const std::map& map, const std::string& key) { + auto it = map.find(key); + return (it != map.end()) ? QString::fromStdString(it->second) : QString(); +} + +void Application::getVerboseCommonInfo(QTextStream& str, const std::map& mConfig) +{ + std::map::iterator it; + const QString deskEnv = + QProcessEnvironment::systemEnvironment().value(QStringLiteral("XDG_CURRENT_DESKTOP"), + QString()); + const QString deskSess = + QProcessEnvironment::systemEnvironment().value(QStringLiteral("DESKTOP_SESSION"), + QString()); + + const QString major = getValueOrEmpty(mConfig, "BuildVersionMajor"); + const QString minor = getValueOrEmpty(mConfig, "BuildVersionMinor"); + const QString point = getValueOrEmpty(mConfig, "BuildVersionPoint"); + const QString suffix = getValueOrEmpty(mConfig, "BuildVersionSuffix"); + const QString build = getValueOrEmpty(mConfig, "BuildRevision"); + const QString buildDate = getValueOrEmpty(mConfig, "BuildRevisionDate"); + + QStringList deskInfoList; + QString deskInfo; + + if (!deskEnv.isEmpty()) { + deskInfoList.append(deskEnv); + } + if (!deskSess.isEmpty()) { + deskInfoList.append(deskSess); + } + + const QString sysType = QSysInfo::productType(); + if (sysType != QLatin1String("windows") && sysType != QLatin1String("macos")) { + QString sessionType = QProcessEnvironment::systemEnvironment().value(QStringLiteral("XDG_SESSION_TYPE"), + QString()); + if (sessionType == QLatin1String("x11")) { + sessionType = QStringLiteral("xcb"); + } + deskInfoList.append(sessionType); + } + if (!deskInfoList.isEmpty()) { + deskInfo = QLatin1String(" (") + deskInfoList.join(QLatin1String("/")) + QLatin1String(")"); + } + + str << "OS: " << prettyProductInfoWrapper() << deskInfo << '\n'; + if (QSysInfo::buildCpuArchitecture() == QSysInfo::currentCpuArchitecture()) { + str << "Architecture: " << QSysInfo::buildCpuArchitecture() << "\n"; + } + else { + str << "Architecture: " << QSysInfo::buildCpuArchitecture() + << "(running on: " << QSysInfo::currentCpuArchitecture() << ")\n"; + } + str << "Version: " << major << "." << minor << "." << point << suffix << "." << build; + +#ifdef FC_CONDA + str << " Conda"; +#endif +#ifdef FC_FLATPAK + str << " Flatpak"; +#endif + const char* appimage = getenv("APPIMAGE"); + if (appimage) { + str << " AppImage"; + } + const char* snap = getenv("SNAP_REVISION"); + if (snap) { + str << " Snap " << snap; + } + str << '\n'; + str << "Build date: " << buildDate << "\n"; + +#if defined(_DEBUG) || defined(DEBUG) + str << "Build type: Debug\n"; +#elif defined(NDEBUG) + str << "Build type: Release\n"; +#elif defined(CMAKE_BUILD_TYPE) + str << "Build type: " << CMAKE_BUILD_TYPE << '\n'; +#else + str << "Build type: Unknown\n"; +#endif + const QString buildRevisionBranch = getValueOrEmpty(mConfig, "BuildRevisionBranch"); + if (!buildRevisionBranch.isEmpty()) { + str << "Branch: " << buildRevisionBranch << '\n'; + } + const QString buildRevisionHash = getValueOrEmpty(mConfig, "BuildRevisionHash"); + if (!buildRevisionHash.isEmpty()) { + str << "Hash: " << buildRevisionHash << '\n'; + } + // report also the version numbers of the most important libraries in FreeCAD + str << "Python " << PY_VERSION << ", "; + str << "Qt " << QT_VERSION_STR << ", "; + str << "Coin " << COIN_VERSION << ", "; + str << "Vtk " << fcVtkVersion << ", "; + str << "boost " << BOOST_LIB_VERSION << ", "; + str << "Eigen3 " << fcEigen3Version << ", "; + str << "PySide " << fcPysideVersion << '\n'; + str << "shiboken " << fcShibokenVersion << ", "; +#ifdef SMESH_VERSION_STR + str << "SMESH " << SMESH_VERSION_STR << ", "; +#endif + str << "xerces-c " << fcXercescVersion << ", "; + + const char* cmd = "import ifcopenshell\n" + "version = ifcopenshell.version"; + PyObject * ifcopenshellVer = nullptr; + + try { + ifcopenshellVer = Base::Interpreter().getValue(cmd, "version"); + } + catch (const Base::Exception& e) { + Base::Console().Log("%s (safe to ignore, unless using the BIM workbench and IFC).\n", e.what()); + } + + if (ifcopenshellVer) { + const char* ifcopenshellVerAsStr = PyUnicode_AsUTF8(ifcopenshellVer); + + if (ifcopenshellVerAsStr) { + str << "IfcOpenShell " << ifcopenshellVerAsStr << ", "; + } + Py_DECREF(ifcopenshellVer); + } + +#if defined(HAVE_OCC_VERSION) + str << "OCC " << OCC_VERSION_MAJOR << "." << OCC_VERSION_MINOR << "." << OCC_VERSION_MAINTENANCE +#ifdef OCC_VERSION_DEVELOPMENT + << "." OCC_VERSION_DEVELOPMENT +#endif + << '\n'; +#endif + QLocale loc; + str << "Locale: " << QLocale::languageToString(loc.language()) << "/" +#if QT_VERSION < QT_VERSION_CHECK(6, 6, 0) + << QLocale::countryToString(loc.country()) +#else + << QLocale::territoryToString(loc.territory()) +#endif + << " (" << loc.name() << ")"; + if (loc != QLocale::system()) { + loc = QLocale::system(); + str << " [ OS: " << QLocale::languageToString(loc.language()) << "/" +#if QT_VERSION < QT_VERSION_CHECK(6, 6, 0) + << QLocale::countryToString(loc.country()) +#else + << QLocale::territoryToString(loc.territory()) +#endif + << " (" << loc.name() << ") ]"; + } + str << "\n"; +} + +void Application::getVerboseAddOnsInfo(QTextStream& str, const std::map& mConfig) { + // Add installed module information: + const auto modDir = fs::path(Application::getUserAppDataDir()) / "Mod"; + bool firstMod = true; + if (fs::exists(modDir) && fs::is_directory(modDir)) { + for (const auto& mod : fs::directory_iterator(modDir)) { + auto dirName = mod.path().string(); + addModuleInfo(str, QString::fromStdString(dirName), firstMod); + } + } + const QString additionalModules = getValueOrEmpty(mConfig, "AdditionalModulePaths"); + + if (!additionalModules.isEmpty()) { + auto mods = additionalModules.split(QChar::fromLatin1(';')); + for (const auto& mod : mods) { + addModuleInfo(str, mod, firstMod); + } + } +} \ No newline at end of file diff --git a/src/App/Application.h b/src/App/Application.h index 93ea57171b..f6eef0365a 100644 --- a/src/App/Application.h +++ b/src/App/Application.h @@ -25,6 +25,7 @@ #define SRC_APP_APPLICATION_H_ #include +#include #include #include @@ -433,6 +434,16 @@ public: static std::string getHelpDir(); //@} + /** @name Verbose Information */ + //@{ + static void getVerboseCommonInfo(QTextStream& str, const std::map& mConfig); + static void getVerboseAddOnsInfo(QTextStream& str, const std::map& mConfig); + static void addModuleInfo(QTextStream& str, const QString& modPath, bool& firstMod); + static QString prettyProductInfoWrapper(); + static QString getValueOrEmpty(const std::map& map, const std::string& key); + static constexpr const char* verboseVersionEmitMessage{"verbose_version"}; + //@} + /** @name Link handling */ //@{ diff --git a/src/Gui/Application.cpp b/src/Gui/Application.cpp index 24c5bceea4..f7680c8b91 100644 --- a/src/Gui/Application.cpp +++ b/src/Gui/Application.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -2631,3 +2632,44 @@ App::Document* Application::reopen(App::Document* doc) } return doc; } + +void Application::getVerboseDPIStyleInfo(QTextStream& str) { + // Add Stylesheet/Theme/Qtstyle information + std::string styleSheet = + App::GetApplication() + .GetParameterGroupByPath("User parameter:BaseApp/Preferences/MainWindow") + ->GetASCII("StyleSheet"); + std::string theme = + App::GetApplication() + .GetParameterGroupByPath("User parameter:BaseApp/Preferences/MainWindow") + ->GetASCII("Theme"); +#if QT_VERSION >= QT_VERSION_CHECK(6, 1, 0) + std::string style = qApp->style()->name().toStdString(); +#else + std::string style = + App::GetApplication() + .GetParameterGroupByPath("User parameter:BaseApp/Preferences/MainWindow") + ->GetASCII("QtStyle"); + if (style.empty()) { + style = "Qt default"; + } +#endif + if (styleSheet.empty()) { + styleSheet = "unset"; + } + if (theme.empty()) { + theme = "unset"; + } + + str << "Stylesheet/Theme/QtStyle: " << QString::fromStdString(styleSheet) << "/" + << QString::fromStdString(theme) << "/" << QString::fromStdString(style) << "\n"; + + // Add DPI information + str << "Logical DPI/Physical DPI/Pixel Ratio: " + << QApplication::primaryScreen()->logicalDotsPerInch() + << "/" + << QApplication::primaryScreen()->physicalDotsPerInch() + << "/" + << QApplication::primaryScreen()->devicePixelRatio() + << "\n"; +} \ No newline at end of file diff --git a/src/Gui/Application.h b/src/Gui/Application.h index 54f7c4dd15..3cece3a157 100644 --- a/src/Gui/Application.h +++ b/src/Gui/Application.h @@ -252,6 +252,9 @@ public: void tryClose( QCloseEvent * e ); //@} + /// get verbose DPI and style info + static void getVerboseDPIStyleInfo(QTextStream& str); + /// whenever GUI is about to start with the main window hidden static bool hiddenMainWindow(); /// return the status bits diff --git a/src/Gui/Dialogs/DlgAbout.cpp b/src/Gui/Dialogs/DlgAbout.cpp index bc8d661407..12b54089a2 100644 --- a/src/Gui/Dialogs/DlgAbout.cpp +++ b/src/Gui/Dialogs/DlgAbout.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -62,59 +63,6 @@ using namespace Gui; using namespace Gui::Dialog; namespace fs = std::filesystem; -static QString prettyProductInfoWrapper() -{ - auto productName = QSysInfo::prettyProductName(); -#if QT_VERSION < QT_VERSION_CHECK(6, 5, 0) -#ifdef FC_OS_MACOSX - auto macosVersionFile = - QStringLiteral("/System/Library/CoreServices/.SystemVersionPlatform.plist"); - auto fi = QFileInfo(macosVersionFile); - if (fi.exists() && fi.isReadable()) { - auto plistFile = QFile(macosVersionFile); - plistFile.open(QIODevice::ReadOnly); - while (!plistFile.atEnd()) { - auto line = plistFile.readLine(); - if (line.contains("ProductUserVisibleVersion")) { - auto nextLine = plistFile.readLine(); - if (nextLine.contains("")) { - QRegularExpression re(QStringLiteral("\\s*(.*)")); - auto matches = re.match(QString::fromUtf8(nextLine)); - if (matches.hasMatch()) { - productName = QStringLiteral("macOS ") + matches.captured(1); - break; - } - } - } - } - } -#endif -#endif -#ifdef FC_OS_WIN64 - QSettings regKey { - QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"), - QSettings::NativeFormat}; - if (regKey.contains(QStringLiteral("CurrentBuildNumber"))) { - auto buildNumber = regKey.value(QStringLiteral("CurrentBuildNumber")).toInt(); - if (buildNumber > 0) { - if (buildNumber < 9200) { - productName = QStringLiteral("Windows 7 build %1").arg(buildNumber); - } - else if (buildNumber < 10240) { - productName = QStringLiteral("Windows 8 build %1").arg(buildNumber); - } - else if (buildNumber < 22000) { - productName = QStringLiteral("Windows 10 build %1").arg(buildNumber); - } - else { - productName = QStringLiteral("Windows 11 build %1").arg(buildNumber); - } - } - } -#endif - return productName; -} - // ------------------------------------------------------------------------------ AboutDialogFactory* AboutDialogFactory::factory = nullptr; @@ -296,7 +244,7 @@ void AboutDialog::setupLabels() ui->labelBuildDate->setText(date); QString os = ui->labelBuildOS->text(); - os.replace(QStringLiteral("Unknown"), prettyProductInfoWrapper()); + os.replace(QStringLiteral("Unknown"), App::Application::prettyProductInfoWrapper()); ui->labelBuildOS->setText(os); QString architecture = ui->labelBuildRunArchitecture->text(); @@ -527,230 +475,14 @@ void AboutDialog::linkActivated(const QUrl& link) licenseView->setSource(link); } -void AboutDialog::addModuleInfo(QTextStream& str, const QString& modPath, bool& firstMod) -{ - QFileInfo mod(modPath); - if (mod.isHidden()) { // Ignore hidden directories - return; - } - if (firstMod) { - firstMod = false; - str << "Installed mods: \n"; - } - str << " * " << (mod.isDir() ? QDir(modPath).dirName() : mod.fileName()); - try { - auto metadataFile = - std::filesystem::path(mod.absoluteFilePath().toStdString()) / "package.xml"; - if (std::filesystem::exists(metadataFile)) { - App::Metadata metadata(metadataFile); - if (metadata.version() != App::Meta::Version()) { - str << QLatin1String(" ") + QString::fromStdString(metadata.version().str()); - } - } - } - catch (const Base::Exception& e) { - auto what = QString::fromUtf8(e.what()).trimmed().replace(QChar::fromLatin1('\n'), - QChar::fromLatin1(' ')); - str << " (Malformed metadata: " << what << ")"; - } - QFileInfo disablingFile(mod.absoluteFilePath(), QStringLiteral("ADDON_DISABLED")); - if (disablingFile.exists()) { - str << " (Disabled)"; - } - - str << "\n"; -} - void AboutDialog::copyToClipboard() { QString data; QTextStream str(&data); std::map& config = App::Application::Config(); - std::map::iterator it; - QString exe = QString::fromStdString(App::Application::getExecutableName()); - - QString major = QString::fromStdString(config["BuildVersionMajor"]); - QString minor = QString::fromStdString(config["BuildVersionMinor"]); - QString point = QString::fromStdString(config["BuildVersionPoint"]); - QString suffix = QString::fromStdString(config["BuildVersionSuffix"]); - QString build = QString::fromStdString(config["BuildRevision"]); - QString buildDate = QString::fromStdString(config["BuildRevisionDate"]); - - QString deskEnv = - QProcessEnvironment::systemEnvironment().value(QStringLiteral("XDG_CURRENT_DESKTOP"), - QString()); - QString deskSess = - QProcessEnvironment::systemEnvironment().value(QStringLiteral("DESKTOP_SESSION"), - QString()); - QStringList deskInfoList; - QString deskInfo; - - if (!deskEnv.isEmpty()) { - deskInfoList.append(deskEnv); - } - if (!deskSess.isEmpty()) { - deskInfoList.append(deskSess); - } - if (qGuiApp->platformName() != QLatin1String("windows") - && qGuiApp->platformName() != QLatin1String("cocoa")) { - deskInfoList.append(qGuiApp->platformName()); - } - if (!deskInfoList.isEmpty()) { - deskInfo = QLatin1String(" (") + deskInfoList.join(QLatin1String("/")) + QLatin1String(")"); - } - - str << "OS: " << prettyProductInfoWrapper() << deskInfo << '\n'; - if (QSysInfo::buildCpuArchitecture() == QSysInfo::currentCpuArchitecture()) { - str << "Architecture: " << QSysInfo::buildCpuArchitecture() << "\n"; - } - else { - str << "Architecture: " << QSysInfo::buildCpuArchitecture() - << "(running on: " << QSysInfo::currentCpuArchitecture() << ")\n"; - } - str << "Version: " << major << "." << minor << "." << point << suffix << "." << build; -#ifdef FC_CONDA - str << " Conda"; -#endif -#ifdef FC_FLATPAK - str << " Flatpak"; -#endif - char* appimage = getenv("APPIMAGE"); - if (appimage) { - str << " AppImage"; - } - char* snap = getenv("SNAP_REVISION"); - if (snap) { - str << " Snap " << snap; - } - str << '\n'; - str << "Build date: " << buildDate << "\n"; - -#if defined(_DEBUG) || defined(DEBUG) - str << "Build type: Debug\n"; -#elif defined(NDEBUG) - str << "Build type: Release\n"; -#elif defined(CMAKE_BUILD_TYPE) - str << "Build type: " << CMAKE_BUILD_TYPE << '\n'; -#else - str << "Build type: Unknown\n"; -#endif - it = config.find("BuildRevisionBranch"); - if (it != config.end()) { - str << "Branch: " << QString::fromStdString(it->second) << '\n'; - } - it = config.find("BuildRevisionHash"); - if (it != config.end()) { - str << "Hash: " << QString::fromStdString(it->second) << '\n'; - } - // report also the version numbers of the most important libraries in FreeCAD - str << "Python " << PY_VERSION << ", "; - str << "Qt " << QT_VERSION_STR << ", "; - str << "Coin " << COIN_VERSION << ", "; - str << "Vtk " << fcVtkVersion << ", "; - - const char* cmd = "import ifcopenshell\n" - "version = ifcopenshell.version"; - PyObject * ifcopenshellVer = nullptr; - - try { - ifcopenshellVer = Base::Interpreter().getValue(cmd, "version"); - } - catch (const Base::Exception& e) { - Base::Console().Log("%s (safe to ignore, unless using the BIM workbench and IFC).\n", e.what()); - } - - if (ifcopenshellVer) { - const char* ifcopenshellVerAsStr = PyUnicode_AsUTF8(ifcopenshellVer); - - if (ifcopenshellVerAsStr) { - str << "IfcOpenShell " << ifcopenshellVerAsStr << ", "; - } - Py_DECREF(ifcopenshellVer); - } - -#if defined(HAVE_OCC_VERSION) - str << "OCC " << OCC_VERSION_MAJOR << "." << OCC_VERSION_MINOR << "." << OCC_VERSION_MAINTENANCE -#ifdef OCC_VERSION_DEVELOPMENT - << "." OCC_VERSION_DEVELOPMENT -#endif - << '\n'; -#endif - QLocale loc; - str << "Locale: " << QLocale::languageToString(loc.language()) << "/" -#if QT_VERSION < QT_VERSION_CHECK(6, 6, 0) - << QLocale::countryToString(loc.country()) -#else - << QLocale::territoryToString(loc.territory()) -#endif - << " (" << loc.name() << ")"; - if (loc != QLocale::system()) { - loc = QLocale::system(); - str << " [ OS: " << QLocale::languageToString(loc.language()) << "/" -#if QT_VERSION < QT_VERSION_CHECK(6, 6, 0) - << QLocale::countryToString(loc.country()) -#else - << QLocale::territoryToString(loc.territory()) -#endif - << " (" << loc.name() << ") ]"; - } - str << "\n"; - - // Add Stylesheet/Theme/Qtstyle information - std::string styleSheet = - App::GetApplication() - .GetParameterGroupByPath("User parameter:BaseApp/Preferences/MainWindow") - ->GetASCII("StyleSheet"); - std::string theme = - App::GetApplication() - .GetParameterGroupByPath("User parameter:BaseApp/Preferences/MainWindow") - ->GetASCII("Theme"); -#if QT_VERSION >= QT_VERSION_CHECK(6, 1, 0) - std::string style = qApp->style()->name().toStdString(); -#else - std::string style = - App::GetApplication() - .GetParameterGroupByPath("User parameter:BaseApp/Preferences/MainWindow") - ->GetASCII("QtStyle"); - if (style.empty()) { - style = "Qt default"; - } -#endif - if (styleSheet.empty()) { - styleSheet = "unset"; - } - if (theme.empty()) { - theme = "unset"; - } - - str << "Stylesheet/Theme/QtStyle: " << QString::fromStdString(styleSheet) << "/" - << QString::fromStdString(theme) << "/" << QString::fromStdString(style) << "\n"; - - // Add DPI information - str << "Logical DPI/Physical DPI/Pixel Ratio: " - << QApplication::primaryScreen()->logicalDotsPerInch() - << "/" - << QApplication::primaryScreen()->physicalDotsPerInch() - << "/" - << QApplication::primaryScreen()->devicePixelRatio() - << "\n"; - - // Add installed module information: - auto modDir = fs::path(App::Application::getUserAppDataDir()) / "Mod"; - bool firstMod = true; - if (fs::exists(modDir) && fs::is_directory(modDir)) { - for (const auto& mod : fs::directory_iterator(modDir)) { - auto dirName = mod.path().string(); - addModuleInfo(str, QString::fromStdString(dirName), firstMod); - } - } - auto additionalModules = config.find("AdditionalModulePaths"); - - if (additionalModules != config.end()) { - auto mods = QString::fromStdString(additionalModules->second).split(QChar::fromLatin1(';')); - for (const auto& mod : mods) { - addModuleInfo(str, mod, firstMod); - } - } + App::Application::getVerboseCommonInfo(str, config); + Gui::Application::getVerboseDPIStyleInfo(str); + App::Application::getVerboseAddOnsInfo(str, config); QClipboard* cb = QApplication::clipboard(); cb->setText(data); diff --git a/src/Main/MainCmd.cpp b/src/Main/MainCmd.cpp index 01ffa7bd78..515d726845 100644 --- a/src/Main/MainCmd.cpp +++ b/src/Main/MainCmd.cpp @@ -38,6 +38,8 @@ #include #include +#include + // FreeCAD Base header #include #include @@ -91,6 +93,17 @@ int main(int argc, char** argv) exit(1); } catch (const Base::ProgramInformation& e) { + if (std::strcmp(e.what(), App::Application::verboseVersionEmitMessage) == 0) { + QString data; + QTextStream str(&data); + const std::map config = App::Application::Config(); + + App::Application::getVerboseCommonInfo(str, config); + App::Application::getVerboseAddOnsInfo(str, config); + + std::cout << data.toStdString(); + exit(0); + } std::cout << e.what(); exit(0); } diff --git a/src/Main/MainGui.cpp b/src/Main/MainGui.cpp index 8d37610671..912c16570c 100644 --- a/src/Main/MainGui.cpp +++ b/src/Main/MainGui.cpp @@ -250,6 +250,17 @@ int main(int argc, char** argv) catch (const Base::ProgramInformation& e) { QApplication app(argc, argv); QString msg = QString::fromUtf8(e.what()); + if (msg == QLatin1String(App::Application::verboseVersionEmitMessage)) { + QString data; + QTextStream str(&data); + const std::map config = App::Application::Config(); + + App::Application::getVerboseCommonInfo(str, config); + Gui::Application::getVerboseDPIStyleInfo(str); + App::Application::getVerboseAddOnsInfo(str, config); + + msg = data; + } DisplayInfo(msg); exit(0); } From cd673390e2d5a534bd06a370612894de25685cc7 Mon Sep 17 00:00:00 2001 From: tarman3 Date: Wed, 16 Apr 2025 12:54:04 +0300 Subject: [PATCH 02/20] CAM: Fix postprocessors Help arguments --postamble and --preamble (#20792) --- .../CAM/Path/Post/scripts/KineticNCBeamicon2_post.py | 10 +++++----- src/Mod/CAM/Path/Post/scripts/centroid_post.py | 8 ++++---- src/Mod/CAM/Path/Post/scripts/dynapath_4060_post.py | 12 ++++++------ src/Mod/CAM/Path/Post/scripts/dynapath_post.py | 12 ++++++------ src/Mod/CAM/Path/Post/scripts/estlcam_post.py | 12 ++++++------ src/Mod/CAM/Path/Post/scripts/fablin_post.py | 8 ++++---- src/Mod/CAM/Path/Post/scripts/fangling_post.py | 10 +++++----- src/Mod/CAM/Path/Post/scripts/fanuc_post.py | 10 +++++----- src/Mod/CAM/Path/Post/scripts/grbl_post.py | 12 ++++++------ src/Mod/CAM/Path/Post/scripts/jtech_post.py | 10 +++++----- src/Mod/CAM/Path/Post/scripts/linuxcnc_post.py | 10 +++++----- src/Mod/CAM/Path/Post/scripts/mach3_mach4_post.py | 10 +++++----- src/Mod/CAM/Path/Post/scripts/marlin_post.py | 10 +++++----- src/Mod/CAM/Path/Post/scripts/rrf_post.py | 10 +++++----- src/Mod/CAM/Path/Post/scripts/smoothie_post.py | 12 ++++++------ src/Mod/CAM/Path/Post/scripts/uccnc_post.py | 6 +++--- src/Mod/CAM/Path/Post/scripts/wedm_post.py | 10 +++++----- 17 files changed, 86 insertions(+), 86 deletions(-) diff --git a/src/Mod/CAM/Path/Post/scripts/KineticNCBeamicon2_post.py b/src/Mod/CAM/Path/Post/scripts/KineticNCBeamicon2_post.py index 2005ca2141..a9f0e083dc 100644 --- a/src/Mod/CAM/Path/Post/scripts/KineticNCBeamicon2_post.py +++ b/src/Mod/CAM/Path/Post/scripts/KineticNCBeamicon2_post.py @@ -68,11 +68,11 @@ parser.add_argument( parser.add_argument("--precision", default="3", help="number of digits of precision, default=3") parser.add_argument( "--preamble", - help='set commands to be issued before the first command, default="%\\nG17 G21 G40 G49 G80 G90\\nM08"', + help='set commands to be issued before the first command, default="%\\nG17 G21 G40 G49 G80 G90\\nM08\\n"', ) parser.add_argument( "--postamble", - help='set commands to be issued after the last command, default="M05 M09\\nG17 G90 G80 G40\\nM30"', + help='set commands to be issued after the last command, default="M05 M09\\nG17 G90 G80 G40\\nM30\\n"', ) parser.add_argument( "--inches", action="store_true", help="Convert output for US imperial mode (G20)" @@ -202,7 +202,7 @@ def export(objectslist, filename, argstring): # Write the preamble if OUTPUT_COMMENTS: gcode += linenumber() + "(begin preamble)\n" - for line in PREAMBLE.splitlines(False): + for line in PREAMBLE.splitlines(): gcode += linenumber() + line + "\n" gcode += linenumber() + UNITS + "\n" @@ -247,8 +247,8 @@ def export(objectslist, filename, argstring): # do the post_amble if OUTPUT_COMMENTS: gcode += "(begin postamble)\n" - for line in POSTAMBLE.splitlines(True): - gcode += linenumber() + line + for line in POSTAMBLE.splitlines(): + gcode += linenumber() + line + "\n" if FreeCAD.GuiUp and SHOW_EDITOR: dia = PostUtils.GCodeEditorDialog() diff --git a/src/Mod/CAM/Path/Post/scripts/centroid_post.py b/src/Mod/CAM/Path/Post/scripts/centroid_post.py index 9047c8f22f..49c58d1137 100644 --- a/src/Mod/CAM/Path/Post/scripts/centroid_post.py +++ b/src/Mod/CAM/Path/Post/scripts/centroid_post.py @@ -193,8 +193,8 @@ def export(objectslist, filename, argstring): ): gcode += ";T{}={}\n".format(item.ToolNumber, item.Name) gcode += linenumber() + ";begin preamble\n" - for line in PREAMBLE.splitlines(True): - gcode += linenumber() + line + for line in PREAMBLE.splitlines(): + gcode += linenumber() + line + "\n" gcode += linenumber() + UNITS + "\n" @@ -221,8 +221,8 @@ def export(objectslist, filename, argstring): gcode += linenumber() + line for line in SAFETYBLOCK.splitlines(True): gcode += linenumber() + line - for line in POSTAMBLE.splitlines(True): - gcode += linenumber() + line + for line in POSTAMBLE.splitlines(): + gcode += linenumber() + line + "\n" if SHOW_EDITOR: dia = PostUtils.GCodeEditorDialog() diff --git a/src/Mod/CAM/Path/Post/scripts/dynapath_4060_post.py b/src/Mod/CAM/Path/Post/scripts/dynapath_4060_post.py index 527ffa2167..f7861567f3 100644 --- a/src/Mod/CAM/Path/Post/scripts/dynapath_4060_post.py +++ b/src/Mod/CAM/Path/Post/scripts/dynapath_4060_post.py @@ -59,11 +59,11 @@ parser.add_argument( parser.add_argument("--precision", default="3", help="number of digits of precision, default=3") parser.add_argument( "--preamble", - help='set commands to be issued before the first command, default="G17\\nG90\\nG80\\nG40"', + help='set commands to be issued before the first command, default="G17\\nG90\\nG80\\nG40\\n"', ) parser.add_argument( "--postamble", - help='set commands to be issued after the last command, default="M09\\nM05\\nG80\\nG40\\nG17\\nG90\\nM30"', + help='set commands to be issued after the last command, default="M09\\nM05\\nG80\\nG40\\nG17\\nG90\\nM30\\n"', ) parser.add_argument( "--inches", action="store_true", help="Convert output for US imperial mode (G70)" @@ -225,8 +225,8 @@ def export(objectslist, filename, argstring): # Write the preamble if OUTPUT_COMMENTS: gcode += linenumber() + "(T)" + "BEGIN PREAMBLE$\n" - for line in PREAMBLE.splitlines(True): - gcode += linenumber() + line + for line in PREAMBLE.splitlines(): + gcode += linenumber() + line + "\n" gcode += linenumber() + UNITS + "\n" for obj in objectslist: @@ -289,8 +289,8 @@ def export(objectslist, filename, argstring): # do the post_amble if OUTPUT_COMMENTS: gcode += linenumber() + "(T)" + "BEGIN POSTAMBLE$\n" - for line in POSTAMBLE.splitlines(True): - gcode += linenumber() + line + for line in POSTAMBLE.splitlines(): + gcode += linenumber() + line + "\n" # Following is required by Dynapath Controls to signify "EOF" when loading in to control # from external media. The control strips the "E" off as part of the load process. gcode += "E\n" diff --git a/src/Mod/CAM/Path/Post/scripts/dynapath_post.py b/src/Mod/CAM/Path/Post/scripts/dynapath_post.py index 4e1b83f3c2..14015f43b9 100644 --- a/src/Mod/CAM/Path/Post/scripts/dynapath_post.py +++ b/src/Mod/CAM/Path/Post/scripts/dynapath_post.py @@ -86,11 +86,11 @@ parser.add_argument( parser.add_argument("--precision", default="3", help="number of digits of precision, default=3") parser.add_argument( "--preamble", - help='set commands to be issued before the first command, default="G17\\nG90\\nG80\\nG40"', + help='set commands to be issued before the first command, default="G17\\nG90\\nG80\\nG40\\n"', ) parser.add_argument( "--postamble", - help='set commands to be issued after the last command, default="M09\\nM05\\nG80\\nG40\\nG17\\nG90\\nM30"', + help='set commands to be issued after the last command, default="M09\\nM05\\nG80\\nG40\\nG17\\nG90\\nM30\\n"', ) parser.add_argument( "--inches", action="store_true", help="Convert output for US imperial mode (G20)" @@ -231,8 +231,8 @@ def export(objectslist, filename, argstring): # Write the preamble if OUTPUT_COMMENTS: gcode += linenumber() + "(begin preamble)\n" - for line in PREAMBLE.splitlines(True): - gcode += linenumber() + line + for line in PREAMBLE.splitlines(): + gcode += linenumber() + line + "\n" gcode += linenumber() + UNITS + "\n" for obj in objectslist: @@ -255,8 +255,8 @@ def export(objectslist, filename, argstring): if OUTPUT_COMMENTS: gcode += "(begin postamble)\n" - for line in POSTAMBLE.splitlines(True): - gcode += linenumber() + line + for line in POSTAMBLE.splitlines(): + gcode += linenumber() + line + "\n" print("show editor: {}".format(SHOW_EDITOR)) if FreeCAD.GuiUp and SHOW_EDITOR: diff --git a/src/Mod/CAM/Path/Post/scripts/estlcam_post.py b/src/Mod/CAM/Path/Post/scripts/estlcam_post.py index 878395c72c..2a571766a1 100644 --- a/src/Mod/CAM/Path/Post/scripts/estlcam_post.py +++ b/src/Mod/CAM/Path/Post/scripts/estlcam_post.py @@ -114,11 +114,11 @@ parser.add_argument( ) parser.add_argument( "--preamble", - help="set commands to be issued before the first command", + help='set commands to be issued before the first command, default=""', ) parser.add_argument( "--postamble", - help="set commands to be issued after the last command", + help='set commands to be issued after the last command, default="M5\\n"', ) parser.add_argument("--precision", default="3", help="number of digits of precision, default=3") parser.add_argument("--inches", action="store_true", help="convert output for US imperial mode") @@ -235,8 +235,8 @@ def export(objectslist, filename, argstring): # Write the preamble if OUTPUT_COMMENTS: gcode += linenumber() + "(Begin preamble)\n" - for line in PREAMBLE.splitlines(True): - gcode += linenumber() + line + for line in PREAMBLE.splitlines(): + gcode += linenumber() + line + "\n" # verify if PREAMBLE have changed UNITS if "G21" in PREAMBLE: UNITS = "G21" @@ -310,8 +310,8 @@ def export(objectslist, filename, argstring): # do the post_amble if OUTPUT_COMMENTS: gcode += linenumber() + "(Begin postamble)\n" - for line in POSTAMBLE.splitlines(True): - gcode += linenumber() + line + for line in POSTAMBLE.splitlines(): + gcode += linenumber() + line + "\n" # show the gCode result dialog if FreeCAD.GuiUp and SHOW_EDITOR: diff --git a/src/Mod/CAM/Path/Post/scripts/fablin_post.py b/src/Mod/CAM/Path/Post/scripts/fablin_post.py index 42aba6ea8c..73c4e640e3 100644 --- a/src/Mod/CAM/Path/Post/scripts/fablin_post.py +++ b/src/Mod/CAM/Path/Post/scripts/fablin_post.py @@ -160,8 +160,8 @@ def export(objectslist, filename, argstring): # Write the preamble if OUTPUT_COMMENTS: gcode += linenumber() + "(begin preamble)\n" - for line in PREAMBLE.splitlines(True): - gcode += linenumber() + line + for line in PREAMBLE.splitlines(): + gcode += linenumber() + line + "\n" for obj in objectslist: @@ -183,8 +183,8 @@ def export(objectslist, filename, argstring): if OUTPUT_COMMENTS: gcode += "(begin postamble)\n" - for line in POSTAMBLE.splitlines(True): - gcode += linenumber() + line + for line in POSTAMBLE.splitlines(): + gcode += linenumber() + line + "\n" if SHOW_EDITOR: dia = PostUtils.GCodeEditorDialog() diff --git a/src/Mod/CAM/Path/Post/scripts/fangling_post.py b/src/Mod/CAM/Path/Post/scripts/fangling_post.py index 7733b978aa..c6938c66b5 100644 --- a/src/Mod/CAM/Path/Post/scripts/fangling_post.py +++ b/src/Mod/CAM/Path/Post/scripts/fangling_post.py @@ -65,11 +65,11 @@ parser.add_argument( ) parser.add_argument("--precision", default="3", help="number of digits of precision, default=3") parser.add_argument( - "--preamble", help='set commands to be issued before the first command, default="G90"' + "--preamble", help='set commands to be issued before the first command, default="G90\\n"' ) parser.add_argument( "--postamble", - help='set commands to be issued after the last command, default="M8\\nG90 G40\\nM2"', + help='set commands to be issued after the last command, default="M8\\nG90 G40\\nM2\\n"', ) parser.add_argument( "--inches", action="store_true", help="Convert output for US imperial mode (G20)" @@ -207,7 +207,7 @@ def export(objectslist, filename, argstring): # Write the preamble if OUTPUT_COMMENTS: gcode += linenumber() + "(begin preamble)\n" - for line in PREAMBLE.splitlines(False): + for line in PREAMBLE.splitlines(): gcode += linenumber() + line + "\n" gcode += linenumber() + UNITS + "\n" @@ -251,8 +251,8 @@ def export(objectslist, filename, argstring): # do the post_amble if OUTPUT_COMMENTS: gcode += "(begin postamble)\n" - for line in POSTAMBLE.splitlines(True): - gcode += linenumber() + line + for line in POSTAMBLE.splitlines(): + gcode += linenumber() + line + "\n" if FreeCAD.GuiUp and SHOW_EDITOR: dia = PostUtils.GCodeEditorDialog() diff --git a/src/Mod/CAM/Path/Post/scripts/fanuc_post.py b/src/Mod/CAM/Path/Post/scripts/fanuc_post.py index fd65a5e731..4487f70457 100644 --- a/src/Mod/CAM/Path/Post/scripts/fanuc_post.py +++ b/src/Mod/CAM/Path/Post/scripts/fanuc_post.py @@ -60,11 +60,11 @@ parser.add_argument( parser.add_argument("--precision", default="3", help="number of digits of precision, default=3") parser.add_argument( "--preamble", - help='set commands to be issued before the first command, default="G17 G54 G40 G49 G80 G90"', + help='set commands to be issued before the first command, default="G17 G54 G40 G49 G80 G90\\n"', ) parser.add_argument( "--postamble", - help='set commands to be issued after the last command, default="M05\\nG17 G54 G90 G80 G40\\nM6 T0\\nM2"', + help='set commands to be issued after the last command, default="M05\\nG17 G54 G90 G80 G40\\nM6 T0\\nM2\\n"', ) parser.add_argument( "--inches", action="store_true", help="Convert output for US imperial mode (G20)" @@ -220,7 +220,7 @@ def export(objectslist, filename, argstring): # Write the preamble if OUTPUT_COMMENTS: gcode += linenumber() + "(BEGIN PREAMBLE)\n" - for line in PREAMBLE.splitlines(False): + for line in PREAMBLE.splitlines(): gcode += linenumber() + line + "\n" gcode += linenumber() + UNITS + "\n" @@ -276,8 +276,8 @@ def export(objectslist, filename, argstring): # do the post_amble if OUTPUT_COMMENTS: gcode += "(BEGIN POSTAMBLE)\n" - for line in POSTAMBLE.splitlines(True): - gcode += linenumber() + line + for line in POSTAMBLE.splitlines(): + gcode += linenumber() + line + "\n" gcode += "%\n" if FreeCAD.GuiUp and SHOW_EDITOR: diff --git a/src/Mod/CAM/Path/Post/scripts/grbl_post.py b/src/Mod/CAM/Path/Post/scripts/grbl_post.py index 1ae2256f8c..3dd7f267af 100644 --- a/src/Mod/CAM/Path/Post/scripts/grbl_post.py +++ b/src/Mod/CAM/Path/Post/scripts/grbl_post.py @@ -123,11 +123,11 @@ parser.add_argument( ) parser.add_argument( "--preamble", - help='set commands to be issued before the first command, default="G17 G90"', + help='set commands to be issued before the first command, default="G17 G90\\n"', ) parser.add_argument( "--postamble", - help='set commands to be issued after the last command, default="M5\\nG17 G90\\nM2"', + help='set commands to be issued after the last command, default="M5\\nG17 G90\\nM2\\n"', ) parser.add_argument( "--inches", action="store_true", help="Convert output for US imperial mode (G20)" @@ -283,8 +283,8 @@ def export(objectslist, filename, argstring): # Write the preamble if OUTPUT_COMMENTS: gcode += linenumber() + "(Begin preamble)\n" - for line in PREAMBLE.splitlines(True): - gcode += linenumber() + line + for line in PREAMBLE.splitlines(): + gcode += linenumber() + line + "\n" # verify if PREAMBLE have changed MOTION_MODE or UNITS if "G90" in PREAMBLE: MOTION_MODE = "G90" @@ -370,8 +370,8 @@ def export(objectslist, filename, argstring): gcode += linenumber() + "(Block-enable: 1)\n" if OUTPUT_COMMENTS: gcode += linenumber() + "(Begin postamble)\n" - for line in POSTAMBLE.splitlines(True): - gcode += linenumber() + line + for line in POSTAMBLE.splitlines(): + gcode += linenumber() + line + "\n" # show the gCode result dialog if FreeCAD.GuiUp and SHOW_EDITOR: diff --git a/src/Mod/CAM/Path/Post/scripts/jtech_post.py b/src/Mod/CAM/Path/Post/scripts/jtech_post.py index 17f89d05b1..35e12487ea 100644 --- a/src/Mod/CAM/Path/Post/scripts/jtech_post.py +++ b/src/Mod/CAM/Path/Post/scripts/jtech_post.py @@ -56,11 +56,11 @@ parser.add_argument( parser.add_argument("--precision", default="3", help="number of digits of precision, default=3") parser.add_argument( "--preamble", - help='set commands to be issued before the first command, default="M05 S0\\nG90"', + help='set commands to be issued before the first command, default="M05 S0\\nG90\\n"', ) parser.add_argument( "--postamble", - help='set commands to be issued after the last command, default="M05 S0\\nM2"', + help='set commands to be issued after the last command, default="M05 S0\\nM2\\n"', ) parser.add_argument( "--inches", action="store_true", help="Convert output for US imperial mode (G20)" @@ -198,7 +198,7 @@ def export(objectslist, filename, argstring): # Write the preamble if OUTPUT_COMMENTS: gcode += linenumber() + "(begin preamble)\n" - for line in PREAMBLE.splitlines(False): + for line in PREAMBLE.splitlines(): gcode += linenumber() + line + "\n" gcode += linenumber() + UNITS + "\n" @@ -221,8 +221,8 @@ def export(objectslist, filename, argstring): # do the post_amble if OUTPUT_COMMENTS: gcode += "(begin postamble)\n" - for line in POSTAMBLE.splitlines(True): - gcode += linenumber() + line + for line in POSTAMBLE.splitlines(): + gcode += linenumber() + line + "\n" if FreeCAD.GuiUp and SHOW_EDITOR: dia = PostUtils.GCodeEditorDialog() diff --git a/src/Mod/CAM/Path/Post/scripts/linuxcnc_post.py b/src/Mod/CAM/Path/Post/scripts/linuxcnc_post.py index 6697d8dc07..5a0e676936 100644 --- a/src/Mod/CAM/Path/Post/scripts/linuxcnc_post.py +++ b/src/Mod/CAM/Path/Post/scripts/linuxcnc_post.py @@ -56,11 +56,11 @@ parser.add_argument( parser.add_argument("--precision", default="3", help="number of digits of precision, default=3") parser.add_argument( "--preamble", - help='set commands to be issued before the first command, default="G17 G54 G40 G49 G80 G90"', + help='set commands to be issued before the first command, default="G17 G54 G40 G49 G80 G90\\n"', ) parser.add_argument( "--postamble", - help='set commands to be issued after the last command, default="M05\\nG17 G54 G90 G80 G40\\nM2"', + help='set commands to be issued after the last command, default="M05\\nG17 G54 G90 G80 G40\\nM2\\n"', ) parser.add_argument( "--inches", action="store_true", help="Convert output for US imperial mode (G20)" @@ -196,7 +196,7 @@ def export(objectslist, filename, argstring): # Write the preamble if OUTPUT_COMMENTS: gcode += linenumber() + "(begin preamble)\n" - for line in PREAMBLE.splitlines(False): + for line in PREAMBLE.splitlines(): gcode += linenumber() + line + "\n" gcode += linenumber() + UNITS + "\n" @@ -252,8 +252,8 @@ def export(objectslist, filename, argstring): # do the post_amble if OUTPUT_COMMENTS: gcode += "(begin postamble)\n" - for line in POSTAMBLE.splitlines(True): - gcode += linenumber() + line + for line in POSTAMBLE.splitlines(): + gcode += linenumber() + line + "\n" if FreeCAD.GuiUp and SHOW_EDITOR: final = gcode diff --git a/src/Mod/CAM/Path/Post/scripts/mach3_mach4_post.py b/src/Mod/CAM/Path/Post/scripts/mach3_mach4_post.py index 6c5fcf5770..a450895333 100644 --- a/src/Mod/CAM/Path/Post/scripts/mach3_mach4_post.py +++ b/src/Mod/CAM/Path/Post/scripts/mach3_mach4_post.py @@ -56,11 +56,11 @@ parser.add_argument( parser.add_argument("--precision", default="3", help="number of digits of precision, default=3") parser.add_argument( "--preamble", - help='set commands to be issued before the first command, default="G17 G54 G40 G49 G80 G90"', + help='set commands to be issued before the first command, default="G17 G54 G40 G49 G80 G90\\n"', ) parser.add_argument( "--postamble", - help='set commands to be issued after the last command, default="M05\\nG17 G54 G90 G80 G40\\nM2"', + help='set commands to be issued after the last command, default="M05\\nG17 G54 G90 G80 G40\\nM2\\n"', ) parser.add_argument( "--inches", action="store_true", help="Convert output for US imperial mode (G20)" @@ -196,7 +196,7 @@ def export(objectslist, filename, argstring): # Write the preamble if OUTPUT_COMMENTS: gcode += linenumber() + "(begin preamble)\n" - for line in PREAMBLE.splitlines(False): + for line in PREAMBLE.splitlines(): gcode += linenumber() + line + "\n" gcode += linenumber() + UNITS + "\n" @@ -255,8 +255,8 @@ def export(objectslist, filename, argstring): # do the post_amble if OUTPUT_COMMENTS: gcode += "(begin postamble)\n" - for line in POSTAMBLE.splitlines(True): - gcode += linenumber() + line + for line in POSTAMBLE.splitlines(): + gcode += linenumber() + line + "\n" if FreeCAD.GuiUp and SHOW_EDITOR: dia = PostUtils.GCodeEditorDialog() diff --git a/src/Mod/CAM/Path/Post/scripts/marlin_post.py b/src/Mod/CAM/Path/Post/scripts/marlin_post.py index df0babcdf9..6705a84797 100644 --- a/src/Mod/CAM/Path/Post/scripts/marlin_post.py +++ b/src/Mod/CAM/Path/Post/scripts/marlin_post.py @@ -156,7 +156,7 @@ parser.add_argument( "--preamble", help='set commands to be issued before the first command, default=""' ) parser.add_argument( - "--postamble", help='set commands to be issued after the last command, default="M5"' + "--postamble", help='set commands to be issued after the last command, default="M5\\n"' ) parser.add_argument("--tool-change", action="store_true", help="Insert M6 for all tool changes") parser.add_argument( @@ -334,8 +334,8 @@ def export(objectslist, filename, argstring): # Write the preamble: if OUTPUT_COMMENTS: gcode += linenumber() + "(Begin preamble)\n" - for line in PREAMBLE.splitlines(True): - gcode += linenumber() + line + for line in PREAMBLE.splitlines(): + gcode += linenumber() + line + "\n" # Write these settings AFTER the preamble, # to prevent the preamble from changing these: @@ -409,8 +409,8 @@ def export(objectslist, filename, argstring): gcode += linenumber() + "(Block-enable: 1)\n" if OUTPUT_COMMENTS: gcode += linenumber() + "(Begin postamble)\n" - for line in POSTAMBLE.splitlines(True): - gcode += linenumber() + line + for line in POSTAMBLE.splitlines(): + gcode += linenumber() + line + "\n" # Optionally add a final XYZ position to the end of the gcode: if RETURN_TO: diff --git a/src/Mod/CAM/Path/Post/scripts/rrf_post.py b/src/Mod/CAM/Path/Post/scripts/rrf_post.py index d6423e5e60..d578a9b17f 100644 --- a/src/Mod/CAM/Path/Post/scripts/rrf_post.py +++ b/src/Mod/CAM/Path/Post/scripts/rrf_post.py @@ -154,7 +154,7 @@ parser.add_argument( "--preamble", help='set commands to be issued before the first command, default=""' ) parser.add_argument( - "--postamble", help='set commands to be issued after the last command, default="M5"' + "--postamble", help='set commands to be issued after the last command, default="M5\\n"' ) parser.add_argument("--tool-change", action="store_true", help="Insert M6 for all tool changes") parser.add_argument( @@ -332,8 +332,8 @@ def export(objectslist, filename, argstring): # Write the preamble: if OUTPUT_COMMENTS: gcode += linenumber() + "(Begin preamble)\n" - for line in PREAMBLE.splitlines(True): - gcode += linenumber() + line + for line in PREAMBLE.splitlines(): + gcode += linenumber() + line + "\n" # Write these settings AFTER the preamble, # to prevent the preamble from changing these: @@ -407,8 +407,8 @@ def export(objectslist, filename, argstring): gcode += linenumber() + "(Block-enable: 1)\n" if OUTPUT_COMMENTS: gcode += linenumber() + "(Begin postamble)\n" - for line in POSTAMBLE.splitlines(True): - gcode += linenumber() + line + for line in POSTAMBLE.splitlines(): + gcode += linenumber() + line + "\n" # Optionally add a final XYZ position to the end of the gcode: if RETURN_TO: diff --git a/src/Mod/CAM/Path/Post/scripts/smoothie_post.py b/src/Mod/CAM/Path/Post/scripts/smoothie_post.py index 70e6761823..98f4160ebc 100644 --- a/src/Mod/CAM/Path/Post/scripts/smoothie_post.py +++ b/src/Mod/CAM/Path/Post/scripts/smoothie_post.py @@ -68,11 +68,11 @@ parser.add_argument( parser.add_argument("--precision", default="4", help="number of digits of precision, default=4") parser.add_argument( "--preamble", - help='set commands to be issued before the first command, default="G17\\nG90"', + help='set commands to be issued before the first command, default="G17\\nG90\\n"', ) parser.add_argument( "--postamble", - help='set commands to be issued after the last command, default="M05\\nG17 G90\\nM2"', + help='set commands to be issued after the last command, default="M05\\nG17 G90\\nM2\\n"', ) parser.add_argument("--IP_ADDR", help="IP Address for machine target machine") parser.add_argument( @@ -228,8 +228,8 @@ def export(objectslist, filename, argstring): # Write the preamble if OUTPUT_COMMENTS: gcode += linenumber() + "(begin preamble)\n" - for line in PREAMBLE.splitlines(True): - gcode += linenumber() + line + for line in PREAMBLE.splitlines(): + gcode += linenumber() + line + "\n" gcode += linenumber() + UNITS + "\n" for obj in objectslist: @@ -252,8 +252,8 @@ def export(objectslist, filename, argstring): if OUTPUT_COMMENTS: gcode += "(begin postamble)\n" - for line in POSTAMBLE.splitlines(True): - gcode += linenumber() + line + for line in POSTAMBLE.splitlines(): + gcode += linenumber() + line + "\n" if SHOW_EDITOR: dia = PostUtils.GCodeEditorDialog() diff --git a/src/Mod/CAM/Path/Post/scripts/uccnc_post.py b/src/Mod/CAM/Path/Post/scripts/uccnc_post.py index ddd6224399..b44a77c506 100644 --- a/src/Mod/CAM/Path/Post/scripts/uccnc_post.py +++ b/src/Mod/CAM/Path/Post/scripts/uccnc_post.py @@ -256,11 +256,11 @@ parser.add_argument( parser.add_argument("--precision", default="3", help="number of digits of precision, default=3") parser.add_argument( "--preamble", - help='set commands to be issued before the first command, default="G17\nG90\nG54"', + help='set commands to be issued before the first command, default="G17\\nG54\\G40\\nG49\\nG90\\nG80\\n"', ) parser.add_argument( "--postamble", - help='set commands to be issued after the last command, default="M05\nM30"', + help='set commands to be issued after the last command, default="M05\\nG17\\nG54\\nG0\\nG90\\nG80\\nM30\\n"', ) parser.add_argument("--inches", action="store_true", help="lengths in [in], G20") parser.add_argument("--metric", action="store_true", help="lengths in [mm], G21") @@ -443,7 +443,7 @@ def export(objectslist, filename, argstring): # if isinstance(obj.Proxy, Path.Tool.Controller.ToolController): # gcode += append("(T{}={})\n".format(obj.ToolNumber, item.Name)) # error: global name 'PathScripts' is not defined - for line in PREAMBLE.splitlines(False): + for line in PREAMBLE.splitlines(): gcode += append(line + "\n") if OUTPUT_COMMENTS: gcode += append("(preamble: done)\n") diff --git a/src/Mod/CAM/Path/Post/scripts/wedm_post.py b/src/Mod/CAM/Path/Post/scripts/wedm_post.py index 141c4c34ee..1b9396f8b9 100644 --- a/src/Mod/CAM/Path/Post/scripts/wedm_post.py +++ b/src/Mod/CAM/Path/Post/scripts/wedm_post.py @@ -68,11 +68,11 @@ parser.add_argument("--precision", default="3", help="number of digits of precis parser.add_argument("--fixed-length", default="0", help="use fixed length coordinates, default=0") parser.add_argument( "--preamble", - help='set commands to be issued before the first command, default="G17 G54 G40 G49 G80 G90"', + help='set commands to be issued before the first command, default="G17 G54 G40 G49 G80 G90\\n"', ) parser.add_argument( "--postamble", - help='set commands to be issued after the last command, default="M05\\nG17 G54 G90 G80 G40\\nM2"', + help='set commands to be issued after the last command, default="M05\\nG17 G54 G90 G80 G40\\nM2\\n"', ) parser.add_argument( "--inches", action="store_true", help="Convert output for US imperial mode (G20)" @@ -271,7 +271,7 @@ def export(objectslist, filename, argstring): # Write the preamble if OUTPUT_COMMENTS: gcode += linenumber() + COMMENT_CHAR + "(begin preamble)\n" - for line in PREAMBLE.splitlines(False): + for line in PREAMBLE.splitlines(): gcode += linenumber() + line + "\n" if not OMIT_UNITS: gcode += linenumber() + UNITS + ENDLINE + "\n" @@ -353,8 +353,8 @@ def export(objectslist, filename, argstring): # do the post_amble if OUTPUT_COMMENTS: gcode += linenumber() + COMMENT_CHAR + "(begin postamble)\n" - for line in POSTAMBLE.splitlines(True): - gcode += linenumber() + line + for line in POSTAMBLE.splitlines(): + gcode += linenumber() + line + "\n" if FreeCAD.GuiUp and SHOW_EDITOR: final = gcode From 04db3175f393f2986bafc4951863e1cbd8b8a1d6 Mon Sep 17 00:00:00 2001 From: Benjamin Nauck Date: Wed, 16 Apr 2025 08:45:20 +0200 Subject: [PATCH 03/20] TechDraw: Potential fix for snap builds, specify type --- src/Mod/TechDraw/Gui/CommandExtensionDims.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Mod/TechDraw/Gui/CommandExtensionDims.cpp b/src/Mod/TechDraw/Gui/CommandExtensionDims.cpp index ea1a86643e..6ddbda5f81 100644 --- a/src/Mod/TechDraw/Gui/CommandExtensionDims.cpp +++ b/src/Mod/TechDraw/Gui/CommandExtensionDims.cpp @@ -24,6 +24,7 @@ #ifndef _PreComp_ # include # include +# include # include # include # include @@ -2130,7 +2131,7 @@ void execCreateVertChamferDimension(Gui::Command* cmd) { dim->Y.setValue(-mid.y); float dx = allVertexes[0].point.x - allVertexes[1].point.x; float dy = allVertexes[0].point.y - allVertexes[1].point.y; - float alpha = round(Base::toDegrees(abs(atan(dx / dy)))); + float alpha = std::round(Base::toDegrees(std::abs(std::atan(dx / dy)))); std::string sAlpha = std::to_string((int)alpha); std::string formatSpec = dim->FormatSpec.getStrValue(); formatSpec = formatSpec + " x" + sAlpha + "°"; From 09ba446acd4d8884c995a916aea50e5fcf2a50ba Mon Sep 17 00:00:00 2001 From: Florian Foinant-Willig Date: Wed, 16 Apr 2025 20:39:58 +0200 Subject: [PATCH 04/20] PartDesign: Fix #20205 where Placement changes at Suppression --- src/Mod/PartDesign/App/Feature.cpp | 14 +++++++++----- src/Mod/PartDesign/App/Feature.h | 2 ++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/Mod/PartDesign/App/Feature.cpp b/src/Mod/PartDesign/App/Feature.cpp index 959a429e65..b519137eda 100644 --- a/src/Mod/PartDesign/App/Feature.cpp +++ b/src/Mod/PartDesign/App/Feature.cpp @@ -98,12 +98,11 @@ App::DocumentObjectExecReturn* Feature::recompute() FC_ERR("Failed to recompute suppressed feature " << getFullName()); } + Shape.setValue(getBaseTopoShape(true)); + if (!failed) { updateSuppressedShape(); } - else { - Shape.setValue(getBaseTopoShape(true)); - } return App::DocumentObject::StdReturn; } @@ -121,7 +120,6 @@ void Feature::setMaterialToBodyMaterial() void Feature::updateSuppressedShape() { - auto baseShape = getBaseTopoShape(true); TopoShape res(getID()); TopoShape shape = Shape.getShape(); shape.setPlacement(Base::Placement()); @@ -139,7 +137,6 @@ void Feature::updateSuppressedShape() res.makeElementCompound(generated); res.setPlacement(Placement.getValue()); } - Shape.setValue(baseShape); SuppressedShape.setValue(res); } @@ -196,6 +193,13 @@ void Feature::onChanged(const App::Property *prop) body->ShapeMaterial.setValue(ShapeMaterial.getValue()); } } + } else if (prop == &Suppressed){ + if (Suppressed.getValue()) { + SuppressedPlacement = Placement.getValue(); + } else { + Placement.setValue(SuppressedPlacement); + SuppressedPlacement = Base::Placement(); + } } } Part::Feature::onChanged(prop); diff --git a/src/Mod/PartDesign/App/Feature.h b/src/Mod/PartDesign/App/Feature.h index cda66bcd30..c85524e809 100644 --- a/src/Mod/PartDesign/App/Feature.h +++ b/src/Mod/PartDesign/App/Feature.h @@ -60,6 +60,8 @@ public: /// Keep a copy of suppressed shapes so that we can restore them (and maybe display them) Part::PropertyPartShape SuppressedShape; + /// Keep a copy of the placement before suppression to restore it back when unsuppressed, fix #20205 + Base::Placement SuppressedPlacement; App::DocumentObjectExecReturn* recompute() override; short mustExecute() const override; From 2af7e8a37e94add50c0fbea7a281a8979a14e703 Mon Sep 17 00:00:00 2001 From: xtemp09 Date: Thu, 17 Apr 2025 01:42:24 +0700 Subject: [PATCH 05/20] [Spreadsheet] Add usage of override cursor in SheetViewHeader (#20786) * [Spreadsheet] Add usage of override cursor in SheetViewHeader Closes #19863 * Update src/Mod/Spreadsheet/Gui/SheetTableView.cpp Co-authored-by: Kacper Donat * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: Kacper Donat Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- src/Mod/Spreadsheet/Gui/SheetTableView.cpp | 13 ++++++++++++- src/Mod/Spreadsheet/Gui/SheetTableView.h | 1 + 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Mod/Spreadsheet/Gui/SheetTableView.cpp b/src/Mod/Spreadsheet/Gui/SheetTableView.cpp index dc8b7623c1..e0f26d9be2 100644 --- a/src/Mod/Spreadsheet/Gui/SheetTableView.cpp +++ b/src/Mod/Spreadsheet/Gui/SheetTableView.cpp @@ -56,7 +56,18 @@ using namespace SpreadsheetGui; using namespace Spreadsheet; using namespace App; -namespace sp = std::placeholders; + +void SheetViewHeader::mouseMoveEvent(QMouseEvent* e) +{ + // for some reason QWidget::setCursor() has no effect in QGraphicsView + // therefore we resort to override cursor + const QCursor currentCursor = this->cursor(); + QHeaderView::mouseMoveEvent(e); + const QCursor newerCursor = this->cursor(); + if (newerCursor != currentCursor) { + qApp->setOverrideCursor(newerCursor); + } +} void SheetViewHeader::mouseReleaseEvent(QMouseEvent* event) { diff --git a/src/Mod/Spreadsheet/Gui/SheetTableView.h b/src/Mod/Spreadsheet/Gui/SheetTableView.h index e63af97da9..078b0aa61f 100644 --- a/src/Mod/Spreadsheet/Gui/SheetTableView.h +++ b/src/Mod/Spreadsheet/Gui/SheetTableView.h @@ -47,6 +47,7 @@ Q_SIGNALS: void resizeFinished(); protected: + void mouseMoveEvent(QMouseEvent* e) override; void mouseReleaseEvent(QMouseEvent* event) override; bool viewportEvent(QEvent* e) override; From b5661da3a6b0209c5c6afdc140a2fbb088dae1c7 Mon Sep 17 00:00:00 2001 From: Max Wilfinger Date: Wed, 16 Apr 2025 09:31:53 +0200 Subject: [PATCH 06/20] Adding pull request GitHub template --- .../pull_request_template.md | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATE/pull_request_template.md diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md new file mode 100644 index 0000000000..a52f6c89de --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md @@ -0,0 +1,47 @@ + + +## Description + + +## Issues + + +## Before and After Images + + + + + From 66a664ae55d4fd1327e92b385dfff88e468c8eae Mon Sep 17 00:00:00 2001 From: Benjamin Nauck Date: Thu, 17 Apr 2025 00:19:26 +0200 Subject: [PATCH 07/20] TechDraw: Potential fix for snap builds, specify type.. again (#20831) * TechDraw: Potential fix for snap builds, specify type * Techdraw: Fix more toDegrees-issues --- src/Mod/TechDraw/Gui/CommandCreateDims.cpp | 3 ++- src/Mod/TechDraw/Gui/CommandExtensionDims.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Mod/TechDraw/Gui/CommandCreateDims.cpp b/src/Mod/TechDraw/Gui/CommandCreateDims.cpp index 706fb80cd5..adf88262b2 100644 --- a/src/Mod/TechDraw/Gui/CommandCreateDims.cpp +++ b/src/Mod/TechDraw/Gui/CommandCreateDims.cpp @@ -23,6 +23,7 @@ #include "PreCompiled.h" #ifndef _PreComp_ +#include #include #include #include @@ -1140,7 +1141,7 @@ protected: TechDraw::pointPair pp = dim->getLinearPoints(); float dx = pp.first().x - pp.second().x; float dy = pp.first().y - pp.second().y; - int alpha = round(Base::toDegrees(abs(atan(type == "DistanceY" ? (dx / dy) : (dy / dx))))); + int alpha = std::round(Base::toDegrees(std::abs(std::atan(type == "DistanceY" ? (dx / dy) : (dy / dx))))); std::string sAlpha = std::to_string(alpha); std::string formatSpec = dim->FormatSpec.getStrValue(); formatSpec = formatSpec + " x" + sAlpha + "°"; diff --git a/src/Mod/TechDraw/Gui/CommandExtensionDims.cpp b/src/Mod/TechDraw/Gui/CommandExtensionDims.cpp index 6ddbda5f81..97c7ed3439 100644 --- a/src/Mod/TechDraw/Gui/CommandExtensionDims.cpp +++ b/src/Mod/TechDraw/Gui/CommandExtensionDims.cpp @@ -2063,7 +2063,7 @@ void execCreateHorizChamferDimension(Gui::Command* cmd) { dim->Y.setValue(-yMax); float dx = allVertexes[0].point.x - allVertexes[1].point.x; float dy = allVertexes[0].point.y - allVertexes[1].point.y; - float alpha = round(Base::toDegrees(abs(atan(dy / dx)))); + float alpha = std::round(Base::toDegrees(std::abs(std::atan(dy / dx)))); std::string sAlpha = std::to_string((int)alpha); std::string formatSpec = dim->FormatSpec.getStrValue(); formatSpec = formatSpec + " x" + sAlpha + "°"; From 5b80376447e57daa781900847ddf858f6a384196 Mon Sep 17 00:00:00 2001 From: Tomas Polak Date: Tue, 15 Apr 2025 17:53:22 +0200 Subject: [PATCH 08/20] BIM change BIM_Setup dialogue default width --- src/Mod/BIM/Resources/ui/dialogSetup.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Mod/BIM/Resources/ui/dialogSetup.ui b/src/Mod/BIM/Resources/ui/dialogSetup.ui index f7f86d518b..705f9cbc52 100644 --- a/src/Mod/BIM/Resources/ui/dialogSetup.ui +++ b/src/Mod/BIM/Resources/ui/dialogSetup.ui @@ -9,7 +9,7 @@ 0 0 - 580 + 640 691 From 09d08593ed7fbc647377e599da0f95b72fe2b627 Mon Sep 17 00:00:00 2001 From: bofdahof <172177156+bofdahof@users.noreply.github.com> Date: Thu, 17 Apr 2025 13:38:08 +1000 Subject: [PATCH 09/20] Remove unused code: verbosity --- src/App/Application.cpp | 2 -- src/Base/Console.cpp | 20 -------------------- src/Base/Console.h | 5 ----- 3 files changed, 27 deletions(-) diff --git a/src/App/Application.cpp b/src/App/Application.cpp index 3acf6856ad..95bcfe56b5 100644 --- a/src/App/Application.cpp +++ b/src/App/Application.cpp @@ -2644,8 +2644,6 @@ void Application::initConfig(int argc, char ** argv) _pConsoleObserverStd->bWrn = false; _pConsoleObserverStd->bErr = false; } - if (mConfig["Verbose"] == "Strict") - Base::Console().UnsetConsoleMode(Base::ConsoleSingleton::Verbose); // file logging Init =========================================================== if (mConfig["LoggingFile"] == "1") { diff --git a/src/Base/Console.cpp b/src/Base/Console.cpp index 9e9b43bd1d..2ae3f1deb5 100644 --- a/src/Base/Console.cpp +++ b/src/Base/Console.cpp @@ -168,26 +168,6 @@ ConsoleSingleton::~ConsoleSingleton() //************************************************************************** // methods -/** - * sets the console in a special mode - */ -void ConsoleSingleton::SetConsoleMode(ConsoleMode mode) -{ - if (mode & Verbose) { - _bVerbose = true; - } -} - -/** - * unsets the console from a special mode - */ -void ConsoleSingleton::UnsetConsoleMode(ConsoleMode mode) -{ - if (mode & Verbose) { - _bVerbose = false; - } -} - /** * \a type can be OR'ed with any of the FreeCAD_ConsoleMsgType flags to enable -- if \a b is true -- * or to disable -- if \a b is false -- a console observer with name \a sObs. diff --git a/src/Base/Console.h b/src/Base/Console.h index 6e3a6e66b8..09352cf1b8 100644 --- a/src/Base/Console.h +++ b/src/Base/Console.h @@ -814,10 +814,6 @@ public: MsgType_Notification = 32, // Special message to for notifications to the user }; - /// Change mode - void SetConsoleMode(ConsoleMode mode); - /// Change mode - void UnsetConsoleMode(ConsoleMode mode); /// Enables or disables message types of a certain console observer ConsoleMsgFlags SetEnabledMsgType(const char* sObs, ConsoleMsgFlags type, bool on); /// Checks if message types of a certain console observer are enabled @@ -869,7 +865,6 @@ private: static PyObject* sPyGetStatus(PyObject* self, PyObject* args); static PyObject* sPyGetObservers(PyObject* self, PyObject* args); - bool _bVerbose {true}; bool _bCanRefresh {true}; ConnectionMode connectionMode {Direct}; From df800794769b0c5365b2edda2aafa4c5432e6b40 Mon Sep 17 00:00:00 2001 From: StepSecurity Bot Date: Wed, 16 Apr 2025 18:45:10 +0000 Subject: [PATCH 10/20] [StepSecurity] Apply security best practices Signed-off-by: StepSecurity Bot --- .github/dependabot.yml | 11 +++ .github/workflows/CI_cleanup.yml | 7 +- ...o-close_stale_issues_and_pull-requests.yml | 13 ++- .github/workflows/dependency-review.yml | 27 +++++++ .github/workflows/issue-metrics.yml | 9 ++- .github/workflows/labeler.yml | 10 ++- .github/workflows/scorecards.yml | 81 +++++++++++++++++++ .github/workflows/sub_buildPixi.yml | 17 ++-- .github/workflows/sub_buildUbuntu.yml | 15 ++-- .github/workflows/sub_buildWindows.yml | 15 ++-- .github/workflows/sub_lint.yml | 14 +++- .github/workflows/sub_prepare.yml | 9 ++- .github/workflows/sub_weeklyBuild.yml | 16 +++- .github/workflows/sub_wrapup.yml | 12 ++- 14 files changed, 222 insertions(+), 34 deletions(-) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/dependency-review.yml create mode 100644 .github/workflows/scorecards.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000..e98caaf1f9 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: daily + + - package-ecosystem: pip + directory: / + schedule: + interval: daily diff --git a/.github/workflows/CI_cleanup.yml b/.github/workflows/CI_cleanup.yml index 6a797e7834..3d8e2edada 100644 --- a/.github/workflows/CI_cleanup.yml +++ b/.github/workflows/CI_cleanup.yml @@ -57,6 +57,11 @@ jobs: env: logdir: /tmp/log/ steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1 + with: + egress-policy: audit + - name: Make needed directories run: | mkdir -p ${{ env.logdir }} @@ -103,7 +108,7 @@ jobs: done - name: Upload logs if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: ${{ github.job }}-Logs path: | diff --git a/.github/workflows/auto-close_stale_issues_and_pull-requests.yml b/.github/workflows/auto-close_stale_issues_and_pull-requests.yml index 5e853db3c6..0c65f869ba 100644 --- a/.github/workflows/auto-close_stale_issues_and_pull-requests.yml +++ b/.github/workflows/auto-close_stale_issues_and_pull-requests.yml @@ -20,9 +20,14 @@ jobs: stale: runs-on: ubuntu-latest steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1 + with: + egress-policy: audit + - name: '🧹 Tag & close stale unconfirmed bugs' id: stale_issues - uses: actions/stale@v9.1.0 + uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0 with: repo-token: ${{ secrets.GITHUB_TOKEN }} days-before-stale: -1 @@ -49,7 +54,7 @@ jobs: - name: '🧹 Close stale requested feedback issues' id: awaiting_issues - uses: actions/stale@v9.1.0 + uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0 with: repo-token: ${{ secrets.GITHUB_TOKEN }} days-before-stale: -1 @@ -77,7 +82,7 @@ jobs: - name: '🧹 Tag & close inactive issues' id: inactive_issues - uses: actions/stale@v9.1.0 + uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0 with: repo-token: ${{ secrets.GITHUB_TOKEN }} days-before-stale: -1 @@ -108,7 +113,7 @@ jobs: - name: '🧹 Tag & close inactive PRs' id: inactive_pr - uses: actions/stale@v9.1.0 + uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0 with: repo-token: ${{ secrets.GITHUB_TOKEN }} days-before-stale: -1 diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml new file mode 100644 index 0000000000..ffa9d8f33b --- /dev/null +++ b/.github/workflows/dependency-review.yml @@ -0,0 +1,27 @@ +# Dependency Review Action +# +# This Action will scan dependency manifest files that change as part of a Pull Request, +# surfacing known-vulnerable versions of the packages declared or updated in the PR. +# Once installed, if the workflow run is marked as required, +# PRs introducing known-vulnerable packages will be blocked from merging. +# +# Source repository: https://github.com/actions/dependency-review-action +name: 'Dependency Review' +on: [pull_request] + +permissions: + contents: read + +jobs: + dependency-review: + runs-on: ubuntu-latest + steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1 + with: + egress-policy: audit + + - name: 'Checkout Repository' + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - name: 'Dependency Review' + uses: actions/dependency-review-action@67d4f4bd7a9b17a0db54d2a7519187c65e339de8 # v4 diff --git a/.github/workflows/issue-metrics.yml b/.github/workflows/issue-metrics.yml index 63257e3330..cb51b3b6c8 100644 --- a/.github/workflows/issue-metrics.yml +++ b/.github/workflows/issue-metrics.yml @@ -16,6 +16,11 @@ jobs: steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1 + with: + egress-policy: audit + - name: Get dates for last month shell: bash run: | @@ -30,13 +35,13 @@ jobs: echo "last_month=$first_day..$last_day" >> "$GITHUB_ENV" - name: Run issue-metrics tool - uses: github/issue-metrics@v3 + uses: github/issue-metrics@4f29f34d9d831fe224cbc6c8a0d711415ebd01b1 # v3.1.1 env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} SEARCH_QUERY: 'repo:FreeCAD/FreeCAD is:issue created:${{ env.last_month }}' - name: Create issue - uses: peter-evans/create-issue-from-file@v4 + uses: peter-evans/create-issue-from-file@433e51abf769039ee20ba1293a088ca19d573b7f # v4.0.1 with: title: Monthly issue metrics report token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 56de386954..65522eb958 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -9,6 +9,9 @@ on: pull_request_target: types: [opened, reopened] +permissions: + contents: read + jobs: label: runs-on: ubuntu-latest @@ -17,7 +20,12 @@ jobs: pull-requests: write steps: - - uses: actions/labeler@v5 + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1 + with: + egress-policy: audit + + - uses: actions/labeler@8558fd74291d67161a8a78ce36a881fa63b766a9 # v5.0.0 with: repo-token: "${{ secrets.GITHUB_TOKEN }}" configuration-path: ".github/labels.yml" diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml new file mode 100644 index 0000000000..9c2d2ec58c --- /dev/null +++ b/.github/workflows/scorecards.yml @@ -0,0 +1,81 @@ +# This workflow uses actions that are not certified by GitHub. They are provided +# by a third-party and are governed by separate terms of service, privacy +# policy, and support documentation. + +name: Scorecard supply-chain security +on: + # For Branch-Protection check. Only the default branch is supported. See + # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection + branch_protection_rule: + # To guarantee Maintained check is occasionally updated. See + # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained + schedule: + - cron: '20 7 * * 2' + push: + branches: ["main"] + +# Declare default permissions as read only. +permissions: read-all + +jobs: + analysis: + name: Scorecard analysis + runs-on: ubuntu-latest + permissions: + # Needed to upload the results to code-scanning dashboard. + security-events: write + # Needed to publish results and get a badge (see publish_results below). + id-token: write + contents: read + actions: read + # To allow GraphQL ListCommits to work + issues: read + pull-requests: read + # To detect SAST tools + checks: read + + steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1 + with: + egress-policy: audit + + - name: "Checkout code" + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: false + + - name: "Run analysis" + uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0 + with: + results_file: results.sarif + results_format: sarif + # (Optional) "write" PAT token. Uncomment the `repo_token` line below if: + # - you want to enable the Branch-Protection check on a *public* repository, or + # - you are installing Scorecards on a *private* repository + # To create the PAT, follow the steps in https://github.com/ossf/scorecard-action#authentication-with-pat. + # repo_token: ${{ secrets.SCORECARD_TOKEN }} + + # Public repositories: + # - Publish results to OpenSSF REST API for easy access by consumers + # - Allows the repository to include the Scorecard badge. + # - See https://github.com/ossf/scorecard-action#publishing-results. + # For private repositories: + # - `publish_results` will always be set to `false`, regardless + # of the value entered here. + publish_results: true + + # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF + # format to the repository Actions tab. + - name: "Upload artifact" + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: SARIF file + path: results.sarif + retention-days: 5 + + # Upload the results to GitHub's code scanning dashboard. + - name: "Upload to code-scanning" + uses: github/codeql-action/upload-sarif@45775bd8235c68ba998cffa5171334d58593da47 # v3.28.15 + with: + sarif_file: results.sarif diff --git a/.github/workflows/sub_buildPixi.yml b/.github/workflows/sub_buildPixi.yml index 23f6bd5c87..9d642ddd67 100644 --- a/.github/workflows/sub_buildPixi.yml +++ b/.github/workflows/sub_buildPixi.yml @@ -69,6 +69,11 @@ jobs: os: [windows-latest, ubuntu-latest, macos-latest] steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1 + with: + egress-policy: audit + - name: Set Platform Environment Variables shell: bash -l {0} env: @@ -81,7 +86,7 @@ jobs: fi - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Add GCC Problem Matcher if: runner.os == 'Linux' @@ -106,13 +111,13 @@ jobs: mkdir -p ${{ env.reportdir }} echo "reportFile=${{ env.reportfilename }}" >> $GITHUB_OUTPUT - - uses: prefix-dev/setup-pixi@v0.8.7 + - uses: prefix-dev/setup-pixi@5044b250243a57e8c78f7c38acd73f6d7954a3cf # v0.8.7 with: pixi-version: v0.45.0 cache: false - name: Restore Compiler Cache - uses: actions/cache/restore@v4 + uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 with: path: ${{ env.CCACHE_DIR }} key: FC-${{ env.cacheKey }}-${{ github.ref }}-${{ github.run_id }} @@ -195,14 +200,14 @@ jobs: - name: Save Compiler Cache if: always() - uses: actions/cache/save@v4 + uses: actions/cache/save@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 with: path: ${{ env.CCACHE_DIR }} key: FC-${{ env.cacheKey }}-${{ github.ref }}-${{ github.run_id }} - name: Upload logs if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: ${{ inputs.artifactBasename }}-${{ matrix.os }}-Logs path: | @@ -211,7 +216,7 @@ jobs: - name: Upload report if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: ${{ env.reportfilename }} path: | diff --git a/.github/workflows/sub_buildUbuntu.yml b/.github/workflows/sub_buildUbuntu.yml index 5c652b1cf2..41d887964b 100644 --- a/.github/workflows/sub_buildUbuntu.yml +++ b/.github/workflows/sub_buildUbuntu.yml @@ -71,8 +71,13 @@ jobs: reportFile: ${{ steps.Init.outputs.reportFile }} steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1 + with: + egress-policy: audit + - name: Checking out source code - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: submodules: true - name: Install FreeCAD dependencies @@ -94,7 +99,7 @@ jobs: compiler: ${{ env.CXX }} qt_major_version: 5 - name: Restore Compiler Cache - uses: actions/cache@v4 + uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 with: save-always: true path: ${{ env.CCACHE_DIR }} @@ -108,7 +113,7 @@ jobs: ccache -z ccache -p - name: Install cmake - uses: jwlawson/actions-setup-cmake@v2 + uses: jwlawson/actions-setup-cmake@802fa1a2c4e212495c05bf94dba2704a92a472be # v2.0.2 with: cmake-version: '3.31.6' - name: CMake Configure @@ -179,7 +184,7 @@ jobs: reportFile: ${{env.reportdir}}${{ env.reportfilename }} - name: Upload logs if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: ${{ inputs.artifactBasename }}-Logs path: | @@ -187,7 +192,7 @@ jobs: /var/crash/*FreeCAD* - name: Upload report if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: ${{ env.reportfilename }} path: | diff --git a/.github/workflows/sub_buildWindows.yml b/.github/workflows/sub_buildWindows.yml index 11dbe16904..af11383bd3 100644 --- a/.github/workflows/sub_buildWindows.yml +++ b/.github/workflows/sub_buildWindows.yml @@ -62,8 +62,13 @@ jobs: reportFile: ${{ steps.Init.outputs.reportFile }} steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1 + with: + egress-policy: audit + - name: Checking out source code - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: submodules: true - name: Make needed directories, files and initializations @@ -85,7 +90,7 @@ jobs: with: libpackdir: ${{ env.libpackdir }} - name: Restore compiler cache - uses: actions/cache@v4 + uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 with: save-always: true path: ${{ env.CCACHE_DIR }} @@ -99,7 +104,7 @@ jobs: . $env:ccachebindir\ccache -z . $env:ccachebindir\ccache -p - name: Install cmake - uses: jwlawson/actions-setup-cmake@v2 + uses: jwlawson/actions-setup-cmake@802fa1a2c4e212495c05bf94dba2704a92a472be # v2.0.2 with: cmake-version: '3.31.6' - name: Configuring CMake @@ -115,7 +120,7 @@ jobs: -DFREECAD_COPY_LIBPACK_BIN_TO_BUILD=ON -DFREECAD_COPY_PLUGINS_BIN_TO_BUILD=ON - name: Add msbuild to PATH - uses: microsoft/setup-msbuild@v2 + uses: microsoft/setup-msbuild@6fb02220983dee41ce7ae257b6f4d8f9bf5ed4ce # v2.0.0 - name: Compiling sources run: | cd $env:builddir @@ -133,7 +138,7 @@ jobs: . ${{ env.builddir }}\bin\FreeCADCmd -t 0 # 2>&1 | tee -filepath ${{ env.logdir }}\integrationTests.log - name: Upload logs if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: ${{ inputs.artifactBasename }}-Logs path: | diff --git a/.github/workflows/sub_lint.yml b/.github/workflows/sub_lint.yml index 61cdbcbde8..3e587cb2a6 100644 --- a/.github/workflows/sub_lint.yml +++ b/.github/workflows/sub_lint.yml @@ -168,6 +168,9 @@ on: reportFile: value: ${{ jobs.Lint.outputs.reportFile }} +permissions: + contents: read + jobs: Lint: @@ -185,8 +188,13 @@ jobs: reportFile: ${{ steps.Init.outputs.reportFile }} steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1 + with: + egress-policy: audit + - name: Check out code - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: submodules: true @@ -335,7 +343,7 @@ jobs: - name: Upload logs and fixes if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: ${{ inputs.artifactBasename }}-Logs path: | @@ -344,7 +352,7 @@ jobs: - name: Upload report if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: ${{ env.reportfilename }} path: | diff --git a/.github/workflows/sub_prepare.yml b/.github/workflows/sub_prepare.yml index d0d10edf58..d715482a0d 100644 --- a/.github/workflows/sub_prepare.yml +++ b/.github/workflows/sub_prepare.yml @@ -71,6 +71,11 @@ jobs: changedCppFiles: ${{ steps.Output.outputs.changedCppFiles }} steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1 + with: + egress-policy: audit + - name: Make needed directories, files and initializations id: Init run: | @@ -148,14 +153,14 @@ jobs: echo "" >> $GITHUB_OUTPUT - name: Upload logs if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: ${{ inputs.artifactBasename }}-Logs path: | ${{ env.logdir }} - name: Upload report if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: ${{ env.reportfilename }} path: | diff --git a/.github/workflows/sub_weeklyBuild.yml b/.github/workflows/sub_weeklyBuild.yml index d611138c7b..d592cef0f5 100644 --- a/.github/workflows/sub_weeklyBuild.yml +++ b/.github/workflows/sub_weeklyBuild.yml @@ -12,7 +12,12 @@ jobs: outputs: build_tag: ${{ steps.tag_build.outputs.build_tag }} steps: - - uses: actions/checkout@v4 + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1 + with: + egress-policy: audit + + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 2 submodules: 'recursive' @@ -59,6 +64,11 @@ jobs: runs-on: ${{ matrix.os }} environment: weekly-build steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1 + with: + egress-policy: audit + - name: Set Platform Environment Variables shell: bash -l {0} env: @@ -71,13 +81,13 @@ jobs: echo 'RATTLER_CACHE_DIR=D:\rattler' >> "$GITHUB_ENV" fi - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 0 fetch-tags: true submodules: 'recursive' - - uses: prefix-dev/setup-pixi@v0.8.3 + - uses: prefix-dev/setup-pixi@92815284c57faa15cd896c4d5cfb2d59f32dc43d # v0.8.3 with: pixi-version: v0.42.1 cache: false diff --git a/.github/workflows/sub_wrapup.yml b/.github/workflows/sub_wrapup.yml index 5d55edf169..f4984b9f0c 100644 --- a/.github/workflows/sub_wrapup.yml +++ b/.github/workflows/sub_wrapup.yml @@ -39,6 +39,9 @@ on: type: string required: true +permissions: + contents: read + jobs: WrapUp: @@ -50,11 +53,16 @@ jobs: shell: bash steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1 + with: + egress-policy: audit + - name: Make needed directories, files and initializations run: | mkdir -p ${{ env.artifactsDownloadDir }} - name: Download artifacts - uses: actions/download-artifact@v4 + uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1 with: path: ${{ env.artifactsDownloadDir }} - name: Save input data to file @@ -111,7 +119,7 @@ jobs: cat report.md >> $GITHUB_STEP_SUMMARY - name: Delete used artifacts continue-on-error: true - uses: geekyeggo/delete-artifact@v5 + uses: geekyeggo/delete-artifact@f275313e70c08f6120db482d7a6b98377786765b # v5.1.0 with: name: | ${{ env.usedArtifacts }} From b1d5765d8d20f680e4291bd2568e25120d95dde8 Mon Sep 17 00:00:00 2001 From: Jacob Oursland Date: Wed, 16 Apr 2025 14:12:00 -0700 Subject: [PATCH 11/20] Assembly: convert if-else to switch. --- src/Mod/Assembly/App/AssemblyObject.cpp | 443 +++++++++++------------- 1 file changed, 208 insertions(+), 235 deletions(-) diff --git a/src/Mod/Assembly/App/AssemblyObject.cpp b/src/Mod/Assembly/App/AssemblyObject.cpp index 495536f6c8..d0c0e2fe26 100644 --- a/src/Mod/Assembly/App/AssemblyObject.cpp +++ b/src/Mod/Assembly/App/AssemblyObject.cpp @@ -1091,77 +1091,82 @@ void Assembly::AssemblyObject::create_mbdSimulationParameters(App::DocumentObjec std::shared_ptr AssemblyObject::makeMbdJointOfType(App::DocumentObject* joint, JointType type) { - if (type == JointType::Fixed) { - if (bundleFixed) { - return nullptr; - } - return CREATE::With(); - } - else if (type == JointType::Revolute) { - return CREATE::With(); - } - else if (type == JointType::Cylindrical) { - return CREATE::With(); - } - else if (type == JointType::Slider) { - return CREATE::With(); - } - else if (type == JointType::Ball) { - return CREATE::With(); - } - else if (type == JointType::Distance) { - return makeMbdJointDistance(joint); - } - else if (type == JointType::Parallel) { - return CREATE::With(); - } - else if (type == JointType::Perpendicular) { - return CREATE::With(); - } - else if (type == JointType::Angle) { - double angle = fabs(Base::toRadians(getJointDistance(joint))); - if (fmod(angle, 2 * std::numbers::pi) < Precision::Confusion()) { + switch (type) { + case JointType::Fixed: + if (bundleFixed) { + return nullptr; + } + return CREATE::With(); + + case JointType::Revolute: + return CREATE::With(); + + case JointType::Cylindrical: + return CREATE::With(); + + case JointType::Slider: + return CREATE::With(); + + case JointType::Ball: + return CREATE::With(); + + case JointType::Distance: + return makeMbdJointDistance(joint); + + case JointType::Parallel: return CREATE::With(); - } - else { + + case JointType::Perpendicular: + return CREATE::With(); + + case JointType::Angle: { + double angle = fabs(Base::toRadians(getJointDistance(joint))); + if (fmod(angle, 2 * std::numbers::pi) < Precision::Confusion()) { + return CREATE::With(); + } auto mbdJoint = CREATE::With(); mbdJoint->theIzJz = angle; return mbdJoint; } - } - else if (type == JointType::RackPinion) { - auto mbdJoint = CREATE::With(); - mbdJoint->pitchRadius = getJointDistance(joint); - return mbdJoint; - } - else if (type == JointType::Screw) { - int slidingIndex = slidingPartIndex(joint); - if (slidingIndex == 0) { // invalid this joint needs a slider + + case JointType::RackPinion: { + auto mbdJoint = CREATE::With(); + mbdJoint->pitchRadius = getJointDistance(joint); + return mbdJoint; + } + + case JointType::Screw: { + int slidingIndex = slidingPartIndex(joint); + if (slidingIndex == 0) { // invalid this joint needs a slider + return nullptr; + } + + if (slidingIndex != 1) { + swapJCS(joint); // make sure that sliding is first. + } + + auto mbdJoint = CREATE::With(); + mbdJoint->pitch = getJointDistance(joint); + return mbdJoint; + } + + case JointType::Gears: { + auto mbdJoint = CREATE::With(); + mbdJoint->radiusI = getJointDistance(joint); + mbdJoint->radiusJ = getJointDistance2(joint); + return mbdJoint; + } + + case JointType::Belt: { + auto mbdJoint = CREATE::With(); + mbdJoint->radiusI = getJointDistance(joint); + mbdJoint->radiusJ = -getJointDistance2(joint); + return mbdJoint; + } + + default: return nullptr; - } - - if (slidingIndex != 1) { - swapJCS(joint); // make sure that sliding is first. - } - - auto mbdJoint = CREATE::With(); - mbdJoint->pitch = getJointDistance(joint); - return mbdJoint; } - else if (type == JointType::Gears) { - auto mbdJoint = CREATE::With(); - mbdJoint->radiusI = getJointDistance(joint); - mbdJoint->radiusJ = getJointDistance2(joint); - return mbdJoint; - } - else if (type == JointType::Belt) { - auto mbdJoint = CREATE::With(); - mbdJoint->radiusI = getJointDistance(joint); - mbdJoint->radiusJ = -getJointDistance2(joint); - return mbdJoint; - } - - return nullptr; } std::shared_ptr AssemblyObject::makeMbdJointDistance(App::DocumentObject* joint) @@ -1173,186 +1178,154 @@ std::shared_ptr AssemblyObject::makeMbdJointDistance(App::DocumentObj auto* obj1 = getLinkedObjFromRef(joint, "Reference1"); auto* obj2 = getLinkedObjFromRef(joint, "Reference2"); - if (type == DistanceType::PointPoint) { - // Point to point distance, or ball joint if distance=0. - double distance = getJointDistance(joint); - if (distance < Precision::Confusion()) { - return CREATE::With(); + switch (type) { + case DistanceType::PointPoint: { + // Point to point distance, or ball joint if distance=0. + double distance = getJointDistance(joint); + if (distance < Precision::Confusion()) { + return CREATE::With(); + } + auto mbdJoint = CREATE::With(); + mbdJoint->distanceIJ = distance; + return mbdJoint; } - auto mbdJoint = CREATE::With(); - mbdJoint->distanceIJ = distance; - return mbdJoint; - } - // Edge - edge cases - else if (type == DistanceType::LineLine) { - auto mbdJoint = CREATE::With(); - mbdJoint->distanceIJ = getJointDistance(joint); - return mbdJoint; - } - else if (type == DistanceType::LineCircle) { - auto mbdJoint = CREATE::With(); - mbdJoint->distanceIJ = getJointDistance(joint) + getEdgeRadius(obj2, elt2); - return mbdJoint; - } - else if (type == DistanceType::CircleCircle) { - auto mbdJoint = CREATE::With(); - mbdJoint->distanceIJ = - getJointDistance(joint) + getEdgeRadius(obj1, elt1) + getEdgeRadius(obj2, elt2); - return mbdJoint; - } - // TODO : other cases od edge-edge : Ellipse, parabola, hyperbola... + // Edge - edge cases + case DistanceType::LineLine: { + auto mbdJoint = CREATE::With(); + mbdJoint->distanceIJ = getJointDistance(joint); + return mbdJoint; + } - // Face - Face cases - else if (type == DistanceType::PlanePlane) { - auto mbdJoint = CREATE::With(); - mbdJoint->offset = getJointDistance(joint); - return mbdJoint; - } - else if (type == DistanceType::PlaneCylinder) { - auto mbdJoint = CREATE::With(); - mbdJoint->offset = getJointDistance(joint) + getFaceRadius(obj2, elt2); - return mbdJoint; - } - else if (type == DistanceType::PlaneSphere) { - auto mbdJoint = CREATE::With(); - mbdJoint->offset = getJointDistance(joint) + getFaceRadius(obj2, elt2); - return mbdJoint; - } - else if (type == DistanceType::PlaneCone) { - // TODO - } - else if (type == DistanceType::PlaneTorus) { - auto mbdJoint = CREATE::With(); - mbdJoint->offset = getJointDistance(joint); - return mbdJoint; - } - else if (type == DistanceType::CylinderCylinder) { - auto mbdJoint = CREATE::With(); - mbdJoint->distanceIJ = - getJointDistance(joint) + getFaceRadius(obj1, elt1) + getFaceRadius(obj2, elt2); - return mbdJoint; - } - else if (type == DistanceType::CylinderSphere) { - auto mbdJoint = CREATE::With(); - mbdJoint->distanceIJ = - getJointDistance(joint) + getFaceRadius(obj1, elt1) + getFaceRadius(obj2, elt2); - return mbdJoint; - } - else if (type == DistanceType::CylinderCone) { - // TODO - } - else if (type == DistanceType::CylinderTorus) { - auto mbdJoint = CREATE::With(); - mbdJoint->distanceIJ = - getJointDistance(joint) + getFaceRadius(obj1, elt1) + getFaceRadius(obj2, elt2); - return mbdJoint; - } - else if (type == DistanceType::ConeCone) { - // TODO - } - else if (type == DistanceType::ConeTorus) { - // TODO - } - else if (type == DistanceType::ConeSphere) { - // TODO - } - else if (type == DistanceType::TorusTorus) { - auto mbdJoint = CREATE::With(); - mbdJoint->offset = getJointDistance(joint); - return mbdJoint; - } - else if (type == DistanceType::TorusSphere) { - auto mbdJoint = CREATE::With(); - mbdJoint->distanceIJ = - getJointDistance(joint) + getFaceRadius(obj1, elt1) + getFaceRadius(obj2, elt2); - return mbdJoint; - } - else if (type == DistanceType::SphereSphere) { - auto mbdJoint = CREATE::With(); - mbdJoint->distanceIJ = - getJointDistance(joint) + getFaceRadius(obj1, elt1) + getFaceRadius(obj2, elt2); - return mbdJoint; - } + case DistanceType::LineCircle: { + auto mbdJoint = CREATE::With(); + mbdJoint->distanceIJ = getJointDistance(joint) + getEdgeRadius(obj2, elt2); + return mbdJoint; + } - // Point - Face cases - else if (type == DistanceType::PointPlane) { - auto mbdJoint = CREATE::With(); - mbdJoint->offset = getJointDistance(joint); - return mbdJoint; - } - else if (type == DistanceType::PointCylinder) { - auto mbdJoint = CREATE::With(); - mbdJoint->distanceIJ = getJointDistance(joint) + getFaceRadius(obj1, elt1); - return mbdJoint; - } - else if (type == DistanceType::PointSphere) { - auto mbdJoint = CREATE::With(); - mbdJoint->distanceIJ = getJointDistance(joint) + getFaceRadius(obj1, elt1); - return mbdJoint; - } - else if (type == DistanceType::PointCone) { - // TODO - } - else if (type == DistanceType::PointTorus) { - // TODO - } + case DistanceType::CircleCircle: { + auto mbdJoint = CREATE::With(); + mbdJoint->distanceIJ = + getJointDistance(joint) + getEdgeRadius(obj1, elt1) + getEdgeRadius(obj2, elt2); + return mbdJoint; + } - // Edge - Face cases - else if (type == DistanceType::LinePlane) { - auto mbdJoint = CREATE::With(); - mbdJoint->offset = getJointDistance(joint); - return mbdJoint; - } - else if (type == DistanceType::LineCylinder) { - // TODO - } - else if (type == DistanceType::LineSphere) { - // TODO - } - else if (type == DistanceType::LineCone) { - // TODO - } - else if (type == DistanceType::LineTorus) { - // TODO - } + // Face - Face cases + case DistanceType::PlanePlane: { + auto mbdJoint = CREATE::With(); + mbdJoint->offset = getJointDistance(joint); + return mbdJoint; + } - else if (type == DistanceType::CurvePlane) { - // TODO - } - else if (type == DistanceType::CurveCylinder) { - // TODO - } - else if (type == DistanceType::CurveSphere) { - // TODO - } - else if (type == DistanceType::CurveCone) { - // TODO - } - else if (type == DistanceType::CurveTorus) { - // TODO - } + case DistanceType::PlaneCylinder: { + auto mbdJoint = CREATE::With(); + mbdJoint->offset = getJointDistance(joint) + getFaceRadius(obj2, elt2); + return mbdJoint; + } - // Point - Edge cases - else if (type == DistanceType::PointLine) { - auto mbdJoint = CREATE::With(); - mbdJoint->distanceIJ = getJointDistance(joint); - return mbdJoint; - } - else if (type == DistanceType::PointCurve) { - // For other curves we do a point in plane-of-the-curve. - // Maybe it would be best tangent / distance to the conic? - // For arcs and circles we could use ASMTRevSphJoint. But is it better than pointInPlane? - auto mbdJoint = CREATE::With(); - mbdJoint->offset = getJointDistance(joint); - return mbdJoint; - } + case DistanceType::PlaneSphere: { + auto mbdJoint = CREATE::With(); + mbdJoint->offset = getJointDistance(joint) + getFaceRadius(obj2, elt2); + return mbdJoint; + } + case DistanceType::PlaneTorus: { + auto mbdJoint = CREATE::With(); + mbdJoint->offset = getJointDistance(joint); + return mbdJoint; + } - // by default we make a planar joint. - auto mbdJoint = CREATE::With(); - mbdJoint->offset = getJointDistance(joint); - return mbdJoint; + case DistanceType::CylinderCylinder: { + auto mbdJoint = CREATE::With(); + mbdJoint->distanceIJ = + getJointDistance(joint) + getFaceRadius(obj1, elt1) + getFaceRadius(obj2, elt2); + return mbdJoint; + } + + case DistanceType::CylinderSphere: { + auto mbdJoint = CREATE::With(); + mbdJoint->distanceIJ = + getJointDistance(joint) + getFaceRadius(obj1, elt1) + getFaceRadius(obj2, elt2); + return mbdJoint; + } + + case DistanceType::CylinderTorus: { + auto mbdJoint = CREATE::With(); + mbdJoint->distanceIJ = + getJointDistance(joint) + getFaceRadius(obj1, elt1) + getFaceRadius(obj2, elt2); + return mbdJoint; + } + + case DistanceType::TorusTorus: { + auto mbdJoint = CREATE::With(); + mbdJoint->offset = getJointDistance(joint); + return mbdJoint; + } + + case DistanceType::TorusSphere: { + auto mbdJoint = CREATE::With(); + mbdJoint->distanceIJ = + getJointDistance(joint) + getFaceRadius(obj1, elt1) + getFaceRadius(obj2, elt2); + return mbdJoint; + } + + case DistanceType::SphereSphere: { + auto mbdJoint = CREATE::With(); + mbdJoint->distanceIJ = + getJointDistance(joint) + getFaceRadius(obj1, elt1) + getFaceRadius(obj2, elt2); + return mbdJoint; + } + + // Point - Face cases + case DistanceType::PointPlane: { + auto mbdJoint = CREATE::With(); + mbdJoint->offset = getJointDistance(joint); + return mbdJoint; + } + + case DistanceType::PointCylinder: { + auto mbdJoint = CREATE::With(); + mbdJoint->distanceIJ = getJointDistance(joint) + getFaceRadius(obj1, elt1); + return mbdJoint; + } + + case DistanceType::PointSphere: { + auto mbdJoint = CREATE::With(); + mbdJoint->distanceIJ = getJointDistance(joint) + getFaceRadius(obj1, elt1); + return mbdJoint; + } + + // Edge - Face cases + case DistanceType::LinePlane: { + auto mbdJoint = CREATE::With(); + mbdJoint->offset = getJointDistance(joint); + return mbdJoint; + } + + // Point - Edge cases + case DistanceType::PointLine: { + auto mbdJoint = CREATE::With(); + mbdJoint->distanceIJ = getJointDistance(joint); + return mbdJoint; + } + + case DistanceType::PointCurve: { + // For other curves we do a point in plane-of-the-curve. + // Maybe it would be best tangent / distance to the conic? + // For arcs and circles we could use ASMTRevSphJoint. But is it better than + // pointInPlane? + auto mbdJoint = CREATE::With(); + mbdJoint->offset = getJointDistance(joint); + return mbdJoint; + } + + default: { + // by default we make a planar joint. + auto mbdJoint = CREATE::With(); + mbdJoint->offset = getJointDistance(joint); + return mbdJoint; + } + } } std::vector> From 54aab69304d85fb3baf4b3fd067d8b288ce68516 Mon Sep 17 00:00:00 2001 From: Jacob Oursland Date: Wed, 16 Apr 2025 14:13:56 -0700 Subject: [PATCH 12/20] Assembly: Remove unused headers. --- src/Mod/Assembly/App/AssemblyObject.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Mod/Assembly/App/AssemblyObject.cpp b/src/Mod/Assembly/App/AssemblyObject.cpp index d0c0e2fe26..c10e996298 100644 --- a/src/Mod/Assembly/App/AssemblyObject.cpp +++ b/src/Mod/Assembly/App/AssemblyObject.cpp @@ -29,9 +29,6 @@ #include #endif -#include -#include - #include #include #include @@ -88,7 +85,6 @@ #include "AssemblyUtils.h" #include "JointGroup.h" #include "ViewGroup.h" -#include "SimulationGroup.h" FC_LOG_LEVEL_INIT("Assembly", true, true, true) From 1d46b54ae5865a6cd687ffb424b281beddabf83d Mon Sep 17 00:00:00 2001 From: Jacob Oursland Date: Wed, 16 Apr 2025 14:14:27 -0700 Subject: [PATCH 13/20] Assembly: align parameter names between decl and impl. --- src/Mod/Assembly/App/AssemblyObject.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Mod/Assembly/App/AssemblyObject.h b/src/Mod/Assembly/App/AssemblyObject.h index 61ceaff796..acf19f668b 100644 --- a/src/Mod/Assembly/App/AssemblyObject.h +++ b/src/Mod/Assembly/App/AssemblyObject.h @@ -31,7 +31,6 @@ #include #include #include -#include "SimulationGroup.h" #include @@ -130,7 +129,7 @@ public: std::shared_ptr part; Base::Placement offsetPlc; // This is the offset within the bundled parts }; - MbDPartData getMbDData(App::DocumentObject* obj); + MbDPartData getMbDData(App::DocumentObject* part); std::shared_ptr makeMbdMarker(std::string& name, Base::Placement& plc); std::vector> makeMbdJoint(App::DocumentObject* joint); std::shared_ptr makeMbdJointOfType(App::DocumentObject* joint, From 4598283cadd2fe5353f5db705746a884b0780ff3 Mon Sep 17 00:00:00 2001 From: Ajinkya Dahale Date: Tue, 15 Apr 2025 00:27:37 +0530 Subject: [PATCH 14/20] Sketcher: Add check for validity of geometry when trimming Possibly solves #19425. --- src/Mod/Sketcher/App/SketchObject.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp index 37edde5188..f1f4c728cc 100644 --- a/src/Mod/Sketcher/App/SketchObject.cpp +++ b/src/Mod/Sketcher/App/SketchObject.cpp @@ -3324,6 +3324,11 @@ int SketchObject::trim(int GeoId, const Base::Vector3d& point) // FIXME: we should be able to transfer these to new curves smoothly // auto geo = getGeometry(GeoId); const auto* geoAsCurve = getGeometry(GeoId); + + if (geoAsCurve == nullptr) { + return -1; + } + bool isOriginalCurveConstruction = GeometryFacade::getConstruction(geoAsCurve); //******************* Step A => Detection of intersection - Common to all Geometries From fdaa53d191a229747236161c44a8a01e86f55585 Mon Sep 17 00:00:00 2001 From: xtemp09 Date: Thu, 17 Apr 2025 18:43:42 +0700 Subject: [PATCH 15/20] [GUI] Layout fixes in DlgActions.ui Closes #20821 --- src/Gui/Dialogs/DlgActions.ui | 465 ++++++++++++++++++---------------- 1 file changed, 246 insertions(+), 219 deletions(-) diff --git a/src/Gui/Dialogs/DlgActions.ui b/src/Gui/Dialogs/DlgActions.ui index 983da6a6ab..126fc46f1f 100644 --- a/src/Gui/Dialogs/DlgActions.ui +++ b/src/Gui/Dialogs/DlgActions.ui @@ -1,245 +1,274 @@ - - - Gui::Dialog::DlgCustomActions 0 0 - 523 + 564 383 Macros - - - 9 - + 6 - + Setup Custom Macros - - - 9 - - - 6 - - - - - - 150 - 16777215 - - - - false - - - - - - - Macro: - - - - - - - - - - Menu text: - - - - - - - - - - Tool tip: - - - - - - - - 7 - 0 - 0 - 0 - - - - - - - - Status text: - - - - - - - - - - What's this: - - - - - - - - - - Accelerator: - - - - - - - - - - Pixmap - - - - - - - - 0 - 0 - 0 - 0 - - - - - 40 - 30 - - - - - 40 - 30 - - - - ... - - - - - - - - 40 - 40 - - - - - 40 - 40 - - - - true - - - - - + + + - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 20 - 20 - - - - - - - - Qt::Vertical - - - QSizePolicy::Expanding - - - - 20 - 20 - - - - - - - - Add + Qt::Orientation::Horizontal + + + + 1 + 0 + + + + false + + + + 1 + + + + + + + 1 + 0 + + + + + + + + + Macro: + + + + + + + Menu text: + + + + + + + Tool tip: + + + + + + + Status text: + + + + + + + What's this: + + + + + + + Accelerator: + + + + + + + + + + Qt::Orientation::Horizontal + + + + 40 + 20 + + + + + + + + Pixmap + + + + + + + + + + 0 + 0 + + + + + 40 + 30 + + + + + 40 + 30 + + + + ... + + + + + + + + 40 + 40 + + + + + 40 + 40 + + + + true + + + + + + + Qt::Orientation::Horizontal + + + QSizePolicy::Policy::Expanding + + + + 20 + 20 + + + + + + + + + + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + + Qt::Orientation::Vertical + + + QSizePolicy::Policy::Expanding + + + + 20 + 20 + + + + + + + + + + Add + + + + + + + Remove + + + + + + + Replace + + + + + + + Qt::Orientation::Horizontal + + + QSizePolicy::Policy::Expanding + + + + 41 + 20 + + + + + + + + - - - - Remove - - - - - - - Replace - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 41 - 20 - - - - - + @@ -250,8 +279,6 @@ Gui::AccelLineEdit QLineEdit
Gui/Widgets.h
- 0 - From 8e19bd75503577f231c9671b34de7dbd03cbcd00 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 17 Apr 2025 09:59:22 +0000 Subject: [PATCH 16/20] Bump debugpy from 1.6.7 to 1.8.14 Bumps [debugpy](https://github.com/microsoft/debugpy) from 1.6.7 to 1.8.14. - [Release notes](https://github.com/microsoft/debugpy/releases) - [Commits](https://github.com/microsoft/debugpy/compare/v1.6.7...v1.8.14) --- updated-dependencies: - dependency-name: debugpy dependency-version: 1.8.14 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index a0d8842924..7fac611b70 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,7 +10,7 @@ opencamlib==2023.1.11 packaging==23.0 Pivy==0.6.8 ply==3.11 -debugpy==1.6.7 +debugpy==1.8.14 pyNastran==1.3.4 pyshp==2.3.1 PySide2==5.15.2.1 From 73df37aabe42652fd3f7c0211988355e5bbc7150 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 17 Apr 2025 09:59:00 +0000 Subject: [PATCH 17/20] Bump prefix-dev/setup-pixi from 0.8.3 to 0.8.8 Bumps [prefix-dev/setup-pixi](https://github.com/prefix-dev/setup-pixi) from 0.8.3 to 0.8.8. - [Release notes](https://github.com/prefix-dev/setup-pixi/releases) - [Commits](https://github.com/prefix-dev/setup-pixi/compare/v0.8.3...19eac09b398e3d0c747adc7921926a6d802df4da) --- updated-dependencies: - dependency-name: prefix-dev/setup-pixi dependency-version: 0.8.8 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/sub_buildPixi.yml | 2 +- .github/workflows/sub_weeklyBuild.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/sub_buildPixi.yml b/.github/workflows/sub_buildPixi.yml index 9d642ddd67..f8dd75ec87 100644 --- a/.github/workflows/sub_buildPixi.yml +++ b/.github/workflows/sub_buildPixi.yml @@ -111,7 +111,7 @@ jobs: mkdir -p ${{ env.reportdir }} echo "reportFile=${{ env.reportfilename }}" >> $GITHUB_OUTPUT - - uses: prefix-dev/setup-pixi@5044b250243a57e8c78f7c38acd73f6d7954a3cf # v0.8.7 + - uses: prefix-dev/setup-pixi@19eac09b398e3d0c747adc7921926a6d802df4da # v0.8.8 with: pixi-version: v0.45.0 cache: false diff --git a/.github/workflows/sub_weeklyBuild.yml b/.github/workflows/sub_weeklyBuild.yml index d592cef0f5..666043a733 100644 --- a/.github/workflows/sub_weeklyBuild.yml +++ b/.github/workflows/sub_weeklyBuild.yml @@ -87,7 +87,7 @@ jobs: fetch-tags: true submodules: 'recursive' - - uses: prefix-dev/setup-pixi@92815284c57faa15cd896c4d5cfb2d59f32dc43d # v0.8.3 + - uses: prefix-dev/setup-pixi@19eac09b398e3d0c747adc7921926a6d802df4da # v0.8.8 with: pixi-version: v0.42.1 cache: false From 5658c96df6a43e53f396638c0bbecf389fae7a4c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 17 Apr 2025 20:33:53 +0000 Subject: [PATCH 18/20] Bump packaging from 23.0 to 24.2 Bumps [packaging](https://github.com/pypa/packaging) from 23.0 to 24.2. - [Release notes](https://github.com/pypa/packaging/releases) - [Changelog](https://github.com/pypa/packaging/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pypa/packaging/compare/23.0...24.2) --- updated-dependencies: - dependency-name: packaging dependency-version: '24.2' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 7fac611b70..d1dac969d2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,7 +7,7 @@ ladybug-core==0.42.2 matplotlib==3.6.3 numpy==1.24.2 opencamlib==2023.1.11 -packaging==23.0 +packaging==24.2 Pivy==0.6.8 ply==3.11 debugpy==1.8.14 From 6036a55aea9d1a783bf681ae26c673e9655ec5e4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 17 Apr 2025 09:59:12 +0000 Subject: [PATCH 19/20] Bump configparser from 5.3.0 to 7.2.0 Bumps [configparser](https://github.com/jaraco/configparser) from 5.3.0 to 7.2.0. - [Release notes](https://github.com/jaraco/configparser/releases) - [Changelog](https://github.com/jaraco/configparser/blob/main/NEWS.rst) - [Commits](https://github.com/jaraco/configparser/compare/v5.3.0...v7.2.0) --- updated-dependencies: - dependency-name: configparser dependency-version: 7.2.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index d1dac969d2..de6b72fe8f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ area==1.1.1 cog==0.6.1 -ConfigParser==5.3.0 +ConfigParser==7.2.0 defusedxml==0.7.1 ifcopenshell==0.7.0.230318 ladybug-core==0.42.2 From 8d679b70f0ec0c1dbcb3e870f7773a8129f643f3 Mon Sep 17 00:00:00 2001 From: Jackson Oursland Date: Thu, 17 Apr 2025 21:41:18 -0700 Subject: [PATCH 20/20] App: Use the legacy macOS version functionality for About FreeCAD dialog (#20858) --- src/App/Application.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/App/Application.cpp b/src/App/Application.cpp index 95bcfe56b5..3e7d942e29 100644 --- a/src/App/Application.cpp +++ b/src/App/Application.cpp @@ -64,6 +64,7 @@ #include #include #include +#include #include #include #include @@ -127,7 +128,6 @@ #include "OriginGroupExtension.h" #include "OriginGroupExtensionPy.h" #include "SuppressibleExtension.h" -#include "SuppressibleExtensionPy.h" #include "Part.h" #include "GeoFeaturePy.h" #include "Placement.h" @@ -3542,7 +3542,6 @@ std::string Application::FindHomePath(const char* sCall) QString Application::prettyProductInfoWrapper() { auto productName = QSysInfo::prettyProductName(); -#if QT_VERSION < QT_VERSION_CHECK(6, 5, 0) #ifdef FC_OS_MACOSX auto macosVersionFile = QStringLiteral("/System/Library/CoreServices/.SystemVersionPlatform.plist"); @@ -3566,7 +3565,6 @@ QString Application::prettyProductInfoWrapper() } } #endif -#endif #ifdef FC_OS_WIN64 QSettings regKey { QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"), @@ -3795,4 +3793,4 @@ void Application::getVerboseAddOnsInfo(QTextStream& str, const std::map