Skip to content

Commit 360bab5

Browse files
authored
Merge branch 'FreeCAD:main' into main
2 parents 4b848ef + c420316 commit 360bab5

File tree

131 files changed

+13417
-98309
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

131 files changed

+13417
-98309
lines changed

.github/workflows/sub_buildPixi.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ jobs:
108108
109109
- uses: prefix-dev/[email protected]
110110
with:
111-
pixi-version: v0.34.0
111+
pixi-version: v0.39.4
112112
cache: false
113113

114114
- name: Restore Compiler Cache

pixi.lock

Lines changed: 9805 additions & 16715 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pixi.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name = "FreeCAD"
33
version = "0.22.0"
44
description = "pixi instructions for FreeCAD"
55
authors = ["looooo <[email protected]>"]
6-
channels = ["conda-forge/label/pivy_rc", "conda-forge"]
6+
channels = ["conda-forge"]
77
platforms = [ "linux-64", "linux-aarch64", "osx-64", "osx-arm64", "win-64" ]
88

99
[dependencies]
@@ -34,7 +34,7 @@ ply = "*"
3434
pre-commit = "*"
3535
pybind11 = "*"
3636
pyside6 = "*"
37-
python = "3.12"
37+
python = "3.13"
3838
pyyaml = "*"
3939
qt6-main = "*"
4040
scipy = ">=1.14.1,<2"
@@ -75,6 +75,7 @@ sed = "*"
7575
sysroot_linux-64 = "*"
7676
xorg-x11-server-common-cos6-x86_64 = "*"
7777
xorg-x11-server-xvfb-cos6-x86_64 = "*"
78+
xorg-xproto = "*"
7879

7980
## Linux Dependencies (aarch64)
8081
[target.linux-aarch64.dependencies]
@@ -108,6 +109,7 @@ sed = "*"
108109
sysroot_linux-aarch64 = "*"
109110
xorg-x11-server-common-cos7-aarch64 = "*"
110111
xorg-x11-server-xvfb-cos7-aarch64 = "*"
112+
xorg-xproto = "*"
111113

112114
## macOS Dependencies (Intel)
113115
[target.osx-64.dependencies]

