Skip to content
Permalink
Browse files

[joins] prevent joining an already joined layer

also fix crash when editing a join with all fields joined
  • Loading branch information
3nids committed Mar 10, 2015
1 parent 4bfbcb2 commit 95ebf45ee858d4e4224f60f1bf07c56b4d37d40e
@@ -25,7 +25,7 @@

#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 )
, mLayer( layer )
{
@@ -35,12 +35,13 @@ QgsJoinDialog::QgsJoinDialog( QgsVectorLayer* layer, QWidget * parent, Qt::Windo
{
return;
}
// adds self layer to the joined layer (cannot join to itself)
alreadyJoinedLayers.append( layer );

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* ) ), this, SLOT( joinedLayerChanged( QgsMapLayer* ) ) );
connect( mJoinFieldComboBox, SIGNAL( fieldChanged( QString ) ), this, SLOT( allowAttrIndexCreation() ) );

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

QStringList* lst = joinInfo.joinFieldNamesSubset();
mUseJoinFieldsSubset->setChecked( lst->count() > 0 );
mUseJoinFieldsSubset->setChecked( lst && lst->count() > 0 );
QAbstractItemModel* model = mJoinFieldsSubsetView->model();
if ( model )
{
for ( int i = 0; i < model->rowCount(); ++i )
{
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 );
}
@@ -27,7 +27,7 @@ class APP_EXPORT QgsJoinDialog: public QDialog, private Ui::QgsJoinDialogBase
{
Q_OBJECT
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();

/** Configure the dialog for an existing join */
@@ -1031,26 +1031,33 @@ void QgsVectorLayerProperties::showListOfStylesFromDatabase()

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 )
{
QgsVectorJoinInfo info = d.joinInfo();
if ( layer )
//create attribute index if possible
if ( d.createAttributeIndex() )
{
//create attribute index if possible
if ( d.createAttributeIndex() )
QgsVectorLayer* joinLayer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( info.joinLayerId ) );
if ( joinLayer )
{
QgsVectorLayer* joinLayer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( info.joinLayerId ) );
if ( joinLayer )
{
joinLayer->dataProvider()->createAttributeIndex( joinLayer->pendingFields().indexFromName( info.joinFieldName ) );
}
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();
}
}
@@ -1063,6 +1070,7 @@ void QgsVectorLayerProperties::on_mButtonEditJoin_clicked()
return;
}

QList<QgsMapLayer*> joinedLayers;
QString joinLayerId = currentJoinItem->data( 0, Qt::UserRole ).toString();
const QList< QgsVectorJoinInfo >& joins = layer->vectorJoins();
int j = -1;
@@ -1071,17 +1079,22 @@ void QgsVectorLayerProperties::on_mButtonEditJoin_clicked()
if ( joins[i].joinLayerId == joinLayerId )
{
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 )
{
return;
}

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


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

// add the new edited
QgsVectorJoinInfo info = d.joinInfo();
if ( layer )

//create attribute index if possible
if ( d.createAttributeIndex() )
{
//create attribute index if possible
if ( d.createAttributeIndex() )
QgsVectorLayer* joinLayer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( info.joinLayerId ) );
if ( joinLayer )
{
QgsVectorLayer* joinLayer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( info.joinLayerId ) );
if ( joinLayer )
{
joinLayer->dataProvider()->createAttributeIndex( joinLayer->pendingFields().indexFromName( info.joinFieldName ) );
}
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();
}
}

@@ -41,13 +41,13 @@ class GUI_EXPORT QgsMapLayerComboBox : public QComboBox
explicit QgsMapLayerComboBox( QWidget *parent = 0 );

//! 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
QgsMapLayerProxyModel::Filters filters() const { return mProxyModel->filters(); }

//! 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
QList<QgsMapLayer*> exceptedLayerList() const {return mProxyModel->exceptedLayerList();}
@@ -7,49 +7,48 @@
<x>0</x>
<y>0</y>
<width>505</width>
<height>460</height>
<height>393</height>
</rect>
</property>
<property name="windowTitle">
<string>Add vector join</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="1" column="0">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="mJoinLayerLabel">
<property name="text">
<string>Join layer</string>
</property>
</widget>
</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">
<property name="text">
<string>Join field</string>
</property>
</widget>
</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">
<property name="text">
<string>Target field</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="mCacheInMemoryCheckBox">
<property name="text">
<string>Cache join layer in virtual memory</string>
</property>
</widget>
<item row="2" column="1">
<widget class="QgsFieldComboBox" name="mTargetFieldComboBox"/>
</item>
<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">
<property name="title">
<string>Choose which fields are joined</string>
@@ -70,7 +69,7 @@
</layout>
</widget>
</item>
<item row="7" column="0" colspan="2">
<item row="6" column="0" colspan="2">
<widget class="QgsCollapsibleGroupBox" name="mUseCustomPrefix">
<property name="title">
<string>Custom field name prefix</string>
@@ -91,21 +90,14 @@
</layout>
</widget>
</item>
<item row="9" column="0" colspan="2">
<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">
<item row="7" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
@@ -114,18 +106,29 @@
</property>
</spacer>
</item>
<item row="1" column="1">
<widget class="QgsMapLayerComboBox" name="mJoinLayerComboBox">
<property name="filters">
<set>QgsMapLayerProxyModel::VectorLayer</set>
<item row="3" column="0" colspan="2">
<widget class="QCheckBox" name="mCacheInMemoryCheckBox">
<property name="text">
<string>Cache join layer in virtual memory</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QgsFieldComboBox" name="mJoinFieldComboBox"/>
<item row="4" 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="3" column="1">
<widget class="QgsFieldComboBox" name="mTargetFieldComboBox"/>
<item row="8" column="0" colspan="2">
<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>
</layout>
</widget>

0 comments on commit 95ebf45

Please sign in to comment.
You can’t perform that action at this time.