[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:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user