Merge branch 'FreeCAD:main' into Fix-Python-getElement

This commit is contained in:
Shai Seger
2024-07-05 16:45:36 +03:00
committed by GitHub
16 changed files with 196 additions and 306 deletions

View File

@@ -24,9 +24,9 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QAction>
# include <QListWidget>
# include <QMessageBox>
#include <QAction>
#include <QListWidget>
#include <QMessageBox>
#endif
#include <Base/Interpreter.h>
@@ -45,20 +45,28 @@ using namespace Gui;
/* TRANSLATOR PartDesignGui::TaskThicknessParameters */
TaskThicknessParameters::TaskThicknessParameters(ViewProviderDressUp *DressUpView, QWidget *parent)
TaskThicknessParameters::TaskThicknessParameters(ViewProviderDressUp* DressUpView, QWidget* parent)
: TaskDressUpParameters(DressUpView, false, true, parent)
, ui(new Ui_TaskThicknessParameters)
{
addContainerWidget();
initControls();
}
void TaskThicknessParameters::addContainerWidget()
{
// we need a separate container widget to add all controls to
proxy = new QWidget(this);
ui->setupUi(proxy);
this->groupLayout()->addWidget(proxy);
}
PartDesign::Thickness* pcThickness = static_cast<PartDesign::Thickness*>(DressUpView->getObject());
void TaskThicknessParameters::initControls()
{
auto pcThickness = dynamic_cast<PartDesign::Thickness*>(DressUpView->getObject());
double a = pcThickness->Value.getValue();
ui->Value->setMinimum(0.0);
ui->Value->setMaximum(89.99);
ui->Value->setValue(a);
ui->Value->selectAll();
QMetaObject::invokeMethod(ui->Value, "setFocus", Qt::QueuedConnection);
@@ -73,54 +81,59 @@ TaskThicknessParameters::TaskThicknessParameters(ViewProviderDressUp *DressUpVie
ui->checkIntersection->setChecked(i);
std::vector<std::string> strings = pcThickness->Base.getSubValues();
for (const auto & string : strings)
{
for (const auto& string : strings) {
ui->listWidgetReferences->addItem(QString::fromStdString(string));
}
setupConnections();
int mode = static_cast<int>(pcThickness->Mode.getValue());
ui->modeComboBox->setCurrentIndex(mode);
int join = static_cast<int>(pcThickness->Join.getValue());
ui->joinComboBox->setCurrentIndex(join);
if (strings.empty()) {
setSelectionMode(refSel);
}
else {
hideOnError();
}
}
void TaskThicknessParameters::setupConnections()
{
// clang-format off
QMetaObject::connectSlotsByName(this);
connect(ui->Value, qOverload<double>(&Gui::QuantitySpinBox::valueChanged),
this, &TaskThicknessParameters::onValueChanged);
this, &TaskThicknessParameters::onValueChanged);
connect(ui->checkReverse, &QCheckBox::toggled,
this, &TaskThicknessParameters::onReversedChanged);
this, &TaskThicknessParameters::onReversedChanged);
connect(ui->checkIntersection, &QCheckBox::toggled,
this, &TaskThicknessParameters::onIntersectionChanged);
this, &TaskThicknessParameters::onIntersectionChanged);
connect(ui->buttonRefSel, &QToolButton::toggled,
this, &TaskThicknessParameters::onButtonRefSel);
this, &TaskThicknessParameters::onButtonRefSel);
connect(ui->modeComboBox, qOverload<int>(&QComboBox::currentIndexChanged),
this, &TaskThicknessParameters::onModeChanged);
this, &TaskThicknessParameters::onModeChanged);
connect(ui->joinComboBox, qOverload<int>(&QComboBox::currentIndexChanged),
this, &TaskThicknessParameters::onJoinTypeChanged);
this, &TaskThicknessParameters::onJoinTypeChanged);
// Create context menu
createDeleteAction(ui->listWidgetReferences);
connect(deleteAction, &QAction::triggered, this, &TaskThicknessParameters::onRefDeleted);
connect(ui->listWidgetReferences, &QListWidget::currentItemChanged,
this, &TaskThicknessParameters::setSelection);
this, &TaskThicknessParameters::setSelection);
connect(ui->listWidgetReferences, &QListWidget::itemClicked,
this, &TaskThicknessParameters::setSelection);
this, &TaskThicknessParameters::setSelection);
connect(ui->listWidgetReferences, &QListWidget::itemDoubleClicked,
this, &TaskThicknessParameters::doubleClicked);
int mode = pcThickness->Mode.getValue();
ui->modeComboBox->setCurrentIndex(mode);
int join = pcThickness->Join.getValue();
ui->joinComboBox->setCurrentIndex(join);
if (strings.size() == 0)
setSelectionMode(refSel);
else
hideOnError();
this, &TaskThicknessParameters::doubleClicked);
// clang-format on
}
void TaskThicknessParameters::onSelectionChanged(const Gui::SelectionChanges& msg)
{
// executed when the user selected something in the CAD object
// adds/deletes the selection accordingly
if (msg.Type == Gui::SelectionChanges::AddSelection) {
if (selectionMode == refSel) {
referenceSelected(msg, ui->listWidgetReferences);
@@ -139,37 +152,41 @@ void TaskThicknessParameters::onRefDeleted()
TaskDressUpParameters::deleteRef(ui->listWidgetReferences);
}
void TaskThicknessParameters::onValueChanged(double angle)
PartDesign::Thickness* TaskThicknessParameters::onBeforeChange()
{
setButtons(none);
PartDesign::Thickness* pcThickness = static_cast<PartDesign::Thickness*>(DressUpView->getObject());
setupTransaction();
pcThickness->Value.setValue(angle);
pcThickness->getDocument()->recomputeFeature(pcThickness);
return dynamic_cast<PartDesign::Thickness*>(DressUpView->getObject());
}
void TaskThicknessParameters::onAfterChange(PartDesign::Thickness* obj)
{
obj->recomputeFeature();
// hide the thickness if there was a computation error
hideOnError();
}
void TaskThicknessParameters::onJoinTypeChanged(int join) {
setButtons(none);
PartDesign::Thickness* pcThickness = static_cast<PartDesign::Thickness*>(DressUpView->getObject());
setupTransaction();
pcThickness->Join.setValue(join);
pcThickness->getDocument()->recomputeFeature(pcThickness);
// hide the thickness if there was a computation error
hideOnError();
void TaskThicknessParameters::onValueChanged(double angle)
{
PartDesign::Thickness* thickness = onBeforeChange();
thickness->Value.setValue(angle);
onAfterChange(thickness);
}
void TaskThicknessParameters::onModeChanged(int mode) {
void TaskThicknessParameters::onJoinTypeChanged(int join)
{
setButtons(none);
PartDesign::Thickness* pcThickness = static_cast<PartDesign::Thickness*>(DressUpView->getObject());
setupTransaction();
pcThickness->Mode.setValue(mode);
pcThickness->getDocument()->recomputeFeature(pcThickness);
// hide the thickness if there was a computation error
hideOnError();
PartDesign::Thickness* thickness = onBeforeChange();
thickness->Join.setValue(join);
onAfterChange(thickness);
}
void TaskThicknessParameters::onModeChanged(int mode)
{
PartDesign::Thickness* thickness = onBeforeChange();
thickness->Mode.setValue(mode);
onAfterChange(thickness);
}
double TaskThicknessParameters::getValue() const
@@ -177,14 +194,11 @@ double TaskThicknessParameters::getValue() const
return ui->Value->value().getValue();
}
void TaskThicknessParameters::onReversedChanged(const bool on) {
setButtons(none);
PartDesign::Thickness* pcThickness = static_cast<PartDesign::Thickness*>(DressUpView->getObject());
setupTransaction();
pcThickness->Reversed.setValue(on);
pcThickness->getDocument()->recomputeFeature(pcThickness);
// hide the thickness if there was a computation error
hideOnError();
void TaskThicknessParameters::onReversedChanged(bool on)
{
PartDesign::Thickness* thickness = onBeforeChange();
thickness->Reversed.setValue(on);
onAfterChange(thickness);
}
bool TaskThicknessParameters::getReversed() const
@@ -192,13 +206,11 @@ bool TaskThicknessParameters::getReversed() const
return ui->checkReverse->isChecked();
}
void TaskThicknessParameters::onIntersectionChanged(const bool on) {
setButtons(none);
PartDesign::Thickness* pcThickness = static_cast<PartDesign::Thickness*>(DressUpView->getObject());
pcThickness->Intersection.setValue(on);
pcThickness->getDocument()->recomputeFeature(pcThickness);
// hide the thickness if there was a computation error
hideOnError();
void TaskThicknessParameters::onIntersectionChanged(bool on)
{
PartDesign::Thickness* thickness = onBeforeChange();
thickness->Intersection.setValue(on);
onAfterChange(thickness);
}
bool TaskThicknessParameters::getIntersection() const
@@ -206,12 +218,14 @@ bool TaskThicknessParameters::getIntersection() const
return ui->checkIntersection->isChecked();
}
int TaskThicknessParameters::getJoinType() const {
int TaskThicknessParameters::getJoinType() const
{
return ui->joinComboBox->currentIndex();
}
int TaskThicknessParameters::getMode() const {
int TaskThicknessParameters::getMode() const
{
return ui->modeComboBox->currentIndex();
}
@@ -223,17 +237,17 @@ TaskThicknessParameters::~TaskThicknessParameters()
Gui::Selection().rmvSelectionGate();
}
catch (const Py::Exception&) {
Base::PyException e; // extract the Python error text
Base::PyException e; // extract the Python error text
e.ReportException();
}
}
bool TaskThicknessParameters::event(QEvent *e)
bool TaskThicknessParameters::event(QEvent* e)
{
return TaskDressUpParameters::KeyEvent(e);
}
void TaskThicknessParameters::changeEvent(QEvent *e)
void TaskThicknessParameters::changeEvent(QEvent* e)
{
TaskBox::changeEvent(e);
if (e->type() == QEvent::LanguageChange) {
@@ -243,9 +257,10 @@ void TaskThicknessParameters::changeEvent(QEvent *e)
void TaskThicknessParameters::apply()
{
//Alert user if he created an empty feature
if (ui->listWidgetReferences->count() == 0)
// Alert user if he created an empty feature
if (ui->listWidgetReferences->count() == 0) {
Base::Console().Warning(tr("Empty thickness created !\n").toStdString().c_str());
}
}
//**************************************************************************
@@ -253,48 +268,32 @@ void TaskThicknessParameters::apply()
// TaskDialog
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
TaskDlgThicknessParameters::TaskDlgThicknessParameters(ViewProviderThickness *DressUpView)
TaskDlgThicknessParameters::TaskDlgThicknessParameters(ViewProviderThickness* DressUpView)
: TaskDlgDressUpParameters(DressUpView)
{
parameter = new TaskThicknessParameters(DressUpView);
parameter = new TaskThicknessParameters(DressUpView);
Content.push_back(parameter);
}
TaskDlgThicknessParameters::~TaskDlgThicknessParameters() = default;
//==== calls from the TaskView ===============================================================
//void TaskDlgThicknessParameters::open()
//{
// // a transaction is already open at creation time of the draft
// if (!Gui::Command::hasPendingCommand()) {
// QString msg = QObject::tr("Edit draft");
// Gui::Command::openCommand((const char*)msg.toUtf8());
// }
//}
//
//void TaskDlgThicknessParameters::clicked(int)
//{
//
//}
bool TaskDlgThicknessParameters::accept()
{
auto obj = vp->getObject();
if (!obj->isError())
if (!obj->isError()) {
parameter->showObject();
}
parameter->apply();
TaskThicknessParameters* draftparameter = static_cast<TaskThicknessParameters*>(parameter);
auto draftparameter = dynamic_cast<TaskThicknessParameters*>(parameter);
FCMD_OBJ_CMD(obj,"Value = " << draftparameter->getValue());
FCMD_OBJ_CMD(obj,"Reversed = " << draftparameter->getReversed());
FCMD_OBJ_CMD(obj,"Mode = " << draftparameter->getMode());
FCMD_OBJ_CMD(obj,"Intersection = " << draftparameter->getIntersection());
FCMD_OBJ_CMD(obj,"Join = " << draftparameter->getJoinType());
FCMD_OBJ_CMD(obj, "Value = " << draftparameter->getValue());
FCMD_OBJ_CMD(obj, "Reversed = " << draftparameter->getReversed());
FCMD_OBJ_CMD(obj, "Mode = " << draftparameter->getMode());
FCMD_OBJ_CMD(obj, "Intersection = " << draftparameter->getIntersection());
FCMD_OBJ_CMD(obj, "Join = " << draftparameter->getJoinType());
return TaskDlgDressUpParameters::accept();
}

View File

@@ -29,14 +29,20 @@
class Ui_TaskThicknessParameters;
namespace PartDesignGui {
namespace PartDesign
{
class Thickness;
}
class TaskThicknessParameters : public TaskDressUpParameters
namespace PartDesignGui
{
class TaskThicknessParameters: public TaskDressUpParameters
{
Q_OBJECT
public:
explicit TaskThicknessParameters(ViewProviderDressUp *DressUpView, QWidget *parent=nullptr);
explicit TaskThicknessParameters(ViewProviderDressUp* DressUpView, QWidget* parent = nullptr);
~TaskThicknessParameters() override;
void apply() override;
@@ -44,34 +50,41 @@ public:
double getValue() const;
bool getReversed() const;
bool getIntersection() const;
int getMode() const;
int getJoinType() const;
int getMode() const;
int getJoinType() const;
private Q_SLOTS:
void onValueChanged(double angle);
void onModeChanged(int mode);
void onJoinTypeChanged(int join);
void onReversedChanged(bool reversed);
void onIntersectionChanged(bool intersection);
void onReversedChanged(bool on);
void onIntersectionChanged(bool on);
void onRefDeleted() override;
protected:
void setButtons(const selectionModes mode) override;
bool event(QEvent *e) override;
void changeEvent(QEvent *e) override;
bool event(QEvent* e) override;
void changeEvent(QEvent* e) override;
void onSelectionChanged(const Gui::SelectionChanges& msg) override;
private:
void addContainerWidget();
void initControls();
void setupConnections();
PartDesign::Thickness* onBeforeChange();
void onAfterChange(PartDesign::Thickness* obj);
private:
std::unique_ptr<Ui_TaskThicknessParameters> ui;
};
/// simulation dialog for the TaskView
class TaskDlgThicknessParameters : public TaskDlgDressUpParameters
class TaskDlgThicknessParameters: public TaskDlgDressUpParameters
{
Q_OBJECT
public:
explicit TaskDlgThicknessParameters(ViewProviderThickness *ThicknessView);
explicit TaskDlgThicknessParameters(ViewProviderThickness* ThicknessView);
~TaskDlgThicknessParameters() override;
public:
@@ -79,6 +92,6 @@ public:
bool accept() override;
};
} //namespace PartDesignGui
} // namespace PartDesignGui
#endif // GUI_TASKVIEW_TASKAPPERANCE_H
#endif // GUI_TASKVIEW_TASKAPPERANCE_H

View File

@@ -427,7 +427,6 @@ void ViewProviderBody::unifyVisualProperty(const App::Property* prop) {
if (prop == &Visibility ||
prop == &Selectable ||
prop == &DisplayModeBody ||
prop == &ShapeAppearance ||
prop == &PointColorArray ||
prop == &LineColorArray) {
return;

View File

@@ -68,111 +68,18 @@ namespace sp = std::placeholders;
/// @namespace PartDesignGui @class Workbench
TYPESYSTEM_SOURCE(PartDesignGui::Workbench, Gui::StdWorkbench)
Workbench::Workbench() {
}
Workbench::Workbench() = default;
Workbench::~Workbench() {
Workbench::~Workbench()
{
WorkflowManager::destruct();
}
void Workbench::_switchToDocument(const App::Document* /*doc*/)
{
// TODO Commented out for thurther remove or rewrite (2015-09-04, Fat-Zer)
// if (doc == NULL) return;
//
// PartDesign::Body* activeBody = NULL;
// std::vector<App::DocumentObject*> bodies = doc->getObjectsOfType(PartDesign::Body::getClassTypeId());
//
// // No tip, so build up structure or migrate
// if (!doc->Tip.getValue())
// {
// ;/*if (doc->countObjects() == 0){
// buildDefaultPartAndBody(doc);
// activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>(PDBODYKEY);
// assert(activeBody);
// } else {
// // empty document with no tip, so do migration
// _doMigration(doc);
// activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>(PDBODYKEY);
// assert(activeBody);
// }
// */
// }
// else
// {
// App::Part *docPart = dynamic_cast<App::Part *>(doc->Tip.getValue());
// if (docPart) {
// App::Part *viewPart = Gui::Application::Instance->activeView()->getActiveObject<App::Part *>("Part");
// if (viewPart != docPart)
// Gui::Application::Instance->activeView()->setActiveObject(docPart, "Part");
// //if (docPart->countObjectsOfType(PartDesign::Body::getClassTypeId()) < 1)
// // setUpPart(docPart);
// PartDesign::Body *tempBody = dynamic_cast<PartDesign::Body *> (docPart->getObjectsOfType(PartDesign::Body::getClassTypeId()).front());
// if (tempBody) {
// PartDesign::Body *viewBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>(PDBODYKEY);
// activeBody = viewBody;
// if (!viewBody)
// activeBody = tempBody;
// else if (!docPart->hasObject(viewBody))
// activeBody = tempBody;
//
// if (activeBody != viewBody)
// Gui::Application::Instance->activeView()->setActiveObject(activeBody, PDBODYKEY);
// }
// }
// }
//
// /*if (activeBody == NULL) {
// QMessageBox::critical(Gui::getMainWindow(), QObject::tr("Could not create body"),
// QObject::tr("No body was found in this document, and none could be created. Please report this bug."
// "We recommend you do not use this document with the PartDesign workbench until the bug has been fixed."
// ));
// }*/
}
void Workbench::slotActiveDocument(const Gui::Document& /*Doc*/)
{
// _switchToDocument(Doc.getDocument());
}
void Workbench::slotNewDocument(const App::Document& /*Doc*/)
{
// _switchToDocument(&Doc);
}
void Workbench::slotFinishRestoreDocument(const App::Document& /*Doc*/)
{
// _switchToDocument(&Doc);
}
void Workbench::slotDeleteDocument(const App::Document&)
{
//ActivePartObject = 0;
//ActiveGuiDoc = 0;
//ActiveAppDoc = 0;
//ActiveVp = 0;
}
/*
This does not work for Std_DuplicateSelection:
Tree.cpp gives: "Cannot reparent unknown object", probably because the signalNewObject is emitted
before the duplication of the object has been completely finished
void Workbench::slotNewObject(const App::DocumentObject& obj)
{
if ((obj.getDocument() == ActiveAppDoc) && (ActivePartObject != NULL)) {
// Add the new object to the active Body
// Note: Will this break Undo? But how else can we catch Edit->Duplicate selection?
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.addObject(App.activeDocument().%s)",
ActivePartObject->getNameInDocument(), obj.getNameInDocument());
}
}
*/
void Workbench::setupContextMenu(const char* recipient, Gui::MenuItem* item) const
{
auto selection = Gui::Selection().getSelection();
// Add move Tip Command
if ( !selection.empty() ) {
if (!selection.empty()) {
App::DocumentObject *feature = selection.front().pObject;
PartDesign::Body *body = nullptr;
@@ -434,7 +341,6 @@ void Workbench::activated()
"PartDesign_Mirrored",
"PartDesign_LinearPattern",
"PartDesign_PolarPattern",
// "PartDesign_Scaled",
"PartDesign_MultiTransform",
nullptr};
Watcher.push_back(new Gui::TaskView::TaskWatcherCommands(
@@ -444,37 +350,18 @@ void Workbench::activated()
"PartDesign_MultiTransform"
));
// make the previously used active Body active again
//PartDesignGui::ActivePartObject = NULL;
_switchToDocument(App::GetApplication().getActiveDocument());
addTaskWatcher(Watcher);
if(App::GetApplication().GetUserParameter().GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/PartDesign")->GetBool("SwitchToTask", true))
Gui::Control().showTaskView();
//NOLINTBEGIN
// Let us be notified when a document is activated, so that we can update the ActivePartObject
activeDoc = Gui::Application::Instance->signalActiveDocument.connect(std::bind(&Workbench::slotActiveDocument, this, sp::_1));
createDoc = App::GetApplication().signalNewDocument.connect(std::bind(&Workbench::slotNewDocument, this, sp::_1));
finishDoc = App::GetApplication().signalFinishRestoreDocument.connect(std::bind(&Workbench::slotFinishRestoreDocument, this, sp::_1));
deleteDoc = App::GetApplication().signalDeleteDocument.connect(std::bind(&Workbench::slotDeleteDocument, this, sp::_1));
//NOLINTEND
}
void Workbench::deactivated()
{
// Let us be notified when a document is activated, so that we can update the ActivePartObject
activeDoc.disconnect();
createDoc.disconnect();
finishDoc.disconnect();
deleteDoc.disconnect();
removeTaskWatcher();
// reset the active Body
Gui::Command::doCommand(Gui::Command::Doc,"import PartDesignGui");
Gui::Workbench::deactivated();
}
Gui::MenuItem* Workbench::setupMenuBar() const
@@ -536,7 +423,6 @@ Gui::MenuItem* Workbench::setupMenuBar() const
<< "PartDesign_LinearPattern"
<< "PartDesign_PolarPattern"
<< "PartDesign_MultiTransform";
// << "PartDesign_Scaled"
// dressups
Gui::MenuItem* dressups = new Gui::MenuItem;
@@ -572,7 +458,6 @@ Gui::MenuItem* Workbench::setupMenuBar() const
<< "Separator"
<< "Part_CheckGeometry"
<< "Separator"
<< "PartDesign_Migrate"
<< "PartDesign_Sprocket";
// For 0.13 a couple of python packages like numpy, matplotlib and others
@@ -650,16 +535,7 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
*part << "PartDesign_Mirrored"
<< "PartDesign_LinearPattern"
<< "PartDesign_PolarPattern"
// << "PartDesign_Scaled"
<< "PartDesign_MultiTransform";
return root;
}
Gui::ToolBarItem* Workbench::setupCommandBars() const
{
// Part tools
Gui::ToolBarItem* root = new Gui::ToolBarItem;
return root;
}

View File

@@ -30,8 +30,6 @@
namespace Gui {
class MenuItem;
class Document;
class ViewProviderDocumentObject;
}
@@ -48,7 +46,7 @@ public:
Workbench();
~Workbench() override;
/** Run some actions when the workbench gets activated. */
/** Run some actions when the workbench gets activated. */
void activated() override;
/** Run some actions when the workbench gets deactivated. */
void deactivated() override;
@@ -57,29 +55,8 @@ public:
void setupContextMenu(const char* recipient, Gui::MenuItem*) const override;
protected:
Gui::MenuItem* setupMenuBar() const override;
Gui::ToolBarItem* setupToolBars() const override;
Gui::ToolBarItem* setupCommandBars() const override;
private:
/// Refresh the Body's highlighting when a document becomes active
void slotActiveDocument(const Gui::Document&);
/// Refresh the highlighting. Migrate legacy documents on loading
void slotFinishRestoreDocument(const App::Document&);
/// Ensure that there are base planes and a body in a new document
void slotNewDocument(const App::Document&);
/// Update the ActivePartObject etc. when a document is closed
void slotDeleteDocument(const App::Document&);
// Add new objects to the body, if appropriate
//void slotNewObject(const App::DocumentObject& obj);
void _switchToDocument(const App::Document* doc);
private:
boost::signals2::connection activeDoc;
boost::signals2::connection createDoc;
boost::signals2::connection finishDoc;
boost::signals2::connection deleteDoc;
Gui::MenuItem* setupMenuBar() const override;
Gui::ToolBarItem* setupToolBars() const override;
};
} // namespace PartDesignGui