Skip to content

Commit

Permalink
[joins] prevent joining an already joined layer
Browse files Browse the repository at this point in the history
also fix crash when editing a join with all fields joined
  • Loading branch information
3nids committed Mar 10, 2015
1 parent 4bfbcb2 commit 95ebf45
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 75 deletions.
11 changes: 6 additions & 5 deletions src/app/qgsjoindialog.cpp
Expand Up @@ -25,7 +25,7 @@


#include <QStandardItemModel> #include <QStandardItemModel>


QgsJoinDialog::QgsJoinDialog( QgsVectorLayer* layer, QWidget * parent, Qt::WindowFlags f ) QgsJoinDialog::QgsJoinDialog( QgsVectorLayer* layer, QList<QgsMapLayer*> alreadyJoinedLayers, QWidget * parent, Qt::WindowFlags f )
: QDialog( parent, f ) : QDialog( parent, f )
, mLayer( layer ) , mLayer( layer )
{ {
Expand All @@ -35,12 +35,13 @@ QgsJoinDialog::QgsJoinDialog( QgsVectorLayer* layer, QWidget * parent, Qt::Windo
{ {
return; return;
} }
// adds self layer to the joined layer (cannot join to itself)
alreadyJoinedLayers.append( layer );


mTargetFieldComboBox->setLayer( mLayer ); mTargetFieldComboBox->setLayer( mLayer );
mJoinLayerComboBox->setExceptedLayerList( QList<QgsMapLayer*>() << mLayer ); mJoinLayerComboBox->setExceptedLayerList( alreadyJoinedLayers );
connect( mJoinLayerComboBox, SIGNAL( layerChanged( QgsMapLayer* ) ), mJoinFieldComboBox, SLOT( setLayer( QgsMapLayer* ) ) ); connect( mJoinLayerComboBox, SIGNAL( layerChanged( QgsMapLayer* ) ), mJoinFieldComboBox, SLOT( setLayer( QgsMapLayer* ) ) );
connect( mJoinLayerComboBox, SIGNAL( layerChanged( QgsMapLayer* ) ), this, SLOT( joinedLayerChanged( QgsMapLayer* ) ) ); connect( mJoinLayerComboBox, SIGNAL( layerChanged( QgsMapLayer* ) ), this, SLOT( joinedLayerChanged( QgsMapLayer* ) ) );
connect( mJoinFieldComboBox, SIGNAL( fieldChanged( QString ) ), this, SLOT( allowAttrIndexCreation() ) );


mCacheInMemoryCheckBox->setChecked( true ); mCacheInMemoryCheckBox->setChecked( true );
} }
Expand All @@ -66,14 +67,14 @@ void QgsJoinDialog::setJoinInfo( const QgsVectorJoinInfo& joinInfo )
} }


