Fix potential race when cancelling DPG creation

This commit is contained in:
WandererFan 2017-01-28 12:40:19 -05:00
parent 722b2d1c04
commit 49c2be14ba
3 changed files with 11 additions and 26 deletions

View File

@ -187,7 +187,8 @@ void DrawProjGroup::onChanged(const App::Property* prop)
App::DocumentObject* sourceObj = Source.getValue();
if (sourceObj != nullptr) {
if (!hasAnchor()) {
addProjection("Front");
// if we have a Source, but no Anchor, make an anchor
Anchor.setValue(addProjection("Front"));
}
} else {
//Source has been changed to null! Why? What to do?
@ -216,9 +217,9 @@ App::DocumentObjectExecReturn *DrawProjGroup::execute(void)
return DrawViewCollection::execute();
}
docObj = Anchor.getValue(); //must have an anchor, so create one as soon as we have a Page and Source
docObj = Anchor.getValue();
if (docObj == nullptr) {
docObj = addProjection("Front");
return DrawViewCollection::execute();
}
double newScale = Scale.getValue();
@ -443,8 +444,6 @@ bool DrawProjGroup::hasProjection(const char *viewProjType) const
App::DocumentObject * DrawProjGroup::addProjection(const char *viewProjType)
{
//if this is the first Projection added, it should automatically be the Anchor/front view
// or if viewProjType == "Front" Anchor.setValue(view)
DrawProjGroupItem *view( nullptr );
if ( checkViewProjType(viewProjType) && !hasProjection(viewProjType) ) {
@ -462,21 +461,8 @@ App::DocumentObject * DrawProjGroup::addProjection(const char *viewProjType)
view->Type.setValue( viewProjType );
view->Label.setValue( viewProjType );
view->Source.setValue( Source.getValue() );
if( strcmp(viewProjType,"Front") == 0 ) {
Anchor.setValue(docObj);
view->Direction.setValue(m_frameToStdDir.at("Front")); //just (Base::Vector3d(0.0,-1.0,0.0))
view->RotationVector.setValue(m_frameToStdRot.at("Front"));
} else {
//TODO: really need to check with Cube to get current dir & rot this uses initial values from table
//if (DPGI(front) and DPGI(right) exist) config = front.face + right.face
//
//else
// use start up values (m_frameToStdDir/m_frameToStdRot)
view->Direction.setValue(m_frameToStdDir.at(viewProjType));
view->RotationVector.setValue(m_frameToStdRot.at(viewProjType));
}
view->Direction.setValue(m_frameToStdDir.at(viewProjType));
view->RotationVector.setValue(m_frameToStdRot.at(viewProjType));
addView(view); //from DrawViewCollection - add to ProjGroup Views
moveToCentre();
view->recomputeFeature();
@ -485,6 +471,7 @@ App::DocumentObject * DrawProjGroup::addProjection(const char *viewProjType)
return view;
}
//NOTE: projections can be deleted without using removeProjection - ie regular DocObject deletion process.
int DrawProjGroup::removeProjection(const char *viewProjType)
{
// TODO: shouldn't be able to delete "Front" unless deleting whole group
@ -498,11 +485,6 @@ int DrawProjGroup::removeProjection(const char *viewProjType)
auto projPtr( dynamic_cast<TechDraw::DrawProjGroupItem *>(it) );
if( projPtr ) {
if ( strcmp(viewProjType, projPtr->Type.getValueAsString()) == 0 ) {
if( strcmp(viewProjType,"Front") == 0 ) {
Base::Console().Warning("DPG - %s: Front projection deleted. Projection group may be corrupt\n",
getNameInDocument());
Anchor.setValue(nullptr);
}
removeView(projPtr); // Remove from collection
getDocument()->remObject( it->getNameInDocument() ); // Remove from the document
moveToCentre();
@ -515,6 +497,7 @@ int DrawProjGroup::removeProjection(const char *viewProjType)
return -1;
}
//removes all DPGI - used when deleting DPG
int DrawProjGroup::purgeProjections()
{
while (!Views.getValues().empty()) {

View File

@ -168,7 +168,7 @@ void DrawProjGroupItem::unsetupObject()
!getGroup()->isDeleting() ) {
Base::Console().Warning("Warning - DPG (%s/%s) may be corrupt - Anchor deleted\n",
getGroup()->getNameInDocument(),getGroup()->Label.getValue());
getGroup()->Anchor.setValue(nullptr);
getGroup()->Anchor.setValue(nullptr); //this catches situation where DPGI is deleted w/o DPG::removeProjection
}
}
}

View File

@ -480,6 +480,8 @@ bool TaskProjGroup::reject()
PageName.c_str(),multiViewName.c_str());
Gui::Command::doCommand(Gui::Command::Gui,"App.activeDocument().removeObject('%s')",multiViewName.c_str());
Gui::Command::doCommand(Gui::Command::Gui,"Gui.ActiveDocument.resetEdit()");
//make sure any dangling objects are cleaned up
Gui::Command::doCommand(Gui::Command::Gui,"App.activeDocument().recompute()");
} else {
if (Gui::Command::hasPendingCommand()) {
std::vector<std::string> undos = Gui::Application::Instance->activeDocument()->getUndoVector();