Skip to content

Commit 9f325df

Browse files
committed
Search widget wrapper for relation reference widget
1 parent 6837996 commit 9f325df

9 files changed

+326
-6
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
2+
/** \ingroup gui
3+
* \class QgsRelationReferenceSearchWidgetWrapper
4+
* Wraps a relation reference search widget.
5+
* \note Added in version 2.16
6+
*/
7+
8+
class QgsRelationReferenceSearchWidgetWrapper : QgsSearchWidgetWrapper
9+
{
10+
%TypeHeaderCode
11+
#include <qgsrelationreferencesearchwidgetwrapper.h>
12+
%End
13+
public:
14+
15+
explicit QgsRelationReferenceSearchWidgetWrapper( QgsVectorLayer* vl, int fieldIdx, QgsMapCanvas* canvas, QWidget* parent = nullptr );
16+
bool applyDirectly();
17+
QString expression();
18+
bool valid() const;
19+
QVariant value() const;
20+
FilterFlags supportedFlags() const;
21+
FilterFlags defaultFlags() const;
22+
virtual QString createExpression( FilterFlags flags ) const;
23+
24+
public slots:
25+
26+
virtual void clearWidget();
27+
virtual void setEnabled( bool enabled );
28+
29+
protected:
30+
QWidget* createWidget( QWidget* parent );
31+
void initWidget( QWidget* editor );
32+
33+
public slots:
34+
35+
//! Called when current value of search widget changes
36+
void onValueChanged( QVariant value );
37+
38+
protected slots:
39+
void setExpression( QString exp );
40+
41+
};
42+

python/gui/gui.sip

+1
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@
258258
%Include editorwidgets/qgsdefaultsearchwidgetwrapper.sip
259259
%Include editorwidgets/qgsdoublespinbox.sip
260260
%Include editorwidgets/qgsmultiedittoolbutton.sip
261+
%Include editorwidgets/qgsrelationreferencesearchwidgetwrapper.sip
261262
%Include editorwidgets/qgsrelationreferencewidget.sip
262263
%Include editorwidgets/qgsrelationreferencewidgetwrapper.sip
263264
%Include editorwidgets/qgsrelationwidgetwrapper.sip

src/app/qgsattributetabledialog.cpp

+4-6
Original file line numberDiff line numberDiff line change
@@ -98,16 +98,14 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *theLayer, QWid
9898
// Initialize the window geometry
9999
restoreGeometry( settings.value( "/Windows/BetterAttributeTable/geometry" ).toByteArray() );
100100

101-
QgsAttributeEditorContext context;
102-
103101
myDa = new QgsDistanceArea();
104102

105103
myDa->setSourceCrs( mLayer->crs() );
106104
myDa->setEllipsoidalMode( QgisApp::instance()->mapCanvas()->mapSettings().hasCrsTransformEnabled() );
107105
myDa->setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) );
108106

109-
context.setDistanceArea( *myDa );
110-
context.setVectorLayerTools( QgisApp::instance()->vectorLayerTools() );
107+
mEditorContext.setDistanceArea( *myDa );
108+
mEditorContext.setVectorLayerTools( QgisApp::instance()->vectorLayerTools() );
111109

112110
QgsFeatureRequest r;
113111
if ( mLayer->geometryType() != QGis::NoGeometry &&
@@ -126,7 +124,7 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *theLayer, QWid
126124
}
127125

128126
// Initialize dual view
129-
mMainView->init( mLayer, QgisApp::instance()->mapCanvas(), r, context );
127+
mMainView->init( mLayer, QgisApp::instance()->mapCanvas(), r, mEditorContext );
130128
mMainView->setAttributeTableConfig( mLayer->attributeTableConfig() );
131129

