[TD]fix crash when Section deleted during creation

- if the Section is deleted while the section dialog
  is still in progress, further processing in the
  dialog would cause a crash.
- should have "update intent" locks to prevent this
This commit is contained in:
wandererfan
2020-03-15 11:08:28 -04:00
committed by WandererFan
parent ee626abef4
commit eb3e4ce56c
2 changed files with 155 additions and 120 deletions

View File

@@ -78,7 +78,8 @@ TaskSectionView::TaskSectionView(TechDraw::DrawViewPart* base) :
m_section(nullptr),
m_dirName(""),
m_createMode(true),
m_saved(false)
m_saved(false),
m_abort(false)
{
// Base::Console().Message("TSV::TSV() - create mode\n");
if (m_base == nullptr) {
@@ -87,8 +88,12 @@ TaskSectionView::TaskSectionView(TechDraw::DrawViewPart* base) :
Base::Console().Error((msg + "\n").c_str());
return;
}
m_sectionName = std::string();
m_doc = m_base->getDocument();
m_saveBaseName = m_base->getNameInDocument();
m_savePageName = m_base->findParentPage()->getNameInDocument();
ui->setupUi(this);
@@ -113,9 +118,9 @@ TaskSectionView::TaskSectionView(TechDraw::DrawViewSection* section) :
m_base(nullptr),
m_section(section),
m_createMode(false),
m_saved(false)
m_saved(false),
m_abort(false)
{
// Base::Console().Message("TS::TS() - edit mode\n");
if (m_section == nullptr) {
//should be caught in CMD caller
@@ -124,6 +129,7 @@ TaskSectionView::TaskSectionView(TechDraw::DrawViewSection* section) :
return;
}
m_sectionName = m_section->getNameInDocument();
App::DocumentObject* newObj = m_section->BaseView.getValue();
m_base = dynamic_cast<TechDraw::DrawViewPart*>(newObj);
if ( (newObj == nullptr) ||
@@ -229,7 +235,6 @@ void TaskSectionView::blockButtons(bool b)
Q_UNUSED(b);
}
// cardinal: 0 - left, 1 - right, 2 - up, 3 - down
void TaskSectionView::onUpClicked(bool b)
{
// Base::Console().Message("TSV::onUpClicked()\n");
@@ -274,29 +279,6 @@ void TaskSectionView::onApplyClicked(bool b)
apply();
}
bool TaskSectionView::apply(void)
{
// Base::Console().Message("TSV::apply() - m_dirName: %s\n", m_dirName.c_str());
if (m_dirName.empty()) {
std::string msg = Base::Tools::toStdString(tr("TaskSectionView::apply - No section direction picked yet"));
Base::Console().Error((msg + "\n").c_str());
return false;
}
if (m_section == nullptr) {
return false;
}
App::Document* doc = m_section->getDocument();
App::DocumentObject* baseObj = doc->getObject(m_saveBaseName.c_str());
TechDraw::DrawViewPart* dvp = dynamic_cast<TechDraw::DrawViewPart*>(baseObj);
if (dvp == nullptr) {
return false;
}
checkAll(false);
applyQuick(m_dirName);
return true;
}
void TaskSectionView::checkAll(bool b)
{
ui->pbUp->setChecked(b);
@@ -306,20 +288,42 @@ void TaskSectionView::checkAll(bool b)
}
//******************************************************************************
bool TaskSectionView::apply(void)
{
// Base::Console().Message("TSV::apply() - m_dirName: %s\n", m_dirName.c_str());
if (m_dirName.empty()) {
std::string msg =
Base::Tools::toStdString(tr("TSV::apply - Nothing to apply. No section direction picked yet"));
Base::Console().Error((msg + "\n").c_str());
return false;
}
if (m_section == nullptr) { //didn't create the feature yet
return false;
}
checkAll(false);
applyQuick(m_dirName);
return true;
}
void TaskSectionView::applyQuick(std::string dir)
{
// Base::Console().Message("TSV::applyQuick(%s)\n", dir.c_str());
Gui::Command::openCommand("Apply Quick");
m_dirName = dir;
if (m_section == nullptr) {
m_section = createSectionView();
createSectionView();
}
if (m_section != nullptr) {
if (isSectionValid()) {
updateSectionView();
m_section->recomputeFeature();
m_section->recomputeFeature();
} else {
failNoObject(m_sectionName);
}
if (m_base != nullptr) {
if (isBaseValid()) {
m_base->requestPaint();
return;
}
}
@@ -330,18 +334,19 @@ void TaskSectionView::applyAligned(void)
m_dirName = "Aligned";
//fiddle with directions here
// m_section->recomputeFeature(); //????
m_section->requestPaint();
m_base->requestPaint();
}
TechDraw::DrawViewSection* TaskSectionView::createSectionView(void)
//*********************************************************************
//pointer to created view is not returned, but stored in m_section
void TaskSectionView::createSectionView(void)
{
// Base::Console().Message("TSV::createSectionView()\n");
if (m_base == nullptr) {
Base::Console().Error("TSV::createSectionView - base object not found!\n");
return nullptr;
if (!isBaseValid()) {
failNoObject(m_baseName);
return;
}
std::string sectionName;
@@ -349,134 +354,160 @@ TechDraw::DrawViewSection* TaskSectionView::createSectionView(void)
double baseScale = m_base->getScale();
Gui::Command::openCommand("Create SectionView");
TechDraw::DrawViewSection* newSection = nullptr;
if (m_section == nullptr) {
sectionName = m_base->getDocument()->getUniqueObjectName("SectionView");
m_sectionName = m_base->getDocument()->getUniqueObjectName("SectionView");
std::string sectionType = "TechDraw::DrawViewSection";
TechDraw::DrawPage* page = m_base->findParentPage();
std::string pageName = page->getNameInDocument();
Command::doCommand(Command::Doc,"App.activeDocument().addObject('%s','%s')",
sectionType.c_str(),sectionName.c_str());
sectionType.c_str(),m_sectionName.c_str());
Command::doCommand(Command::Doc,"App.activeDocument().%s.addView(App.activeDocument().%s)",
pageName.c_str(), sectionName.c_str());
m_savePageName.c_str(), m_sectionName.c_str());
Command::doCommand(Command::Doc,"App.activeDocument().%s.BaseView = App.activeDocument().%s",
sectionName.c_str(),baseName.c_str());
m_sectionName.c_str(),baseName.c_str());
Command::doCommand(Command::Doc,"App.activeDocument().%s.Source = App.activeDocument().%s.Source",
sectionName.c_str(),baseName.c_str());
m_sectionName.c_str(),baseName.c_str());
Command::doCommand(Command::Doc,
"App.activeDocument().%s.SectionOrigin = FreeCAD.Vector(%.3f,%.3f,%.3f)",
m_sectionName.c_str(),
ui->sbOrgX->value().getValue(),
ui->sbOrgY->value().getValue(),
ui->sbOrgZ->value().getValue());
Command::doCommand(Command::Doc,"App.activeDocument().%s.Scale = %0.6f",
sectionName.c_str(), baseScale);
m_sectionName.c_str(), baseScale);
App::DocumentObject* newObj = m_base->getDocument()->getObject(sectionName.c_str());
newSection = dynamic_cast<TechDraw::DrawViewSection*>(newObj);
App::DocumentObject* newObj = m_base->getDocument()->getObject(m_sectionName.c_str());
m_section = dynamic_cast<TechDraw::DrawViewSection*>(newObj);
if ( (newObj == nullptr) ||
(newSection == nullptr) ) {
(m_section == nullptr) ) {
throw Base::RuntimeError("TaskSectionView - new section object not found");
}
}
return newSection;
Gui::Command::updateActive();
Gui::Command::commitCommand();
return;
}
void TaskSectionView::updateSectionView(void)
{
// Base::Console().Message("TSV::updateSectionView()\n");
// Base::Console().Message("TSV::updateSectionView() - m_sectionName: %s\n", m_sectionName.c_str());
if (!isSectionValid()) {
failNoObject(m_sectionName);
return;
}
if (m_section != nullptr) {
std::string sectionName = m_section->getNameInDocument();
Command::doCommand(Command::Doc,"App.activeDocument().%s.SectionDirection = '%s'",
sectionName.c_str(),m_dirName.c_str());
m_sectionName.c_str(),m_dirName.c_str());
Command::doCommand(Command::Doc,
"App.activeDocument().%s.SectionOrigin = FreeCAD.Vector(%.3f,%.3f,%.3f)",
sectionName.c_str(),
m_sectionName.c_str(),
ui->sbOrgX->value().getValue(),
ui->sbOrgY->value().getValue(),
ui->sbOrgZ->value().getValue());
QString qTemp = ui->leSymbol->text();
std::string temp = Base::Tools::toStdString(qTemp);
Command::doCommand(Command::Doc,"App.activeDocument().%s.SectionSymbol = '%s'",
sectionName.c_str(),
m_sectionName.c_str(),
temp.c_str());
std::string lblText = "Section " +
temp +
" - " +
temp;
Command::doCommand(Command::Doc,"App.activeDocument().%s.Label = '%s'",
sectionName.c_str(),
m_sectionName.c_str(),
lblText.c_str());
Command::doCommand(Command::Doc,"App.activeDocument().%s.Scale = %0.6f",
sectionName.c_str(),
m_sectionName.c_str(),
ui->sbScale->value());
m_section->setCSFromBase(m_dirName.c_str());
}
}
void TaskSectionView::failNoObject(std::string objectName)
{
QString qObjectName = Base::Tools::fromStdString(objectName);
QString msg = tr("Can not continue. Object * %1 * not found.").arg(qObjectName);
QMessageBox::critical(Gui::getMainWindow(), QObject::tr("Operation Failed"), msg);
Gui::Control().closeDialog();
m_abort = true;
}
bool TaskSectionView::isBaseValid(void)
{
bool result = true;
if (m_base == nullptr) {
result = false;
} else {
App::DocumentObject* baseObj = m_doc->getObject(m_saveBaseName.c_str());
if (baseObj == nullptr) {
result = false;
}
}
return result;
}
bool TaskSectionView::isSectionValid(void)
{
bool result = true;
if (m_section == nullptr) {
result = false;
} else {
App::DocumentObject* sectionObj = m_doc->getObject(m_sectionName.c_str());
if (sectionObj == nullptr) {
result = false;
}
}
return result;
}
//******************************************************************************
bool TaskSectionView::accept()
{
// Base::Console().Message("TSV::accept()\n");
if (m_createMode) {
if (m_section == nullptr) {
apply();
} else {
updateSectionView();
}
Gui::Command::updateActive();
Gui::Command::commitCommand();
} else {
Gui::Command::openCommand("Edit SectionView");
try {
updateSectionView();
}
catch (...) {
Base::Console().Error("TSV::accept - failed to update section\n");
}
Gui::Command::updateActive();
Gui::Command::commitCommand();
if (m_abort) {
return true;
}
apply();
Gui::Command::doCommand(Gui::Command::Gui,"Gui.ActiveDocument.resetEdit()");
if (m_section != nullptr) {
m_section->requestPaint();
App::Document* doc = m_section->getDocument();
App::DocumentObject* baseObj = doc->getObject(m_saveBaseName.c_str());
TechDraw::DrawViewPart* dvp = dynamic_cast<TechDraw::DrawViewPart*>(baseObj);
if (dvp != nullptr) {
dvp->requestPaint();
}
}
return true;
}
bool TaskSectionView::reject()
{
// Base::Console().Message("TSV::reject()\n");
if (m_section != nullptr) {
if (m_createMode) {
std::string SectionName = m_section->getNameInDocument();
Gui::Command::doCommand(Gui::Command::Gui,
"App.activeDocument().%s.removeView(App.activeDocument().%s)",
m_savePageName.c_str(),SectionName.c_str());
Gui::Command::doCommand(Gui::Command::Gui,
"App.activeDocument().removeObject('%s')",
SectionName.c_str());
} else {
restoreSectionState();
//check undo stack?
if (m_section != nullptr) {
m_section->requestPaint();
App::Document* doc = m_section->getDocument();
App::DocumentObject* baseObj = doc->getObject(m_saveBaseName.c_str());
TechDraw::DrawViewPart* dvp = dynamic_cast<TechDraw::DrawViewPart*>(baseObj);
if (dvp != nullptr) {
dvp->requestPaint();
}
}
}
if (m_section == nullptr) { //no section created, nothing to undo
Gui::Command::doCommand(Gui::Command::Gui,"Gui.ActiveDocument.resetEdit()");
return false;
}
if (!isSectionValid()) { //section !exist. nothing to undo
if (isBaseValid()) {
m_base->requestPaint();
}
Gui::Command::doCommand(Gui::Command::Gui,"Gui.ActiveDocument.resetEdit()");
return false;
}
if (m_createMode) {
std::string SectionName = m_section->getNameInDocument();
Gui::Command::doCommand(Gui::Command::Gui,
"App.activeDocument().%s.removeView(App.activeDocument().%s)",
m_savePageName.c_str(),SectionName.c_str());
Gui::Command::doCommand(Gui::Command::Gui,
"App.activeDocument().removeObject('%s')",
SectionName.c_str());
} else {
restoreSectionState();
m_section->recomputeFeature();
m_section->requestPaint();
}
if (isBaseValid()) {
m_base->requestPaint();
}
Gui::Command::doCommand(Gui::Command::Gui,"App.activeDocument().recompute()");
Gui::Command::doCommand(Gui::Command::Gui,"Gui.ActiveDocument.resetEdit()");
return false;
@@ -529,13 +560,6 @@ bool TaskDlgSectionView::accept()
return true;
}
//bool TaskDlgSectionView::apply()
//{
// Base::Console().Message("TDSV::apply()\n");
// widget->apply();
// return true;
//}
bool TaskDlgSectionView::reject()
{
widget->reject();