Skip to content

Commit 95a7408

Browse files
committedMay 26, 2015
Merge pull request #2059 from carolinux/search-widgets
[FEATURE] Search widgets Makes it easier to filter the attribute table if there are attribute domains attached
2 parents b5801af + e015a7e commit 95a7408

12 files changed

+224
-13
lines changed
 

‎src/app/qgsattributetabledialog.cpp

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242
#include "qgsexpressionselectiondialog.h"
4343
#include "qgsfeaturelistmodel.h"
4444
#include "qgsrubberband.h"
45+
#include "qgsfield.h"
46+
#include "qgseditorwidgetregistry.h"
4547

4648
class QgsAttributeTableDock : public QDockWidget
4749
{
@@ -64,6 +66,7 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *theLayer, QWid
6466
, mDock( 0 )
6567
, mLayer( theLayer )
6668
, mRubberBand( 0 )
69+
, mCurrentSearchWidgetWrapper( 0 )
6770
{
6871
setupUi( this );
6972

@@ -402,12 +405,37 @@ void QgsAttributeTableDialog::runFieldCalculation( QgsVectorLayer* layer, QStrin
402405
mLayer->endEditCommand();
403406
}
404407

408+
void QgsAttributeTableDialog::replaceSearchWidget(QWidget* oldw, QWidget* neww)
409+
{
410+
mFilterLayout->removeWidget(oldw);
411+
oldw->setVisible(false);
412+
mFilterLayout->addWidget(neww,0,0,0);
413+
neww->setVisible(true);
414+
}
415+
405416
void QgsAttributeTableDialog::filterColumnChanged( QObject* filterAction )
406417
{
407418
mFilterButton->setDefaultAction( qobject_cast<QAction *>( filterAction ) );
408419
mFilterButton->setPopupMode( QToolButton::InstantPopup );
409420
mCbxCaseSensitive->setVisible( true );
410-
mFilterQuery->setVisible( true );
421+
// replace the search line edit with a search widget that is suited to the selected field
422+
// delete previous widget
423+
if ( mCurrentSearchWidgetWrapper != 0 )
424+
{
425+
delete mCurrentSearchWidgetWrapper;
426+
}
427+
QString fieldName = mFilterButton->defaultAction()->text();
428+
// get the search widget
429+
int fldIdx = mLayer->fieldNameIndex( fieldName );
430+
if ( fldIdx < 0 )
431+
return;
432+
const QString widgetType = mLayer->editorWidgetV2( fldIdx );
433+
const QgsEditorWidgetConfig widgetConfig = mLayer->editorWidgetV2Config( fldIdx );
434+
mCurrentSearchWidgetWrapper= QgsEditorWidgetRegistry::instance()->
435+
createSearchWidget(widgetType, mLayer, fldIdx, widgetConfig, mFilterContainer);
436+
437+
replaceSearchWidget(mFilterQuery, mCurrentSearchWidgetWrapper->widget());
438+
411439
mApplyFilterButton->setVisible( true );
412440
}
413441

@@ -677,7 +705,6 @@ void QgsAttributeTableDialog::filterQueryChanged( const QString& query )
677705
else
678706
{
679707
QString fieldName = mFilterButton->defaultAction()->text();
680-
681708
const QgsFields& flds = mLayer->pendingFields();
682709
int fldIndex = mLayer->fieldNameIndex( fieldName );
683710
if ( fldIndex < 0 )
@@ -694,8 +721,9 @@ void QgsAttributeTableDialog::filterQueryChanged( const QString& query )
694721

695722
QSettings settings;
696723
QString nullValue = settings.value( "qgis/nullValue", "NULL" ).toString();
724+
QString value = mCurrentSearchWidgetWrapper->value().toString();
697725

698-
if ( mFilterQuery->displayText() == nullValue )
726+
if ( value == nullValue )
699727
{
700728
str = QString( "%1 IS NULL" ).arg( QgsExpression::quotedColumnRef( fieldName ) );
701729
}
@@ -705,9 +733,9 @@ void QgsAttributeTableDialog::filterQueryChanged( const QString& query )
705733
.arg( QgsExpression::quotedColumnRef( fieldName ) )
706734
.arg( numeric ? "=" : sensString )
707735
.arg( numeric
708-
? mFilterQuery->displayText().replace( "'", "''" )
736+
? value.replace( "'", "''" )
709737
:
710-
"%" + mFilterQuery->displayText().replace( "'", "''" ) + "%" ); // escape quotes
738+
"%" + value.replace( "'", "''" ) + "%" ); // escape quotes
711739
}
712740
}
713741

