Skip to content

Commit 57c2307

Browse files
committed
[FIX #7543] Dual View Table/Form: Preview column not saved in project
1 parent 9c9dd2b commit 57c2307

File tree

6 files changed

+138
-36
lines changed

6 files changed

+138
-36
lines changed

src/core/qgsvectorlayer.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1511,6 +1511,18 @@ bool QgsVectorLayer::readXml( const QDomNode& layer_node )
15111511
updateFields();
15121512
connect( QgsMapLayerRegistry::instance(), SIGNAL( layerWillBeRemoved( QString ) ), this, SLOT( checkJoinLayerRemove( QString ) ) );
15131513

1514+
QDomNode prevExpNode = layer_node.namedItem( "previewExpression" );
1515+
1516+
if( prevExpNode.isNull() )
1517+
{
1518+
mDisplayExpression = "";
1519+
}
1520+
else
1521+
{
1522+
QDomElement prevExpElem = prevExpNode.toElement();
1523+
mDisplayExpression = prevExpElem.text();
1524+
}
1525+
15141526
QString errorMsg;
15151527
if ( !readSymbology( layer_node, errorMsg ) )
15161528
{
@@ -1658,6 +1670,12 @@ bool QgsVectorLayer::writeXml( QDomNode & layer_node,
16581670
layer_node.appendChild( provider );
16591671
}
16601672

1673+
// save preview expression
1674+
QDomElement prevExpElem = document.createElement( "previewExpression" );
1675+
QDomText prevExpText = document.createTextNode( mDisplayExpression );
1676+
prevExpElem.appendChild( prevExpText );
1677+
layer_node.appendChild( prevExpElem );
1678+
16611679
//save joins
16621680
mJoinBuffer->writeXml( layer_node, document );
16631681

@@ -2790,6 +2808,16 @@ const QString QgsVectorLayer::displayField() const
27902808
return mDisplayField;
27912809
}
27922810

2811+
void QgsVectorLayer::setDisplayExpression( const QString displayExpression )
2812+
{
2813+
mDisplayExpression = displayExpression;
2814+
}
2815+
2816+
const QString QgsVectorLayer::displayExpression()
2817+
{
2818+
return mDisplayExpression;
2819+
}
2820+
27932821
bool QgsVectorLayer::isEditable() const
27942822
{
27952823
return ( mEditBuffer && mDataProvider );

src/core/qgsvectorlayer.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,24 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
257257
/** Returns the primary display field name used in the identify results dialog */
258258
const QString displayField() const;
259259

260+
/** Set the preview expression, used to create a human readable preview string.
261+
* Used e.g. in the attribute table feature list. Uses @link {QgsExpression}.
262+
*
263+
* @param previewExpression The expression which will be used to preview features
264+
* for this layer
265+
* @note added in 2.0
266+
*/
267+
void setDisplayExpression( const QString displayExpression );
268+
269+
/**
270+
* Get the preview expression, used to create a human readable preview string.
271+
* Uses @link {QgsExpression}.
272+
*
273+
* @return The expression which will be used to preview features for this layer
274+
* @note added in 2.0
275+
*/
276+
const QString displayExpression();
277+
260278
/** Returns the data provider */
261279
QgsVectorDataProvider* dataProvider();
262280

@@ -973,6 +991,9 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
973991
/** index of the primary label field */
974992
QString mDisplayField;
975993

994+
/** the preview expression used to generate a human readable preview string for features */
995+
QString mDisplayExpression;
996+
976997
/** Data provider key */
977998
QString mProviderKey;
978999

src/gui/attributetable/qgsdualview.cpp

Lines changed: 63 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ QgsDualView::QgsDualView( QWidget* parent )
4646
// Connect layer list preview signals
4747
connect( mActionExpressionPreview, SIGNAL( triggered() ), SLOT( previewExpressionBuilder() ) );
4848
connect( mPreviewActionMapper, SIGNAL( mapped( QObject* ) ), SLOT( previewColumnChanged( QObject* ) ) );
49+
connect( mFeatureList, SIGNAL( displayExpressionChanged(QString) ), this, SLOT( previewExpressionChanged(QString) ) );
4950
}
5051

5152
QgsDualView::~QgsDualView()
@@ -76,6 +77,54 @@ void QgsDualView::init( QgsVectorLayer* layer, QgsMapCanvas* mapCanvas, QgsDista
7677

7778
void QgsDualView::columnBoxInit()
7879
{
80+
// load fields
81+
QList<QgsField> fields = mLayerCache->layer()->pendingFields().toList();
82+
83+
// default expression: saved value
84+
QString displayExpression = mLayerCache->layer()->displayExpression();
85+
86+
// if no display expression is saved: use display field instead
87+
if ( displayExpression == "" )
88+
{
89+
displayExpression = mLayerCache->layer()->displayField();
90+
}
91+
92+
// if neither diaplay expression nor display field is saved...
93+
if ( displayExpression == "" )
94+
{
95+
QgsAttributeList pkAttrs = mLayerCache->layer()->pendingPkAttributesList();
96+
97+
if ( pkAttrs.size() > 0 )
98+
{
99+
// ... If there are primary key(s) defined
100+
QStringList pkFields;
101+
102+
foreach ( int attr, pkAttrs )
103+
{
104+
pkFields.append( "\"" + fields[attr].name() + "\"" );
105+
}
106+
107+
displayExpression = pkFields.join( "||', '||" );
108+
}
109+
else if ( fields.size() > 0 )
110+
{
111+
// ... concat all fields
112+
QStringList fieldNames;
113+
foreach ( QgsField field, fields )
114+
{
115+
fieldNames.append( "\"" + field.name() + "\"" );
116+
}
117+
118+
displayExpression = fieldNames.join( "||', '||" );
119+
}
120+
else
121+
{
122+
// ... there isn't really much to display
123+
displayExpression = "[Please define preview text]";
124+
}
125+
}
126+
127+
// now initialise the menu
79128
QList< QAction* > previewActions = mFeatureListPreviewButton->actions();
80129
foreach ( QAction* a, previewActions )
81130
{
@@ -89,8 +138,6 @@ void QgsDualView::columnBoxInit()
89138
mFeatureListPreviewButton->addAction( mActionExpressionPreview );
90139
mFeatureListPreviewButton->addAction( mActionPreviewColumnsMenu );
91140

92-
QList<QgsField> fields = mLayerCache->layer()->pendingFields().toList();
93-
94141
foreach ( const QgsField field, fields )
95142
{
96143
if ( mLayerCache->layer()->editType( mLayerCache->layer()->fieldNameIndex( field.name() ) ) != QgsVectorLayer::Hidden )
@@ -104,45 +151,18 @@ void QgsDualView::columnBoxInit()
104151
connect( previewAction, SIGNAL( triggered() ), mPreviewActionMapper, SLOT( map() ) );
105152
mPreviewColumnsMenu->addAction( previewAction );
106153

107-
if ( text == mLayerCache->layer()->displayField() )
154+
if ( text == displayExpression )
108155
{
109156
mFeatureListPreviewButton->setDefaultAction( previewAction );
110157
}
111158
}
112159
}
113160

114-
// Most likely no displayField is defined
115-
// Join primary key fields
161+
// If there is no single field found as preview
116162
if ( !mFeatureListPreviewButton->defaultAction() )
117163
{
164+
mFeatureList->setDisplayExpression( displayExpression );
118165
mFeatureListPreviewButton->setDefaultAction( mActionExpressionPreview );
119-
QgsAttributeList pkAttrs = mLayerCache->layer()->pendingPkAttributesList();
120-
// If there is a primary key defined
121-
if ( pkAttrs.size() > 0 )
122-
{
123-
QStringList pkFields;
124-
125-
foreach ( int attr, pkAttrs )
126-
{
127-
pkFields.append( "\"" + fields[attr].name() + "\"" );
128-
}
129-
130-
mFeatureList->setDisplayExpression( pkFields.join( "||', '||" ) );
131-
}
132-
else if ( fields.size() > 0 )
133-
{
134-
QStringList fieldNames;
135-
foreach ( QgsField field, fields )
136-
{
137-
fieldNames.append( "\"" + field.name() + "\"" );
138-
}
139-
140-
mFeatureList->setDisplayExpression( fieldNames.join( "||', '||" ) );
141-
}
142-
else
143-
{
144-
mFeatureList->setDisplayExpression( "[Please define preview text]" );
145-
}
146166
}
147167
else
148168
{
@@ -193,6 +213,7 @@ void QgsDualView::initModels( QgsMapCanvas* mapCanvas )
193213
mFilterModel = new QgsAttributeTableFilterModel( mapCanvas, mMasterModel, mMasterModel );
194214

195215
connect( mFilterModel, SIGNAL( filterInvalidated() ), this, SIGNAL( filterChanged() ) );
216+
connect( mFeatureList, SIGNAL( displayExpressionChanged(QString) ), this, SIGNAL( displayExpressionChanged(QString) ) );
196217

197218
mFeatureListModel = new QgsFeatureListModel( mFilterModel, mFilterModel );
198219
}
@@ -275,9 +296,11 @@ void QgsDualView::previewColumnChanged( QObject* action )
275296
.arg( mFeatureList->parserErrorString() )
276297
);
277298
}
278-
279-
mFeatureListPreviewButton->setDefaultAction( previewAction );
280-
mFeatureListPreviewButton->setPopupMode( QToolButton::InstantPopup );
299+
else
300+
{
301+
mFeatureListPreviewButton->setDefaultAction( previewAction );
302+
mFeatureListPreviewButton->setPopupMode( QToolButton::InstantPopup );
303+
}
281304
}
282305

