Skip to content

Commit 95ebf45

Browse files
committed
[joins] prevent joining an already joined layer
also fix crash when editing a join with all fields joined
1 parent 4bfbcb2 commit 95ebf45

5 files changed

+90
-75
lines changed

src/app/qgsjoindialog.cpp

+6-5
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
#include <QStandardItemModel>
2727

28-
QgsJoinDialog::QgsJoinDialog( QgsVectorLayer* layer, QWidget * parent, Qt::WindowFlags f )
28+
QgsJoinDialog::QgsJoinDialog( QgsVectorLayer* layer, QList<QgsMapLayer*> alreadyJoinedLayers, QWidget * parent, Qt::WindowFlags f )
2929
: QDialog( parent, f )
3030
, mLayer( layer )
3131
{
@@ -35,12 +35,13 @@ QgsJoinDialog::QgsJoinDialog( QgsVectorLayer* layer, QWidget * parent, Qt::Windo
3535
{
3636
return;
3737
}
38+
// adds self layer to the joined layer (cannot join to itself)
39+
alreadyJoinedLayers.append( layer );
3840

3941
mTargetFieldComboBox->setLayer( mLayer );
40-
mJoinLayerComboBox->setExceptedLayerList( QList<QgsMapLayer*>() << mLayer );
42+
mJoinLayerComboBox->setExceptedLayerList( alreadyJoinedLayers );
4143
connect( mJoinLayerComboBox, SIGNAL( layerChanged( QgsMapLayer* ) ), mJoinFieldComboBox, SLOT( setLayer( QgsMapLayer* ) ) );
4244
connect( mJoinLayerComboBox, SIGNAL( layerChanged( QgsMapLayer* ) ), this, SLOT( joinedLayerChanged( QgsMapLayer* ) ) );
43-
connect( mJoinFieldComboBox, SIGNAL( fieldChanged( QString ) ), this, SLOT( allowAttrIndexCreation() ) );
4445

4546
mCacheInMemoryCheckBox->setChecked( true );
4647
}
@@ -66,14 +67,14 @@ void QgsJoinDialog::setJoinInfo( const QgsVectorJoinInfo& joinInfo )
6667
}
6768

