diff --git a/src/Gui/Control.cpp b/src/Gui/Control.cpp index d0b6c99c3..c5322e7be 100644 --- a/src/Gui/Control.cpp +++ b/src/Gui/Control.cpp @@ -124,7 +124,7 @@ void ControlSingleton::showDialog(Gui::TaskView::TaskDialog *dlg) if (ActiveDialog == dlg) return; // dialog is already defined ActiveDialog = dlg; - connect(dlg, SIGNAL(destroyed()), this, SLOT(closedDialog())); + connect(dlg, SIGNAL(aboutToBeDestroyed()), this, SLOT(closedDialog())); } // not all workbenches have the combo view enabled else if (!_taskPanel) { diff --git a/src/Gui/TaskView/TaskDialog.cpp b/src/Gui/TaskView/TaskDialog.cpp index c389d3a3d..5c784c602 100644 --- a/src/Gui/TaskView/TaskDialog.cpp +++ b/src/Gui/TaskView/TaskDialog.cpp @@ -100,4 +100,6 @@ void TaskDialog::helpRequested() } + + #include "moc_TaskDialog.cpp" diff --git a/src/Gui/TaskView/TaskDialog.h b/src/Gui/TaskView/TaskDialog.h index 2f05ec435..39cafc0f6 100644 --- a/src/Gui/TaskView/TaskDialog.h +++ b/src/Gui/TaskView/TaskDialog.h @@ -104,6 +104,13 @@ public: /// is called by the framework if the user press the help button virtual void helpRequested(); + void emitDestructionSignal() { + Q_EMIT aboutToBeDestroyed(); + } + +Q_SIGNALS: + void aboutToBeDestroyed(); + protected: /// List of TaskBoxes of that dialog std::vector Content; diff --git a/src/Gui/TaskView/TaskView.cpp b/src/Gui/TaskView/TaskView.cpp index c93961318..c08addf9c 100644 --- a/src/Gui/TaskView/TaskView.cpp +++ b/src/Gui/TaskView/TaskView.cpp @@ -570,12 +570,13 @@ void TaskView::removeDialog(void) ActiveCtrl = 0; } + TaskDialog* remove = NULL; if (ActiveDialog) { const std::vector &cont = ActiveDialog->getDialogContent(); for(std::vector::const_iterator it=cont.begin();it!=cont.end();++it){ taskPanel->removeWidget(*it); } - delete ActiveDialog; + remove = ActiveDialog; ActiveDialog = 0; } @@ -583,6 +584,11 @@ void TaskView::removeDialog(void) // put the watcher back in control addTaskWatcher(); + + if(remove) { + remove->emitDestructionSignal(); + delete remove; + } } void TaskView::updateWatcher(void) diff --git a/src/Gui/ViewProviderLine.cpp b/src/Gui/ViewProviderLine.cpp index 92fc1fefd..ae4fcc03f 100644 --- a/src/Gui/ViewProviderLine.cpp +++ b/src/Gui/ViewProviderLine.cpp @@ -63,11 +63,11 @@ using namespace Gui; PROPERTY_SOURCE(Gui::ViewProviderLine, Gui::ViewProviderGeometryObject) -ViewProviderLine::ViewProviderLine() +ViewProviderLine::ViewProviderLine() { ADD_PROPERTY(Size,(1.0)); - + pMat = new SoMaterial(); pMat->ref(); @@ -96,16 +96,16 @@ ViewProviderLine::ViewProviderLine() pLines->ref(); pLines->coordIndex.setNum(3); pLines->coordIndex.setValues(0, 3, lines); - + pFont = new SoFont(); pFont->size.setValue(Size.getValue()/10.); - + pTranslation = new SoTranslation(); pTranslation->translation.setValue(SbVec3f(-1,0,0)); - + pText = new SoAsciiText(); pText->width.setValue(-1); - + sPixmap = "view-measurement"; } @@ -161,26 +161,26 @@ void ViewProviderLine::attach(App::DocumentObject* pcObject) SoMaterialBinding* matBinding = new SoMaterialBinding; matBinding->value = SoMaterialBinding::OVERALL; - + sep->addChild(matBinding); sep->addChild(pMat); - sep->addChild(getHighlightNode()); - pcHighlight->addChild(style); - pcHighlight->addChild(pCoords); - pcHighlight->addChild(pLines); - +// sep->addChild(getHighlightNode()); +// pcHighlight->addChild(style); +// pcHighlight->addChild(pCoords); +// pcHighlight->addChild(pLines); + style = new SoDrawStyle(); style->lineWidth = 2.0f; style->linePattern.setValue(0x00FF); lineSep->addChild(style); lineSep->addChild(pLines); - lineSep->addChild(pFont); + lineSep->addChild(pFont); pText->string.setValue(SbString(pcObject->Label.getValue())); lineSep->addChild(pTranslation); lineSep->addChild(pText); - pcHighlight->addChild(lineSep); - - pcHighlight->style = SoFCSelection::EMISSIVE_DIFFUSE; +// pcHighlight->addChild(lineSep); +// +// pcHighlight->style = SoFCSelection::EMISSIVE_DIFFUSE; addDisplayMaskMode(sep, "Base"); } @@ -209,7 +209,7 @@ std::string ViewProviderLine::getElement(const SoDetail* detail) const SoDetail* ViewProviderLine::getDetail(const char* subelement) const { SoLineDetail* detail = 0; - std::string subelem(subelement); + std::string subelem(subelement); int edge = -1; if(subelem == "Main") edge = 0; @@ -222,7 +222,7 @@ SoDetail* ViewProviderLine::getDetail(const char* subelement) const return detail; } -bool ViewProviderLine::isSelectable(void) const +bool ViewProviderLine::isSelectable(void) const { return true; } @@ -234,7 +234,7 @@ bool ViewProviderLine::setEdit(int ModNum) void ViewProviderLine::unsetEdit(int ModNum) { - + } // ---------------------------------------------------------------------------- diff --git a/src/Gui/ViewProviderPlane.cpp b/src/Gui/ViewProviderPlane.cpp index eb3ebc07e..33f48503b 100644 --- a/src/Gui/ViewProviderPlane.cpp +++ b/src/Gui/ViewProviderPlane.cpp @@ -63,7 +63,7 @@ using namespace Gui; PROPERTY_SOURCE(Gui::ViewProviderPlane, Gui::ViewProviderGeometryObject) -ViewProviderPlane::ViewProviderPlane() +ViewProviderPlane::ViewProviderPlane() { ADD_PROPERTY(Size,(1.0)); @@ -171,13 +171,13 @@ void ViewProviderPlane::attach(App::DocumentObject* pcObject) highlight->addChild(style); highlight->addChild(pCoords); highlight->addChild(pLines); - + style = new SoDrawStyle(); style->lineWidth = 2.0f; style->linePattern.setValue(0x00FF); lineSep->addChild(style); lineSep->addChild(pLines); - lineSep->addChild(pFont); + lineSep->addChild(pFont); pText->string.setValue(SbString(pcObject->Label.getValue())); lineSep->addChild(pTranslation); lineSep->addChild(pText); @@ -212,7 +212,7 @@ std::string ViewProviderPlane::getElement(const SoDetail* detail) const SoDetail* ViewProviderPlane::getDetail(const char* subelement) const { SoLineDetail* detail = 0; - std::string subelem(subelement); + std::string subelem(subelement); int edge = -1; if(subelem == "Main") edge = 0; @@ -225,7 +225,7 @@ SoDetail* ViewProviderPlane::getDetail(const char* subelement) const return detail; } -bool ViewProviderPlane::isSelectable(void) const +bool ViewProviderPlane::isSelectable(void) const { return true; } @@ -237,7 +237,7 @@ bool ViewProviderPlane::setEdit(int ModNum) void ViewProviderPlane::unsetEdit(int ModNum) { - + } // ---------------------------------------------------------------------------- diff --git a/src/Mod/PartDesign/Gui/CMakeLists.txt b/src/Mod/PartDesign/Gui/CMakeLists.txt index f29459322..e72aab283 100644 --- a/src/Mod/PartDesign/Gui/CMakeLists.txt +++ b/src/Mod/PartDesign/Gui/CMakeLists.txt @@ -28,7 +28,7 @@ set(PartDesignGui_LIBS ) set(PartDesignGui_MOC_HDRS - FeaturePickDialog.h + TaskFeaturePick.h TaskSketchBasedParameters.h TaskPadParameters.h TaskPocketParameters.h @@ -55,7 +55,7 @@ SOURCE_GROUP("Moc" FILES ${PartDesignGui_MOC_SRCS}) qt4_add_resources(PartDesignGui_SRCS Resources/PartDesign.qrc) set(PartDesignGui_UIC_SRCS - FeaturePickDialog.ui + TaskFeaturePick.ui TaskPadParameters.ui TaskPocketParameters.ui TaskChamferParameters.ui @@ -124,9 +124,9 @@ SET(PartDesignGuiViewProvider_SRCS SOURCE_GROUP("ViewProvider" FILES ${PartDesignGuiViewProvider_SRCS}) SET(PartDesignGuiTaskDlgs_SRCS - FeaturePickDialog.ui - FeaturePickDialog.cpp - FeaturePickDialog.h + TaskFeaturePick.ui + TaskFeaturePick.cpp + TaskFeaturePick.h ReferenceSelection.cpp ReferenceSelection.h TaskSketchBasedParameters.cpp diff --git a/src/Mod/PartDesign/Gui/Command.cpp b/src/Mod/PartDesign/Gui/Command.cpp index 0f85ce473..13493bd04 100644 --- a/src/Mod/PartDesign/Gui/Command.cpp +++ b/src/Mod/PartDesign/Gui/Command.cpp @@ -77,11 +77,10 @@ #include #include #include "Workbench.h" -#include "FeaturePickDialog.h" -#include "Workbench.h" using namespace std; +#include "TaskFeaturePick.h" #include "ReferenceSelection.h" //=========================================================================== @@ -510,79 +509,10 @@ const QString getReferenceString(Gui::Command* cmd) QString::fromAscii(",'')]"); } } - else { - // Get a valid datum feature from the user - std::vector status; - std::vector refs = cmd->getDocument()->getObjectsOfType(App::Plane::getClassTypeId()); - std::vector refstmp = cmd->getDocument()->getObjectsOfType(PartDesign::Plane::getClassTypeId()); - refs.insert(refs.end(), refstmp.begin(), refstmp.end()); - refstmp = cmd->getDocument()->getObjectsOfType(PartDesign::Line::getClassTypeId()); - refs.insert(refs.end(), refstmp.begin(), refstmp.end()); - refstmp = cmd->getDocument()->getObjectsOfType(PartDesign::Point::getClassTypeId()); - refs.insert(refs.end(), refstmp.begin(), refstmp.end()); - - unsigned validRefs = 0; - std::vector chosenRefs; - - for (std::vector::iterator r = refs.begin(); r != refs.end(); r++) { - // Check whether this reference is a base plane - bool base = false; - for (unsigned i = 0; i < 3; i++) { - if (strcmp(App::Part::BaseplaneTypes[i], (*r)->getNameInDocument()) == 0) { - status.push_back(PartDesignGui::FeaturePickDialog::basePlane); - if (chosenRefs.empty()) - chosenRefs.push_back(*r); - validRefs++; - base = true; - break; - } - } - if (base) continue; - - // Check whether this reference belongs to the active body - PartDesign::Body* body = PartDesignGui::getBody(); - if (!body->hasFeature(*r)) { - status.push_back(PartDesignGui::FeaturePickDialog::otherBody); - continue; - } else if (body->isAfterTip(*r)) { - status.push_back(PartDesignGui::FeaturePickDialog::afterTip); - continue; - } - - // All checks passed - found a valid reference - if (chosenRefs.empty()) - chosenRefs.push_back(*r); - validRefs++; - status.push_back(PartDesignGui::FeaturePickDialog::validFeature); - } - - if (validRefs == 0) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid references in this document"), - QObject::tr("Please select a datum feature, or a face, edge or vertex")); - return QString::fromAscii(""); - } - - // If there is more than one possibility, show dialog and let user pick references - if (validRefs > 1) { - PartDesignGui::FeaturePickDialog Dlg(refs, status); - if ((Dlg.exec() != QDialog::Accepted) || (chosenRefs = Dlg.getFeatures()).empty()) - return QString::fromAscii(""); // Cancelled or nothing selected - if (chosenRefs.size() > 3) - Base::Console().Warning("You have chosen more than three references for a datum feature. The extra references are being ignored"); - } - - // TODO: Allow user to choose front or back of the plane - - referenceString = QString::fromAscii("["); - for (int i = 0; i < chosenRefs.size(); i++) { - referenceString += QString::fromAscii(i == 0 ? "" : ",") + - QString::fromAscii("(App.activeDocument().") + QString::fromUtf8(chosenRefs[i]->getNameInDocument()) + - QString::fromAscii(",'front')"); - } - - referenceString += QString::fromAscii("]"); - return referenceString; - } + + //datum features task can start without reference, as every needed one can be set from + //withing the task. + return QString::fromAscii(""); } /* Datum feature commands =======================================================*/ @@ -822,7 +752,7 @@ void CmdPartDesignNewSketch::activated(int iMsg) } else { // Get a valid plane from the user - std::vector status; + std::vector status; std::vector planes = getDocument()->getObjectsOfType(App::Plane::getClassTypeId()); std::vector planestmp = getDocument()->getObjectsOfType(PartDesign::Plane::getClassTypeId()); planes.insert(planes.end(), planestmp.begin(), planestmp.end()); @@ -835,7 +765,7 @@ void CmdPartDesignNewSketch::activated(int iMsg) bool base = false; for (unsigned i = 0; i < 3; i++) { if (strcmp(App::Part::BaseplaneTypes[i], (*p)->getNameInDocument()) == 0) { - status.push_back(PartDesignGui::FeaturePickDialog::basePlane); + status.push_back(PartDesignGui::TaskFeaturePick::basePlane); if (firstValidPlane == planes.end()) firstValidPlane = p; validPlanes++; @@ -847,11 +777,11 @@ void CmdPartDesignNewSketch::activated(int iMsg) // Check whether this plane belongs to the active body if (!pcActiveBody->hasFeature(*p)) { - status.push_back(PartDesignGui::FeaturePickDialog::otherBody); + status.push_back(PartDesignGui::TaskFeaturePick::otherBody); continue; } else { if (pcActiveBody->isAfterTip(*p)) - status.push_back(PartDesignGui::FeaturePickDialog::afterTip); + status.push_back(PartDesignGui::TaskFeaturePick::afterTip); continue; } @@ -859,7 +789,7 @@ void CmdPartDesignNewSketch::activated(int iMsg) if (firstValidPlane == planes.end()) firstValidPlane = p; validPlanes++; - status.push_back(PartDesignGui::FeaturePickDialog::validFeature); + status.push_back(PartDesignGui::TaskFeaturePick::validFeature); } if (validPlanes == 0) { @@ -868,29 +798,58 @@ void CmdPartDesignNewSketch::activated(int iMsg) return; } + auto accepter = [=](const std::vector& features) -> bool { + + if(features.empty()) + return false; + + return true; + }; + + auto worker = [=](const std::vector& features) { + App::Plane* plane = static_cast(features.front()); + std::string FeatName = getUniqueObjectName("Sketch"); + std::string supportString = std::string("(App.activeDocument().") + plane->getNameInDocument() + + ", ['" + (false ? "back" : "front") + "'])"; + + Gui::Command::openCommand("Create a new Sketch"); + Gui::Command::doCommand(Doc,"App.activeDocument().addObject('Sketcher::SketchObject','%s')",FeatName.c_str()); + Gui::Command::doCommand(Doc,"App.activeDocument().%s.Support = %s",FeatName.c_str(),supportString.c_str()); + Gui::Command::updateActive(); // Make sure the Support's Placement property is updated + Gui::Command::doCommand(Doc,"App.activeDocument().%s.addFeature(App.activeDocument().%s)", + pcActiveBody->getNameInDocument(), FeatName.c_str()); + //doCommand(Gui,"Gui.activeDocument().activeView().setCamera('%s')",cam.c_str()); + Gui::Command::doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); + }; + // If there is more than one possibility, show dialog and let user pick plane bool reversed = false; if (validPlanes > 1) { - PartDesignGui::FeaturePickDialog Dlg(planes, status); - if ((Dlg.exec() != QDialog::Accepted) || (planes = Dlg.getFeatures()).empty()) - return; // Cancelled or nothing selected - firstValidPlane = planes.begin(); - reversed = Dlg.getReverse(); + + Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); + PartDesignGui::TaskDlgFeaturePick *pickDlg = qobject_cast(dlg); + if (dlg && !pickDlg) { + QMessageBox msgBox; + msgBox.setText(QObject::tr("A dialog is already open in the task panel")); + msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?")); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + msgBox.setDefaultButton(QMessageBox::Yes); + int ret = msgBox.exec(); + if (ret == QMessageBox::Yes) + Gui::Control().closeDialog(); + else + return; + } + + if(dlg) + Gui::Control().closeDialog(); + + Gui::Selection().clearSelection(); + Gui::Control().showDialog(new PartDesignGui::TaskDlgFeaturePick(planes, status, accepter, worker)); + } + else { + worker(planes); } - - App::Plane* plane = static_cast(*firstValidPlane); - std::string FeatName = getUniqueObjectName("Sketch"); - std::string supportString = std::string("(App.activeDocument().") + plane->getNameInDocument() + - ", ['" + (reversed ? "back" : "front") + "'])"; - - openCommand("Create a new Sketch"); - doCommand(Doc,"App.activeDocument().addObject('Sketcher::SketchObject','%s')",FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Support = %s",FeatName.c_str(),supportString.c_str()); - updateActive(); // Make sure the Support's Placement property is updated - doCommand(Doc,"App.activeDocument().%s.addFeature(App.activeDocument().%s)", - pcActiveBody->getNameInDocument(), FeatName.c_str()); - //doCommand(Gui,"Gui.activeDocument().activeView().setCamera('%s')",cam.c_str()); - doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); } } @@ -939,7 +898,7 @@ void finishFeature(const Gui::Command* cmd, const std::string& FeatName, const b // Take a list of Part2DObjects and erase those which are not eligible for creating a // SketchBased feature. const unsigned validateSketches(std::vector& sketches, - std::vector& status, + std::vector& status, std::vector::iterator& firstValidSketch) { // TODO: If the user previously opted to allow multiple use of sketches or use of sketches from other bodies, @@ -961,14 +920,14 @@ void finishFeature(const Gui::Command* cmd, const std::string& FeatName, const b ++o; } if (inList.size() > 0) { - status.push_back(PartDesignGui::FeaturePickDialog::isUsed); + status.push_back(PartDesignGui::TaskFeaturePick::isUsed); continue; } // Check whether this sketch belongs to the active body PartDesign::Body* body = PartDesignGui::getBody(); if (!body->hasFeature(*s)) { - status.push_back(PartDesignGui::FeaturePickDialog::otherBody); + status.push_back(PartDesignGui::TaskFeaturePick::otherBody); continue; } @@ -976,7 +935,7 @@ void finishFeature(const Gui::Command* cmd, const std::string& FeatName, const b Part::Part2DObject* sketch = static_cast(*s); const TopoDS_Shape& shape = sketch->Shape.getValue(); if (shape.IsNull()) { - status.push_back(PartDesignGui::FeaturePickDialog::invalidShape); + status.push_back(PartDesignGui::TaskFeaturePick::invalidShape); continue; } @@ -987,7 +946,7 @@ void finishFeature(const Gui::Command* cmd, const std::string& FeatName, const b ctWires++; } if (ctWires == 0) { - status.push_back(PartDesignGui::FeaturePickDialog::noWire); + status.push_back(PartDesignGui::TaskFeaturePick::noWire); continue; } @@ -995,21 +954,21 @@ void finishFeature(const Gui::Command* cmd, const std::string& FeatName, const b if (firstValidSketch == sketches.end()) firstValidSketch = s; validSketches++; - status.push_back(PartDesignGui::FeaturePickDialog::validFeature); + status.push_back(PartDesignGui::TaskFeaturePick::validFeature); } return validSketches; } -void prepareSketchBased(Gui::Command* cmd, const std::string& which, Part::Part2DObject*& sketch, std::string& FeatName) +void prepareSketchBased(Gui::Command* cmd, const std::string& which, + boost::function func) { PartDesign::Body *pcActiveBody = PartDesignGui::getBody(); if (!pcActiveBody) return; // Get a valid sketch from the user // First check selections - FeatName = ""; // Empty string means prepareSketchBased() was not successful - std::vector status; + std::vector status; std::vector::iterator firstValidSketch; std::vector sketches = cmd->getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId()); // Next let the user choose from a list of all eligible objects @@ -1024,23 +983,61 @@ void prepareSketchBased(Gui::Command* cmd, const std::string& which, Part::Part2 return; } } + + auto accepter = [=](const std::vector& features) -> bool { + + if(features.empty()) + return false; + + return true; + }; + + auto worker = [which, cmd, func](std::vector features) { + + auto firstValidSketch = features.begin(); + Part::Part2DObject* sketch = static_cast(*firstValidSketch); + + std::string FeatName = cmd->getUniqueObjectName(which.c_str()); + + Gui::Command::openCommand((std::string("Make ") + which).c_str()); + Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject(\"PartDesign::%s\",\"%s\")", + which.c_str(), FeatName.c_str()); + Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Sketch = App.activeDocument().%s", + FeatName.c_str(), sketch->getNameInDocument()); + //Gui::Command::doCommand(cmd->Doc,"App.activeDocument().%s.addFeature(App.activeDocument().%s)", + // pcActiveBody->getNameInDocument(), FeatName.c_str()); + + func(sketch, FeatName); + }; + // If there is more than one selection/possibility, show dialog and let user pick sketch if (validSketches > 1) { - PartDesignGui::FeaturePickDialog Dlg(sketches, status); - if ((Dlg.exec() != QDialog::Accepted) || (sketches = Dlg.getFeatures()).empty()) - return; // Cancelled or nothing selected - firstValidSketch = sketches.begin(); + + Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); + PartDesignGui::TaskDlgFeaturePick *pickDlg = qobject_cast(dlg); + if (dlg && !pickDlg) { + QMessageBox msgBox; + msgBox.setText(QObject::tr("A dialog is already open in the task panel")); + msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?")); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + msgBox.setDefaultButton(QMessageBox::Yes); + int ret = msgBox.exec(); + if (ret == QMessageBox::Yes) + Gui::Control().closeDialog(); + else + return; + } + + if(dlg) + Gui::Control().closeDialog(); + + Gui::Selection().clearSelection(); + Gui::Control().showDialog(new PartDesignGui::TaskDlgFeaturePick(sketches, status, accepter, worker)); } - - sketch = static_cast(*firstValidSketch); - - FeatName = cmd->getUniqueObjectName(which.c_str()); - - cmd->openCommand((std::string("Make ") + which).c_str()); - cmd->doCommand(cmd->Doc,"App.activeDocument().addObject(\"PartDesign::%s\",\"%s\")", - which.c_str(), FeatName.c_str()); - cmd->doCommand(cmd->Doc,"App.activeDocument().%s.Sketch = App.activeDocument().%s", - FeatName.c_str(), sketch->getNameInDocument()); + else { + worker(sketches); + } + } void finishSketchBased(const Gui::Command* cmd, const Part::Part2DObject* sketch, const std::string& FeatName) @@ -1069,17 +1066,28 @@ CmdPartDesignPad::CmdPartDesignPad() } void CmdPartDesignPad::activated(int iMsg) -{ - Part::Part2DObject* sketch; - std::string FeatName; - prepareSketchBased(this, "Pad", sketch, FeatName); - if (FeatName.empty()) return; +{ + Gui::Command* cmd = this; + auto worker = [cmd](Part::Part2DObject* sketch, std::string FeatName) { + + if (FeatName.empty()) return; + + // specific parameters for Pad + Gui::Command::doCommand(Doc,"App.activeDocument().%s.Length = 10.0",FeatName.c_str()); + App::DocumentObjectGroup* grp = sketch->getGroup(); + if (grp) { + Gui::Command::doCommand(Doc,"App.activeDocument().%s.addObject(App.activeDocument().%s)" + ,grp->getNameInDocument(),FeatName.c_str()); + Gui::Command::doCommand(Doc,"App.activeDocument().%s.removeObject(App.activeDocument().%s)" + ,grp->getNameInDocument(),sketch->getNameInDocument()); + } + Gui::Command::updateActive(); - // specific parameters for Pad - doCommand(Doc,"App.activeDocument().%s.Length = 10.0",FeatName.c_str()); - - finishSketchBased(this, sketch, FeatName); - adjustCameraPosition(); + finishSketchBased(cmd, sketch, FeatName); + //adjustCameraPosition(); + }; + + prepareSketchBased(this, "Pad", worker); } bool CmdPartDesignPad::isActive(void) @@ -1106,15 +1114,17 @@ CmdPartDesignPocket::CmdPartDesignPocket() void CmdPartDesignPocket::activated(int iMsg) { - Part::Part2DObject* sketch; - std::string FeatName; - prepareSketchBased(this, "Pocket", sketch, FeatName); - if (FeatName.empty()) return; - - doCommand(Doc,"App.activeDocument().%s.Length = 5.0",FeatName.c_str()); - - finishSketchBased(this, sketch, FeatName); - adjustCameraPosition(); + Gui::Command* cmd = this; + auto worker = [cmd](Part::Part2DObject* sketch, std::string FeatName) { + + if (FeatName.empty()) return; + + Gui::Command::doCommand(Doc,"App.activeDocument().%s.Length = 5.0",FeatName.c_str()); + finishSketchBased(cmd, sketch, FeatName); + //adjustCameraPosition(); + }; + + prepareSketchBased(this, "Pocket", worker); } bool CmdPartDesignPocket::isActive(void) @@ -1141,20 +1151,23 @@ CmdPartDesignRevolution::CmdPartDesignRevolution() void CmdPartDesignRevolution::activated(int iMsg) { - Part::Part2DObject* sketch; - std::string FeatName; - prepareSketchBased(this, "Revolution", sketch, FeatName); - if (FeatName.empty()) return; + Gui::Command* cmd = this; + auto worker = [cmd](Part::Part2DObject* sketch, std::string FeatName) { + + if (FeatName.empty()) return; - doCommand(Doc,"App.activeDocument().%s.ReferenceAxis = (App.activeDocument().%s,['V_Axis'])", - FeatName.c_str(), sketch->getNameInDocument()); - doCommand(Doc,"App.activeDocument().%s.Angle = 360.0",FeatName.c_str()); - PartDesign::Revolution* pcRevolution = static_cast(getDocument()->getObject(FeatName.c_str())); - if (pcRevolution && pcRevolution->suggestReversed()) - doCommand(Doc,"App.activeDocument().%s.Reversed = 1",FeatName.c_str()); - - finishSketchBased(this, sketch, FeatName); - adjustCameraPosition(); + Gui::Command::doCommand(Doc,"App.activeDocument().%s.ReferenceAxis = (App.activeDocument().%s,['V_Axis'])", + FeatName.c_str(), sketch->getNameInDocument()); + Gui::Command::doCommand(Doc,"App.activeDocument().%s.Angle = 360.0",FeatName.c_str()); + PartDesign::Revolution* pcRevolution = static_cast(cmd->getDocument()->getObject(FeatName.c_str())); + if (pcRevolution && pcRevolution->suggestReversed()) + Gui::Command::doCommand(Doc,"App.activeDocument().%s.Reversed = 1",FeatName.c_str()); + + finishSketchBased(cmd, sketch, FeatName); + //adjustCameraPosition(); + }; + + prepareSketchBased(this, "Pocket", worker); } bool CmdPartDesignRevolution::isActive(void) @@ -1180,21 +1193,24 @@ CmdPartDesignGroove::CmdPartDesignGroove() } void CmdPartDesignGroove::activated(int iMsg) -{ - Part::Part2DObject* sketch; - std::string FeatName; - prepareSketchBased(this, "Groove", sketch, FeatName); - if (FeatName.empty()) return; +{ + Gui::Command* cmd = this; + auto worker = [cmd](Part::Part2DObject* sketch, std::string FeatName) { + + if (FeatName.empty()) return; - doCommand(Doc,"App.activeDocument().%s.ReferenceAxis = (App.activeDocument().%s,['V_Axis'])", + Gui::Command::doCommand(Doc,"App.activeDocument().%s.ReferenceAxis = (App.activeDocument().%s,['V_Axis'])", FeatName.c_str(), sketch->getNameInDocument()); - doCommand(Doc,"App.activeDocument().%s.Angle = 360.0",FeatName.c_str()); - PartDesign::Groove* pcGroove = static_cast(getDocument()->getObject(FeatName.c_str())); - if (pcGroove && pcGroove->suggestReversed()) - doCommand(Doc,"App.activeDocument().%s.Reversed = 1",FeatName.c_str()); + Gui::Command::doCommand(Doc,"App.activeDocument().%s.Angle = 360.0",FeatName.c_str()); + PartDesign::Groove* pcGroove = static_cast(cmd->getDocument()->getObject(FeatName.c_str())); + if (pcGroove && pcGroove->suggestReversed()) + Gui::Command::doCommand(Doc,"App.activeDocument().%s.Reversed = 1",FeatName.c_str()); - finishSketchBased(this, sketch, FeatName); - adjustCameraPosition(); + finishSketchBased(cmd, sketch, FeatName); + //adjustCameraPosition(); + }; + + prepareSketchBased(this, "Pocket", worker); } bool CmdPartDesignGroove::isActive(void) @@ -1510,13 +1526,40 @@ bool CmdPartDesignDraft::isActive(void) // Common functions for all Transformed features //=========================================================================== -void prepareTransformed(Gui::Command* cmd, const std::string& which, - std::vector& features, std::string& FeatName, - std::vector& selList, std::string& selNames) +void prepareTransformed(Gui::Command* cmd, const std::string& which, + boost::function)> func) { + std::string FeatName = cmd->getUniqueObjectName(which.c_str()); + + auto accepter = [=](std::vector features) -> bool{ + + if(features.empty()) + return false; + + return true; + }; + + auto worker = [=](std::vector features) { + std::stringstream str; + str << "App.activeDocument()." << FeatName << ".Originals = ["; + for (std::vector::iterator it = features.begin(); it != features.end(); ++it){ + str << "App.activeDocument()." << (*it)->getNameInDocument() << ","; + } + str << "]"; + + Gui::Command::openCommand((std::string("Make ") + which + " feature").c_str()); + Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject(\"PartDesign::%s\",\"%s\")",which.c_str(), FeatName.c_str()); + // FIXME: There seems to be kind of a race condition here, leading to sporadic errors like + // Exception (Thu Sep 6 11:52:01 2012): 'App.Document' object has no attribute 'Mirrored' + Gui::Command::updateActive(); // Helps to ensure that the object already exists when the next command comes up + Gui::Command::doCommand(Gui::Command::Doc, str.str().c_str()); + + func(FeatName, features); + }; + // Get a valid original from the user // First check selections - features = cmd->getSelection().getObjectsOfType(PartDesign::Additive::getClassTypeId()); + std::vector features = cmd->getSelection().getObjectsOfType(PartDesign::Additive::getClassTypeId()); std::vector subtractive = cmd->getSelection().getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); features.insert(features.end(), subtractive.begin(), subtractive.end()); // Next create a list of all eligible objects @@ -1526,45 +1569,43 @@ void prepareTransformed(Gui::Command* cmd, const std::string& which, features.insert(features.end(), subtractive.begin(), subtractive.end()); // If there is more than one selected or eligible object, show dialog and let user pick one if (features.size() > 1) { - std::vector status; + std::vector status; for (unsigned i = 0; i < features.size(); i++) - status.push_back(PartDesignGui::FeaturePickDialog::validFeature); - PartDesignGui::FeaturePickDialog Dlg(features, status); - if ((Dlg.exec() != QDialog::Accepted) || (features = Dlg.getFeatures()).empty()) { - features.clear(); - return; // Cancelled or nothing selected + status.push_back(PartDesignGui::TaskFeaturePick::validFeature); + + Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); + PartDesignGui::TaskDlgFeaturePick *pickDlg = qobject_cast(dlg); + if (dlg && !pickDlg) { + QMessageBox msgBox; + msgBox.setText(QObject::tr("A dialog is already open in the task panel")); + msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?")); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + msgBox.setDefaultButton(QMessageBox::Yes); + int ret = msgBox.exec(); + if (ret == QMessageBox::Yes) + Gui::Control().closeDialog(); + else + return; } + + if(dlg) + Gui::Control().closeDialog(); + + Gui::Selection().clearSelection(); + Gui::Control().showDialog(new PartDesignGui::TaskDlgFeaturePick(features, status, accepter, worker)); } else { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid features in this document"), QObject::tr("Please create a subtractive or additive feature first.")); return; } } - - FeatName = cmd->getUniqueObjectName(which.c_str()); - - std::stringstream str; - str << "App.activeDocument()." << FeatName << ".Originals = ["; - for (std::vector::iterator it = features.begin(); it != features.end(); ++it){ - str << "App.activeDocument()." << (*it)->getNameInDocument() << ","; - selList.push_back((*it)->getNameInDocument()); + else { + worker(features); } - str << "]"; - selNames = str.str(); - - cmd->openCommand((std::string("Make ") + which + " feature").c_str()); - cmd->doCommand(cmd->Doc,"App.activeDocument().addObject(\"PartDesign::%s\",\"%s\")",which.c_str(), FeatName.c_str()); - // FIXME: There seems to be kind of a race condition here, leading to sporadic errors like - // Exception (Thu Sep 6 11:52:01 2012): 'App.Document' object has no attribute 'Mirrored' - cmd->updateActive(); // Helps to ensure that the object already exists when the next command comes up - cmd->doCommand(cmd->Doc,selNames.c_str()); } -void finishTransformed(Gui::Command* cmd, std::string& FeatName, std::vector& selList) +void finishTransformed(Gui::Command* cmd, std::string& FeatName) { - //for (std::vector::iterator it = selList.begin(); it != selList.end(); ++it) - // cmd->doCommand(cmd->Gui,"Gui.activeDocument().%s.Visibility=False",it->c_str()); - finishFeature(cmd, FeatName); } @@ -1587,19 +1628,21 @@ CmdPartDesignMirrored::CmdPartDesignMirrored() void CmdPartDesignMirrored::activated(int iMsg) { - std::string FeatName, selNames; - std::vector features; - std::vector selList; - prepareTransformed(this, "Mirrored", features, FeatName, selList, selNames); - if (features.empty()) + Gui::Command* cmd = this; + auto worker = [cmd](std::string FeatName, std::vector features) { + + if (features.empty()) return; + + Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(); + if (sketch) + Gui::Command::doCommand(Doc,"App.activeDocument().%s.MirrorPlane = (App.activeDocument().%s, [\"V_Axis\"])", + FeatName.c_str(), sketch->getNameInDocument()); - Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(); - if (sketch) - doCommand(Doc,"App.activeDocument().%s.MirrorPlane = (App.activeDocument().%s, [\"V_Axis\"])", - FeatName.c_str(), sketch->getNameInDocument()); - - finishTransformed(this, FeatName, selList); + finishTransformed(cmd, FeatName); + }; + + prepareTransformed(this, "Mirrored", worker); } bool CmdPartDesignMirrored::isActive(void) @@ -1626,21 +1669,22 @@ CmdPartDesignLinearPattern::CmdPartDesignLinearPattern() void CmdPartDesignLinearPattern::activated(int iMsg) { - std::string FeatName, selNames; - std::vector features; - std::vector selList; - prepareTransformed(this, "LinearPattern", features, FeatName, selList, selNames); - if (features.empty()) + Gui::Command* cmd = this; + auto worker = [cmd](std::string FeatName, std::vector features) { + + if (features.empty()) return; - Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(); - if (sketch) - doCommand(Doc,"App.activeDocument().%s.Direction = (App.activeDocument().%s, [\"H_Axis\"])", - FeatName.c_str(), sketch->getNameInDocument()); - doCommand(Doc,"App.activeDocument().%s.Length = 100", FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Occurrences = 2", FeatName.c_str()); + Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(); + if (sketch) + doCommand(Doc,"App.activeDocument().%s.Direction = (App.activeDocument().%s, [\"H_Axis\"])", + FeatName.c_str(), sketch->getNameInDocument()); + doCommand(Doc,"App.activeDocument().%s.Length = 100", FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Occurrences = 2", FeatName.c_str()); - finishTransformed(this, FeatName, selList); + finishTransformed(cmd, FeatName); + }; + prepareTransformed(this, "LinearPattern", worker); } bool CmdPartDesignLinearPattern::isActive(void) @@ -1666,22 +1710,24 @@ CmdPartDesignPolarPattern::CmdPartDesignPolarPattern() } void CmdPartDesignPolarPattern::activated(int iMsg) -{ - std::string FeatName, selNames; - std::vector features; - std::vector selList; - prepareTransformed(this, "PolarPattern", features, FeatName, selList, selNames); - if (features.empty()) - return; +{ + Gui::Command* cmd = this; + auto worker = [cmd](std::string FeatName, std::vector features) { + + if (features.empty()) + return; + + Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(); + if (sketch) + doCommand(Doc,"App.activeDocument().%s.Axis = (App.activeDocument().%s, [\"N_Axis\"])", + FeatName.c_str(), sketch->getNameInDocument()); + doCommand(Doc,"App.activeDocument().%s.Angle = 360", FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Occurrences = 2", FeatName.c_str()); - Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(); - if (sketch) - doCommand(Doc,"App.activeDocument().%s.Axis = (App.activeDocument().%s, [\"N_Axis\"])", - FeatName.c_str(), sketch->getNameInDocument()); - doCommand(Doc,"App.activeDocument().%s.Angle = 360", FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Occurrences = 2", FeatName.c_str()); - - finishTransformed(this, FeatName, selList); + finishTransformed(cmd, FeatName); + }; + + prepareTransformed(this, "PolarPattern", worker); } bool CmdPartDesignPolarPattern::isActive(void) @@ -1707,18 +1753,20 @@ CmdPartDesignScaled::CmdPartDesignScaled() } void CmdPartDesignScaled::activated(int iMsg) -{ - std::string FeatName, selNames; - std::vector features; - std::vector selList; - prepareTransformed(this, "Scaled", features, FeatName, selList, selNames); - if (features.empty()) +{ + Gui::Command* cmd = this; + auto worker = [cmd](std::string FeatName, std::vector features) { + + if (features.empty()) return; + + doCommand(Doc,"App.activeDocument().%s.Factor = 2", FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Occurrences = 2", FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Factor = 2", FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Occurrences = 2", FeatName.c_str()); - - finishTransformed(this, FeatName, selList); + finishTransformed(cmd, FeatName); + }; + + prepareTransformed(this, "Scaled", worker); } bool CmdPartDesignScaled::isActive(void) @@ -1796,27 +1844,24 @@ void CmdPartDesignMultiTransform::activated(int iMsg) Gui::Selection().clearSelection(); } // otherwise the insert point remains at the new MultiTransform, which is fine } else { - std::string FeatName, selNames; - std::vector selList; - prepareTransformed(this, "MultiTransform", features, FeatName, selList, selNames); - if (features.empty()) - return; + + Gui::Command* cmd = this; + auto worker = [cmd, pcActiveBody](std::string FeatName, std::vector features) { + + if (features.empty()) + return; - PartDesign::Body *pcActiveBody = PartDesignGui::getBody(); - if (!pcActiveBody) - return; - updateActive(); - doCommand(Doc,selNames.c_str()); - - // Make sure the user isn't presented with an empty screen because no transformations are defined yet... - App::DocumentObject* prevSolid = pcActiveBody->getPrevSolidFeature(NULL, true); - if (prevSolid != NULL) { - Part::Feature* feat = static_cast(prevSolid); - doCommand(Doc,"App.activeDocument().%s.Shape = App.activeDocument().%s.Shape", - FeatName.c_str(), feat->getNameInDocument()); - } - - finishFeature(this, FeatName); + // Make sure the user isn't presented with an empty screen because no transformations are defined yet... + App::DocumentObject* prevSolid = pcActiveBody->getPrevSolidFeature(NULL, true); + if (prevSolid != NULL) { + Part::Feature* feat = static_cast(prevSolid); + doCommand(Doc,"App.activeDocument().%s.Shape = App.activeDocument().%s.Shape", + FeatName.c_str(), feat->getNameInDocument()); + } + finishFeature(cmd, FeatName); + }; + + prepareTransformed(this, "MultiTransform", worker); } } diff --git a/src/Mod/PartDesign/Gui/TaskFeaturePick.cpp b/src/Mod/PartDesign/Gui/TaskFeaturePick.cpp new file mode 100644 index 000000000..fab9a2830 --- /dev/null +++ b/src/Mod/PartDesign/Gui/TaskFeaturePick.cpp @@ -0,0 +1,233 @@ +/****************************************************************************** + * Copyright (c)2012 Jan Rheinlaender * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ******************************************************************************/ + +#include "PreCompiled.h" + +#ifndef _PreComp_ +# include +# include +# include +#endif + +#include +#include +#include +#include +#include + +#include "ui_TaskFeaturePick.h" +#include "TaskFeaturePick.h" + +using namespace PartDesignGui; + +const QString TaskFeaturePick::getFeatureStatusString(const featureStatus st) +{ + switch (st) { + case validFeature: return tr("Valid"); + case invalidShape: return tr("Invalid shape"); + case noWire: return tr("No wire in sketch"); + case isUsed: return tr("Sketch already used by other feature"); + case otherBody: return tr("Sketch belongs to another Body feature"); + case basePlane: return tr("Base plane"); + case afterTip: return tr("Feature is located after the Tip feature"); + } + + return tr(""); +} + +TaskFeaturePick::TaskFeaturePick(std::vector& objects, + const std::vector& status, + QWidget* parent) + : TaskBox(Gui::BitmapFactory().pixmap("edit-select-box"), + QString::fromAscii("Select feature"), true, parent), ui(new Ui_TaskFeaturePick) +{ + + proxy = new QWidget(this); + ui->setupUi(proxy); + + connect(ui->checkReverse, SIGNAL(toggled(bool)), this, SLOT(onCheckReverse(bool))); + connect(ui->checkOtherBody, SIGNAL(toggled(bool)), this, SLOT(onCheckOtherBody(bool))); + connect(ui->checkOtherFeature, SIGNAL(toggled(bool)), this, SLOT(onCheckOtherFeature(bool))); + connect(ui->radioIndependent, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool))); + connect(ui->radioDependent, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool))); + connect(ui->radioXRef, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool))); + + ui->checkReverse->setChecked(false); + ui->checkOtherBody->setChecked(true); + ui->checkOtherBody->setEnabled(false); // TODO: implement + ui->checkOtherFeature->setChecked(false); + ui->checkOtherFeature->setEnabled(false); // TODO: implement + ui->radioIndependent->setChecked(true); + ui->radioIndependent->setEnabled(false); + // These are not implemented yet + ui->radioDependent->setEnabled(false); + ui->radioXRef->setEnabled(false); + + std::vector::const_iterator st = status.begin(); + for (std::vector::const_iterator o = objects.begin(); o != objects.end(); o++) { + QListWidgetItem* item = new QListWidgetItem(QString::fromAscii((*o)->getNameInDocument()) + + QString::fromAscii(" (") + getFeatureStatusString(*st) + QString::fromAscii(")")); + ui->listWidget->addItem(item); + st++; + } + + groupLayout()->addWidget(proxy); + statuses = status; + updateList(); +} + +TaskFeaturePick::~TaskFeaturePick() +{ + +} + +void TaskFeaturePick::updateList() +{ + int index = 0; + + for (std::vector::const_iterator st = statuses.begin(); st != statuses.end(); st++) { + QListWidgetItem* item = ui->listWidget->item(index); + + switch (*st) { + case validFeature: item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); break; + case invalidShape: item->setFlags(Qt::NoItemFlags); break; + case noWire: item->setFlags(Qt::NoItemFlags); break; + case isUsed: item->setFlags(ui->checkOtherFeature->isChecked() ? Qt::ItemIsSelectable | Qt::ItemIsEnabled : Qt::NoItemFlags); break; + case otherBody: item->setFlags(ui->checkOtherBody->isChecked() ? Qt::ItemIsSelectable | Qt::ItemIsEnabled : Qt::NoItemFlags); break; + case basePlane: item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); break; + case afterTip: item->setFlags(Qt::NoItemFlags); break; + } + + index++; + } +} + +void TaskFeaturePick::onCheckReverse(bool checked) +{ +} + +void TaskFeaturePick::onCheckOtherFeature(bool checked) +{ + ui->radioIndependent->setEnabled(checked); + // TODO: Not implemented yet + //ui->radioDependent->setEnabled(checked); + //ui->radioXRef->setEnabled(checked); + + updateList(); +} + +void TaskFeaturePick::onCheckOtherBody(bool checked) +{ + ui->radioIndependent->setEnabled(checked); + // TODO: Not implemented yet + //ui->radioDependent->setEnabled(checked); + //ui->radioXRef->setEnabled(checked); + + updateList(); +} + +void TaskFeaturePick::onUpdate(bool) +{ + updateList(); +} + +bool TaskFeaturePick::getReverse() +{ + return ui->checkReverse->isChecked(); +} + +std::vector TaskFeaturePick::getFeatures() { + + features.clear(); + QListIterator i(ui->listWidget->selectedItems()); + while (i.hasNext()) { + QString t = i.next()->text(); + t = t.left(t.indexOf(QString::fromAscii("(")) - 1); + features.push_back(t); + } + + std::vector result; + + for (std::vector::const_iterator s = features.begin(); s != features.end(); s++) + result.push_back(App::GetApplication().getActiveDocument()->getObject(s->toAscii().data())); + + return result; +} + +void TaskFeaturePick::onSelectionChanged(const Gui::SelectionChanges& msg) +{ + +} + +//************************************************************************** +//************************************************************************** +// TaskDialog +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +TaskDlgFeaturePick::TaskDlgFeaturePick(std::vector &objects, + const std::vector &status, + boost::function)> afunc, + boost::function)> wfunc) + : TaskDialog() +{ + pick = new TaskFeaturePick(objects, status); + Content.push_back(pick); + + acceptFunction = afunc; + workFunction = wfunc; +} + +TaskDlgFeaturePick::~TaskDlgFeaturePick() +{ + //do the work now as before in accept() the dialog is still open, hence the work + //function could not open annother dialog + if(accepted) + workFunction(pick->getFeatures()); +} + +//==== calls from the TaskView =============================================================== + + +void TaskDlgFeaturePick::open() +{ + +} + +void TaskDlgFeaturePick::clicked(int) +{ + +} + +bool TaskDlgFeaturePick::accept() +{ + accepted = acceptFunction(pick->getFeatures()); + + return accepted; +} + +bool TaskDlgFeaturePick::reject() +{ + accepted = false; + return true; +} + +#include "moc_TaskFeaturePick.cpp" diff --git a/src/Mod/PartDesign/Gui/TaskFeaturePick.h b/src/Mod/PartDesign/Gui/TaskFeaturePick.h new file mode 100644 index 000000000..ab83ec761 --- /dev/null +++ b/src/Mod/PartDesign/Gui/TaskFeaturePick.h @@ -0,0 +1,119 @@ +/****************************************************************************** + * Copyright (c)2012 Jan Rheinlaender * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ******************************************************************************/ + +#ifndef PARTDESIGNGUI_FeaturePickDialog_H +#define PARTDESIGNGUI_FeaturePickDialog_H + +#include +#include +#include +#include + +#include + +namespace PartDesignGui { + +class Ui_TaskFeaturePick; +class TaskFeaturePick : public Gui::TaskView::TaskBox, public Gui::SelectionObserver +{ + Q_OBJECT + +public: + enum featureStatus { + validFeature = 0, + invalidShape, + noWire, + isUsed, + otherBody, + basePlane, + afterTip + }; + + TaskFeaturePick(std::vector &objects, + const std::vector &status, + QWidget *parent = 0); + + ~TaskFeaturePick(); + + std::vector getFeatures(); + bool getReverse(); + +protected Q_SLOTS: + void onCheckReverse(bool); + void onCheckOtherFeature(bool); + void onCheckOtherBody(bool); + void onUpdate(bool); + + void onSelectionChanged(const Gui::SelectionChanges& msg); + +private: + Ui_TaskFeaturePick* ui; + QWidget* proxy; + + std::vector features; + std::vector statuses; + + void updateList(); + + const QString getFeatureStatusString(const featureStatus st); +}; + + +/// simulation dialog for the TaskView +class TaskDlgFeaturePick : public Gui::TaskView::TaskDialog +{ + Q_OBJECT + +public: + TaskDlgFeaturePick(std::vector &objects, + const std::vector &status, + boost::function)> acceptfunc, + boost::function)> workfunc); + ~TaskDlgFeaturePick(); + +public: + /// is called the TaskView when the dialog is opened + virtual void open(); + /// is called by the framework if an button is clicked which has no accept or reject role + virtual void clicked(int); + /// is called by the framework if the dialog is accepted (Ok) + virtual bool accept(); + /// is called by the framework if the dialog is rejected (Cancel) + virtual bool reject(); + /// is called by the framework if the user presses the help button + virtual bool isAllowedAlterDocument(void) const + { return false; } + + /// returns for Close and Help button + virtual QDialogButtonBox::StandardButtons getStandardButtons(void) const + { return QDialogButtonBox::Ok|QDialogButtonBox::Cancel; } + +protected: + TaskFeaturePick *pick; + bool accepted = false; + boost::function)> acceptFunction; + boost::function)> workFunction; +}; + +} + +#endif // PARTDESIGNGUI_FeaturePickDialog_H diff --git a/src/Mod/PartDesign/Gui/TaskFeaturePick.ui b/src/Mod/PartDesign/Gui/TaskFeaturePick.ui new file mode 100644 index 000000000..7e53ae312 --- /dev/null +++ b/src/Mod/PartDesign/Gui/TaskFeaturePick.ui @@ -0,0 +1,73 @@ + + + PartDesignGui::TaskFeaturePick + + + + 0 + 0 + 328 + 445 + + + + Form + + + + + + + + + Reverse direction + + + + + + + Qt::Horizontal + + + + + + + Allow feature from other Body + + + + + + + Allow sketch used by other feature + + + + + + + Make independent copy (recommended) + + + + + + + Make dependent copy + + + + + + + Create cross-reference + + + + + + + +