@@ -717,7 +745,9 @@ void QgsAttributeTableDialog::filterQueryChanged( const QString& query )
717745

718746
void QgsAttributeTableDialog::filterQueryAccepted()
719747
{
720-
if ( mFilterQuery->text().isEmpty() )
748+
if ( (mFilterQuery->isVisible() && mFilterQuery->text().isEmpty()) ||
749+
(mCurrentSearchWidgetWrapper!=0 && mCurrentSearchWidgetWrapper->widget()->isVisible()
750+
&& mCurrentSearchWidgetWrapper->value().toString().isEmpty() ))
721751
{
722752
filterShowAll();
723753
return;
@@ -731,7 +761,12 @@ void QgsAttributeTableDialog::setFilterExpression( QString filterString )
731761
mFilterButton->setDefaultAction( mActionAdvancedFilter );
732762
mFilterButton->setPopupMode( QToolButton::MenuButtonPopup );
733763
mCbxCaseSensitive->setVisible( false );
764+
734765
mFilterQuery->setVisible( true );
766+
if ( mCurrentSearchWidgetWrapper != 0 )
767+
{
768+
replaceSearchWidget(mCurrentSearchWidgetWrapper->widget(),mFilterQuery);
769+
}
735770
mApplyFilterButton->setVisible( true );
736771
mMainView->setFilterMode( QgsAttributeTableFilterModel::ShowFilteredList );
737772

‎src/app/qgsattributetabledialog.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "qgsattributedialog.h"
3030
#include "qgsvectorlayer.h" //QgsFeatureIds
3131
#include "qgsfieldmodel.h"
32+
#include "qgseditorwidgetwrapper.h"
3233

3334
class QDialogButtonBox;
3435
class QPushButton;
@@ -158,6 +159,10 @@ class APP_EXPORT QgsAttributeTableDialog : public QDialog, private Ui::QgsAttrib
158159
void updateTitle();
159160

160161
void updateButtonStatus( QString fieldName, bool isValid );
162+
163+
/* replace the search widget with a new one */
164+
void replaceSearchWidget(QWidget* oldw, QWidget* neww);
165+
161166
signals:
162167
/**
163168
* Informs that editing mode has been toggled
@@ -207,7 +212,8 @@ class APP_EXPORT QgsAttributeTableDialog : public QDialog, private Ui::QgsAttrib
207212
QgsVectorLayer* mLayer;
208213
QgsFieldModel* mFieldModel;
209214

210-
QgsRubberBand *mRubberBand;
215+
QgsRubberBand* mRubberBand;
216+
QgsEditorWidgetWrapper* mCurrentSearchWidgetWrapper;
211217
};
212218

213219
#endif

‎src/gui/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ attributetable/qgsfeatureselectionmodel.cpp
6060
attributetable/qgsgenericfeatureselectionmanager.cpp
6161
attributetable/qgsvectorlayerselectionmanager.cpp
6262

63+
editorwidgets/core/qgsdefaultsearchwidgetwrapper.cpp
6364
editorwidgets/core/qgseditorconfigwidget.cpp
6465
editorwidgets/core/qgseditorwidgetfactory.cpp
6566
editorwidgets/core/qgseditorwidgetregistry.cpp
@@ -407,6 +408,9 @@ SET(QGIS_GUI_MOC_HDRS
407408
effects/qgspainteffectwidget.h
408409
effects/qgseffectstackpropertieswidget.h
409410

411+
editorwidgets/core/qgsdefaultsearchwidgetwrapper.h
412+
editorwidgets/core/qgseditorconfigwidget.h
413+
editorwidgets/core/qgseditorwidgetregistry.h
410414
editorwidgets/core/qgseditorconfigwidget.h
411415
editorwidgets/core/qgseditorwidgetregistry.h
412416
editorwidgets/core/qgseditorwidgetwrapper.h
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/***************************************************************************
2+
qgstexteditwrapper.cpp
3+
--------------------------------------
4+
Date : 5.1.2014
5+
Copyright : (C) 2014 Matthias Kuhn
6+
Email : matthias dot kuhn at gmx dot ch
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 "qgsdefaultsearchwidgetwrapper.h"
17+
18+
#include "qgsfield.h"
19+
#include "qgsfieldvalidator.h"
20+
21+
#include <QSettings>
22+
#include <QSizePolicy>
23+
24+
QgsDefaultSearchWidgetWrapper::QgsDefaultSearchWidgetWrapper( QgsVectorLayer* vl, int fieldIdx, QWidget* editor, QWidget* parent )
25+
: QgsEditorWidgetWrapper( vl, fieldIdx, editor, parent )
26+
, mLineEdit( NULL )
27+
{
28+
}
29+
30+
QVariant QgsDefaultSearchWidgetWrapper::value()
31+
{
32+
return mLineEdit->text();
33+
}
34+
35+
QWidget* QgsDefaultSearchWidgetWrapper::createWidget( QWidget* parent )
36+
{
37+
return new QgsFilterLineEdit( parent );
38+
}
39+
40+
void QgsDefaultSearchWidgetWrapper::initWidget( QWidget* widget )
41+
{
42+
mLineEdit = qobject_cast<QgsFilterLineEdit*>( widget );
43+
mLineEdit->setSizePolicy(QSizePolicy ::Expanding , QSizePolicy ::Fixed );
44+
connect( widget, SIGNAL( textChanged( QString ) ), this, SLOT( valueChanged( QString ) ) );
45+
}
46+
47+
void QgsDefaultSearchWidgetWrapper::setValue( const QVariant& value )
48+
{
49+
mLineEdit->setText( value.toString() ); //FIXME no null check :(
50+
}
51+
52+
void QgsDefaultSearchWidgetWrapper::setEnabled( bool enabled )
53+
{
54+
mLineEdit->setReadOnly( !enabled );
55+
//if ( enabled )
56+
//mLineEdit->setPalette( mWritablePalette );
57+
//else
58+
//mLineEdit->setPalette( mReadOnlyPalette );
59+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/***************************************************************************
2+
qgsdefaultsearchwidgetwrapper.h
3+
--------------------------------------
4+
Date : 21.5.2015
5+
Copyright : (C) 2015 Karolina Alexiou
6+
Email : carolinegr 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+
#ifndef QGSDEFAULTSEARCHWIDGETWRAPPER_H
17+
#define QGSDEFAULTSEARCHWIDGETWRAPPER_H
18+
19+
#include "qgseditorwidgetwrapper.h"
20+
#include <qgsfilterlineedit.h>
21+
22+
23+
/**
24+
* Wraps a search widget. Default form is just a QgsLineFilterEdit
25+
*
26+
*/
27+
28+
class GUI_EXPORT QgsDefaultSearchWidgetWrapper : public QgsEditorWidgetWrapper
29+
{
30+
Q_OBJECT
31+
public:
32+
explicit QgsDefaultSearchWidgetWrapper( QgsVectorLayer* vl, int fieldIdx, QWidget* editor = 0, QWidget* parent = 0 );
33+
34+
// QgsEditorWidgetWrapper interface
35+
public:
36+
QVariant value() override;
37+
38+
protected:
39+
QWidget* createWidget( QWidget* parent ) override;
40+
void initWidget( QWidget* editor ) override;
41+
42+
public slots:
43+
void setValue( const QVariant& value ) override;
44+
void setEnabled( bool enabled ) override;
45+
46+
private:
47+
QgsFilterLineEdit* mLineEdit;
48+
};
49+
50+
#endif // QGSDEFAULTSEARCHWIDGETWRAPPER_H

‎src/gui/editorwidgets/core/qgseditorwidgetfactory.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,12 @@
1414
***************************************************************************/
1515

1616
#include "qgseditorwidgetfactory.h"
17+
#include "qgsdefaultsearchwidgetwrapper.h"
1718

1819
#include <QSettings>
1920

21+
class QgsDefaultSearchWidgetWrapper;
22+
2023
QgsEditorWidgetFactory::QgsEditorWidgetFactory( const QString& name )
2124
: mName( name )
2225
{
@@ -26,6 +29,15 @@ QgsEditorWidgetFactory::~QgsEditorWidgetFactory()
2629
{
2730
}
2831

32+
/** Override in own factory to get something different than the default (a simple QgsFilterLineEdit)
33+
*
34+
*/
35+
QgsEditorWidgetWrapper* QgsEditorWidgetFactory::createSearchWidget( QgsVectorLayer* vl, int fieldIdx, QWidget* parent )
36+
{
37+
38+
return new QgsDefaultSearchWidgetWrapper(vl, fieldIdx, 0, parent);
39+
}
40+
2941
QString QgsEditorWidgetFactory::name()
3042
{
3143
return mName;

‎src/gui/editorwidgets/core/qgseditorwidgetfactory.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include "qgseditorwidgetwrapper.h"
2020
#include "qgsapplication.h"
21+
#include "qgsdefaultsearchwidgetwrapper.h"
2122

2223
#include <QDomNode>
2324
#include <QMap>
@@ -60,6 +61,8 @@ class GUI_EXPORT QgsEditorWidgetFactory
6061
*/
6162
virtual QgsEditorWidgetWrapper* create( QgsVectorLayer* vl, int fieldIdx, QWidget* editor, QWidget* parent ) const = 0;
6263

64+
virtual QgsEditorWidgetWrapper* createSearchWidget( QgsVectorLayer* vl, int fieldIdx, QWidget* parent );
65+
6366
/**
6467
* Return The human readable identifier name of this widget type
6568
*

‎src/gui/editorwidgets/core/qgseditorwidgetregistry.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#include "qgseditorwidgetregistry.h"
1717

1818
#include "qgsattributeeditorcontext.h"
19-
#include "qgseditorwidgetfactory.h"
19+
//#include "qgseditorwidgetfactory.h"
2020
#include "qgslegacyhelpers.h"
2121
#include "qgsmessagelog.h"
2222
#include "qgsproject.h"
@@ -102,6 +102,25 @@ QgsEditorWidgetWrapper* QgsEditorWidgetRegistry::create( const QString& widgetId
102102
return 0;
103103
}
104104

105+
QgsEditorWidgetWrapper* QgsEditorWidgetRegistry::createSearchWidget( const QString& widgetId, QgsVectorLayer* vl, int fieldIdx, const QgsEditorWidgetConfig& config, QWidget* parent, const QgsAttributeEditorContext &context )
106+
{
107+
if ( mWidgetFactories.contains( widgetId ) )
108+
{
109+
QgsEditorWidgetWrapper* ww = mWidgetFactories[widgetId]->createSearchWidget( vl, fieldIdx, parent );
110+
111+
if ( ww )
112+
{
113+
ww->setConfig( config );
114+
ww->setContext( context );
115+
// Make sure that there is a widget created at this point
116+
// so setValue() et al won't crash
117+
ww->widget();
118+
return ww;
119+
}
120+
}
121+
return 0;
122+
}
123+
105124
QgsEditorConfigWidget* QgsEditorWidgetRegistry::createConfigWidget( const QString& widgetId, QgsVectorLayer* vl, int fieldIdx, QWidget* parent )
106125
{
107126
if ( mWidgetFactories.contains( widgetId ) )

‎src/gui/editorwidgets/core/qgseditorwidgetregistry.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,13 @@ class GUI_EXPORT QgsEditorWidgetRegistry : public QObject
8383
QWidget* parent,
8484
const QgsAttributeEditorContext& context = QgsAttributeEditorContext() );
8585

86+
QgsEditorWidgetWrapper* createSearchWidget( const QString& widgetId,
87+
QgsVectorLayer* vl,
88+
int fieldIdx,
89+
const QgsEditorWidgetConfig& config,
90+
QWidget* parent,
91+
const QgsAttributeEditorContext& context = QgsAttributeEditorContext() );
92+
8693
/**
8794
* Creates a configuration widget
8895
*

‎src/gui/editorwidgets/qgsvaluemapwidgetfactory.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ QgsEditorWidgetWrapper* QgsValueMapWidgetFactory::create( QgsVectorLayer* vl, in
2929
return new QgsValueMapWidgetWrapper( vl, fieldIdx, editor, parent );
3030
}
3131

32+
33+
QgsEditorWidgetWrapper* QgsValueMapWidgetFactory::createSearchWidget( QgsVectorLayer* vl, int fieldIdx, QWidget* parent )
34+
{
35+
return new QgsValueMapWidgetWrapper( vl, fieldIdx, 0, parent );
36+
}
37+
3238
QgsEditorConfigWidget* QgsValueMapWidgetFactory::configWidget( QgsVectorLayer* vl, int fieldIdx, QWidget* parent ) const
3339
{
3440
return new QgsValueMapConfigDlg( vl, fieldIdx, parent );

‎src/gui/editorwidgets/qgsvaluemapwidgetfactory.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class GUI_EXPORT QgsValueMapWidgetFactory : public QgsEditorWidgetFactory
2626
// QgsEditorWidgetFactory interface
2727
public:
2828
QgsEditorWidgetWrapper* create( QgsVectorLayer* vl, int fieldIdx, QWidget* editor, QWidget* parent ) const override;
29+
QgsEditorWidgetWrapper* createSearchWidget( QgsVectorLayer* vl, int fieldIdx, QWidget* parent ) override;
2930
QgsEditorConfigWidget* configWidget( QgsVectorLayer* vl, int fieldIdx, QWidget* parent ) const override;
3031
QgsEditorWidgetConfig readConfig( const QDomElement& configElement, QgsVectorLayer* layer, int fieldIdx ) override;
3132
void writeConfig( const QgsEditorWidgetConfig& config, QDomElement& configElement, QDomDocument& doc, const QgsVectorLayer* layer, int fieldIdx ) override;

‎src/ui/qgsattributetabledialog.ui

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -541,10 +541,19 @@
541541
</widget>
542542
</item>
543543
<item>
544-
<widget class="QgsFilterLineEdit" name="mFilterQuery"/>
545-
</item>
546-
<item>
547-
<widget class="QWidget" name="mSpacer" native="true"/>
544+
<widget class="QWidget" name="mFilterContainer" native="true">
545+
<layout class="QGridLayout" name="mFilterLayout">
546+
<property name="sizeConstraint">
547+
<enum>QLayout::SetDefaultConstraint</enum>
548+
</property>
549+
<property name="margin">
550+
<number>0</number>
551+
</property>
552+
<item row="0" column="0">
553+
<widget class="QgsFilterLineEdit" name="mFilterQuery"/>
554+
</item>
555+
</layout>
556+
</widget>
548557
</item>
549558
<item>
550559
<widget class="QToolButton" name="mApplyFilterButton">
@@ -656,7 +665,7 @@
656665
</widget>
657666
</item>
658667
<item>
659-
<widget class="QgsFieldExpressionWidget" name="mUpdateExpressionText" native="true">
668+
<widget class="QgsFieldExpressionWidget" name="mUpdateExpressionText">
660669
<property name="sizePolicy">
661670
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
662671
<horstretch>0</horstretch>

0 commit comments

Comments
 (0)
Please sign in to comment.