Duplicate Selection: Add duplicated features to active Body

This commit is contained in:
jrheinlaender 2013-05-16 14:46:33 +04:30 committed by Stefan Tröger
parent 880587a627
commit ffc09ec50c
4 changed files with 111 additions and 0 deletions

View File

@ -196,6 +196,13 @@ const bool Body::isAllowed(const App::DocumentObject* f)
void Body::addFeature(App::DocumentObject *feature)
{
/*
// Remove this test if Workbench::slotNewObject() has been tested sufficiently in respect to Undo() and
// the addFeature() calls have been removed in Command.cpp
if (hasFeature(feature))
return;
*/
// Set the BaseFeature property
if (feature->getTypeId().isDerivedFrom(PartDesign::Feature::getClassTypeId())) {
App::DocumentObject* prevSolidFeature = getPrevSolidFeature(NULL, true);

View File

@ -210,6 +210,78 @@ bool CmdPartDesignMoveTip::isActive(void)
return hasActiveDocument();
}
//===========================================================================
// PartDesign_DuplicateSelection
//===========================================================================
DEF_STD_CMD_A(CmdPartDesignDuplicateSelection);
CmdPartDesignDuplicateSelection::CmdPartDesignDuplicateSelection()
:Command("PartDesign_DuplicateSelection")
{
sAppModule = "PartDesign";
sGroup = QT_TR_NOOP("PartDesign");
sMenuText = QT_TR_NOOP("Duplicate selected object");
sToolTipText = QT_TR_NOOP("Duplicates the selected object and adds it to the active body");
sWhatsThis = sToolTipText;
sStatusTip = sToolTipText;
sPixmap = "";
}
void CmdPartDesignDuplicateSelection::activated(int iMsg)
{
PartDesign::Body *pcActiveBody = PartDesignGui::getBody();
if(!pcActiveBody) return;
std::vector<App::DocumentObject*> features = getSelection().getObjectsOfType(Part::Feature::getClassTypeId());
if (features.empty()) return;
App::DocumentObject* selFeature = features.front();
if (!pcActiveBody->hasFeature(selFeature)) {
// NOTE: We assume all selected features will be in the same document
// Switch to other body
pcActiveBody = static_cast<PartDesign::Body*>(Part::BodyBase::findBodyOf(selFeature));
if (pcActiveBody != NULL)
Gui::Command::doCommand(Gui::Command::Gui,"PartDesignGui.setActivePart(App.activeDocument().%s)",
pcActiveBody->getNameInDocument());
else
return;
}
std::vector<App::DocumentObject*> beforeFeatures = PartDesignGui::ActiveAppDoc->getObjects();
openCommand("Duplicate a PartDesign object");
doCommand(Doc,"FreeCADGui.runCommand('Std_DuplicateSelection')");
// Find the features that were added
std::vector<App::DocumentObject*> afterFeatures = PartDesignGui::ActiveAppDoc->getObjects();
std::vector<App::DocumentObject*> newFeatures;
std::set_difference(afterFeatures.begin(), afterFeatures.end(), beforeFeatures.begin(), beforeFeatures.end(),
std::back_inserter(newFeatures));
for (std::vector<App::DocumentObject*>::const_iterator f = newFeatures.begin(); f != newFeatures.end(); f++) {
if (PartDesign::Body::isAllowed(*f)) {
doCommand(Doc,"App.activeDocument().%s.addFeature(App.activeDocument().%s)",
pcActiveBody->getNameInDocument(), (*f)->getNameInDocument());
doCommand(Gui,"Gui.activeDocument().hide(\"%s\")", (*f)->getNameInDocument());
}
}
// Adjust visibility of features
doCommand(Gui,"Gui.activeDocument().show(\"%s\")", newFeatures.back()->getNameInDocument());
App::DocumentObject* prevSolidFeature = pcActiveBody->getPrevSolidFeature();
if ((prevSolidFeature != NULL) && !PartDesign::Body::isSolidFeature(selFeature))
doCommand(Gui,"Gui.activeDocument().show(\"%s\")", prevSolidFeature->getNameInDocument());
}
bool CmdPartDesignDuplicateSelection::isActive(void)
{
if (getActiveGuiDocument())
return true;
else
return false;
}
//===========================================================================
// PartDesign_Datum
//===========================================================================
@ -1524,17 +1596,24 @@ void CreatePartDesignCommands(void)
rcCmdMgr.addCommand(new CmdPartDesignBody());
rcCmdMgr.addCommand(new CmdPartDesignMoveTip());
rcCmdMgr.addCommand(new CmdPartDesignDuplicateSelection());
rcCmdMgr.addCommand(new CmdPartDesignPlane());
rcCmdMgr.addCommand(new CmdPartDesignLine());
rcCmdMgr.addCommand(new CmdPartDesignPoint());
rcCmdMgr.addCommand(new CmdPartDesignNewSketch());
rcCmdMgr.addCommand(new CmdPartDesignPad());
rcCmdMgr.addCommand(new CmdPartDesignPocket());
rcCmdMgr.addCommand(new CmdPartDesignRevolution());
rcCmdMgr.addCommand(new CmdPartDesignGroove());
rcCmdMgr.addCommand(new CmdPartDesignFillet());
rcCmdMgr.addCommand(new CmdPartDesignDraft());
rcCmdMgr.addCommand(new CmdPartDesignChamfer());
rcCmdMgr.addCommand(new CmdPartDesignMirrored());
rcCmdMgr.addCommand(new CmdPartDesignLinearPattern());
rcCmdMgr.addCommand(new CmdPartDesignPolarPattern());

View File

@ -256,6 +256,21 @@ void Workbench::slotDeleteDocument(const App::Document&)
ActiveAppDoc = 0;
ActiveVp = 0;
}
/*
This does not work for Std_DuplicateSelection:
Tree.cpp gives: "Cannot reparent unknown object", probably because the signalNewObject is emitted
before the duplication of the object has been completely finished
void Workbench::slotNewObject(const App::DocumentObject& obj)
{
if ((obj.getDocument() == ActiveAppDoc) && (ActivePartObject != NULL)) {
// Add the new object to the active Body
// Note: Will this break Undo? But how else can we catch Edit->Duplicate selection?
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.addFeature(App.activeDocument().%s)",
ActivePartObject->getNameInDocument(), obj.getNameInDocument());
}
}
*/
void Workbench::setupContextMenu(const char* recipient, Gui::MenuItem* item) const
{
@ -437,6 +452,8 @@ void Workbench::activated()
App::GetApplication().signalNewDocument.connect(boost::bind(&Workbench::slotNewDocument, this, _1));
App::GetApplication().signalFinishRestoreDocument.connect(boost::bind(&Workbench::slotFinishRestoreDocument, this, _1));
App::GetApplication().signalDeleteDocument.connect(boost::bind(&Workbench::slotDeleteDocument, this, _1));
// Watch out for objects being added to the active document, so that we can add them to the body
//App::GetApplication().signalNewObject.connect(boost::bind(&Workbench::slotNewObject, this, _1));
}
void Workbench::deactivated()
@ -446,6 +463,7 @@ void Workbench::deactivated()
App::GetApplication().signalNewDocument.disconnect(boost::bind(&Workbench::slotNewDocument, this, _1));
App::GetApplication().signalFinishRestoreDocument.disconnect(boost::bind(&Workbench::slotFinishRestoreDocument, this, _1));
App::GetApplication().signalDeleteDocument.disconnect(boost::bind(&Workbench::slotDeleteDocument, this, _1));
//App::GetApplication().signalNewObject.disconnect(boost::bind(&Workbench::slotNewObject, this, _1));
removeTaskWatcher();
// reset the active Body
@ -513,6 +531,11 @@ Gui::MenuItem* Workbench::setupMenuBar() const
*part << "Separator" << "PartDesign_WizardShaft";
}
// Replace the "Duplicate selection" menu item with a replacement that is compatible with Body
item = root->findItem("&Edit");
Gui::MenuItem* dup = item->findItem("Std_DuplicateSelection");
dup->setCommand("PartDesign_DuplicateSelection");
return root;
}

View File

@ -86,6 +86,8 @@ private:
void slotNewDocument(const App::Document&);
/// Update the ActivePartObject etc. when a document is closed
void slotDeleteDocument(const App::Document&);
// Add new objects to the body, if appropriate
//void slotNewObject(const App::DocumentObject& obj);
};
} // namespace PartDesignGui