Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Prevent saving invalid json
  • Loading branch information
stev-0 committed Nov 22, 2019
1 parent 5885c17 commit b4769c5
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 20 deletions.
Expand Up @@ -308,6 +308,8 @@ attribute ``attributeName`` to ``attributeValue``
.. versionadded:: 3.2
%End

protected:


};

Expand Down
2 changes: 2 additions & 0 deletions python/gui/auto_generated/qgsattributeform.sip.in
Expand Up @@ -44,6 +44,8 @@ class QgsAttributeForm : QWidget

const QgsFeature &feature();

void displayWarning( QString message );


void hideButtonBox();
%Docstring
Expand Down
5 changes: 3 additions & 2 deletions src/gui/editorwidgets/core/qgseditorwidgetwrapper.h
Expand Up @@ -307,14 +307,15 @@ class GUI_EXPORT QgsEditorWidgetWrapper : public QgsWidgetWrapper
*/
bool setFormFeatureAttribute( const QString &attributeName, const QVariant &attributeValue );


private:
protected:

/**
* mFieldIdx the widget feature field id
*/
int mFieldIdx = -1;

private:

/**
* The feature currently being edited, in its current state
*/
Expand Down
21 changes: 20 additions & 1 deletion src/gui/editorwidgets/qgstexteditwrapper.cpp
Expand Up @@ -20,6 +20,8 @@
#include "qgsfilterlineedit.h"
#include "qgsapplication.h"
#include "qgsjsonutils.cpp"
#include "qgsmessagebar.h"
#include "qgslogger.h"

#include <QSettings>
#include <nlohmann/json.hpp>
Expand Down Expand Up @@ -82,11 +84,14 @@ QVariant QgsTextEditWrapper::value() const
if ( json::accept( v.toUtf8() ) )
{
QVariant qjson = QgsJsonUtils::parseJson( v.toStdString() );
mInvalidJSON = false;
return qjson;
}
else
// return null value if json is invalid
{
return res;
mInvalidJSON = true;
return QVariant();
}
}
else
Expand All @@ -97,6 +102,7 @@ QVariant QgsTextEditWrapper::value() const

