Skip to content

Commit

Permalink
[TD]fix crash on Dim delete
Browse files Browse the repository at this point in the history
- adjust index/cache options to avoid "dirty" screen
  region errors.
- may be masking missing "prepareGeometryChange"
  • Loading branch information
WandererFan committed Mar 6, 2020
1 parent fa07197 commit fb2454d
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 13 deletions.
6 changes: 6 additions & 0 deletions src/Mod/TechDraw/Gui/MDIViewPage.cpp
Expand Up @@ -123,6 +123,10 @@ MDIViewPage::MDIViewPage(ViewProviderPage *pageVp, Gui::Document* doc, QWidget*

setMouseTracking(true);
m_scene = new QGraphicsScene(this);
m_scene->setItemIndexMethod(QGraphicsScene::NoIndex); //this prevents crash when deleting dims.
//scene(view?) indices of dirty regions gets
//out of sync. missing prepareGeometryChange
//somewhere???? QTBUG-18021???
m_view = new QGVPage(pageVp,m_scene,this);

m_toggleKeepUpdatedAction = new QAction(tr("Toggle &Keep Updated"), this);
Expand Down Expand Up @@ -398,9 +402,11 @@ bool MDIViewPage::attachView(App::DocumentObject *obj)
void MDIViewPage::onDeleteObject(const App::DocumentObject& obj)
{
//if this page has a QView for this obj, delete it.
blockSelection(true);
if (obj.isDerivedFrom(TechDraw::DrawView::getClassTypeId())) {
(void) m_view->removeQViewByName(obj.getNameInDocument());
}
blockSelection(false);
}

void MDIViewPage::onTimer() {
Expand Down
10 changes: 10 additions & 0 deletions src/Mod/TechDraw/Gui/QGIView.cpp
Expand Up @@ -627,6 +627,16 @@ MDIViewPage* QGIView::getMDIViewPage(void) const
return MDIViewPage::getFromScene(scene());
}

//remove a child of this from scene while keeping scene indexes valid
void QGIView::removeChild(QGIView* child)
{
if ( (child != nullptr) &&
(child->parentItem() == this) ) {
prepareGeometryChange();
scene()->removeItem(child);
}
}

bool QGIView::getFrameState(void)
{
// Base::Console().Message("QGIV::getFrameState() - %s\n",getViewName());
Expand Down
1 change: 1 addition & 0 deletions src/Mod/TechDraw/Gui/QGIView.h
Expand Up @@ -122,6 +122,7 @@ class TechDrawGuiExport QGIView : public QObject, public QGraphicsItemGroup
static const double DefaultFontSizeInMM;

MDIViewPage* getMDIViewPage(void) const;
virtual void removeChild(QGIView* child);

// Mouse handling
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
Expand Down
3 changes: 3 additions & 0 deletions src/Mod/TechDraw/Gui/QGIViewDimension.cpp
Expand Up @@ -217,6 +217,7 @@ void QGIDatumLabel::paint(QPainter *painter, const QStyleOptionGraphicsItem *opt

void QGIDatumLabel::setPosFromCenter(const double &xCenter, const double &yCenter)
{
prepareGeometryChange();
QGIViewDimension* qgivd = dynamic_cast<QGIViewDimension*>(parentItem());
if( qgivd == nullptr ) {
return; //tarfu
Expand Down Expand Up @@ -266,6 +267,7 @@ void QGIDatumLabel::setLabelCenter()

void QGIDatumLabel::setFont(QFont f)
{
prepareGeometryChange();
m_dimText->setFont(f);
m_unitText->setFont(f);
QFont tFont(f);
Expand Down Expand Up @@ -679,6 +681,7 @@ QString QGIViewDimension::getLabelText(void)

void QGIViewDimension::draw()
{
prepareGeometryChange();
if (!isVisible()) {
return;
}
Expand Down
27 changes: 14 additions & 13 deletions src/Mod/TechDraw/Gui/QGVPage.cpp
Expand Up @@ -137,7 +137,11 @@ QGVPage::QGVPage(ViewProviderPage *vp, QGraphicsScene* s, QWidget *parent)
setMouseTracking(true);
viewport()->setMouseTracking(true);

setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
// setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
setViewportUpdateMode(QGraphicsView::FullViewportUpdate); //this prevents crash when deleting dims.
//scene(view?) indices of dirty regions gets
//out of sync. missing prepareGeometryChange
//somewhere???? QTBUG-18021????
setCacheMode(QGraphicsView::CacheBackground);

Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()
Expand Down Expand Up @@ -306,25 +310,22 @@ int QGVPage::removeQViewByName(const char* name)
balloon->disconnect();
}
removeQViewFromScene(ourItem);
delete ourItem;
delete ourItem; //commenting this prevents crash but means a small memory waste.
//alternate fix(?) is to change indexing/caching option in scene/view
}

return 0;
}

void QGVPage::removeQViewFromScene(QGIView *view)
{
QGraphicsItemGroup* grp = view->group();
if (grp) {
grp->removeFromGroup(view);
}

if (view->parentItem()) { //not top level
view->setParentItem(0);
}

if (view->scene()) {
view->scene()->removeItem(view);
if (view->scene() != nullptr) {
QGIView* qgParent = dynamic_cast<QGIView*>(view->parentItem());
if (qgParent != nullptr) {
qgParent->removeChild(view);
} else {
view->scene()->removeItem(view);
}
}
}

Expand Down

0 comments on commit fb2454d

Please sign in to comment.