132130
// Initialize filter gui elements
@@ -494,7 +492,7 @@ void QgsAttributeTableDialog::filterColumnChanged( QObject* filterAction )
494492
const QString widgetType = mLayer->editFormConfig()->widgetType( fldIdx );
495493
const QgsEditorWidgetConfig widgetConfig = mLayer->editFormConfig()->widgetConfig( fldIdx );
496494
mCurrentSearchWidgetWrapper = QgsEditorWidgetRegistry::instance()->
497-
createSearchWidget( widgetType, mLayer, fldIdx, widgetConfig, mFilterContainer );
495+
createSearchWidget( widgetType, mLayer, fldIdx, widgetConfig, mFilterContainer, mEditorContext );
498496
if ( mCurrentSearchWidgetWrapper->applyDirectly() )
499497
{
500498
connect( mCurrentSearchWidgetWrapper, SIGNAL( expressionChanged( QString ) ), SLOT( filterQueryChanged( QString ) ) );

src/app/qgsattributetabledialog.h

+1
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ class APP_EXPORT QgsAttributeTableDialog : public QDialog, private Ui::QgsAttrib
234234
QgsRubberBand* mRubberBand;
235235
QgsSearchWidgetWrapper* mCurrentSearchWidgetWrapper;
236236
QStringList mVisibleFields;
237+
QgsAttributeEditorContext mEditorContext;
237238

238239
void updateMultiEditButtonState();
239240

src/gui/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ SET(QGIS_GUI_SRCS
130130
editorwidgets/qgsrelationwidgetwrapper.cpp
131131
editorwidgets/qgsrelationreferenceconfigdlg.cpp
132132
editorwidgets/qgsrelationreferencefactory.cpp
133+
editorwidgets/qgsrelationreferencesearchwidgetwrapper.cpp
133134
editorwidgets/qgsrelationreferencewidget.cpp
134135
editorwidgets/qgsrelationreferencewidgetwrapper.cpp
135136
editorwidgets/qgstexteditconfigdlg.cpp
@@ -548,6 +549,7 @@ SET(QGIS_GUI_MOC_HDRS
548549
editorwidgets/qgsrangeconfigdlg.h
549550
editorwidgets/qgsrangewidgetwrapper.h
550551
editorwidgets/qgsrelationreferenceconfigdlg.h
552+
editorwidgets/qgsrelationreferencesearchwidgetwrapper.h
551553
editorwidgets/qgsrelationreferencewidget.h
552554
editorwidgets/qgsrelationreferencewidgetwrapper.h
553555
editorwidgets/qgsrelationwidgetwrapper.h

src/gui/editorwidgets/qgsrelationreferencefactory.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include "qgsrelationreferencewidgetwrapper.h"
2020
#include "qgsrelationreferenceconfigdlg.h"
21+
#include "qgsrelationreferencesearchwidgetwrapper.h"
2122

2223
QgsRelationReferenceFactory::QgsRelationReferenceFactory( const QString& name, QgsMapCanvas* canvas, QgsMessageBar* messageBar )
2324
: QgsEditorWidgetFactory( name )
@@ -31,6 +32,11 @@ QgsEditorWidgetWrapper* QgsRelationReferenceFactory::create( QgsVectorLayer* vl,
3132
return new QgsRelationReferenceWidgetWrapper( vl, fieldIdx, editor, mCanvas, mMessageBar, parent );
3233
}
3334

35+
QgsSearchWidgetWrapper*QgsRelationReferenceFactory::createSearchWidget( QgsVectorLayer* vl, int fieldIdx, QWidget* parent ) const
36+
{
37+
return new QgsRelationReferenceSearchWidgetWrapper( vl, fieldIdx, mCanvas, parent );
38+
}
39+
3440
QgsEditorConfigWidget* QgsRelationReferenceFactory::configWidget( QgsVectorLayer* vl, int fieldIdx, QWidget* parent ) const
3541
{
3642
return new QgsRelationReferenceConfigDlg( vl, fieldIdx, parent );

src/gui/editorwidgets/qgsrelationreferencefactory.h

+2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ class GUI_EXPORT QgsRelationReferenceFactory : public QgsEditorWidgetFactory
4545
*/
4646
virtual QgsEditorWidgetWrapper* create( QgsVectorLayer* vl, int fieldIdx, QWidget* editor, QWidget* parent ) const override;
4747

48+
QgsSearchWidgetWrapper* createSearchWidget( QgsVectorLayer* vl, int fieldIdx, QWidget* parent ) const override;
49+
4850
/**
4951
* Override this in your implementation.
5052
* Create a new configuration widget for this widget type.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
/***************************************************************************
2+
qgsrelationreferencesearchwidgetwrapper.cpp
3+
------------------------------------------
4+
Date : 2016-05-25
5+
Copyright : (C) 2016 Nyall Dawson
6+
Email : nyall dot dawson at gmail dot com
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#include "qgsrelationreferencesearchwidgetwrapper.h"
17+
18+
#include "qgsfield.h"
19+
#include "qgsmaplayerregistry.h"
20+
#include "qgsvaluerelationwidgetfactory.h"
21+
#include "qgsvectorlayer.h"
22+
#include "qgsproject.h"
23+
24+
#include <QSettings>
25+
#include <QStringListModel>
26+
27+
QgsRelationReferenceSearchWidgetWrapper::QgsRelationReferenceSearchWidgetWrapper( QgsVectorLayer* vl, int fieldIdx, QgsMapCanvas* canvas, QWidget* parent )
28+
: QgsSearchWidgetWrapper( vl, fieldIdx, parent )
29+
, mWidget( nullptr )
30+
, mLayer( nullptr )
31+
, mCanvas( canvas )
32+
{
33+
34+
}
35+
36+
bool QgsRelationReferenceSearchWidgetWrapper::applyDirectly()
37+
{
38+
return true;
39+
}
40+
41+
QString QgsRelationReferenceSearchWidgetWrapper::expression()
42+
{
43+
return mExpression;
44+
}
45+
46+
QVariant QgsRelationReferenceSearchWidgetWrapper::value() const
47+
{
48+
if ( mWidget )
49+
{
50+
return mWidget->foreignKey();
51+
}
52+
return QVariant();
53+
}
54+
55+
QgsSearchWidgetWrapper::FilterFlags QgsRelationReferenceSearchWidgetWrapper::supportedFlags() const
56+
{
57+
return EqualTo | NotEqualTo | IsNull | IsNotNull;
58+
}
59+
60+
QgsSearchWidgetWrapper::FilterFlags QgsRelationReferenceSearchWidgetWrapper::defaultFlags() const
61+
{
62+
return EqualTo;
63+
}
64+
65+
QString QgsRelationReferenceSearchWidgetWrapper::createExpression( QgsSearchWidgetWrapper::FilterFlags flags ) const
66+
{
67+
QString fieldName = QgsExpression::quotedColumnRef( layer()->fields().at( mFieldIdx ).name() );
68+
69+
//clear any unsupported flags
70+
flags &= supportedFlags();
71+
if ( flags & IsNull )
72+
return fieldName + " IS NULL";
73+
if ( flags & IsNotNull )
74+
return fieldName + " IS NOT NULL";
75+
76+
QVariant v = value();
77+
if ( !v.isValid() )
78+
return QString();
79+
80+
switch ( v.type() )
81+
{
82+
case QVariant::Int:
83+
case QVariant::UInt:
84+
case QVariant::Double:
85+
case QVariant::LongLong:
86+
case QVariant::ULongLong:
87+
{
88+
if ( flags & EqualTo )
89+
return fieldName + '=' + v.toString();
90+
else if ( flags & NotEqualTo )
91+
return fieldName + "<>" + v.toString();
92+
break;
93+
}
94+
95+
default:
96+
{
97+
if ( flags & EqualTo )
98+
return fieldName + "='" + v.toString() + '\'';
99+
else if ( flags & NotEqualTo )
100+
return fieldName + "<>'" + v.toString() + '\'';
101+
break;
102+
}
103+
}
104+
105+
return QString();
106+
}
107+
108+
void QgsRelationReferenceSearchWidgetWrapper::clearWidget()
109+
{
110+
if ( mWidget )
111+
{
112+
mWidget->showIndeterminateState();
113+
}
114+
}
115+
116+
void QgsRelationReferenceSearchWidgetWrapper::setEnabled( bool enabled )
117+
{
118+
if ( mWidget )
119+
{
120+
mWidget->setEnabled( enabled );
121+
}
122+
}
123+
124+
bool QgsRelationReferenceSearchWidgetWrapper::valid() const
125+
{
126+
return true;
127+
}
128+
129+
void QgsRelationReferenceSearchWidgetWrapper::onValueChanged( QVariant value )
130+
{
131+
if ( !value.isValid() )
132+
{
133+
clearExpression();
134+
emit valueCleared();
135+
}
136+
else
137+
{
138+
QSettings settings;
139+
setExpression( value.isNull() ? settings.value( "qgis/nullValue", "NULL" ).toString() : value.toString() );
140+
emit valueChanged();
141+
}
142+
emit expressionChanged( mExpression );
143+
}
144+
145+
void QgsRelationReferenceSearchWidgetWrapper::setExpression( QString exp )
146+
{
147+
QSettings settings;
148+
QString nullValue = settings.value( "qgis/nullValue", "NULL" ).toString();
149+
QString fieldName = layer()->fields().at( mFieldIdx ).name();
150+
151+
QString str;
152+
if ( exp == nullValue )
153+
{
154+
str = QString( "%1 IS NULL" ).arg( QgsExpression::quotedColumnRef( fieldName ) );
155+
}
156+
else
157+
{
158+
str = QString( "%1 = '%3'" )
159+
.arg( QgsExpression::quotedColumnRef( fieldName ),
160+
exp.replace( '\'', "''" )
161+
);
162+
}
163+
mExpression = str;
164+
}
165+
166+
QWidget* QgsRelationReferenceSearchWidgetWrapper::createWidget( QWidget* parent )
167+
{
168+
return new QgsRelationReferenceWidget( parent );
169+
}
170+
171+
void QgsRelationReferenceSearchWidgetWrapper::initWidget( QWidget* editor )
172+
{
173+
mWidget = qobject_cast<QgsRelationReferenceWidget*>( editor );
174+
if ( !mWidget )
175+
return;
176+
177+
mWidget->setEditorContext( context(), mCanvas, nullptr );
178+
179+
mWidget->setEmbedForm( false );
180+
mWidget->setReadOnlySelector( false );
181+
mWidget->setAllowMapIdentification( config( "MapIdentification", false ).toBool() );
182+
mWidget->setOrderByValue( config( "OrderByValue", false ).toBool() );
183+
mWidget->setAllowAddFeatures( false );
184+
mWidget->setOpenFormButtonVisible( false );
185+
186+
QgsRelation relation = QgsProject::instance()->relationManager()->relation( config( "Relation" ).toString() );
187+
mWidget->setRelation( relation, false );
188+
189+
mWidget->showIndeterminateState();
190+
connect( mWidget, SIGNAL( foreignKeyChanged( QVariant ) ), this, SLOT( onValueChanged( QVariant ) ) );
191+
}
192+
193+

0 commit comments

Comments
 (0)