6869
QStringList* lst = joinInfo.joinFieldNamesSubset();
69-
mUseJoinFieldsSubset->setChecked( lst->count() > 0 );
70+
mUseJoinFieldsSubset->setChecked( lst && lst->count() > 0 );
7071
QAbstractItemModel* model = mJoinFieldsSubsetView->model();
7172
if ( model )
7273
{
7374
for ( int i = 0; i < model->rowCount(); ++i )
7475
{
7576
QModelIndex index = model->index( i, 0 );
76-
if ( lst->contains( model->data( index, Qt::DisplayRole ).toString() ) )
77+
if ( lst && lst->contains( model->data( index, Qt::DisplayRole ).toString() ) )
7778
{
7879
model->setData( index, Qt::Checked, Qt::CheckStateRole );
7980
}

src/app/qgsjoindialog.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class APP_EXPORT QgsJoinDialog: public QDialog, private Ui::QgsJoinDialogBase
2727
{
2828
Q_OBJECT
2929
public:
30-
QgsJoinDialog( QgsVectorLayer* layer, QWidget * parent = 0, Qt::WindowFlags f = 0 );
30+
QgsJoinDialog( QgsVectorLayer* layer, QList<QgsMapLayer*> alreadyJoinedLayers, QWidget * parent = 0, Qt::WindowFlags f = 0 );
3131
~QgsJoinDialog();
3232

3333
/** Configure the dialog for an existing join */

src/app/qgsvectorlayerproperties.cpp

+40-29
Original file line numberDiff line numberDiff line change
@@ -1031,26 +1031,33 @@ void QgsVectorLayerProperties::showListOfStylesFromDatabase()
10311031

10321032
void QgsVectorLayerProperties::on_mButtonAddJoin_clicked()
10331033
{
1034-
QgsJoinDialog d( layer );
1034+
if ( !layer )
1035+
return;
1036+
1037+
QList<QgsMapLayer*> joinedLayers;
1038+
const QList< QgsVectorJoinInfo >& joins = layer->vectorJoins();
1039+
for ( int i = 0; i < joins.size(); ++i )
1040+
{
1041+
joinedLayers.append( QgsMapLayerRegistry::instance()->mapLayer( joins[i].joinLayerId ) );
1042+
}
1043+
1044+
QgsJoinDialog d( layer, joinedLayers );
10351045
if ( d.exec() == QDialog::Accepted )
10361046
{
10371047
QgsVectorJoinInfo info = d.joinInfo();
1038-
if ( layer )
1048+
//create attribute index if possible
1049+
if ( d.createAttributeIndex() )
10391050
{
1040-
//create attribute index if possible
1041-
if ( d.createAttributeIndex() )
1051+
QgsVectorLayer* joinLayer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( info.joinLayerId ) );
1052+
if ( joinLayer )
10421053
{
1043-
QgsVectorLayer* joinLayer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( info.joinLayerId ) );
1044-
if ( joinLayer )
1045-
{
1046-
joinLayer->dataProvider()->createAttributeIndex( joinLayer->pendingFields().indexFromName( info.joinFieldName ) );
1047-
}
1054+
joinLayer->dataProvider()->createAttributeIndex( joinLayer->pendingFields().indexFromName( info.joinFieldName ) );
10481055
}
1049-
layer->addJoin( info );
1050-
addJoinToTreeWidget( info );
1051-
pbnQueryBuilder->setEnabled( layer && layer->dataProvider() && layer->dataProvider()->supportsSubsetString() &&
1052-
!layer->isEditable() && layer->vectorJoins().size() < 1 );
10531056
}
1057+
layer->addJoin( info );
1058+
addJoinToTreeWidget( info );
1059+
pbnQueryBuilder->setEnabled( layer && layer->dataProvider() && layer->dataProvider()->supportsSubsetString() &&
1060+
!layer->isEditable() && layer->vectorJoins().size() < 1 );
10541061
mFieldsPropertiesDialog->init();
10551062
}
10561063
}
@@ -1063,6 +1070,7 @@ void QgsVectorLayerProperties::on_mButtonEditJoin_clicked()
10631070
return;
10641071
}
10651072

1073+
QList<QgsMapLayer*> joinedLayers;
10661074
QString joinLayerId = currentJoinItem->data( 0, Qt::UserRole ).toString();
10671075
const QList< QgsVectorJoinInfo >& joins = layer->vectorJoins();
10681076
int j = -1;
@@ -1071,17 +1079,22 @@ void QgsVectorLayerProperties::on_mButtonEditJoin_clicked()
10711079
if ( joins[i].joinLayerId == joinLayerId )
10721080
{
10731081
j = i;
1074-
break;
1082+
}
1083+
else
1084+
{
1085+
// remove already joined layers from possible list to be displayed in dialog
1086+
joinedLayers.append( QgsMapLayerRegistry::instance()->mapLayer( joins[i].joinLayerId ) );
10751087
}
10761088
}
10771089
if ( j == -1 )
10781090
{
10791091
return;
10801092
}
10811093

1082-
QgsJoinDialog d( layer );
1094+
QgsJoinDialog d( layer, joinedLayers );
10831095
d.setJoinInfo( joins[j] );
10841096

