Skip to content

Commit

Permalink
Merge pull request #8114 from signedav/bugfix_not_deleting_relation
Browse files Browse the repository at this point in the history
More intuitive relation reference widget text filter
  • Loading branch information
m-kuhn committed Oct 29, 2018
2 parents d4cf8cf + 9768fdd commit 8fc4378
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 3 deletions.
2 changes: 2 additions & 0 deletions python/gui/auto_generated/qgsfilterlineedit.sip.in
Expand Up @@ -268,6 +268,8 @@ Will select all text when this widget receives the focus.
protected:
virtual void focusInEvent( QFocusEvent *e );

virtual void mouseReleaseEvent( QMouseEvent *e );


};

Expand Down
13 changes: 11 additions & 2 deletions src/gui/qgsfeaturelistcombobox.cpp
Expand Up @@ -51,8 +51,10 @@ QgsFeatureListComboBox::QgsFeatureListComboBox( QWidget *parent )

connect( this, static_cast<void( QgsFeatureListComboBox::* )( int )>( &QgsFeatureListComboBox::currentIndexChanged ), this, &QgsFeatureListComboBox::onCurrentIndexChanged );

mLineEdit = new QgsFilterLineEdit();
mLineEdit = new QgsFilterLineEdit( nullptr, QgsApplication::nullRepresentation() );
mLineEdit->setSelectOnFocus( true );
mLineEdit->setShowClearButton( true );

setEditable( true );
setLineEdit( mLineEdit );
setModel( mModel );
Expand Down Expand Up @@ -109,7 +111,8 @@ void QgsFeatureListComboBox::onItemSelected( const QModelIndex &index )

void QgsFeatureListComboBox::onCurrentIndexChanged( int i )
{
mIsCurrentlyEdited = false;
if ( !mHasStoredEditState )
mIsCurrentlyEdited = false;
QModelIndex modelIndex = mModel->index( i, 0, QModelIndex() );
mModel->setExtraIdentifierValue( mModel->data( modelIndex, QgsFeatureFilterModel::IdentifierValueRole ) );
mLineEdit->setText( mModel->data( modelIndex, QgsFeatureFilterModel::ValueRole ).toString() );
Expand All @@ -128,13 +131,19 @@ void QgsFeatureListComboBox::onActivated( QModelIndex modelIndex )
void QgsFeatureListComboBox::storeLineEditState()
{
if ( mIsCurrentlyEdited )
{
mHasStoredEditState = true;
mLineEditState.store( mLineEdit );
}
}

void QgsFeatureListComboBox::restoreLineEditState()
{
if ( mIsCurrentlyEdited )
{
mHasStoredEditState = false;
mLineEditState.restore( mLineEdit );
}
}

int QgsFeatureListComboBox::nullIndex() const
Expand Down
3 changes: 3 additions & 0 deletions src/gui/qgsfeaturelistcombobox.h
Expand Up @@ -219,7 +219,10 @@ class GUI_EXPORT QgsFeatureListComboBox : public QComboBox
QgsFilterLineEdit *mLineEdit;
bool mPopupRequested = false;
bool mIsCurrentlyEdited = false;
bool mHasStoredEditState = false;
LineEditState mLineEditState;

friend class TestQgsFeatureListComboBox;
};

#endif // QGSFIELDLISTCOMBOBOX_H
12 changes: 11 additions & 1 deletion src/gui/qgsfilterlineedit.cpp
Expand Up @@ -90,6 +90,16 @@ void QgsFilterLineEdit::focusInEvent( QFocusEvent *e )
if ( e->reason() == Qt::MouseFocusReason && ( isNull() || mSelectOnFocus ) )
{
mFocusInEvent = true;
mWaitingForMouseRelease = true;
}
}

void QgsFilterLineEdit::mouseReleaseEvent( QMouseEvent *e )
{
QLineEdit::mouseReleaseEvent( e );
if ( mWaitingForMouseRelease )
{
mWaitingForMouseRelease = false;
selectAll();
}
}
Expand Down Expand Up @@ -198,7 +208,7 @@ bool QgsFilterLineEdit::shouldShowClear() const

bool QgsFilterLineEdit::event( QEvent *event )
{
if ( event->type() == QEvent::ReadOnlyChange )
if ( event->type() == QEvent::ReadOnlyChange || event->type() == QEvent::EnabledChange )
updateClearIcon();

return QLineEdit::event( event );;
Expand Down
4 changes: 4 additions & 0 deletions src/gui/qgsfilterlineedit.h
Expand Up @@ -265,6 +265,7 @@ class GUI_EXPORT QgsFilterLineEdit : public QLineEdit

protected:
void focusInEvent( QFocusEvent *e ) override;
void mouseReleaseEvent( QMouseEvent *e ) override;

private slots:
void onTextChanged( const QString &text );
Expand All @@ -286,12 +287,15 @@ class GUI_EXPORT QgsFilterLineEdit : public QLineEdit
QString mDefaultValue;
QString mStyleSheet;
bool mFocusInEvent = false;
bool mWaitingForMouseRelease = false;
bool mSelectOnFocus = false;

QgsAnimatedIcon *mBusySpinnerAnimatedIcon = nullptr;

//! Returns true if clear button should be shown
bool shouldShowClear() const;

friend class TestQgsFeatureListComboBox;
};

