Skip to content
Permalink
Browse files
Fix attribute dialog crash on close
  • Loading branch information
m-kuhn committed Jul 23, 2014
1 parent 677abbf commit ad5aa3050e7691cdfd07f08ec6e739f49cc384a3
Showing with 38 additions and 97 deletions.
  1. +1 −1 src/app/qgisappinterface.cpp
  2. +6 −6 src/app/qgsfeatureaction.cpp
  3. +3 −3 src/gui/editorwidgets/qgsrelationreferencewidget.cpp
  4. +18 −71 src/gui/qgsattributedialog.cpp
  5. +10 −16 src/gui/qgsattributedialog.h
@@ -628,7 +628,7 @@ QDialog* QgisAppInterface::getFeatureForm( QgsVectorLayer *l, QgsFeature &featur
myDa.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) );

QgsAttributeDialog *dialog = new QgsAttributeDialog( l, &feature, false, NULL, true );
return dialog->dialog();
return dialog;
}

QgsVectorLayerTools* QgisAppInterface::vectorLayerTools()
@@ -64,11 +64,11 @@ QgsAttributeDialog *QgsFeatureAction::newDialog( bool cloneFeature )

if ( mLayer->actions()->size() > 0 )
{
dialog->dialog()->setContextMenuPolicy( Qt::ActionsContextMenu );
dialog->setContextMenuPolicy( Qt::ActionsContextMenu );

QAction *a = new QAction( tr( "Run actions" ), dialog->dialog() );
QAction *a = new QAction( tr( "Run actions" ), dialog );
a->setEnabled( false );
dialog->dialog()->addAction( a );
dialog->addAction( a );

for ( int i = 0; i < mLayer->actions()->size(); i++ )
{
@@ -77,11 +77,11 @@ QgsAttributeDialog *QgsFeatureAction::newDialog( bool cloneFeature )
if ( !action.runable() )
continue;

QgsFeatureAction *a = new QgsFeatureAction( action.name(), *f, mLayer, i, -1, dialog->dialog() );
dialog->dialog()->addAction( a );
QgsFeatureAction *a = new QgsFeatureAction( action.name(), *f, mLayer, i, -1, dialog );
dialog->addAction( a );
connect( a, SIGNAL( triggered() ), a, SLOT( execute() ) );

QAbstractButton *pb = dialog->dialog()->findChild<QAbstractButton *>( action.name() );
QAbstractButton *pb = dialog->findChild<QAbstractButton *>( action.name() );
if ( pb )
connect( pb, SIGNAL( clicked() ), a, SLOT( execute() ) );
}
@@ -182,14 +182,14 @@ void QgsRelationReferenceWidget::referenceChanged( int index )
// Backup old dialog and delete only after creating the new dialog, so we can "hot-swap" the contained QgsFeature
QgsAttributeDialog* oldDialog = mAttributeDialog;

if ( mAttributeDialog && mAttributeDialog->dialog() )
if ( mAttributeDialog )
{
mAttributeEditorLayout->removeWidget( mAttributeDialog->dialog() );
mAttributeEditorLayout->removeWidget( mAttributeDialog );
}

// TODO: Get a proper QgsDistanceArea thingie
mAttributeDialog = new QgsAttributeDialog( mReferencedLayer, new QgsFeature( feat ), true, mAttributeEditorFrame, false, mEditorContext );
QWidget* attrDialog = mAttributeDialog->dialog();
QWidget* attrDialog = mAttributeDialog;
attrDialog->setWindowFlags( Qt::Widget ); // Embed instead of opening as window
mAttributeEditorLayout->addWidget( attrDialog );
attrDialog->show();
@@ -25,7 +25,7 @@


QgsAttributeDialog::QgsAttributeDialog( QgsVectorLayer* vl, QgsFeature* thepFeature, bool featureOwner, QgsDistanceArea myDa, QWidget* parent, bool showDialogButtons )
: QObject( parent )
: QDialog( parent )
, mHighlight( 0 )
{
QgsAttributeEditorContext context;
@@ -40,7 +40,7 @@ QgsAttributeDialog::QgsAttributeDialog( QgsVectorLayer* vl, QgsFeature* thepFeat
}

QgsAttributeDialog::QgsAttributeDialog( QgsVectorLayer* vl, QgsFeature* thepFeature, bool featureOwner, QWidget* parent, bool showDialogButtons, QgsAttributeEditorContext context )
: QObject( parent )
: QDialog( parent )
, mHighlight( 0 )
{
init( vl, thepFeature, context, parent );
@@ -60,25 +60,17 @@ QgsAttributeDialog::~QgsAttributeDialog()
delete mHighlight;
}

delete mDialog;
saveGeometry();
}

void QgsAttributeDialog::saveGeometry()
{
if ( mDialog )
{
QSettings settings;
settings.setValue( mSettingsPath + "geometry", mDialog->saveGeometry() );
}
QSettings().setValue( mSettingsPath + "geometry", QDialog::saveGeometry() );
}

void QgsAttributeDialog::restoreGeometry()
{
if ( mDialog )
{
QSettings settings;
mDialog->restoreGeometry( settings.value( mSettingsPath + "geometry" ).toByteArray() );
}
QDialog::restoreGeometry( QSettings().value( mSettingsPath + "geometry" ).toByteArray() );
}

void QgsAttributeDialog::setHighlight( QgsHighlight* h )
@@ -91,73 +83,28 @@ void QgsAttributeDialog::setHighlight( QgsHighlight* h )
void QgsAttributeDialog::accept()
{
mAttributeForm->save();
QDialog::accept();
}

int QgsAttributeDialog::exec()
void QgsAttributeDialog::show( bool autoDelete )
{
if ( mDialog )
{
return mDialog->exec();
}
else
{
QgsDebugMsg( "No dialog" );
return QDialog::Accepted;
}
}
if ( autoDelete )
setAttribute( Qt::WA_DeleteOnClose );

void QgsAttributeDialog::show()
{
if ( mDialog )
{
mDialog->setAttribute( Qt::WA_DeleteOnClose );
mDialog->show();
mDialog->raise();
mDialog->activateWindow();
mDialog->installEventFilter( this );
setParent( mDialog );
}
}

bool QgsAttributeDialog::eventFilter( QObject* obj, QEvent* e )
{
if ( mHighlight && obj == mDialog )
{
switch ( e->type() )
{
case QEvent::WindowActivate:
mHighlight->show();
break;

case QEvent::WindowDeactivate:
mHighlight->hide();
break;

default:
break;
}
}

return false;
}

void QgsAttributeDialog::onDialogFinished( int result )
{
Q_UNUSED( result )
saveGeometry();
QDialog::show();
raise();
activateWindow();
}

void QgsAttributeDialog::init( QgsVectorLayer* layer, QgsFeature* feature, QgsAttributeEditorContext& context, QWidget* parent )
{
mDialog = new QDialog( parent );
mDialog->setWindowTitle( tr( "Feature Attributes" ) );
mDialog->setLayout( new QGridLayout() );
mDialog->layout()->setMargin( 0 );
setWindowTitle( tr( "Feature Attributes" ) );
setLayout( new QGridLayout() );
layout()->setMargin( 0 );
mAttributeForm = new QgsAttributeForm( layer, *feature, context, parent );
mDialog->layout()->addWidget( mAttributeForm );
layout()->addWidget( mAttributeForm );
QDialogButtonBox* buttonBox = mAttributeForm->findChild<QDialogButtonBox*>();
connect( buttonBox, SIGNAL( rejected() ), mDialog, SLOT( reject() ) );
connect( buttonBox, SIGNAL( accepted() ), mDialog, SLOT( accept() ) );
connect( mDialog, SIGNAL( finished( int ) ), this, SLOT( onDialogFinished( int ) ) );
connect( buttonBox, SIGNAL( rejected() ), this, SLOT( reject() ) );
connect( buttonBox, SIGNAL( accepted() ), this, SLOT( accept() ) );
restoreGeometry();
}
@@ -22,7 +22,6 @@
#include "qgsattributeform.h"

#include <QDialog>
#include <QPointer>

class QLayout;

@@ -33,7 +32,7 @@ class QgsHighlight;
class QgsVectorLayer;
class QgsVectorLayerTools;

class GUI_EXPORT QgsAttributeDialog : public QObject
class GUI_EXPORT QgsAttributeDialog : public QDialog
{
Q_OBJECT

@@ -83,7 +82,14 @@ class GUI_EXPORT QgsAttributeDialog : public QObject
*/
void setHighlight( QgsHighlight *h );

QDialog *dialog() { return mDialog; }
/**
* @brief Returns reference to self. Only here for legacy compliance
*
* @return this
*
* @deprecated Do not use. Just use this object itself. Or QgsAttributeForm if you want to embed.
*/
Q_DECL_DEPRECATED QDialog *dialog() { return this; }

QgsAttributeForm* attributeForm() { return mAttributeForm; }

@@ -115,25 +121,13 @@ class GUI_EXPORT QgsAttributeDialog : public QObject
public slots:
void accept();

//! Show the dialog and block the application until the dialog is closed. Ownership of this object is not changed.
int exec();

//! Show the dialog non-blocking. Reparents this dialog to be a child of the dialog form and is deleted when
//! closed.
void show();

protected:
bool eventFilter( QObject *obj, QEvent *e );

private slots:
void onDialogFinished( int result );
void show( bool autoDelete = true );

private:
void init( QgsVectorLayer* layer, QgsFeature* feature, QgsAttributeEditorContext& context, QWidget* parent );

// Using a guarded pointer we can savely delete the dialog in the destructor even
// when the dialog is this object's parent
QPointer<QDialog> mDialog;
QString mSettingsPath;
// Used to sync multiple widgets for the same field
QgsHighlight *mHighlight;

0 comments on commit ad5aa30

Please sign in to comment.