QWidget *QgsTextEditWrapper::createWidget( QWidget *parent )
{
mForm = qobject_cast<QgsAttributeForm *>( parent );
if ( config( QStringLiteral( "IsMultiline" ) ).toBool() )
{
if ( config( QStringLiteral( "UseHtml" ) ).toBool() )
Expand All @@ -116,6 +122,7 @@ QWidget *QgsTextEditWrapper::createWidget( QWidget *parent )

void QgsTextEditWrapper::initWidget( QWidget *editor )
{
mInvalidJSON = false;
mTextBrowser = qobject_cast<QTextBrowser *>( editor );
mTextEdit = qobject_cast<QTextEdit *>( editor );
mPlainTextEdit = qobject_cast<QPlainTextEdit *>( editor );
Expand Down Expand Up @@ -186,6 +193,18 @@ void QgsTextEditWrapper::showIndeterminateState()
mLineEdit->blockSignals( false );
}

void QgsTextEditWrapper::setFeature( const QgsFeature &feature )
{
// Do nothing if the value has not changed
if ( mInvalidJSON )
mForm->displayWarning( tr( "Your JSON is invalid and will be reverted back to what was in the datastore before editing" ) );
{
mInvalidJSON = false;
}
setFormFeature( feature );
setValue( feature.attribute( mFieldIdx ) );
}

void QgsTextEditWrapper::setValue( const QVariant &val )
{
if ( mLineEdit )
Expand Down
4 changes: 4 additions & 0 deletions src/gui/editorwidgets/qgstexteditwrapper.h
Expand Up @@ -21,6 +21,7 @@
#include <QLineEdit>
#include <QPlainTextEdit>
#include <QTextBrowser>
#include "qgsattributeform.h"
#include "qgis_gui.h"

SIP_NO_FILE
Expand Down Expand Up @@ -74,11 +75,14 @@ class GUI_EXPORT QgsTextEditWrapper : public QgsEditorWidgetWrapper
public slots:
void setValue( const QVariant &value ) override;
void setEnabled( bool enabled ) override;
void setFeature( const QgsFeature &feature );

private slots:
void textChanged( const QString &text );

private:
bool mutable mInvalidJSON;
QgsAttributeForm *mForm;
QTextBrowser *mTextBrowser = nullptr;
QTextEdit *mTextEdit = nullptr;
QPlainTextEdit *mPlainTextEdit = nullptr;
Expand Down
8 changes: 8 additions & 0 deletions src/gui/qgsattributeform.cpp
Expand Up @@ -497,6 +497,14 @@ void QgsAttributeForm::pushSelectedFeaturesMessage()
}
}

void QgsAttributeForm::displayWarning( QString message )
{
mMessageBar->pushMessage( QString(),
message,
Qgis::Warning,
messageTimeout() );
}

void QgsAttributeForm::runSearchSelect( QgsVectorLayer::SelectBehavior behavior )
{
QString filter = createFilterExpression();
Expand Down
2 changes: 2 additions & 0 deletions src/gui/qgsattributeform.h
Expand Up @@ -75,6 +75,8 @@ class GUI_EXPORT QgsAttributeForm : public QWidget

const QgsFeature &feature() { return mFeature; }

void displayWarning( QString message );

// TODO QGIS 4.0 - make private

/**
Expand Down
23 changes: 6 additions & 17 deletions tests/src/gui/testqgstexteditwrapper.cpp
Expand Up @@ -109,18 +109,15 @@ void TestQgsTextEditWrapper::testWithJsonInPostgres()

//test empty
widget->setText( QString( "" ) );
QVERIFY( w_json.value().isValid() );
QVERIFY( !w_json.value().isValid() );
// w_json value is QMapVariant
QCOMPARE( QString::fromUtf8( QJsonDocument::fromVariant( w_json.value() ).toJson( QJsonDocument::Compact ).data() ), QStringLiteral( "" ) );
QVERIFY( w_json.value().userType() == QMetaType::QString );

// test invalid JSON
widget->setText( QString( "{\"body\";\"text\"}" ) );
QVERIFY( w_json.value().isValid() );
QVERIFY( !w_json.value().isValid() );
//invalid JSON will be parsed as text - it is up to the Postgres provider to reject it
QCOMPARE( QString::fromUtf8( QJsonDocument::fromVariant( w_json.value() ).toJson( QJsonDocument::Compact ).data() ), QStringLiteral( "" ) );
QCOMPARE( w_json.value().toString(), QStringLiteral( "{\"body\";\"text\"}" ) );
QVERIFY( w_json.value().userType() == QMetaType::QString );

// test with bare integer (without container) which is valid JSON
widget->setText( QString( "2" ) );
Expand All @@ -131,10 +128,8 @@ void TestQgsTextEditWrapper::testWithJsonInPostgres()

// test with bare string (not valid JSON)
widget->setText( QString( "abc" ) );
QVERIFY( w_json.value().isValid() ) ;
QVERIFY( !w_json.value().isValid() ) ;
QCOMPARE( QString::fromUtf8( QJsonDocument::fromVariant( w_json.value() ).toJson( QJsonDocument::Compact ).data() ), QStringLiteral( "" ) );
QCOMPARE( w_json.value().toString(), QStringLiteral( "abc" ) );
QVERIFY( w_json.value().userType() == QMetaType::QString );
}

void TestQgsTextEditWrapper::testWithJsonBInPostgres()
Expand Down Expand Up @@ -178,18 +173,14 @@ void TestQgsTextEditWrapper::testWithJsonBInPostgres()

//test empty
widget->setText( QString( "" ) );
QVERIFY( w_json.value().isValid() );
QVERIFY( !w_json.value().isValid() );
// w_json value is QMapVariant
QCOMPARE( QString::fromUtf8( QJsonDocument::fromVariant( w_json.value() ).toJson( QJsonDocument::Compact ).data() ), QStringLiteral( "" ) );
QVERIFY( w_json.value().userType() == QMetaType::QString );

// test invalid JSON
widget->setText( QString( "{\"body\";\"text\"}" ) );
QVERIFY( w_json.value().isValid() );
//invalid JSON will be parsed as text - it is up to the Postgres provider to reject it
QVERIFY( !w_json.value().isValid() );
QCOMPARE( QString::fromUtf8( QJsonDocument::fromVariant( w_json.value() ).toJson( QJsonDocument::Compact ).data() ), QStringLiteral( "" ) );
QCOMPARE( w_json.value().toString(), QStringLiteral( "{\"body\";\"text\"}" ) );
QVERIFY( w_json.value().userType() == QMetaType::QString );

// test with bare integer (without container) which is valid JSON
widget->setText( QString( "2" ) );
Expand All @@ -200,10 +191,8 @@ void TestQgsTextEditWrapper::testWithJsonBInPostgres()

// test with bare string (not valid JSON)
widget->setText( QString( "abc" ) );
QVERIFY( w_json.value().isValid() );
QVERIFY( !w_json.value().isValid() );
QCOMPARE( QString::fromUtf8( QJsonDocument::fromVariant( w_json.value() ).toJson( QJsonDocument::Compact ).data() ), QStringLiteral( "" ) );
QCOMPARE( w_json.value().toString(), QStringLiteral( "abc" ) );
QVERIFY( w_json.value().userType() == QMetaType::QString );
}

QGSTEST_MAIN( TestQgsTextEditWrapper )
Expand Down

0 comments on commit b4769c5

Please sign in to comment.