[TD]fix crash on Dim delete

- adjust index/cache options to avoid "dirty" screen
  region errors.
- may be masking missing "prepareGeometryChange"
This commit is contained in:
wandererfan
2020-03-05 16:43:54 -05:00
committed by WandererFan
parent b8da1e3bea
commit b5ea5ed31e
5 changed files with 34 additions and 13 deletions

View File

@@ -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);
@@ -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() {

View File

@@ -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());

View File

@@ -122,6 +122,7 @@ public:
static const double DefaultFontSizeInMM;
MDIViewPage* getMDIViewPage(void) const;
virtual void removeChild(QGIView* child);
// Mouse handling
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) override;

View File

@@ -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
@@ -266,6 +267,7 @@ void QGIDatumLabel::setLabelCenter()
void QGIDatumLabel::setFont(QFont f)
{
prepareGeometryChange();
m_dimText->setFont(f);
m_unitText->setFont(f);
QFont tFont(f);
@@ -679,6 +681,7 @@ QString QGIViewDimension::getLabelText(void)
void QGIViewDimension::draw()
{
prepareGeometryChange();
if (!isVisible()) {
return;
}

View File

@@ -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()
@@ -306,7 +310,8 @@ 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;
@@ -314,17 +319,13 @@ int QGVPage::removeQViewByName(const char* name)
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);
}
}
}