/// @cond PRIVATE
Expand Down
46 changes: 46 additions & 0 deletions tests/src/gui/testqgsfeaturelistcombobox.cpp
Expand Up @@ -18,6 +18,7 @@

#include "qgsapplication.h"
#include "qgsfeaturelistcombobox.h"
#include "qgsfilterlineedit.h"
#include "qgsvectorlayer.h"
#include "qgsfeaturefiltermodel.h"
#include "qgsgui.h"
Expand All @@ -26,6 +27,8 @@

#include <QLineEdit>

class QgsFilterLineEdit;

class TestQgsFeatureListComboBox : public QObject
{
Q_OBJECT
Expand All @@ -41,12 +44,15 @@ class TestQgsFeatureListComboBox : public QObject
void testSetGetLayer();
void testSetGetForeignKey();
void testAllowNull();
void testValuesAndSelection();
void nullRepresentation();

private:
void waitForLoaded( QgsFeatureListComboBox *cb );

std::unique_ptr<QgsVectorLayer> mLayer;

friend class QgsFeatureListComboBox;
};

void TestQgsFeatureListComboBox::initTestCase()
Expand Down Expand Up @@ -137,6 +143,46 @@ void TestQgsFeatureListComboBox::testAllowNull()
// Note to self: implement this!
}

void TestQgsFeatureListComboBox::testValuesAndSelection()
{
QgsApplication::setNullRepresentation( QStringLiteral( "nope" ) );
std::unique_ptr<QgsFeatureListComboBox> cb( new QgsFeatureListComboBox() );

cb->setSourceLayer( mLayer.get() );
cb->setDisplayExpression( QStringLiteral( "\"raccord\"" ) );
cb->setAllowNull( true );

//check if everything is fine:
waitForLoaded( cb.get() );
QCOMPARE( cb->currentIndex(), cb->nullIndex() );
QCOMPARE( cb->currentText(), QStringLiteral( "nope" ) );

//check if text correct, selected and if the clear button disappeared:
cb->mLineEdit->clearValue();
waitForLoaded( cb.get() );
QCOMPARE( cb->currentIndex(), cb->nullIndex() );
QCOMPARE( cb->currentText(), QStringLiteral( "nope" ) );
QCOMPARE( cb->lineEdit()->selectedText(), QStringLiteral( "nope" ) );
QVERIFY( ! cb->mLineEdit->mClearAction );

//check if text is selected after receiving focus
cb->setFocus();
waitForLoaded( cb.get() );
QCOMPARE( cb->currentIndex(), cb->nullIndex() );
QCOMPARE( cb->currentText(), QStringLiteral( "nope" ) );
QCOMPARE( cb->lineEdit()->selectedText(), QStringLiteral( "nope" ) );
QVERIFY( ! cb->mLineEdit->mClearAction );

//check with another entry, clear button needs to be there then:
QTest::keyClicks( cb.get(), QStringLiteral( "sleeve" ) );
//QTest::keyClick(cb.get(), Qt::Key_Enter );
waitForLoaded( cb.get() );
QCOMPARE( cb->currentText(), QStringLiteral( "sleeve" ) );
QVERIFY( cb->mLineEdit->mClearAction );
//QVERIFY( cb->currentIndex() != cb->nullIndex());
//QCOMPARE( cb->model()->data( cb->currentModelIndex() ).toString(), QStringLiteral( "sleeve" ) );
}

void TestQgsFeatureListComboBox::nullRepresentation()
{

Expand Down
12 changes: 12 additions & 0 deletions tests/src/python/test_qgsfilterlineedit.py
Expand Up @@ -119,6 +119,18 @@ def testClearToDefault(self):
self.assertEqual(w.text(), 'def')
self.assertFalse(w.isNull())

def test_selectedText(self):
""" test that NULL value is selected on focus and not-null value is not"""
w = qgis.gui.QgsFilterLineEdit(nullValue='my_null_value')
w.clearValue()
self.assertEqual(w.selectedText(), 'my_null_value')

w.setValue('my new value')
self.assertEqual(w.selectedText(), '')

w.clearValue()
self.assertEqual(w.selectedText(), 'my_null_value')

@unittest.skipIf(not use_signal_spy, "No QSignalSpy available")
def test_ChangedSignals(self):
""" test that signals are correctly emitted when clearing"""
Expand Down

0 comments on commit 8fc4378

Please sign in to comment.