From 858ad6b2079a2250f7d619e6e41a8a4310ee6837 Mon Sep 17 00:00:00 2001 From: jrheinlaender Date: Sun, 21 Oct 2012 16:57:44 +0200 Subject: [PATCH] PartDesign: Be more helpful if user clicks on a Sketchbased feature icon without having selected any sketch --- src/Mod/PartDesign/Gui/Command.cpp | 257 ++++++++++++++++------------- 1 file changed, 141 insertions(+), 116 deletions(-) diff --git a/src/Mod/PartDesign/Gui/Command.cpp b/src/Mod/PartDesign/Gui/Command.cpp index cd584a3f0..1145dd8e6 100644 --- a/src/Mod/PartDesign/Gui/Command.cpp +++ b/src/Mod/PartDesign/Gui/Command.cpp @@ -54,6 +54,63 @@ using namespace std; #include "FeaturePickDialog.h" +namespace Gui { +//=========================================================================== +// Common utility functions +//=========================================================================== + +// Take a list of Part2DObjects and erase those which are not eligible for creating a +// SketchBased feature. If supportRequired is true, also erase those that cannot be used to define +// a Subtractive feature +void validateSketches(std::vector& sketches, const bool supportRequired) +{ + std::vector::iterator s = sketches.begin(); + + while (s != sketches.end()) { + // Check whether this sketch is already being used by another feature + if ((*s)->getInList().size() != 0) { + // TODO: Display some information message that this sketch was removed? + s = sketches.erase(s); + continue; + } + + // Check whether the sketch shape is valid + Part::Part2DObject* sketch = static_cast(*s); + const TopoDS_Shape& shape = sketch->Shape.getValue(); + if (shape.IsNull()) { + s = sketches.erase(s); + continue; + // TODO: Display some information message that this sketch was removed? + } + + // count free wires + int ctWires=0; + TopExp_Explorer ex; + for (ex.Init(shape, TopAbs_WIRE); ex.More(); ex.Next()) { + ctWires++; + } + if (ctWires == 0) { + s = sketches.erase(s); + continue; + // TODO: Display some information message that this sketch was removed? + } + + // Check for support + if (supportRequired) { + App::DocumentObject* support = sketch->Support.getValue(); + if (support == NULL) { + s = sketches.erase(s); + continue; + // TODO: Display some information message that this sketch was removed? + } + } + + // All checks passed - go on to next candidate + s++; + } +} +} // namespace Gui + //=========================================================================== // Part_Pad //=========================================================================== @@ -118,37 +175,30 @@ CmdPartDesignPad::CmdPartDesignPad() void CmdPartDesignPad::activated(int iMsg) { - unsigned int n = getSelection().countObjectsOfType(Part::Part2DObject::getClassTypeId()); - if (n != 1) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("Select a sketch or 2D object.")); - return; - } - - std::string FeatName = getUniqueObjectName("Pad"); - - std::vector Sel = getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId()); - Part::Part2DObject* sketch = static_cast(Sel.front()); - const TopoDS_Shape& shape = sketch->Shape.getValue(); - if (shape.IsNull()) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("The shape of the selected object is empty.")); - return; - } - - // count free wires - int ctWires=0; - TopExp_Explorer ex; - for (ex.Init(shape, TopAbs_WIRE); ex.More(); ex.Next()) { - ctWires++; - } - if (ctWires == 0) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("The shape of the selected object is not a wire.")); - return; + // Get a valid sketch from the user + // First check selections + std::vector sketches = getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId()); + Gui::validateSketches(sketches, false); + // Next let the user choose from a list of all eligible objects + if (sketches.size() == 0) { + sketches = getDocument()->getObjectsOfType(Part::Part2DObject::getClassTypeId()); + Gui::validateSketches(sketches, false); + if (sketches.size() == 0) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid sketches in this document"), + QObject::tr("Please create a sketch or 2D object first")); + return; + } + } + // If there is more than one selection/possibility, show dialog and let user pick sketch + if (sketches.size() > 1) { + PartDesignGui::FeaturePickDialog Dlg(sketches); + if ((Dlg.exec() != QDialog::Accepted) || (sketches = Dlg.getFeatures()).empty()) + return; // Cancelled or nothing selected } + Part::Part2DObject* sketch = static_cast(sketches.front()); App::DocumentObject* support = sketch->Support.getValue(); + std::string FeatName = getUniqueObjectName("Pad"); openCommand("Make Pad"); doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Pad\",\"%s\")",FeatName.c_str()); @@ -196,41 +246,30 @@ CmdPartDesignPocket::CmdPartDesignPocket() void CmdPartDesignPocket::activated(int iMsg) { - unsigned int n = getSelection().countObjectsOfType(Part::Part2DObject::getClassTypeId()); - if (n != 1) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("Select a sketch or 2D object.")); - return; + // Get a valid sketch from the user + // First check selections + std::vector sketches = getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId()); + Gui::validateSketches(sketches, true); + // Next let the user choose from a list of all eligible objects + if (sketches.size() == 0) { + sketches = getDocument()->getObjectsOfType(Part::Part2DObject::getClassTypeId()); + Gui::validateSketches(sketches, true); + if (sketches.size() == 0) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid sketches in this document"), + QObject::tr("Please create a sketch or 2D object first. It must have a support face on a solid")); + return; + } + } + // If there is more than one selection/possibility, show dialog and let user pick sketch + if (sketches.size() > 1) { + PartDesignGui::FeaturePickDialog Dlg(sketches); + if ((Dlg.exec() != QDialog::Accepted) || (sketches = Dlg.getFeatures()).empty()) + return; // Cancelled or nothing selected } - std::string FeatName = getUniqueObjectName("Pocket"); - - std::vector Sel = getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId()); - Part::Part2DObject* sketch = static_cast(Sel.front()); - const TopoDS_Shape& shape = sketch->Shape.getValue(); - if (shape.IsNull()) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("The shape of the selected object is empty.")); - return; - } - - // count free wires - int ctWires=0; - TopExp_Explorer ex; - for (ex.Init(shape, TopAbs_WIRE); ex.More(); ex.Next()) { - ctWires++; - } - if (ctWires == 0) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("The shape of the selected object is not a wire.")); - return; - } + Part::Part2DObject* sketch = static_cast(sketches.front()); App::DocumentObject* support = sketch->Support.getValue(); - if (support == 0) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No Support"), - QObject::tr("The sketch has to have a support for the pocket feature.\nCreate the sketch on a face.")); - return; - } + std::string FeatName = getUniqueObjectName("Pocket"); openCommand("Make Pocket"); doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Pocket\",\"%s\")",FeatName.c_str()); @@ -272,37 +311,30 @@ CmdPartDesignRevolution::CmdPartDesignRevolution() void CmdPartDesignRevolution::activated(int iMsg) { - unsigned int n = getSelection().countObjectsOfType(Part::Part2DObject::getClassTypeId()); - if (n != 1) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("Select a sketch or 2D object.")); - return; - } - - std::string FeatName = getUniqueObjectName("Revolution"); - - std::vector Sel = getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId()); - Part::Part2DObject* sketch = static_cast(Sel.front()); - const TopoDS_Shape& shape = sketch->Shape.getValue(); - if (shape.IsNull()) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("The shape of the selected object is empty.")); - return; - } - - // count free wires - int ctWires=0; - TopExp_Explorer ex; - for (ex.Init(shape, TopAbs_WIRE); ex.More(); ex.Next()) { - ctWires++; - } - if (ctWires == 0) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("The shape of the selected object is not a wire.")); - return; + // Get a valid sketch from the user + // First check selections + std::vector sketches = getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId()); + Gui::validateSketches(sketches, false); + // Next let the user choose from a list of all eligible objects + if (sketches.size() == 0) { + sketches = getDocument()->getObjectsOfType(Part::Part2DObject::getClassTypeId()); + Gui::validateSketches(sketches, false); + if (sketches.size() == 0) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid sketches in this document"), + QObject::tr("Please create a sketch or 2D object first")); + return; + } + } + // If there is more than one selection/possibility, show dialog and let user pick sketch + if (sketches.size() > 1) { + PartDesignGui::FeaturePickDialog Dlg(sketches); + if ((Dlg.exec() != QDialog::Accepted) || (sketches = Dlg.getFeatures()).empty()) + return; // Cancelled or nothing selected } + Part::Part2DObject* sketch = static_cast(sketches.front()); App::DocumentObject* support = sketch->Support.getValue(); + std::string FeatName = getUniqueObjectName("Revolution"); openCommand("Make Revolution"); doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Revolution\",\"%s\")",FeatName.c_str()); @@ -349,37 +381,30 @@ CmdPartDesignGroove::CmdPartDesignGroove() void CmdPartDesignGroove::activated(int iMsg) { - unsigned int n = getSelection().countObjectsOfType(Part::Part2DObject::getClassTypeId()); - if (n != 1) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("Select a sketch or 2D object.")); - return; - } - - std::string FeatName = getUniqueObjectName("Groove"); - - std::vector Sel = getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId()); - Part::Part2DObject* sketch = static_cast(Sel.front()); - const TopoDS_Shape& shape = sketch->Shape.getValue(); - if (shape.IsNull()) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("The shape of the selected object is empty.")); - return; - } - - // count free wires - int ctWires=0; - TopExp_Explorer ex; - for (ex.Init(shape, TopAbs_WIRE); ex.More(); ex.Next()) { - ctWires++; - } - if (ctWires == 0) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("The shape of the selected object is not a wire.")); - return; + // Get a valid sketch from the user + // First check selections + std::vector sketches = getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId()); + Gui::validateSketches(sketches, true); + // Next let the user choose from a list of all eligible objects + if (sketches.size() == 0) { + sketches = getDocument()->getObjectsOfType(Part::Part2DObject::getClassTypeId()); + Gui::validateSketches(sketches, true); + if (sketches.size() == 0) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid sketches in this document"), + QObject::tr("Please create a sketch or 2D object first. It must have a support face on a solid")); + return; + } + } + // If there is more than one selection/possibility, show dialog and let user pick sketch + if (sketches.size() > 1) { + PartDesignGui::FeaturePickDialog Dlg(sketches); + if ((Dlg.exec() != QDialog::Accepted) || (sketches = Dlg.getFeatures()).empty()) + return; // Cancelled or nothing selected } + Part::Part2DObject* sketch = static_cast(sketches.front()); App::DocumentObject* support = sketch->Support.getValue(); + std::string FeatName = getUniqueObjectName("Groove"); openCommand("Make Groove"); doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Groove\",\"%s\")",FeatName.c_str());