src/App/Application.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2252,6 +2252,7 @@ void parseProgramOptions(int ac, char ** av, const string& exe, variables_map& v
22522252
("run-test,t", value<string>()->implicit_value(""),"Run a given test case (use 0 (zero) to run all tests). If no argument is provided then return list of all available tests.")
22532253
("run-open,r", value<string>()->implicit_value(""),"Run a given test case (use 0 (zero) to run all tests). If no argument is provided then return list of all available tests. Keeps UI open after test(s) complete.")
22542254
("module-path,M", value< vector<string> >()->composing(),"Additional module paths")
2255+
("macro-path,E", value< vector<string> >()->composing(),"Additional macro paths")
22552256
("python-path,P", value< vector<string> >()->composing(),"Additional python paths")
22562257
("disable-addon", value< vector<string> >()->composing(),"Disable a given addon.")
22572258
("single-instance", "Allow to run a single instance of the application")
@@ -2294,7 +2295,7 @@ void parseProgramOptions(int ac, char ** av, const string& exe, variables_map& v
22942295
#endif
22952296
;
22962297

2297-
2298+
22982299
//0000723: improper handling of qt specific command line arguments
22992300
std::vector<std::string> args;
23002301
bool merge=false;
@@ -2429,6 +2430,15 @@ void processProgramOptions(const variables_map& vm, std::map<std::string,std::st
24292430
mConfig["AdditionalModulePaths"] = temp;
24302431
}
24312432

2433+
if (vm.count("macro-path")) {
2434+
vector<string> Macros = vm["macro-path"].as< vector<string> >();
2435+
string temp;
2436+
for (const auto & It : Macros)
2437+
temp += It + ";";
2438+
temp.erase(temp.end()-1);
2439+
mConfig["AdditionalMacroPaths"] = temp;
2440+
}
2441+
24322442
if (vm.count("python-path")) {
24332443
vector<string> Paths = vm["python-path"].as< vector<string> >();
24342444
for (const auto & It : Paths)
@@ -2593,7 +2603,7 @@ void Application::initConfig(int argc, char ** argv)
25932603

25942604
// extract home paths
25952605
ExtractUserPath();
2596-
2606+
25972607
if (vm.count("safe-mode")) {
25982608
SafeMode::StartSafeMode();
25992609
}

src/App/FreeCADInit.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,8 @@ def InitApplications():
9898
LibFcDir = os.path.realpath(LibFcDir)
9999
if (os.path.exists(LibFcDir) and not LibFcDir in libpaths):
100100
libpaths.append(LibFcDir)
101-
AddPath = FreeCAD.ConfigGet("AdditionalModulePaths").split(";")
101+
AddPath = FreeCAD.ConfigGet("AdditionalModulePaths").split(";") + \
102+
FreeCAD.ConfigGet("AdditionalMacroPaths").split(";")
102103
HomeMod = FreeCAD.getUserAppDataDir()+"Mod"
103104
HomeMod = os.path.realpath(HomeMod)
104105
MacroStd = App.getUserMacroDir(False)

src/Gui/DlgAbout.cpp

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,40 @@ void AboutDialog::linkActivated(const QUrl& link)
534534
licenseView->setSource(link);
535535
}
536536

537+
void AboutDialog::addModuleInfo(QTextStream& str, const QString& modPath, bool& firstMod)
538+
{
539+
QFileInfo mod(modPath);
540+
if (mod.isHidden()) { // Ignore hidden directories
541+
return;
542+
}
543+
if (firstMod) {
544+
firstMod = false;
545+
str << "Installed mods: \n";
546+
}
547+
str << " * " << (mod.isDir() ? QDir(modPath).dirName() : mod.fileName());
548+
try {
549+
auto metadataFile =
550+
boost::filesystem::path(mod.absoluteFilePath().toStdString()) / "package.xml";
551+
if (boost::filesystem::exists(metadataFile)) {
552+
App::Metadata metadata(metadataFile);
553+
if (metadata.version() != App::Meta::Version()) {
554+
str << QLatin1String(" ") + QString::fromStdString(metadata.version().str());
555+
}
556+
}
557+
}
558+
catch (const Base::Exception& e) {
559+
auto what = QString::fromUtf8(e.what()).trimmed().replace(QChar::fromLatin1('\n'),
560+
QChar::fromLatin1(' '));
561+
str << " (Malformed metadata: " << what << ")";
562+
}
563+
QFileInfo disablingFile(mod.absoluteFilePath(), QString::fromLatin1("ADDON_DISABLED"));
564+
if (disablingFile.exists()) {
565+
str << " (Disabled)";
566+
}
567+
568+
str << "\n";
569+
}
570+
537571
void AboutDialog::copyToClipboard()
538572
{
539573
QString data;
@@ -680,28 +714,16 @@ void AboutDialog::copyToClipboard()
680714
bool firstMod = true;
681715
if (fs::exists(modDir) && fs::is_directory(modDir)) {
682716
for (const auto& mod : fs::directory_iterator(modDir)) {
683-
auto dirName = mod.path().filename().string();
684-
if (dirName[0] == '.') { // Ignore dot directories
685-
continue;
686-
}
687-
if (firstMod) {
688-
firstMod = false;
689-
str << "Installed mods: \n";
690-
}
691-
str << " * " << QString::fromStdString(mod.path().filename().string());
692-
auto metadataFile = mod.path() / "package.xml";
693-
if (fs::exists(metadataFile)) {
694-
App::Metadata metadata(metadataFile);
695-
if (metadata.version() != App::Meta::Version()) {
696-
str << QLatin1String(" ") + QString::fromStdString(metadata.version().str());
697-
}
698-
}
699-
auto disablingFile = mod.path() / "ADDON_DISABLED";
700-
if (fs::exists(disablingFile)) {
701-
str << " (Disabled)";
702-
}
717+
auto dirName = mod.path().string();
718+
addModuleInfo(str, QString::fromStdString(dirName), firstMod);
719+
}
720+
}
721+
auto additionalModules = config.find("AdditionalModulePaths");
703722

704-
str << "\n";
723+
if (additionalModules != config.end()) {
724+
auto mods = QString::fromStdString(additionalModules->second).split(QChar::fromLatin1(';'));
725+
for (const auto& mod : mods) {
726+
addModuleInfo(str, mod, firstMod);
705727
}
706728
}
707729

src/Gui/DlgAbout.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <QDialog>
2727
#include <QTextBrowser>
2828
#include <Gui/MDIView.h>
29+
#include <qlocale.h>
2930

3031
namespace Gui
3132
{
@@ -88,6 +89,7 @@ class GuiExport AboutDialog: public QDialog
8889
void showCollectionInformation();
8990
void showPrivacyPolicy();
9091
void showOrHideImage(const QRect& rect);
92+
void addModuleInfo(QTextStream& inout_str, const QString& modPath, bool& inout_first);
9193

9294
protected:
9395
QPixmap aboutImage() const;

src/Gui/DlgMacroExecuteImp.cpp

Lines changed: 44 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,30 @@ namespace Dialog
6060
class MacroItem: public QTreeWidgetItem
6161
{
6262
public:
63-
MacroItem(QTreeWidget* widget, bool systemwide)
63+
MacroItem(QTreeWidget* widget, bool systemwide, const QString& dirPath)
6464
: QTreeWidgetItem(widget)
6565
, systemWide(systemwide)
66+
, dirPath(dirPath)
6667
{}
6768

69+
/**
70+
* Acts same as setText method but additionally set toolTip with text of
71+
* absolute file path. There may be different macros with same names from
72+
* different system paths. So it could be helpful for user to show where
73+
* exactly macro is placed.
74+
*/
75+
void setFileName(int column, const QString& text)
76+
{
77+
QFileInfo file(dirPath, text);
78+
79+
setToolTip(column, file.absoluteFilePath());
80+
return QTreeWidgetItem::setText(column, text);
81+
}
82+
6883
~MacroItem() override = default;
6984

7085
bool systemWide;
86+
QString dirPath;
7187
};
7288
} // namespace Dialog
7389
} // namespace Gui
@@ -229,23 +245,37 @@ QStringList DlgMacroExecuteImp::filterFiles(const QString& folder)
229245
* Fills up the list with macro files found in the specified location
230246
* that have been filtered by both filename and by content
231247
*/
232-
void DlgMacroExecuteImp::fillUpList()
248+
void DlgMacroExecuteImp::fillUpListForDir(const QString& dirPath, bool systemWide)
233249
{
234-
QStringList filteredByContent = this->filterFiles(this->macroPath);
250+
QStringList filteredByContent = this->filterFiles(dirPath);
235251
ui->userMacroListBox->clear();
236-
for (auto fn : filteredByContent) {
237-
auto item = new MacroItem(ui->userMacroListBox, false);
238-
item->setText(0, fn);
252+
for (auto& fn : filteredByContent) {
253+
auto* parent = systemWide ? ui->systemMacroListBox : ui->userMacroListBox;
254+
auto item = new MacroItem(parent, systemWide, dirPath);
255+
item->setFileName(0, fn);
239256
}
257+
}
258+
259+
/**
260+
* Fills up the list with macro files found in all system paths and specified by
261+
* user location that have been filtered by both filename and by content
262+
*/
263+
void DlgMacroExecuteImp::fillUpList()
264+
{
265+
fillUpListForDir(this->macroPath, false);
240266

241267
QString dirstr =
242268
QString::fromStdString(App::Application::getHomePath()) + QString::fromLatin1("Macro");
243-
filteredByContent = this->filterFiles(dirstr);
244-
245-
ui->systemMacroListBox->clear();
246-
for (auto fn : filteredByContent) {
247-
auto item = new MacroItem(ui->systemMacroListBox, true);
248-
item->setText(0, fn);
269+
fillUpListForDir(dirstr, true);
270+
271+
auto& config = App::Application::Config();
272+
auto additionalMacros = config.find("AdditionalMacroPaths");
273+
if (additionalMacros != config.end()) {
274+
QString dirsstrs = QString::fromStdString(additionalMacros->second);
275+
QStringList dirs = dirsstrs.split(QChar::fromLatin1(';'));
276+
for (const auto& dirstr : dirs) {
277+
fillUpListForDir(dirstr, true);
278+
}
249279
}
250280
}
251281

@@ -392,17 +422,7 @@ void DlgMacroExecuteImp::accept()
392422

393423
auto mitem = static_cast<MacroItem*>(item);
394424

395-
QDir dir;
396-
397-
if (!mitem->systemWide) {
398-
dir = QDir(this->macroPath);
399-
}
400-
else {
401-
QString dirstr =
402-
QString::fromStdString(App::Application::getHomePath()) + QString::fromLatin1("Macro");
403-
dir = QDir(dirstr);
404-
}
405-
425+
QDir dir(mitem->dirPath);
406426
QFileInfo fi(dir, item->text(0));
407427
try {
408428
getMainWindow()->setCursor(Qt::WaitCursor);
@@ -444,26 +464,23 @@ void DlgMacroExecuteImp::onFileChooserFileNameChanged(const QString& fn)
444464
*/
445465
void DlgMacroExecuteImp::onEditButtonClicked()
446466
{
447-
QDir dir;
448467
QTreeWidgetItem* item = nullptr;
449468

450469
int index = ui->tabMacroWidget->currentIndex();
451470
if (index == 0) { // user-specific
452471
item = ui->userMacroListBox->currentItem();
453-
dir.setPath(this->macroPath);
454472
}
455473
else {
456474
// index == 1 system-wide
457475
item = ui->systemMacroListBox->currentItem();
458-
dir.setPath(QString::fromStdString(App::Application::getHomePath())
459-
+ QString::fromLatin1("Macro"));
460476
}
461477

462478
if (!item) {
463479
return;
464480
}
465481

466482
auto mitem = static_cast<MacroItem*>(item);
483+
QDir dir(mitem->dirPath);
467484

468485
QString file = QString::fromLatin1("%1/%2").arg(dir.absolutePath(), item->text(0));
469486
auto editor = new PythonEditor();

src/Gui/DlgMacroExecuteImp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ class DlgMacroExecuteImp : public QDialog, public Gui::WindowParameter
6969

7070
protected:
7171
void fillUpList();
72+
void fillUpListForDir(const QString& dirPath, bool systemWide);
7273
QStringList filterFiles(const QString&);
7374

7475
protected:

src/Gui/DlgPreferencesImp.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,9 @@ PreferencePage* DlgPreferencesImp::createPreferencePage(const std::string& pageN
289289

290290
auto resetMargins = [](QWidget* widget) {
291291
widget->setContentsMargins(0, 0, 0, 0);
292-
widget->layout()->setContentsMargins(0, 0, 0, 0);
292+
if (auto layout = widget->layout()) {
293+
layout->setContentsMargins(0, 0, 0, 0);
294+
}
293295
};
294296

295297
// settings layout already takes care for margins, we need to reset everything to 0

0 commit comments

Comments
 (0)