Skip to content

Commit

Permalink
Merge pull request #36722 from rouault/fix_30210
Browse files Browse the repository at this point in the history
 QgsBinaryWidgetWrapper: fix focus-related crash
  • Loading branch information
rouault committed May 26, 2020
2 parents 63c34e3 + 46c9d1f commit bcea438
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 10 deletions.
1 change: 1 addition & 0 deletions src/gui/CMakeLists.txt
Expand Up @@ -416,6 +416,7 @@ SET(QGIS_GUI_SRCS
qgsfilterlineedit.cpp
qgsfindfilesbypatternwidget.cpp
qgsfloatingwidget.cpp
qgsfocuskeeper.cpp
qgsfocuswatcher.cpp
qgsfontbutton.cpp
qgsformannotation.cpp
Expand Down
37 changes: 27 additions & 10 deletions src/gui/editorwidgets/qgsbinarywidgetwrapper.cpp
Expand Up @@ -17,6 +17,7 @@
#include "qgsvectorlayer.h"
#include "qgsvectordataprovider.h"
#include "qgsfileutils.h"
#include "qgsfocuskeeper.h"
#include "qgssettings.h"
#include "qgsmessagebar.h"
#include "qgsapplication.h"
Expand Down Expand Up @@ -135,10 +136,16 @@ void QgsBinaryWidgetWrapper::updateValues( const QVariant &value, const QVariant
void QgsBinaryWidgetWrapper::saveContent()
{
QgsSettings s;
QString file = QFileDialog::getSaveFileName( nullptr,
tr( "Save Contents to File" ),
defaultPath(),
tr( "All files" ) + " (*.*)" );

QString file;
{
QgsFocusKeeper focusKeeper;

file = QFileDialog::getSaveFileName( nullptr,
tr( "Save Contents to File" ),
defaultPath(),
tr( "All files" ) + " (*.*)" );
}
if ( file.isEmpty() )
{
return;
Expand All @@ -160,10 +167,17 @@ void QgsBinaryWidgetWrapper::saveContent()
void QgsBinaryWidgetWrapper::setContent()
{
QgsSettings s;
QString file = QFileDialog::getOpenFileName( nullptr,
tr( "Embed File" ),
defaultPath(),
tr( "All files" ) + " (*.*)" );

QString file;
{
QgsFocusKeeper focusKeeper;

file = QFileDialog::getOpenFileName( nullptr,
tr( "Embed File" ),
defaultPath(),
tr( "All files" ) + " (*.*)" );
}

QFileInfo fi( file );
if ( file.isEmpty() || !fi.exists() )
{
Expand All @@ -184,8 +198,11 @@ void QgsBinaryWidgetWrapper::setContent()

void QgsBinaryWidgetWrapper::clear()
{
if ( QMessageBox::question( nullptr, tr( "Clear Contents" ), tr( "Are you sure you want the clear this field's content?" ), QMessageBox::Yes | QMessageBox::No, QMessageBox::No ) != QMessageBox::Yes )
return;
{
QgsFocusKeeper focusKeeper;
if ( QMessageBox::question( nullptr, tr( "Clear Contents" ), tr( "Are you sure you want the clear this field's content?" ), QMessageBox::Yes | QMessageBox::No, QMessageBox::No ) != QMessageBox::Yes )
return;
}

updateValues( QByteArray() );
emitValueChanged();
Expand Down
40 changes: 40 additions & 0 deletions src/gui/qgsfocuskeeper.cpp
@@ -0,0 +1,40 @@
/***************************************************************************
qgsfocuskeeper.cpp
-----------------
Date : May 2020
Copyright : (C) 2020 Even Rouault
Email : even dot rouault at spatialys dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsfocuskeeper.h"

#include <QApplication>
#include <QEvent>
#include <QWidget>

QgsFocusKeeper::QgsFocusKeeper(): mWidgetToKeepFocused( QApplication::focusWidget() )
{
mWidgetToKeepFocused->installEventFilter( this );
}

QgsFocusKeeper::~QgsFocusKeeper()
{
mWidgetToKeepFocused->removeEventFilter( this );
}

bool QgsFocusKeeper::eventFilter( QObject *obj, QEvent *event )
{
if ( obj == mWidgetToKeepFocused && event &&
( event->type() == QEvent::FocusOut || event->type() == QEvent::FocusAboutToChange ) )
{
return true;
}
return QObject::eventFilter( obj, event );
}
48 changes: 48 additions & 0 deletions src/gui/qgsfocuskeeper.h
@@ -0,0 +1,48 @@
/***************************************************************************
qgsfocuskeeper.h
---------------
Date : May 2020
Copyright : (C) 2020 Even Rouault
Email : even dot rouault at spatialys dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSFOCUSKEEPER_H
#define QGSFOCUSKEEPER_H

#include "qgis_gui.h"

#define SIP_NO_FILE

#include <QObject>

class QWidget;

/**
* \ingroup gui
* \class QgsFocusKeeper
* Trick to keep a widget focused and avoid QT crashes
* \note not available in Python bindings
* \since QGIS 3.14
*/
class GUI_EXPORT QgsFocusKeeper : public QObject
{
Q_OBJECT

QWidget *mWidgetToKeepFocused = nullptr;

public:
QgsFocusKeeper();
~QgsFocusKeeper() override;

protected:
bool eventFilter( QObject *obj, QEvent *event ) override;
};

#endif // QGSFOCUSKEEPER_H

0 comments on commit bcea438

Please sign in to comment.