1097+
10851098
if ( d.exec() == QDialog::Accepted )
10861099
{
10871100
// remove old join
@@ -1090,24 +1103,22 @@ void QgsVectorLayerProperties::on_mButtonEditJoin_clicked()
10901103

10911104
// add the new edited
10921105
QgsVectorJoinInfo info = d.joinInfo();
1093-
if ( layer )
1106+
1107+
//create attribute index if possible
1108+
if ( d.createAttributeIndex() )
10941109
{
1095-
//create attribute index if possible
1096-
if ( d.createAttributeIndex() )
1110+
QgsVectorLayer* joinLayer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( info.joinLayerId ) );
1111+
if ( joinLayer )
10971112
{
1098-
QgsVectorLayer* joinLayer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( info.joinLayerId ) );
1099-
if ( joinLayer )
1100-
{
1101-
joinLayer->dataProvider()->createAttributeIndex( joinLayer->pendingFields().indexFromName( info.joinFieldName ) );
1102-
}
1113+
joinLayer->dataProvider()->createAttributeIndex( joinLayer->pendingFields().indexFromName( info.joinFieldName ) );
11031114
}
1104-
layer->addJoin( info );
1105-
addJoinToTreeWidget( info );
1106-
1107-
pbnQueryBuilder->setEnabled( layer && layer->dataProvider() && layer->dataProvider()->supportsSubsetString() &&
1108-
!layer->isEditable() && layer->vectorJoins().size() < 1 );
1109-
mFieldsPropertiesDialog->init();
11101115
}
1116+
layer->addJoin( info );
1117+
addJoinToTreeWidget( info );
1118+
1119+
pbnQueryBuilder->setEnabled( layer && layer->dataProvider() && layer->dataProvider()->supportsSubsetString() &&
1120+
!layer->isEditable() && layer->vectorJoins().size() < 1 );
1121+
mFieldsPropertiesDialog->init();
11111122
}
11121123
}
11131124

src/gui/qgsmaplayercombobox.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,13 @@ class GUI_EXPORT QgsMapLayerComboBox : public QComboBox
4141
explicit QgsMapLayerComboBox( QWidget *parent = 0 );
4242

4343
//! setFilters allows fitering according to layer type and/or geometry type.
44-
void setFilters( QgsMapLayerProxyModel::Filters filters ) { mProxyModel->setFilters( filters ); }
44+
void setFilters( QgsMapLayerProxyModel::Filters filters ) { mProxyModel->setFilters( filters ); }
4545

4646
//! currently used filter on list layers
4747
QgsMapLayerProxyModel::Filters filters() const { return mProxyModel->filters(); }
4848

4949
//! except a list of layers not to be listed
50-
void setExceptedLayerList( QList<QgsMapLayer*> layerList ) { mProxyModel->setExceptedLayerList( layerList ); }
50+
void setExceptedLayerList( QList<QgsMapLayer*> layerList ) { mProxyModel->setExceptedLayerList( layerList );}
5151

5252
//! returns the list of excepted layers
5353
QList<QgsMapLayer*> exceptedLayerList() const {return mProxyModel->exceptedLayerList();}

src/ui/qgsjoindialogbase.ui