QStringList* lst = joinInfo.joinFieldNamesSubset(); QStringList* lst = joinInfo.joinFieldNamesSubset();
mUseJoinFieldsSubset->setChecked( lst->count() > 0 ); mUseJoinFieldsSubset->setChecked( lst && lst->count() > 0 );
QAbstractItemModel* model = mJoinFieldsSubsetView->model(); QAbstractItemModel* model = mJoinFieldsSubsetView->model();
if ( model ) if ( model )
{ {
for ( int i = 0; i < model->rowCount(); ++i ) for ( int i = 0; i < model->rowCount(); ++i )
{ {
QModelIndex index = model->index( i, 0 ); QModelIndex index = model->index( i, 0 );
if ( lst->contains( model->data( index, Qt::DisplayRole ).toString() ) ) if ( lst && lst->contains( model->data( index, Qt::DisplayRole ).toString() ) )
{ {
model->setData( index, Qt::Checked, Qt::CheckStateRole ); model->setData( index, Qt::Checked, Qt::CheckStateRole );
} }
Expand Down
2 changes: 1 addition & 1 deletion src/app/qgsjoindialog.h
Expand Up @@ -27,7 +27,7 @@ class APP_EXPORT QgsJoinDialog: public QDialog, private Ui::QgsJoinDialogBase
{ {
Q_OBJECT Q_OBJECT
public: public:
QgsJoinDialog( QgsVectorLayer* layer, QWidget * parent = 0, Qt::WindowFlags f = 0 ); QgsJoinDialog( QgsVectorLayer* layer, QList<QgsMapLayer*> alreadyJoinedLayers, QWidget * parent = 0, Qt::WindowFlags f = 0 );
~QgsJoinDialog(); ~QgsJoinDialog();


/** Configure the dialog for an existing join */ /** Configure the dialog for an existing join */
Expand Down
69 changes: 40 additions & 29 deletions src/app/qgsvectorlayerproperties.cpp
Expand Up @@ -1031,26 +1031,33 @@ void QgsVectorLayerProperties::showListOfStylesFromDatabase()


void QgsVectorLayerProperties::on_mButtonAddJoin_clicked() void QgsVectorLayerProperties::on_mButtonAddJoin_clicked()
{ {
QgsJoinDialog d( layer ); if ( !layer )
return;

QList<QgsMapLayer*> joinedLayers;
const QList< QgsVectorJoinInfo >& joins = layer->vectorJoins();
for ( int i = 0; i < joins.size(); ++i )
{
joinedLayers.append( QgsMapLayerRegistry::instance()->mapLayer( joins[i].joinLayerId ) );
}

QgsJoinDialog d( layer, joinedLayers );
if ( d.exec() == QDialog::Accepted ) if ( d.exec() == QDialog::Accepted )
{ {
QgsVectorJoinInfo info = d.joinInfo(); QgsVectorJoinInfo info = d.joinInfo();
if ( layer ) //create attribute index if possible
if ( d.createAttributeIndex() )
{ {
//create attribute index if possible QgsVectorLayer* joinLayer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( info.joinLayerId ) );
if ( d.createAttributeIndex() ) if ( joinLayer )
{ {
QgsVectorLayer* joinLayer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( info.joinLayerId ) ); joinLayer->dataProvider()->createAttributeIndex( joinLayer->pendingFields().indexFromName( info.joinFieldName ) );
if ( joinLayer )
{
joinLayer->dataProvider()->createAttributeIndex( joinLayer->pendingFields().indexFromName( info.joinFieldName ) );
}
} }
layer->addJoin( info );
addJoinToTreeWidget( info );
pbnQueryBuilder->setEnabled( layer && layer->dataProvider() && layer->dataProvider()->supportsSubsetString() &&
!layer->isEditable() && layer->vectorJoins().size() < 1 );
} }
layer->addJoin( info );
addJoinToTreeWidget( info );
pbnQueryBuilder->setEnabled( layer && layer->dataProvider() && layer->dataProvider()->supportsSubsetString() &&
!layer->isEditable() && layer->vectorJoins().size() < 1 );
mFieldsPropertiesDialog->init(); mFieldsPropertiesDialog->init();
} }
} }
Expand All @@ -1063,6 +1070,7 @@ void QgsVectorLayerProperties::on_mButtonEditJoin_clicked()
return; return;
} }


QList<QgsMapLayer*> joinedLayers;
QString joinLayerId = currentJoinItem->data( 0, Qt::UserRole ).toString(); QString joinLayerId = currentJoinItem->data( 0, Qt::UserRole ).toString();
const QList< QgsVectorJoinInfo >& joins = layer->vectorJoins(); const QList< QgsVectorJoinInfo >& joins = layer->vectorJoins();
int j = -1; int j = -1;
Expand All @@ -1071,17 +1079,22 @@ void QgsVectorLayerProperties::on_mButtonEditJoin_clicked()
if ( joins[i].joinLayerId == joinLayerId ) if ( joins[i].joinLayerId == joinLayerId )
{ {
j = i; j = i;
break; }
else
{
// remove already joined layers from possible list to be displayed in dialog
joinedLayers.append( QgsMapLayerRegistry::instance()->mapLayer( joins[i].joinLayerId ) );
} }
} }
if ( j == -1 ) if ( j == -1 )
{ {
return; return;
} }


QgsJoinDialog d( layer ); QgsJoinDialog d( layer, joinedLayers );
d.setJoinInfo( joins[j] ); d.setJoinInfo( joins[j] );



if ( d.exec() == QDialog::Accepted ) if ( d.exec() == QDialog::Accepted )
{ {
// remove old join // remove old join
Expand All @@ -1090,24 +1103,22 @@ void QgsVectorLayerProperties::on_mButtonEditJoin_clicked()


// add the new edited // add the new edited
QgsVectorJoinInfo info = d.joinInfo(); QgsVectorJoinInfo info = d.joinInfo();
if ( layer )
//create attribute index if possible
if ( d.createAttributeIndex() )
{ {
//create attribute index if possible QgsVectorLayer* joinLayer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( info.joinLayerId ) );
if ( d.createAttributeIndex() ) if ( joinLayer )
{ {
QgsVectorLayer* joinLayer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( info.joinLayerId ) ); joinLayer->dataProvider()->createAttributeIndex( joinLayer->pendingFields().indexFromName( info.joinFieldName ) );
if ( joinLayer )
{
joinLayer->dataProvider()->createAttributeIndex( joinLayer->pendingFields().indexFromName( info.joinFieldName ) );
}
} }
layer->addJoin( info );
addJoinToTreeWidget( info );

pbnQueryBuilder->setEnabled( layer && layer->dataProvider() && layer->dataProvider()->supportsSubsetString() &&
!layer->isEditable() && layer->vectorJoins().size() < 1 );
mFieldsPropertiesDialog->init();
} }
layer->addJoin( info );
addJoinToTreeWidget( info );

pbnQueryBuilder->setEnabled( layer && layer->dataProvider() && layer->dataProvider()->supportsSubsetString() &&
!layer->isEditable() && layer->vectorJoins().size() < 1 );
mFieldsPropertiesDialog->init();
} }
} }


