PartDesign: Fillet, Chamfer, Draft, Thickness : Enable tool to start with no selection.
This commit is contained in:
@@ -109,7 +109,8 @@ App::DocumentObjectExecReturn *Chamfer::execute()
|
||||
Part::TopoShape TopShape;
|
||||
try {
|
||||
TopShape = getBaseShape();
|
||||
} catch (Base::Exception& e) {
|
||||
}
|
||||
catch (Base::Exception& e) {
|
||||
return new App::DocumentObjectExecReturn(e.what());
|
||||
}
|
||||
|
||||
@@ -130,9 +131,6 @@ App::DocumentObjectExecReturn *Chamfer::execute()
|
||||
|
||||
getContinuousEdges(TopShape, SubNames, FaceNames);
|
||||
|
||||
if (SubNames.empty())
|
||||
return new App::DocumentObjectExecReturn("No edges specified");
|
||||
|
||||
const int chamferType = ChamferType.getValue();
|
||||
const double size = Size.getValue();
|
||||
const double size2 = Size2.getValue();
|
||||
@@ -145,6 +143,13 @@ App::DocumentObjectExecReturn *Chamfer::execute()
|
||||
}
|
||||
|
||||
this->positionByBaseFeature();
|
||||
|
||||
//If no element is selected, then we use a copy of previous feature.
|
||||
if (SubNames.empty()) {
|
||||
this->Shape.setValue(TopShape);
|
||||
return App::DocumentObject::StdReturn;
|
||||
}
|
||||
|
||||
// create an untransformed copy of the basefeature shape
|
||||
Part::TopoShape baseShape(TopShape);
|
||||
baseShape.setTransform(Base::Matrix4D());
|
||||
|
||||
@@ -102,15 +102,21 @@ App::DocumentObjectExecReturn *Draft::execute()
|
||||
Part::TopoShape TopShape;
|
||||
try {
|
||||
TopShape = getBaseShape();
|
||||
} catch (Base::Exception& e) {
|
||||
}
|
||||
catch (Base::Exception& e) {
|
||||
return new App::DocumentObjectExecReturn(e.what());
|
||||
}
|
||||
|
||||
// Faces where draft should be applied
|
||||
// Note: Cannot be const reference currently because of BRepOffsetAPI_DraftAngle::Remove() bug, see below
|
||||
std::vector<std::string> SubVals = Base.getSubValuesStartsWith("Face");
|
||||
if (SubVals.empty())
|
||||
return new App::DocumentObjectExecReturn("No faces specified");
|
||||
|
||||
//If no element is selected, then we use a copy of previous feature.
|
||||
if (SubVals.empty()) {
|
||||
this->positionByBaseFeature();
|
||||
this->Shape.setValue(TopShape);
|
||||
return App::DocumentObject::StdReturn;
|
||||
}
|
||||
|
||||
// Draft angle
|
||||
double angle = Base::toRadians(Angle.getValue());
|
||||
|
||||
@@ -68,7 +68,8 @@ App::DocumentObjectExecReturn *Fillet::execute()
|
||||
Part::TopoShape TopShape;
|
||||
try {
|
||||
TopShape = getBaseShape();
|
||||
} catch (Base::Exception& e) {
|
||||
}
|
||||
catch (Base::Exception& e) {
|
||||
return new App::DocumentObjectExecReturn(e.what());
|
||||
}
|
||||
std::vector<std::string> SubNames = std::vector<std::string>(Base.getSubValues());
|
||||
@@ -86,9 +87,6 @@ App::DocumentObjectExecReturn *Fillet::execute()
|
||||
|
||||
getContinuousEdges(TopShape, SubNames);
|
||||
|
||||
if (SubNames.empty())
|
||||
return new App::DocumentObjectExecReturn("Fillet not possible on selected shapes");
|
||||
|
||||
double radius = Radius.getValue();
|
||||
|
||||
if(radius <= 0)
|
||||
@@ -96,6 +94,12 @@ App::DocumentObjectExecReturn *Fillet::execute()
|
||||
|
||||
this->positionByBaseFeature();
|
||||
|
||||
//If no element is selected, then we use a copy of previous feature.
|
||||
if (SubNames.empty()) {
|
||||
this->Shape.setValue(TopShape);
|
||||
return App::DocumentObject::StdReturn;
|
||||
}
|
||||
|
||||
// create an untransformed copy of the base shape
|
||||
Part::TopoShape baseShape(TopShape);
|
||||
baseShape.setTransform(Base::Matrix4D());
|
||||
|
||||
@@ -72,8 +72,16 @@ App::DocumentObjectExecReturn *Thickness::execute()
|
||||
return new App::DocumentObjectExecReturn(e.what());
|
||||
}
|
||||
|
||||
TopTools_ListOfShape closingFaces;
|
||||
const std::vector<std::string>& subStrings = Base.getSubValues();
|
||||
|
||||
//If no element is selected, then we use a copy of previous feature.
|
||||
if (subStrings.empty()) {
|
||||
this->Shape.setValue(TopShape);
|
||||
return App::DocumentObject::StdReturn;
|
||||
}
|
||||
|
||||
TopTools_ListOfShape closingFaces;
|
||||
|
||||
for (std::vector<std::string>::const_iterator it = subStrings.begin(); it != subStrings.end(); ++it) {
|
||||
TopoDS_Face face = TopoDS::Face(TopShape.getSubShape(it->c_str()));
|
||||
closingFaces.Append(face);
|
||||
|
||||
@@ -1541,7 +1541,7 @@ bool CmdPartDesignSubtractiveHelix::isActive()
|
||||
//===========================================================================
|
||||
|
||||
bool dressupGetSelected(Gui::Command* cmd, const std::string& which,
|
||||
Gui::SelectionObject &selected, bool &useAllEdges)
|
||||
Gui::SelectionObject &selected, bool &useAllEdges, bool& noSelection)
|
||||
{
|
||||
// No PartDesign feature without Body past FreeCAD 0.16
|
||||
App::Document *doc = cmd->getDocument();
|
||||
@@ -1556,10 +1556,10 @@ bool dressupGetSelected(Gui::Command* cmd, const std::string& which,
|
||||
std::vector<Gui::SelectionObject> selection = cmd->getSelection().getSelectionEx();
|
||||
|
||||
if (selection.empty()) {
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
|
||||
QObject::tr("Select an edge, face, or body."));
|
||||
return false;
|
||||
} else if (selection.size() != 1) {
|
||||
noSelection = true;
|
||||
return true;
|
||||
}
|
||||
else if (selection.size() != 1) {
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
|
||||
QObject::tr("Select an edge, face, or body from a single body."));
|
||||
return false;
|
||||
@@ -1615,12 +1615,6 @@ bool dressupGetSelected(Gui::Command* cmd, const std::string& which,
|
||||
void finishDressupFeature(const Gui::Command* cmd, const std::string& which,
|
||||
Part::Feature *base, const std::vector<std::string> & SubNames, const bool useAllEdges)
|
||||
{
|
||||
if (SubNames.empty()) {
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
|
||||
QString::fromStdString(which) + QObject::tr(" not possible on selected faces/edges."));
|
||||
return;
|
||||
}
|
||||
|
||||
std::ostringstream str;
|
||||
str << '(' << Gui::Command::getObjectCmd(base) << ",[";
|
||||
for (std::vector<std::string>::const_iterator it = SubNames.begin();it!=SubNames.end();++it){
|
||||
@@ -1656,13 +1650,20 @@ void finishDressupFeature(const Gui::Command* cmd, const std::string& which,
|
||||
void makeChamferOrFillet(Gui::Command* cmd, const std::string& which)
|
||||
{
|
||||
bool useAllEdges = false;
|
||||
bool noSelection = false;
|
||||
Gui::SelectionObject selected;
|
||||
if (!dressupGetSelected ( cmd, which, selected, useAllEdges))
|
||||
if (!dressupGetSelected ( cmd, which, selected, useAllEdges, noSelection))
|
||||
return;
|
||||
|
||||
Part::Feature *base = static_cast<Part::Feature*>(selected.getObject());
|
||||
|
||||
std::vector<std::string> SubNames = std::vector<std::string>(selected.getSubNames());
|
||||
Part::Feature *base;
|
||||
std::vector<std::string> SubNames;
|
||||
if (noSelection) {
|
||||
base = static_cast<Part::Feature*>(PartDesignGui::getBody(true)->Tip.getValue());
|
||||
}
|
||||
else {
|
||||
base = static_cast<Part::Feature*>(selected.getObject());
|
||||
SubNames = std::vector<std::string>(selected.getSubNames());
|
||||
}
|
||||
|
||||
finishDressupFeature (cmd, which, base, SubNames, useAllEdges);
|
||||
}
|
||||
@@ -1746,31 +1747,41 @@ void CmdPartDesignDraft::activated(int iMsg)
|
||||
Q_UNUSED(iMsg);
|
||||
Gui::SelectionObject selected;
|
||||
bool useAllEdges = false;
|
||||
if (!dressupGetSelected ( this, "Draft", selected, useAllEdges))
|
||||
bool noSelection = false;
|
||||
if (!dressupGetSelected ( this, "Draft", selected, useAllEdges, noSelection))
|
||||
return;
|
||||
|
||||
Part::Feature *base = static_cast<Part::Feature*>(selected.getObject());
|
||||
std::vector<std::string> SubNames = std::vector<std::string>(selected.getSubNames());
|
||||
const Part::TopoShape& TopShape = base->Shape.getShape();
|
||||
size_t i = 0;
|
||||
Part::Feature* base;
|
||||
std::vector<std::string> SubNames;
|
||||
if (noSelection) {
|
||||
base = static_cast<Part::Feature*>(PartDesignGui::getBody(true)->Tip.getValue());
|
||||
}
|
||||
else {
|
||||
base = static_cast<Part::Feature*>(selected.getObject());
|
||||
SubNames = std::vector<std::string>(selected.getSubNames());
|
||||
|
||||
// filter out the edges
|
||||
while(i < SubNames.size())
|
||||
{
|
||||
std::string aSubName = static_cast<std::string>(SubNames.at(i));
|
||||
const Part::TopoShape& TopShape = base->Shape.getShape();
|
||||
|
||||
if (aSubName.compare(0, 4, "Face") == 0) {
|
||||
// Check for valid face types
|
||||
TopoDS_Face face = TopoDS::Face(TopShape.getSubShape(aSubName.c_str()));
|
||||
BRepAdaptor_Surface sf(face);
|
||||
if ((sf.GetType() != GeomAbs_Plane) && (sf.GetType() != GeomAbs_Cylinder) && (sf.GetType() != GeomAbs_Cone))
|
||||
SubNames.erase(SubNames.begin()+i);
|
||||
} else {
|
||||
// empty name or any other sub-element
|
||||
SubNames.erase(SubNames.begin()+i);
|
||||
// filter out the edges
|
||||
size_t i = 0;
|
||||
while (i < SubNames.size())
|
||||
{
|
||||
std::string aSubName = static_cast<std::string>(SubNames.at(i));
|
||||
|
||||
if (aSubName.compare(0, 4, "Face") == 0) {
|
||||
// Check for valid face types
|
||||
TopoDS_Face face = TopoDS::Face(TopShape.getSubShape(aSubName.c_str()));
|
||||
BRepAdaptor_Surface sf(face);
|
||||
if ((sf.GetType() != GeomAbs_Plane) && (sf.GetType() != GeomAbs_Cylinder) && (sf.GetType() != GeomAbs_Cone))
|
||||
SubNames.erase(SubNames.begin() + i);
|
||||
}
|
||||
else {
|
||||
// empty name or any other sub-element
|
||||
SubNames.erase(SubNames.begin() + i);
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
finishDressupFeature (this, "Draft", base, SubNames, useAllEdges);
|
||||
@@ -1804,23 +1815,32 @@ void CmdPartDesignThickness::activated(int iMsg)
|
||||
Q_UNUSED(iMsg);
|
||||
Gui::SelectionObject selected;
|
||||
bool useAllEdges = false;
|
||||
if (!dressupGetSelected ( this, "Thickness", selected, useAllEdges))
|
||||
bool noSelection = false;
|
||||
if (!dressupGetSelected ( this, "Thickness", selected, useAllEdges, noSelection))
|
||||
return;
|
||||
|
||||
Part::Feature *base = static_cast<Part::Feature*>(selected.getObject());
|
||||
std::vector<std::string> SubNames = std::vector<std::string>(selected.getSubNames());
|
||||
size_t i = 0;
|
||||
|
||||
// filter out the edges
|
||||
while(i < SubNames.size())
|
||||
{
|
||||
std::string aSubName = static_cast<std::string>(SubNames.at(i));
|
||||
Part::Feature* base;
|
||||
std::vector<std::string> SubNames;
|
||||
if (noSelection) {
|
||||
base = static_cast<Part::Feature*>(PartDesignGui::getBody(true)->Tip.getValue());
|
||||
}
|
||||
else {
|
||||
base = static_cast<Part::Feature*>(selected.getObject());
|
||||
SubNames = std::vector<std::string>(selected.getSubNames());
|
||||
|
||||
if (aSubName.compare(0, 4, "Face") != 0) {
|
||||
// empty name or any other sub-element
|
||||
SubNames.erase(SubNames.begin()+i);
|
||||
// filter out the edges
|
||||
size_t i = 0;
|
||||
while (i < SubNames.size())
|
||||
{
|
||||
std::string aSubName = static_cast<std::string>(SubNames.at(i));
|
||||
|
||||
if (aSubName.compare(0, 4, "Face") != 0) {
|
||||
// empty name or any other sub-element
|
||||
SubNames.erase(SubNames.begin() + i);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
finishDressupFeature (this, "Thickness", base, SubNames, useAllEdges);
|
||||
|
||||
@@ -103,8 +103,10 @@ TaskChamferParameters::TaskChamferParameters(ViewProviderDressUp *DressUpView, Q
|
||||
connect(ui->listWidgetReferences, &QListWidget::itemDoubleClicked,
|
||||
this, &TaskChamferParameters::doubleClicked);
|
||||
|
||||
// the dialog can be called on a broken chamfer, then hide the chamfer
|
||||
hideOnError();
|
||||
if (strings.size() == 0)
|
||||
setSelectionMode(refSel);
|
||||
else
|
||||
hideOnError();
|
||||
}
|
||||
|
||||
void TaskChamferParameters::setUpUI(PartDesign::Chamfer* pcChamfer)
|
||||
@@ -152,40 +154,17 @@ void TaskChamferParameters::onSelectionChanged(const Gui::SelectionChanges& msg)
|
||||
// executed when the user selected something in the CAD object
|
||||
// adds/deletes the selection accordingly
|
||||
|
||||
if (selectionMode == none)
|
||||
return;
|
||||
|
||||
if (msg.Type == Gui::SelectionChanges::AddSelection) {
|
||||
if (referenceSelected(msg)) {
|
||||
// Clear selection.
|
||||
Gui::Selection().clearSelection();
|
||||
|
||||
if (removeItemFromListWidget(ui->listWidgetReferences, msg.pSubName)) {
|
||||
// if there is only one item left, it cannot be deleted
|
||||
if (ui->listWidgetReferences->count() == 1) {
|
||||
deleteAction->setEnabled(false);
|
||||
deleteAction->setStatusTip(tr("There must be at least one item"));
|
||||
// we must also end the selection mode
|
||||
exitSelectionMode();
|
||||
clearButtons(none);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ui->listWidgetReferences->addItem(QString::fromStdString(msg.pSubName));
|
||||
// it might be the second one so we can enable the context menu
|
||||
if (ui->listWidgetReferences->count() > 1) {
|
||||
deleteAction->setEnabled(true);
|
||||
deleteAction->setStatusTip(QString());
|
||||
}
|
||||
}
|
||||
// highlight existing references for possible further selections
|
||||
DressUpView->highlightReferences(true);
|
||||
if (selectionMode == refSel) {
|
||||
referenceSelected(msg, ui->listWidgetReferences);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TaskChamferParameters::onCheckBoxUseAllEdgesToggled(bool checked)
|
||||
{
|
||||
if(checked)
|
||||
setSelectionMode(none);
|
||||
PartDesign::Chamfer* pcChamfer = static_cast<PartDesign::Chamfer*>(DressUpView->getObject());
|
||||
ui->buttonRefSel->setEnabled(!checked);
|
||||
ui->listWidgetReferences->setEnabled(!checked);
|
||||
@@ -193,60 +172,15 @@ void TaskChamferParameters::onCheckBoxUseAllEdgesToggled(bool checked)
|
||||
pcChamfer->getDocument()->recomputeFeature(pcChamfer);
|
||||
}
|
||||
|
||||
void TaskChamferParameters::clearButtons(const selectionModes notThis)
|
||||
void TaskChamferParameters::setButtons(const selectionModes mode)
|
||||
{
|
||||
if (notThis != refSel) ui->buttonRefSel->setChecked(false);
|
||||
DressUpView->highlightReferences(false);
|
||||
ui->buttonRefSel->setChecked(mode == refSel);
|
||||
ui->buttonRefSel->setText(mode == refSel ? tr("End selection") : tr("Start selection"));
|
||||
}
|
||||
|
||||
void TaskChamferParameters::onRefDeleted()
|
||||
{
|
||||
// assure we we are not in selection mode
|
||||
exitSelectionMode();
|
||||
clearButtons(none);
|
||||
// delete any selections since the reference(s) might be highlighted
|
||||
Gui::Selection().clearSelection();
|
||||
DressUpView->highlightReferences(false);
|
||||
|
||||
// get the list of items to be deleted
|
||||
QList<QListWidgetItem*> selectedList = ui->listWidgetReferences->selectedItems();
|
||||
|
||||
// if all items are selected, we must stop because one must be kept to avoid that the feature gets broken
|
||||
if (selectedList.count() == ui->listWidgetReferences->model()->rowCount()) {
|
||||
QMessageBox::warning(this, tr("Selection error"), tr("At least one item must be kept."));
|
||||
return;
|
||||
}
|
||||
|
||||
// get the chamfer object
|
||||
PartDesign::Chamfer* pcChamfer = static_cast<PartDesign::Chamfer*>(DressUpView->getObject());
|
||||
App::DocumentObject* base = pcChamfer->Base.getValue();
|
||||
// get all chamfer references
|
||||
std::vector<std::string> refs = pcChamfer->Base.getSubValues();
|
||||
setupTransaction();
|
||||
|
||||
// delete the selection backwards to assure the list index keeps valid for the deletion
|
||||
for (int i = selectedList.count() - 1; i > -1; i--) {
|
||||
// the ref index is the same as the listWidgetReferences index
|
||||
// so we can erase using the row number of the element to be deleted
|
||||
int rowNumber = ui->listWidgetReferences->row(selectedList.at(i));
|
||||
// erase the reference
|
||||
refs.erase(refs.begin() + rowNumber);
|
||||
// remove from the list
|
||||
ui->listWidgetReferences->model()->removeRow(rowNumber);
|
||||
}
|
||||
|
||||
// update the object
|
||||
pcChamfer->Base.setValue(base, refs);
|
||||
// recompute the feature
|
||||
pcChamfer->recomputeFeature();
|
||||
// hide the chamfer if there was a computation error
|
||||
hideOnError();
|
||||
|
||||
// if there is only one item left, it cannot be deleted
|
||||
if (ui->listWidgetReferences->count() == 1) {
|
||||
deleteAction->setEnabled(false);
|
||||
deleteAction->setStatusTip(tr("There must be at least one item"));
|
||||
}
|
||||
TaskDressUpParameters::deleteRef(ui->listWidgetReferences);
|
||||
}
|
||||
|
||||
void TaskChamferParameters::onAddAllEdges()
|
||||
@@ -256,6 +190,7 @@ void TaskChamferParameters::onAddAllEdges()
|
||||
|
||||
void TaskChamferParameters::onTypeChanged(int index)
|
||||
{
|
||||
setSelectionMode(none);
|
||||
PartDesign::Chamfer* pcChamfer = static_cast<PartDesign::Chamfer*>(DressUpView->getObject());
|
||||
pcChamfer->ChamferType.setValue(index);
|
||||
ui->stackedWidget->setCurrentIndex(index);
|
||||
@@ -267,6 +202,7 @@ void TaskChamferParameters::onTypeChanged(int index)
|
||||
|
||||
void TaskChamferParameters::onSizeChanged(double len)
|
||||
{
|
||||
setSelectionMode(none);
|
||||
PartDesign::Chamfer* pcChamfer = static_cast<PartDesign::Chamfer*>(DressUpView->getObject());
|
||||
setupTransaction();
|
||||
pcChamfer->Size.setValue(len);
|
||||
@@ -277,6 +213,7 @@ void TaskChamferParameters::onSizeChanged(double len)
|
||||
|
||||
void TaskChamferParameters::onSize2Changed(double len)
|
||||
{
|
||||
setSelectionMode(none);
|
||||
PartDesign::Chamfer* pcChamfer = static_cast<PartDesign::Chamfer*>(DressUpView->getObject());
|
||||
setupTransaction();
|
||||
pcChamfer->Size2.setValue(len);
|
||||
@@ -287,6 +224,7 @@ void TaskChamferParameters::onSize2Changed(double len)
|
||||
|
||||
void TaskChamferParameters::onAngleChanged(double angle)
|
||||
{
|
||||
setSelectionMode(none);
|
||||
PartDesign::Chamfer* pcChamfer = static_cast<PartDesign::Chamfer*>(DressUpView->getObject());
|
||||
setupTransaction();
|
||||
pcChamfer->Angle.setValue(angle);
|
||||
@@ -297,6 +235,7 @@ void TaskChamferParameters::onAngleChanged(double angle)
|
||||
|
||||
void TaskChamferParameters::onFlipDirection(bool flip)
|
||||
{
|
||||
setSelectionMode(none);
|
||||
PartDesign::Chamfer* pcChamfer = static_cast<PartDesign::Chamfer*>(DressUpView->getObject());
|
||||
setupTransaction();
|
||||
pcChamfer->FlipDirection.setValue(flip);
|
||||
|
||||
@@ -55,7 +55,7 @@ private Q_SLOTS:
|
||||
void onCheckBoxUseAllEdgesToggled(bool checked);
|
||||
|
||||
protected:
|
||||
void clearButtons(const selectionModes notThis) override;
|
||||
void setButtons(const selectionModes mode) override;
|
||||
bool event(QEvent *e) override;
|
||||
void changeEvent(QEvent *e) override;
|
||||
void onSelectionChanged(const Gui::SelectionChanges& msg) override;
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
click again to end selection</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Select</string>
|
||||
<string>Enter selection</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
|
||||
@@ -111,8 +111,10 @@ TaskDraftParameters::TaskDraftParameters(ViewProviderDressUp *DressUpView, QWidg
|
||||
strings = pcDraft->PullDirection.getSubValues();
|
||||
ui->lineLine->setText(getRefStr(ref, strings));
|
||||
|
||||
// the dialog can be called on a broken draft, then hide the draft
|
||||
hideOnError();
|
||||
if (strings.size() == 0)
|
||||
setSelectionMode(refSel);
|
||||
else
|
||||
hideOnError();
|
||||
}
|
||||
|
||||
void TaskDraftParameters::onSelectionChanged(const Gui::SelectionChanges& msg)
|
||||
@@ -120,34 +122,9 @@ void TaskDraftParameters::onSelectionChanged(const Gui::SelectionChanges& msg)
|
||||
// executed when the user selected something in the CAD object
|
||||
// adds/deletes the selection accordingly
|
||||
|
||||
if (selectionMode == none)
|
||||
return;
|
||||
|
||||
if (msg.Type == Gui::SelectionChanges::AddSelection) {
|
||||
if (referenceSelected(msg)) {
|
||||
// Clear selection.
|
||||
Gui::Selection().clearSelection();
|
||||
|
||||
if (removeItemFromListWidget(ui->listWidgetReferences, msg.pSubName)) {
|
||||
// if there is only one item left, it cannot be deleted
|
||||
if (ui->listWidgetReferences->count() == 1) {
|
||||
deleteAction->setEnabled(false);
|
||||
deleteAction->setStatusTip(tr("There must be at least one item"));
|
||||
// we must also end the selection mode
|
||||
exitSelectionMode();
|
||||
clearButtons(none);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ui->listWidgetReferences->addItem(QString::fromStdString(msg.pSubName));
|
||||
// it might be the second one so we can enable the context menu
|
||||
if (ui->listWidgetReferences->count() > 1) {
|
||||
deleteAction->setEnabled(true);
|
||||
deleteAction->setStatusTip(QString());
|
||||
}
|
||||
}
|
||||
// highlight existing references for possible further selections
|
||||
DressUpView->highlightReferences(true);
|
||||
if (selectionMode == refSel) {
|
||||
referenceSelected(msg, ui->listWidgetReferences);
|
||||
}
|
||||
else if (selectionMode == plane) {
|
||||
PartDesign::Draft* pcDraft = static_cast<PartDesign::Draft*>(DressUpView->getObject());
|
||||
@@ -186,18 +163,18 @@ void TaskDraftParameters::onSelectionChanged(const Gui::SelectionChanges& msg)
|
||||
}
|
||||
}
|
||||
|
||||
void TaskDraftParameters::clearButtons(const selectionModes notThis)
|
||||
void TaskDraftParameters::setButtons(const selectionModes mode)
|
||||
{
|
||||
if (notThis != refSel) ui->buttonRefSel->setChecked(false);
|
||||
if (notThis != line) ui->buttonLine->setChecked(false);
|
||||
if (notThis != plane) ui->buttonPlane->setChecked(false);
|
||||
DressUpView->highlightReferences(false);
|
||||
ui->buttonRefSel->setText(mode == refSel ? tr("End selection") : tr("Start selection"));
|
||||
ui->buttonRefSel->setChecked(mode == refSel);
|
||||
ui->buttonLine->setChecked(mode == line);
|
||||
ui->buttonPlane->setChecked(mode == plane);
|
||||
}
|
||||
|
||||
void TaskDraftParameters::onButtonPlane(bool checked)
|
||||
{
|
||||
if (checked) {
|
||||
clearButtons(plane);
|
||||
setButtons(plane);
|
||||
hideObject();
|
||||
selectionMode = plane;
|
||||
Gui::Selection().clearSelection();
|
||||
@@ -210,7 +187,7 @@ void TaskDraftParameters::onButtonPlane(bool checked)
|
||||
void TaskDraftParameters::onButtonLine(bool checked)
|
||||
{
|
||||
if (checked) {
|
||||
clearButtons(line);
|
||||
setButtons(line);
|
||||
hideObject();
|
||||
selectionMode = line;
|
||||
Gui::Selection().clearSelection();
|
||||
@@ -221,52 +198,7 @@ void TaskDraftParameters::onButtonLine(bool checked)
|
||||
|
||||
void TaskDraftParameters::onRefDeleted(void)
|
||||
{
|
||||
// assure we we are not in selection mode
|
||||
exitSelectionMode();
|
||||
clearButtons(none);
|
||||
// delete any selections since the reference(s) might be highlighted
|
||||
Gui::Selection().clearSelection();
|
||||
DressUpView->highlightReferences(false);
|
||||
|
||||
// get the list of items to be deleted
|
||||
QList<QListWidgetItem*> selectedList = ui->listWidgetReferences->selectedItems();
|
||||
|
||||
// if all items are selected, we must stop because one must be kept to avoid that the feature gets broken
|
||||
if (selectedList.count() == ui->listWidgetReferences->model()->rowCount()) {
|
||||
QMessageBox::warning(this, tr("Selection error"), tr("At least one item must be kept."));
|
||||
return;
|
||||
}
|
||||
|
||||
// get the draft object
|
||||
PartDesign::Draft* pcDraft = static_cast<PartDesign::Draft*>(DressUpView->getObject());
|
||||
App::DocumentObject* base = pcDraft->Base.getValue();
|
||||
// get all draft references
|
||||
std::vector<std::string> refs = pcDraft->Base.getSubValues();
|
||||
setupTransaction();
|
||||
|
||||
// delete the selection backwards to assure the list index keeps valid for the deletion
|
||||
for (int i = selectedList.count() - 1; i > -1; i--) {
|
||||
// the ref index is the same as the listWidgetReferences index
|
||||
// so we can erase using the row number of the element to be deleted
|
||||
int rowNumber = ui->listWidgetReferences->row(selectedList.at(i));
|
||||
// erase the reference
|
||||
refs.erase(refs.begin() + rowNumber);
|
||||
// remove from the list
|
||||
ui->listWidgetReferences->model()->removeRow(rowNumber);
|
||||
}
|
||||
|
||||
// update the object
|
||||
pcDraft->Base.setValue(base, refs);
|
||||
// recompute the feature
|
||||
pcDraft->recomputeFeature();
|
||||
// hide the draft if there was a computation error
|
||||
hideOnError();
|
||||
|
||||
// if there is only one item left, it cannot be deleted
|
||||
if (ui->listWidgetReferences->count() == 1) {
|
||||
deleteAction->setEnabled(false);
|
||||
deleteAction->setStatusTip(tr("There must be at least one item"));
|
||||
}
|
||||
TaskDressUpParameters::deleteRef(ui->listWidgetReferences);
|
||||
}
|
||||
|
||||
void TaskDraftParameters::getPlane(App::DocumentObject*& obj, std::vector<std::string>& sub) const
|
||||
@@ -289,7 +221,7 @@ void TaskDraftParameters::getLine(App::DocumentObject*& obj, std::vector<std::st
|
||||
|
||||
void TaskDraftParameters::onAngleChanged(double angle)
|
||||
{
|
||||
clearButtons(none);
|
||||
setButtons(none);
|
||||
PartDesign::Draft* pcDraft = static_cast<PartDesign::Draft*>(DressUpView->getObject());
|
||||
setupTransaction();
|
||||
pcDraft->Angle.setValue(angle);
|
||||
@@ -304,7 +236,7 @@ double TaskDraftParameters::getAngle(void) const
|
||||
}
|
||||
|
||||
void TaskDraftParameters::onReversedChanged(const bool on) {
|
||||
clearButtons(none);
|
||||
setButtons(none);
|
||||
PartDesign::Draft* pcDraft = static_cast<PartDesign::Draft*>(DressUpView->getObject());
|
||||
setupTransaction();
|
||||
pcDraft->Reversed.setValue(on);
|
||||
|
||||
@@ -54,7 +54,7 @@ private Q_SLOTS:
|
||||
void onRefDeleted() override;
|
||||
|
||||
protected:
|
||||
void clearButtons(const selectionModes notThis) override;
|
||||
void setButtons(const selectionModes mode) override;
|
||||
bool event(QEvent *e) override;
|
||||
void changeEvent(QEvent *e) override;
|
||||
void onSelectionChanged(const Gui::SelectionChanges& msg) override;
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
click again to end selection</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Select face</string>
|
||||
<string>Enter selection</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
#include <Gui/Tools.h>
|
||||
#include <Gui/WaitCursor.h>
|
||||
#include <Mod/PartDesign/App/Body.h>
|
||||
#include <Mod/PartDesign/App/FeatureDressUp.h>
|
||||
#include <Mod/PartDesign/Gui/ReferenceSelection.h>
|
||||
|
||||
#include "TaskDressUpParameters.h"
|
||||
@@ -95,96 +94,102 @@ void TaskDressUpParameters::setupTransaction()
|
||||
transactionID = App::GetApplication().setActiveTransaction(n.c_str());
|
||||
}
|
||||
|
||||
bool TaskDressUpParameters::referenceSelected(const Gui::SelectionChanges& msg)
|
||||
void TaskDressUpParameters::referenceSelected(const Gui::SelectionChanges& msg, QListWidget* widget)
|
||||
{
|
||||
if ((msg.Type == Gui::SelectionChanges::AddSelection) && (selectionMode == refSel)) {
|
||||
if (strcmp(msg.pDocName, DressUpView->getObject()->getDocument()->getName()) != 0)
|
||||
return;
|
||||
|
||||
if (strcmp(msg.pDocName, DressUpView->getObject()->getDocument()->getName()) != 0)
|
||||
return false;
|
||||
Gui::Selection().clearSelection();
|
||||
|
||||
PartDesign::DressUp* pcDressUp = static_cast<PartDesign::DressUp*>(DressUpView->getObject());
|
||||
App::DocumentObject* base = this->getBase();
|
||||
PartDesign::DressUp* pcDressUp = static_cast<PartDesign::DressUp*>(DressUpView->getObject());
|
||||
App::DocumentObject* base = this->getBase();
|
||||
|
||||
// TODO: Must we make a copy here instead of assigning to const char* ?
|
||||
const char* fname = base->getNameInDocument();
|
||||
if (strcmp(msg.pObjectName, fname) != 0)
|
||||
return false;
|
||||
// TODO: Must we make a copy here instead of assigning to const char* ?
|
||||
const char* fname = base->getNameInDocument();
|
||||
if (strcmp(msg.pObjectName, fname) != 0)
|
||||
return;
|
||||
|
||||
std::string subName(msg.pSubName);
|
||||
std::vector<std::string> refs = pcDressUp->Base.getSubValues();
|
||||
std::vector<std::string>::iterator f = std::find(refs.begin(), refs.end(), subName);
|
||||
std::string subName(msg.pSubName);
|
||||
std::vector<std::string> refs = pcDressUp->Base.getSubValues();
|
||||
std::vector<std::string>::iterator f = std::find(refs.begin(), refs.end(), subName);
|
||||
|
||||
if (f != refs.end())
|
||||
refs.erase(f);
|
||||
else
|
||||
refs.push_back(subName);
|
||||
|
||||
DressUpView->highlightReferences(false);
|
||||
setupTransaction();
|
||||
pcDressUp->Base.setValue(base, refs);
|
||||
pcDressUp->getDocument()->recomputeFeature(pcDressUp);
|
||||
|
||||
return true;
|
||||
if (f != refs.end()) { //If it's found then it's in the list so we remove it.
|
||||
refs.erase(f);
|
||||
removeItemFromListWidget(widget, msg.pSubName);
|
||||
}
|
||||
else { //if it's not found then it's not yet in the list so we add it.
|
||||
refs.push_back(subName);
|
||||
widget->addItem(QString::fromStdString(msg.pSubName));
|
||||
}
|
||||
|
||||
return false;
|
||||
updateFeature(pcDressUp, refs);
|
||||
}
|
||||
|
||||
void TaskDressUpParameters::addAllEdges(QListWidget* widget)
|
||||
{
|
||||
PartDesign::DressUp* pcDressUp = static_cast<PartDesign::DressUp*>(DressUpView->getObject());
|
||||
if (pcDressUp) {
|
||||
App::DocumentObject* base = pcDressUp->Base.getValue();
|
||||
if (base) {
|
||||
Gui::WaitCursor wait;
|
||||
int count = pcDressUp->getBaseTopoShape().countSubElements("Edge");
|
||||
std::vector<std::string> edgeNames;
|
||||
for (int ii = 0; ii < count; ii++){
|
||||
std::ostringstream edgeName;
|
||||
edgeName << "Edge" << ii+1;
|
||||
edgeNames.push_back(edgeName.str());
|
||||
}
|
||||
|
||||
for (std::vector<std::string>::const_iterator it = edgeNames.begin(); it != edgeNames.end(); ++it){
|
||||
if (widget->findItems(QLatin1String(it->c_str()), Qt::MatchExactly).isEmpty()){
|
||||
widget->addItem(QLatin1String(it->c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
pcDressUp->Base.setValue(base, edgeNames);
|
||||
pcDressUp->getDocument()->recomputeFeature(pcDressUp);
|
||||
hideObject();
|
||||
DressUpView->highlightReferences(true);
|
||||
onButtonRefSel(true);
|
||||
|
||||
if (deleteAction) {
|
||||
deleteAction->setEnabled(widget->count() > 1);
|
||||
}
|
||||
}
|
||||
Gui::WaitCursor wait;
|
||||
int count = pcDressUp->getBaseTopoShape().countSubElements("Edge");
|
||||
std::vector<std::string> edgeNames;
|
||||
for (int ii = 0; ii < count; ii++){
|
||||
std::ostringstream edgeName;
|
||||
edgeName << "Edge" << ii+1;
|
||||
edgeNames.push_back(edgeName.str());
|
||||
}
|
||||
|
||||
//First we need to clear the widget in case the user had faces selected. Else the faces will still be in widget but not in the feature refs!
|
||||
QSignalBlocker block(widget);
|
||||
widget->clear();
|
||||
|
||||
for (std::vector<std::string>::const_iterator it = edgeNames.begin(); it != edgeNames.end(); ++it){
|
||||
widget->addItem(QLatin1String(it->c_str()));
|
||||
}
|
||||
|
||||
updateFeature(pcDressUp, edgeNames);
|
||||
}
|
||||
|
||||
void TaskDressUpParameters::deleteRef(QListWidget* widget)
|
||||
{
|
||||
// delete any selections since the reference(s) being deleted might be highlighted
|
||||
Gui::Selection().clearSelection();
|
||||
|
||||
// get the list of items to be deleted
|
||||
QList<QListWidgetItem*> selectedList = widget->selectedItems();
|
||||
|
||||
PartDesign::DressUp* pcDressUp = static_cast<PartDesign::DressUp*>(DressUpView->getObject());
|
||||
std::vector<std::string> refs = pcDressUp->Base.getSubValues();
|
||||
|
||||
// delete the selection backwards to assure the list index keeps valid for the deletion
|
||||
QSignalBlocker block(widget);
|
||||
for (int i = selectedList.count() - 1; i > -1; i--) {
|
||||
// the ref index is the same as the listWidgetReferences index
|
||||
// so we can erase using the row number of the element to be deleted
|
||||
int rowNumber = widget->row(selectedList.at(i));
|
||||
refs.erase(refs.begin() + rowNumber);
|
||||
widget->model()->removeRow(rowNumber);
|
||||
}
|
||||
|
||||
updateFeature(pcDressUp, refs);
|
||||
}
|
||||
|
||||
void TaskDressUpParameters::updateFeature(PartDesign::DressUp* pcDressUp, const std::vector<std::string>& refs)
|
||||
{
|
||||
if (selectionMode == refSel)
|
||||
DressUpView->highlightReferences(false);
|
||||
|
||||
setupTransaction();
|
||||
pcDressUp->Base.setValue(pcDressUp->Base.getValue(), refs);
|
||||
pcDressUp->recomputeFeature();
|
||||
if (selectionMode == refSel)
|
||||
DressUpView->highlightReferences(true);
|
||||
else
|
||||
hideOnError();
|
||||
}
|
||||
|
||||
void TaskDressUpParameters::onButtonRefSel(bool checked)
|
||||
{
|
||||
if (checked) {
|
||||
clearButtons(refSel);
|
||||
hideObject();
|
||||
selectionMode = refSel;
|
||||
if (addAllEdgesAction)
|
||||
addAllEdgesAction->setEnabled(true);
|
||||
AllowSelectionFlags allow;
|
||||
allow.setFlag(AllowSelection::EDGE, allowEdges);
|
||||
allow.setFlag(AllowSelection::FACE, allowFaces);
|
||||
Gui::Selection().clearSelection();
|
||||
Gui::Selection().addSelectionGate(new ReferenceSelection(this->getBase(), allow));
|
||||
DressUpView->highlightReferences(true);
|
||||
}
|
||||
else {
|
||||
if (addAllEdgesAction)
|
||||
addAllEdgesAction->setEnabled(false);
|
||||
exitSelectionMode();
|
||||
DressUpView->highlightReferences(false);
|
||||
}
|
||||
setSelectionMode(checked ? refSel : none);
|
||||
}
|
||||
|
||||
void TaskDressUpParameters::doubleClicked(QListWidgetItem* item) {
|
||||
@@ -195,14 +200,7 @@ void TaskDressUpParameters::doubleClicked(QListWidgetItem* item) {
|
||||
wasDoubleClicked = true;
|
||||
|
||||
// assure we are not in selection mode
|
||||
exitSelectionMode();
|
||||
clearButtons(none);
|
||||
|
||||
// assure the fillets are shown
|
||||
showObject();
|
||||
// remove any highlights and selections
|
||||
DressUpView->highlightReferences(false);
|
||||
Gui::Selection().clearSelection();
|
||||
setSelectionMode(none);
|
||||
|
||||
// enable next possible single-click event after double-click time passed
|
||||
QTimer::singleShot(QApplication::doubleClickInterval(), this, &TaskDressUpParameters::itemClickedTimeout);
|
||||
@@ -225,15 +223,16 @@ void TaskDressUpParameters::setSelection(QListWidgetItem* current) {
|
||||
if (body) {
|
||||
std::string objName = body->getNameInDocument();
|
||||
|
||||
// hide fillet to see the original edge
|
||||
// (a fillet creates new edges so that the original one is not available)
|
||||
hideObject();
|
||||
// highlight all objects in the list
|
||||
DressUpView->highlightReferences(true);
|
||||
// clear existing selection because only the current item is highlighted, not all selected ones to keep the overview
|
||||
Gui::Selection().clearSelection();
|
||||
// Enter selection mode
|
||||
if (selectionMode == none)
|
||||
setSelectionMode(refSel);
|
||||
else
|
||||
Gui::Selection().clearSelection();
|
||||
|
||||
// highlight the selected item
|
||||
bool block = this->blockSelection(true);
|
||||
Gui::Selection().addSelection(docName.c_str(), objName.c_str(), subName.c_str(), 0, 0, 0);
|
||||
this->blockSelection(block);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -254,12 +253,10 @@ void TaskDressUpParameters::createAddAllEdgesAction(QListWidget* parentList)
|
||||
addAllEdgesAction->setShortcutVisibleInContextMenu(true);
|
||||
#endif
|
||||
parentList->addAction(addAllEdgesAction);
|
||||
addAllEdgesAction->setEnabled(false);
|
||||
addAllEdgesAction->setStatusTip(tr("Adds all edges to the list box (active only when in add selection mode)."));
|
||||
parentList->setContextMenuPolicy(Qt::ActionsContextMenu);
|
||||
}
|
||||
|
||||
|
||||
void TaskDressUpParameters::createDeleteAction(QListWidget* parentList)
|
||||
{
|
||||
// creates a context menu, a shortcut for it and connects it to a slot function
|
||||
@@ -271,11 +268,6 @@ void TaskDressUpParameters::createDeleteAction(QListWidget* parentList)
|
||||
deleteAction->setShortcutVisibleInContextMenu(true);
|
||||
#endif
|
||||
parentList->addAction(deleteAction);
|
||||
// if there is only one item, it cannot be deleted
|
||||
if (parentList->count() == 1) {
|
||||
deleteAction->setEnabled(false);
|
||||
deleteAction->setStatusTip(tr("There must be at least one item"));
|
||||
}
|
||||
parentList->setContextMenuPolicy(Qt::ActionsContextMenu);
|
||||
}
|
||||
|
||||
@@ -319,7 +311,7 @@ const std::vector<std::string> TaskDressUpParameters::getReferences() const
|
||||
}
|
||||
|
||||
// TODO: This code is identical with TaskTransformedParameters::removeItemFromListWidget()
|
||||
bool TaskDressUpParameters::removeItemFromListWidget(QListWidget* widget, const char* itemstr)
|
||||
void TaskDressUpParameters::removeItemFromListWidget(QListWidget* widget, const char* itemstr)
|
||||
{
|
||||
QList<QListWidgetItem*> items = widget->findItems(QString::fromLatin1(itemstr), Qt::MatchExactly);
|
||||
if (!items.empty()) {
|
||||
@@ -327,9 +319,7 @@ bool TaskDressUpParameters::removeItemFromListWidget(QListWidget* widget, const
|
||||
QListWidgetItem* it = widget->takeItem(widget->row(*i));
|
||||
delete it;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void TaskDressUpParameters::hideOnError()
|
||||
@@ -369,12 +359,31 @@ Part::Feature* TaskDressUpParameters::getBase(void) const
|
||||
return pcDressUp->getBaseObject();
|
||||
}
|
||||
|
||||
void TaskDressUpParameters::exitSelectionMode()
|
||||
void TaskDressUpParameters::setSelectionMode(selectionModes mode)
|
||||
{
|
||||
selectionMode = none;
|
||||
Gui::Selection().rmvSelectionGate();
|
||||
selectionMode = mode;
|
||||
setButtons(mode);
|
||||
|
||||
if (mode == none) {
|
||||
showObject();
|
||||
|
||||
Gui::Selection().rmvSelectionGate();
|
||||
|
||||
// remove any highlights and selections
|
||||
DressUpView->highlightReferences(false);
|
||||
}
|
||||
else {
|
||||
hideObject();
|
||||
|
||||
AllowSelectionFlags allow;
|
||||
allow.setFlag(AllowSelection::EDGE, allowEdges);
|
||||
allow.setFlag(AllowSelection::FACE, allowFaces);
|
||||
Gui::Selection().addSelectionGate(new ReferenceSelection(this->getBase(), allow));
|
||||
|
||||
DressUpView->highlightReferences(true);
|
||||
}
|
||||
|
||||
Gui::Selection().clearSelection();
|
||||
showObject();
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#define GUI_TASKVIEW_TaskDressUpParameters_H
|
||||
|
||||
#include <Gui/TaskView/TaskView.h>
|
||||
#include <Mod/PartDesign/App/FeatureDressUp.h>
|
||||
|
||||
#include "TaskFeatureParameters.h"
|
||||
#include "ViewProviderDressUp.h"
|
||||
@@ -72,17 +73,19 @@ protected Q_SLOTS:
|
||||
void createAddAllEdgesAction(QListWidget* parentList);
|
||||
|
||||
protected:
|
||||
void exitSelectionMode();
|
||||
bool referenceSelected(const Gui::SelectionChanges& msg);
|
||||
void referenceSelected(const Gui::SelectionChanges& msg, QListWidget* widget);
|
||||
bool wasDoubleClicked = false;
|
||||
bool KeyEvent(QEvent *e);
|
||||
void hideOnError();
|
||||
void addAllEdges(QListWidget* listWidget);
|
||||
void deleteRef(QListWidget* listWidget);
|
||||
void updateFeature(PartDesign::DressUp* pcDressUp, const std::vector<std::string>& refs);
|
||||
|
||||
protected:
|
||||
enum selectionModes { none, refSel, plane, line };
|
||||
virtual void clearButtons(const selectionModes notThis) = 0;
|
||||
static bool removeItemFromListWidget(QListWidget* widget, const char* itemstr);
|
||||
void setSelectionMode(selectionModes mode);
|
||||
virtual void setButtons(const selectionModes mode) = 0;
|
||||
static void removeItemFromListWidget(QListWidget* widget, const char* itemstr);
|
||||
|
||||
ViewProviderDressUp* getDressUpView() const
|
||||
{ return DressUpView; }
|
||||
|
||||
@@ -52,7 +52,6 @@ TaskFilletParameters::TaskFilletParameters(ViewProviderDressUp *DressUpView, QWi
|
||||
// we need a separate container widget to add all controls to
|
||||
proxy = new QWidget(this);
|
||||
ui->setupUi(proxy);
|
||||
|
||||
this->groupLayout()->addWidget(proxy);
|
||||
|
||||
PartDesign::Fillet* pcFillet = static_cast<PartDesign::Fillet*>(DressUpView->getObject());
|
||||
@@ -97,8 +96,10 @@ TaskFilletParameters::TaskFilletParameters(ViewProviderDressUp *DressUpView, QWi
|
||||
connect(ui->listWidgetReferences, &QListWidget::itemDoubleClicked,
|
||||
this, &TaskFilletParameters::doubleClicked);
|
||||
|
||||
// the dialog can be called on a broken fillet, then hide the fillet
|
||||
hideOnError();
|
||||
if (strings.size() == 0)
|
||||
setSelectionMode(refSel);
|
||||
else
|
||||
hideOnError();
|
||||
}
|
||||
|
||||
void TaskFilletParameters::onSelectionChanged(const Gui::SelectionChanges& msg)
|
||||
@@ -106,40 +107,17 @@ void TaskFilletParameters::onSelectionChanged(const Gui::SelectionChanges& msg)
|
||||
// executed when the user selected something in the CAD object
|
||||
// adds/deletes the selection accordingly
|
||||
|
||||
if (selectionMode == none)
|
||||
return;
|
||||
|
||||
if (msg.Type == Gui::SelectionChanges::AddSelection) {
|
||||
if (referenceSelected(msg)) {
|
||||
// Clear selection.
|
||||
Gui::Selection().clearSelection();
|
||||
|
||||
if (removeItemFromListWidget(ui->listWidgetReferences, msg.pSubName)) {
|
||||
// if there is only one item left, it cannot be deleted
|
||||
if (ui->listWidgetReferences->count() == 1) {
|
||||
deleteAction->setEnabled(false);
|
||||
deleteAction->setStatusTip(tr("There must be at least one item"));
|
||||
// we must also end the selection mode
|
||||
exitSelectionMode();
|
||||
clearButtons(none);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ui->listWidgetReferences->addItem(QString::fromStdString(msg.pSubName));
|
||||
// it might be the second one so we can enable the context menu
|
||||
if (ui->listWidgetReferences->count() > 1) {
|
||||
deleteAction->setEnabled(true);
|
||||
deleteAction->setStatusTip(QString());
|
||||
}
|
||||
}
|
||||
// highlight existing references for possible further selections
|
||||
DressUpView->highlightReferences(true);
|
||||
if (selectionMode == refSel) {
|
||||
referenceSelected(msg, ui->listWidgetReferences);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TaskFilletParameters::onCheckBoxUseAllEdgesToggled(bool checked)
|
||||
{
|
||||
if (checked)
|
||||
setSelectionMode(none);
|
||||
PartDesign::Fillet* pcFillet = static_cast<PartDesign::Fillet*>(DressUpView->getObject());
|
||||
ui->buttonRefSel->setEnabled(!checked);
|
||||
ui->listWidgetReferences->setEnabled(!checked);
|
||||
@@ -147,60 +125,15 @@ void TaskFilletParameters::onCheckBoxUseAllEdgesToggled(bool checked)
|
||||
pcFillet->getDocument()->recomputeFeature(pcFillet);
|
||||
}
|
||||
|
||||
void TaskFilletParameters::clearButtons(const selectionModes notThis)
|
||||
void TaskFilletParameters::setButtons(const selectionModes mode)
|
||||
{
|
||||
if (notThis != refSel) ui->buttonRefSel->setChecked(false);
|
||||
DressUpView->highlightReferences(false);
|
||||
ui->buttonRefSel->setChecked(mode == refSel);
|
||||
ui->buttonRefSel->setText(mode == refSel ? tr("End selection") : tr("Start selection"));
|
||||
}
|
||||
|
||||
void TaskFilletParameters::onRefDeleted()
|
||||
{
|
||||
// assure we we are not in selection mode
|
||||
exitSelectionMode();
|
||||
clearButtons(none);
|
||||
// delete any selections since the reference(s) might be highlighted
|
||||
Gui::Selection().clearSelection();
|
||||
DressUpView->highlightReferences(false);
|
||||
|
||||
// get the list of items to be deleted
|
||||
QList<QListWidgetItem*> selectedList = ui->listWidgetReferences->selectedItems();
|
||||
|
||||
// if all items are selected, we must stop because one must be kept to avoid that the feature gets broken
|
||||
if (selectedList.count() == ui->listWidgetReferences->model()->rowCount()){
|
||||
QMessageBox::warning(this, tr("Selection error"), tr("At least one item must be kept."));
|
||||
return;
|
||||
}
|
||||
|
||||
// get the fillet object
|
||||
PartDesign::Fillet* pcFillet = static_cast<PartDesign::Fillet*>(DressUpView->getObject());
|
||||
App::DocumentObject* base = pcFillet->Base.getValue();
|
||||
// get all fillet references
|
||||
std::vector<std::string> refs = pcFillet->Base.getSubValues();
|
||||
setupTransaction();
|
||||
|
||||
// delete the selection backwards to assure the list index keeps valid for the deletion
|
||||
for (int i = selectedList.count()-1; i > -1; i--) {
|
||||
// the ref index is the same as the listWidgetReferences index
|
||||
// so we can erase using the row number of the element to be deleted
|
||||
int rowNumber = ui->listWidgetReferences->row(selectedList.at(i));
|
||||
// erase the reference
|
||||
refs.erase(refs.begin() + rowNumber);
|
||||
// remove from the list
|
||||
ui->listWidgetReferences->model()->removeRow(rowNumber);
|
||||
}
|
||||
|
||||
// update the object
|
||||
pcFillet->Base.setValue(base, refs);
|
||||
// recompute the feature
|
||||
pcFillet->recomputeFeature();
|
||||
// hide the fillet if there was a computation error
|
||||
hideOnError();
|
||||
|
||||
// if there is only one item left, it cannot be deleted
|
||||
if (ui->listWidgetReferences->count() == 1) {
|
||||
deleteAction->setEnabled(false);
|
||||
deleteAction->setStatusTip(tr("There must be at least one item"));
|
||||
}
|
||||
TaskDressUpParameters::deleteRef(ui->listWidgetReferences);
|
||||
}
|
||||
|
||||
void TaskFilletParameters::onAddAllEdges()
|
||||
@@ -210,7 +143,7 @@ void TaskFilletParameters::onAddAllEdges()
|
||||
|
||||
void TaskFilletParameters::onLengthChanged(double len)
|
||||
{
|
||||
clearButtons(none);
|
||||
setSelectionMode(none);
|
||||
PartDesign::Fillet* pcFillet = static_cast<PartDesign::Fillet*>(DressUpView->getObject());
|
||||
setupTransaction();
|
||||
pcFillet->Radius.setValue(len);
|
||||
|
||||
@@ -49,7 +49,7 @@ private Q_SLOTS:
|
||||
|
||||
protected:
|
||||
double getLength() const;
|
||||
void clearButtons(const selectionModes notThis) override;
|
||||
void setButtons(const selectionModes mode) override;
|
||||
bool event(QEvent *e) override;
|
||||
void changeEvent(QEvent *e) override;
|
||||
void onSelectionChanged(const Gui::SelectionChanges& msg) override;
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
click again to end selection</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Select</string>
|
||||
<string>Enter selection</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
|
||||
@@ -110,8 +110,10 @@ TaskThicknessParameters::TaskThicknessParameters(ViewProviderDressUp *DressUpVie
|
||||
int join = pcThickness->Join.getValue();
|
||||
ui->joinComboBox->setCurrentIndex(join);
|
||||
|
||||
// the dialog can be called on a broken thickness, then hide the thickness
|
||||
hideOnError();
|
||||
if (strings.size() == 0)
|
||||
setSelectionMode(refSel);
|
||||
else
|
||||
hideOnError();
|
||||
}
|
||||
|
||||
void TaskThicknessParameters::onSelectionChanged(const Gui::SelectionChanges& msg)
|
||||
@@ -119,97 +121,27 @@ void TaskThicknessParameters::onSelectionChanged(const Gui::SelectionChanges& ms
|
||||
// executed when the user selected something in the CAD object
|
||||
// adds/deletes the selection accordingly
|
||||
|
||||
if (selectionMode == none)
|
||||
return;
|
||||
|
||||
if (msg.Type == Gui::SelectionChanges::AddSelection) {
|
||||
if (referenceSelected(msg)) {
|
||||
// Clear selection.
|
||||
Gui::Selection().clearSelection();
|
||||
|
||||
if (removeItemFromListWidget(ui->listWidgetReferences, msg.pSubName)) {
|
||||
// if there is only one item left, it cannot be deleted
|
||||
if (ui->listWidgetReferences->count() == 1) {
|
||||
deleteAction->setEnabled(false);
|
||||
deleteAction->setStatusTip(tr("There must be at least one item"));
|
||||
// we must also end the selection mode
|
||||
exitSelectionMode();
|
||||
clearButtons(none);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ui->listWidgetReferences->addItem(QString::fromStdString(msg.pSubName));
|
||||
// it might be the second one so we can enable the context menu
|
||||
if (ui->listWidgetReferences->count() > 1) {
|
||||
deleteAction->setEnabled(true);
|
||||
deleteAction->setStatusTip(QString());
|
||||
}
|
||||
}
|
||||
// highlight existing references for possible further selections
|
||||
DressUpView->highlightReferences(true);
|
||||
if (selectionMode == refSel) {
|
||||
referenceSelected(msg, ui->listWidgetReferences);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TaskThicknessParameters::clearButtons(const selectionModes notThis)
|
||||
void TaskThicknessParameters::setButtons(const selectionModes mode)
|
||||
{
|
||||
if (notThis != refSel) ui->buttonRefSel->setChecked(false);
|
||||
DressUpView->highlightReferences(false);
|
||||
ui->buttonRefSel->setChecked(mode == refSel);
|
||||
ui->buttonRefSel->setText(mode == refSel ? tr("End selection") : tr("Start selection"));
|
||||
}
|
||||
|
||||
void TaskThicknessParameters::onRefDeleted(void)
|
||||
{
|
||||
// assure we we are not in selection mode
|
||||
exitSelectionMode();
|
||||
clearButtons(none);
|
||||
// delete any selections since the reference(s) might be highlighted
|
||||
Gui::Selection().clearSelection();
|
||||
DressUpView->highlightReferences(false);
|
||||
|
||||
// get the list of items to be deleted
|
||||
QList<QListWidgetItem*> selectedList = ui->listWidgetReferences->selectedItems();
|
||||
|
||||
// if all items are selected, we must stop because one must be kept to avoid that the feature gets broken
|
||||
if (selectedList.count() == ui->listWidgetReferences->model()->rowCount()) {
|
||||
QMessageBox::warning(this, tr("Selection error"), tr("At least one item must be kept."));
|
||||
return;
|
||||
}
|
||||
|
||||
// get the thickness object
|
||||
PartDesign::Thickness* pcThickness = static_cast<PartDesign::Thickness*>(DressUpView->getObject());
|
||||
App::DocumentObject* base = pcThickness->Base.getValue();
|
||||
// get all thickness references
|
||||
std::vector<std::string> refs = pcThickness->Base.getSubValues();
|
||||
setupTransaction();
|
||||
|
||||
// delete the selection backwards to assure the list index keeps valid for the deletion
|
||||
for (int i = selectedList.count() - 1; i > -1; i--) {
|
||||
// the ref index is the same as the listWidgetReferences index
|
||||
// so we can erase using the row number of the element to be deleted
|
||||
int rowNumber = ui->listWidgetReferences->row(selectedList.at(i));
|
||||
// erase the reference
|
||||
refs.erase(refs.begin() + rowNumber);
|
||||
// remove from the list
|
||||
ui->listWidgetReferences->model()->removeRow(rowNumber);
|
||||
}
|
||||
|
||||
// update the object
|
||||
pcThickness->Base.setValue(base, refs);
|
||||
// recompute the feature
|
||||
pcThickness->recomputeFeature();
|
||||
// hide the thickness if there was a computation error
|
||||
hideOnError();
|
||||
|
||||
// if there is only one item left, it cannot be deleted
|
||||
if (ui->listWidgetReferences->count() == 1) {
|
||||
deleteAction->setEnabled(false);
|
||||
deleteAction->setStatusTip(tr("There must be at least one item"));
|
||||
}
|
||||
TaskDressUpParameters::deleteRef(ui->listWidgetReferences);
|
||||
}
|
||||
|
||||
void TaskThicknessParameters::onValueChanged(double angle)
|
||||
{
|
||||
clearButtons(none);
|
||||
setButtons(none);
|
||||
PartDesign::Thickness* pcThickness = static_cast<PartDesign::Thickness*>(DressUpView->getObject());
|
||||
setupTransaction();
|
||||
pcThickness->Value.setValue(angle);
|
||||
@@ -220,7 +152,7 @@ void TaskThicknessParameters::onValueChanged(double angle)
|
||||
|
||||
void TaskThicknessParameters::onJoinTypeChanged(int join) {
|
||||
|
||||
clearButtons(none);
|
||||
setButtons(none);
|
||||
PartDesign::Thickness* pcThickness = static_cast<PartDesign::Thickness*>(DressUpView->getObject());
|
||||
setupTransaction();
|
||||
pcThickness->Join.setValue(join);
|
||||
@@ -231,7 +163,7 @@ void TaskThicknessParameters::onJoinTypeChanged(int join) {
|
||||
|
||||
void TaskThicknessParameters::onModeChanged(int mode) {
|
||||
|
||||
clearButtons(none);
|
||||
setButtons(none);
|
||||
PartDesign::Thickness* pcThickness = static_cast<PartDesign::Thickness*>(DressUpView->getObject());
|
||||
setupTransaction();
|
||||
pcThickness->Mode.setValue(mode);
|
||||
@@ -246,7 +178,7 @@ double TaskThicknessParameters::getValue(void) const
|
||||
}
|
||||
|
||||
void TaskThicknessParameters::onReversedChanged(const bool on) {
|
||||
clearButtons(none);
|
||||
setButtons(none);
|
||||
PartDesign::Thickness* pcThickness = static_cast<PartDesign::Thickness*>(DressUpView->getObject());
|
||||
setupTransaction();
|
||||
pcThickness->Reversed.setValue(on);
|
||||
@@ -261,7 +193,7 @@ bool TaskThicknessParameters::getReversed(void) const
|
||||
}
|
||||
|
||||
void TaskThicknessParameters::onIntersectionChanged(const bool on) {
|
||||
clearButtons(none);
|
||||
setButtons(none);
|
||||
PartDesign::Thickness* pcThickness = static_cast<PartDesign::Thickness*>(DressUpView->getObject());
|
||||
pcThickness->Intersection.setValue(on);
|
||||
pcThickness->getDocument()->recomputeFeature(pcThickness);
|
||||
|
||||
@@ -54,7 +54,7 @@ private Q_SLOTS:
|
||||
void onRefDeleted(void) override;
|
||||
|
||||
protected:
|
||||
void clearButtons(const selectionModes notThis) override;
|
||||
void setButtons(const selectionModes mode) override;
|
||||
bool event(QEvent *e) override;
|
||||
void changeEvent(QEvent *e) override;
|
||||
void onSelectionChanged(const Gui::SelectionChanges& msg) override;
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
click again to end selection</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Select face</string>
|
||||
<string>Start selection</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
|
||||
Reference in New Issue
Block a user