283306
Q_ASSERT( previewAction );
@@ -328,6 +351,11 @@ void QgsDualView::viewWillShowContextMenu( QMenu* menu, QModelIndex atIndex )
328351
menu->addAction( tr( "Open form" ), a, SLOT( featureForm() ) );
329352
}
330353

354+
void QgsDualView::previewExpressionChanged( const QString expression )
355+
{
356+
mLayerCache->layer()->setDisplayExpression( expression );
357+
}
358+
331359
void QgsDualView::setFilteredFeatures( QgsFeatureIds filteredFeatures )
332360
{
333361
mFilterModel->setFilteredFeatures( filteredFeatures );

src/gui/attributetable/qgsdualview.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,15 @@ class GUI_EXPORT QgsDualView : public QStackedWidget, private Ui::QgsDualViewBas
9898
void setCurrentEditSelection( const QgsFeatureIds& fids );
9999

100100
signals:
101+
/**
102+
* Is emitted, whenever the display expression is successfully changed
103+
* @param The expression that was applied
104+
*/
105+
void displayExpressionChanged( const QString expression );
106+
107+
/**
108+
* Is emitted, whenever the filter changes
109+
*/
101110
void filterChanged();
102111

103112
private slots:
@@ -114,6 +123,8 @@ class GUI_EXPORT QgsDualView : public QStackedWidget, private Ui::QgsDualViewBas
114123

115124
void viewWillShowContextMenu( QMenu* menu, QModelIndex atIndex );
116125

126+
void previewExpressionChanged( const QString expression );
127+
117128
/**
118129
* Will be called periodically, when loading layers from slow data providers.
119130
*

src/gui/attributetable/qgsfeaturelistview.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,15 @@ void QgsFeatureListView::setModel( QgsFeatureListModel* featureListModel )
7373

7474
bool QgsFeatureListView::setDisplayExpression( const QString expression )
7575
{
76-
return mModel->setDisplayExpression( expression );
76+
if ( mModel->setDisplayExpression( expression ) )
77+
{
78+
emit displayExpressionChanged( expression );
79+
return true;
80+
}
81+
else
82+
{
83+
return false;
84+
}
7785
}
7886

7987
const QString& QgsFeatureListView::displayExpression() const

src/gui/attributetable/qgsfeaturelistview.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,12 @@ class GUI_EXPORT QgsFeatureListView : public QListView
111111
*/
112112
void currentEditSelectionChanged( QgsFeature &feat );
113113

114+
/**
115+
* Is emitted, whenever the display expression is successfully changed
116+
* @param The expression that was applied
117+
*/
118+
void displayExpressionChanged( const QString expression );
119+
114120
public slots:
115121
/**
116122
* Set the feature(s) to be edited

0 commit comments

Comments
 (0)