Expand Down
4 changes: 2 additions & 2 deletions src/gui/qgsmaplayercombobox.h
Expand Up @@ -41,13 +41,13 @@ class GUI_EXPORT QgsMapLayerComboBox : public QComboBox
explicit QgsMapLayerComboBox( QWidget *parent = 0 ); explicit QgsMapLayerComboBox( QWidget *parent = 0 );


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


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


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


//! returns the list of excepted layers //! returns the list of excepted layers
QList<QgsMapLayer*> exceptedLayerList() const {return mProxyModel->exceptedLayerList();} QList<QgsMapLayer*> exceptedLayerList() const {return mProxyModel->exceptedLayerList();}
Expand Down
79 changes: 41 additions & 38 deletions src/ui/qgsjoindialogbase.ui
Expand Up @@ -7,49 +7,48 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>505</width> <width>505</width>
<height>460</height> <height>393</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Add vector join</string> <string>Add vector join</string>
</property> </property>
<layout class="QFormLayout" name="formLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="1" column="0"> <item row="0" column="0">
<widget class="QLabel" name="mJoinLayerLabel"> <widget class="QLabel" name="mJoinLayerLabel">
<property name="text"> <property name="text">
<string>Join layer</string> <string>Join layer</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="0"> <item row="0" column="1">
<widget class="QgsMapLayerComboBox" name="mJoinLayerComboBox">
<property name="filters">
<set>QgsMapLayerProxyModel::VectorLayer</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="mJoinFieldLabel"> <widget class="QLabel" name="mJoinFieldLabel">
<property name="text"> <property name="text">
<string>Join field</string> <string>Join field</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="0"> <item row="1" column="1">
<widget class="QgsFieldComboBox" name="mJoinFieldComboBox"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="mTargetFieldLabel"> <widget class="QLabel" name="mTargetFieldLabel">
<property name="text"> <property name="text">
<string>Target field</string> <string>Target field</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="0"> <item row="2" column="1">
<widget class="QCheckBox" name="mCacheInMemoryCheckBox"> <widget class="QgsFieldComboBox" name="mTargetFieldComboBox"/>
<property name="text">
<string>Cache join layer in virtual memory</string>
</property>
</widget>
</item> </item>
<item row="5" column="0" colspan="2"> <item row="5" column="0" colspan="2">
<widget class="QCheckBox" name="mCreateIndexCheckBox">
<property name="text">
<string>Create attribute index on join field</string>
</property>
</widget>
</item>
<item row="6" column="0" colspan="2">
<widget class="QgsCollapsibleGroupBox" name="mUseJoinFieldsSubset"> <widget class="QgsCollapsibleGroupBox" name="mUseJoinFieldsSubset">
<property name="title"> <property name="title">
<string>Choose which fields are joined</string> <string>Choose which fields are joined</string>
Expand All @@ -70,7 +69,7 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="7" column="0" colspan="2"> <item row="6" column="0" colspan="2">
<widget class="QgsCollapsibleGroupBox" name="mUseCustomPrefix"> <widget class="QgsCollapsibleGroupBox" name="mUseCustomPrefix">
<property name="title"> <property name="title">
<string>Custom field name prefix</string> <string>Custom field name prefix</string>
Expand All @@ -91,21 +90,14 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="9" column="0" colspan="2"> <item row="7" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="8" column="0">
<spacer name="verticalSpacer"> <spacer name="verticalSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>
<width>20</width> <width>20</width>
Expand All @@ -114,18 +106,29 @@
</property> </property>
</spacer> </spacer>
</item> </item>
<item row="1" column="1"> <item row="3" column="0" colspan="2">
<widget class="QgsMapLayerComboBox" name="mJoinLayerComboBox"> <widget class="QCheckBox" name="mCacheInMemoryCheckBox">
<property name="filters"> <property name="text">
<set>QgsMapLayerProxyModel::VectorLayer</set> <string>Cache join layer in virtual memory</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="4" column="0" colspan="2">
<widget class="QgsFieldComboBox" name="mJoinFieldComboBox"/> <widget class="QCheckBox" name="mCreateIndexCheckBox">
<property name="text">
<string>Create attribute index on join field</string>
</property>
</widget>
</item> </item>
<item row="3" column="1"> <item row="8" column="0" colspan="2">
<widget class="QgsFieldComboBox" name="mTargetFieldComboBox"/> <widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item> </item>
</layout> </layout>
</widget> </widget>
Expand Down

0 comments on commit 95ebf45

Please sign in to comment.