+41-38
Original file line numberDiff line numberDiff line change
@@ -7,49 +7,48 @@
77
<x>0</x>
88
<y>0</y>
99
<width>505</width>
10-
<height>460</height>
10+
<height>393</height>
1111
</rect>
1212
</property>
1313
<property name="windowTitle">
1414
<string>Add vector join</string>
1515
</property>
16-
<layout class="QFormLayout" name="formLayout">
17-
<item row="1" column="0">
16+
<layout class="QGridLayout" name="gridLayout">
17+
<item row="0" column="0">
1818
<widget class="QLabel" name="mJoinLayerLabel">
1919
<property name="text">
2020
<string>Join layer</string>
2121
</property>
2222
</widget>
2323
</item>
24-
<item row="2" column="0">
24+
<item row="0" column="1">
25+
<widget class="QgsMapLayerComboBox" name="mJoinLayerComboBox">
26+
<property name="filters">
27+
<set>QgsMapLayerProxyModel::VectorLayer</set>
28+
</property>
29+
</widget>
30+
</item>
31+
<item row="1" column="0">
2532
<widget class="QLabel" name="mJoinFieldLabel">
2633
<property name="text">
2734
<string>Join field</string>
2835
</property>
2936
</widget>
3037
</item>
31-
<item row="3" column="0">
38+
<item row="1" column="1">
39+
<widget class="QgsFieldComboBox" name="mJoinFieldComboBox"/>
40+
</item>
41+
<item row="2" column="0">
3242
<widget class="QLabel" name="mTargetFieldLabel">
3343
<property name="text">
3444
<string>Target field</string>
3545
</property>
3646
</widget>
3747
</item>
38-
<item row="4" column="0">
39-
<widget class="QCheckBox" name="mCacheInMemoryCheckBox">
40-
<property name="text">
41-
<string>Cache join layer in virtual memory</string>
42-
</property>
43-
</widget>
48+
<item row="2" column="1">
49+
<widget class="QgsFieldComboBox" name="mTargetFieldComboBox"/>
4450
</item>
4551
<item row="5" column="0" colspan="2">
46-
<widget class="QCheckBox" name="mCreateIndexCheckBox">
47-
<property name="text">
48-
<string>Create attribute index on join field</string>
49-
</property>
50-
</widget>
51-
</item>
52-
<item row="6" column="0" colspan="2">
5352
<widget class="QgsCollapsibleGroupBox" name="mUseJoinFieldsSubset">
5453
<property name="title">
5554
<string>Choose which fields are joined</string>
@@ -70,7 +69,7 @@
7069
</layout>
7170
</widget>
7271
</item>
73-
<item row="7" column="0" colspan="2">
72+
<item row="6" column="0" colspan="2">
7473
<widget class="QgsCollapsibleGroupBox" name="mUseCustomPrefix">
7574
<property name="title">
7675
<string>Custom field name prefix</string>
@@ -91,21 +90,14 @@
9190
</layout>
9291
</widget>
9392
</item>
94-
<item row="9" column="0" colspan="2">
95-
<widget class="QDialogButtonBox" name="buttonBox">
96-
<property name="orientation">
97-
<enum>Qt::Horizontal</enum>
98-
</property>
99-
<property name="standardButtons">
100-
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
101-
</property>
102-
</widget>
103-
</item>
104-
<item row="8" column="0">
93+
<item row="7" column="0">
10594
<spacer name="verticalSpacer">
10695
<property name="orientation">
10796
<enum>Qt::Vertical</enum>
10897
</property>
98+
<property name="sizeType">
99+
<enum>QSizePolicy::Expanding</enum>
100+
</property>
109101
<property name="sizeHint" stdset="0">
110102
<size>
111103
<width>20</width>
@@ -114,18 +106,29 @@
114106
</property>
115107
</spacer>
116108
</item>
117-
<item row="1" column="1">
118-
<widget class="QgsMapLayerComboBox" name="mJoinLayerComboBox">
119-
<property name="filters">
120-
<set>QgsMapLayerProxyModel::VectorLayer</set>
109+
<item row="3" column="0" colspan="2">
110+
<widget class="QCheckBox" name="mCacheInMemoryCheckBox">
111+
<property name="text">
112+
<string>Cache join layer in virtual memory</string>
121113
</property>
122114
</widget>
123115
</item>
124-
<item row="2" column="1">
125-
<widget class="QgsFieldComboBox" name="mJoinFieldComboBox"/>
116+
<item row="4" column="0" colspan="2">
117+
<widget class="QCheckBox" name="mCreateIndexCheckBox">
118+
<property name="text">
119+
<string>Create attribute index on join field</string>
120+
</property>
121+
</widget>
126122
</item>
127-
<item row="3" column="1">
128-
<widget class="QgsFieldComboBox" name="mTargetFieldComboBox"/>
123+
<item row="8" column="0" colspan="2">
124+
<widget class="QDialogButtonBox" name="buttonBox">
125+
<property name="orientation">
126+
<enum>Qt::Horizontal</enum>
127+
</property>
128+
<property name="standardButtons">
129+
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
130+
</property>
131+
</widget>
129132
</item>
130133
</layout>
131134
</widget>

0 commit comments

Comments
 (0)