Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Allow adding a new entry from the relation reference widget
  • Loading branch information
m-kuhn committed Apr 6, 2016
1 parent 8f7a6aa commit 226339c
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 44 deletions.
9 changes: 9 additions & 0 deletions python/gui/editorwidgets/qgsrelationreferencewidget.sip
Expand Up @@ -75,6 +75,15 @@ class QgsRelationReferenceWidget : QWidget
* @note added in QGIS 2.16
*/
void showIndeterminateState();
/**
* Determines if a button for adding new features should be shown.
*/
bool allowAddFeatures() const;

/**
* Determines if a button for adding new features should be shown.
*/
void setAllowAddFeatures( bool allowAddFeatures );

public slots:
//! open the form of the related feature in a new dialog
Expand Down
20 changes: 12 additions & 8 deletions src/gui/editorwidgets/qgsrelationreferenceconfigdlg.cpp
Expand Up @@ -59,44 +59,47 @@ void QgsRelationReferenceConfigDlg::setConfig( const QMap<QString, QVariant>& co
{
if ( config.contains( "AllowNULL" ) )
{
mCbxAllowNull->setChecked( config[ "AllowNULL" ].toBool() );
mCbxAllowNull->setChecked( config.value( "AllowNULL" ).toBool() );
}

if ( config.contains( "OrderByValue" ) )
{
mCbxOrderByValue->setChecked( config[ "OrderByValue" ].toBool() );
mCbxOrderByValue->setChecked( config.value( "OrderByValue" ).toBool() );
}

if ( config.contains( "ShowForm" ) )
{
mCbxShowForm->setChecked( config[ "ShowForm" ].toBool() );
mCbxShowForm->setChecked( config.value( "ShowForm" ).toBool() );
}

if ( config.contains( "Relation" ) )
{
mComboRelation->setCurrentIndex( mComboRelation->findData( config[ "Relation" ].toString() ) );
mComboRelation->setCurrentIndex( mComboRelation->findData( config.value( "Relation" ).toString() ) );
relationChanged( mComboRelation->currentIndex() );
}

if ( config.contains( "MapIdentification" ) )
{
mCbxMapIdentification->setChecked( config[ "MapIdentification"].toBool() );
mCbxMapIdentification->setChecked( config.value( "MapIdentification" ).toBool() );
}

if ( config.contains( "AllowAddFeatures" ) )
mCbxAllowAddFeatures->setChecked( config.value( "AllowAddFeatures" ).toBool() );

if ( config.contains( "ReadOnly" ) )
{
mCbxReadOnly->setChecked( config[ "ReadOnly"].toBool() );
mCbxReadOnly->setChecked( config.value( "ReadOnly" ).toBool() );
}

if ( config.contains( "FilterFields" ) )
{
mFilterGroupBox->setChecked( true );
Q_FOREACH ( const QString& fld, config["FilterFields"].toStringList() )
Q_FOREACH ( const QString& fld, config.value( "FilterFields" ).toStringList() )
{
addFilterField( fld );
}

mCbxChainFilters->setChecked( config["ChainFilters"].toBool() );
mCbxChainFilters->setChecked( config.value( "ChainFilters" ).toBool() );
}
}

Expand Down Expand Up @@ -142,6 +145,7 @@ QgsEditorWidgetConfig QgsRelationReferenceConfigDlg::config()
myConfig.insert( "MapIdentification", mCbxMapIdentification->isEnabled() && mCbxMapIdentification->isChecked() );
myConfig.insert( "ReadOnly", mCbxReadOnly->isChecked() );
myConfig.insert( "Relation", mComboRelation->itemData( mComboRelation->currentIndex() ) );
myConfig.insert( "AllowAddFeatures", mCbxAllowAddFeatures->isChecked() );

if ( mFilterGroupBox->isChecked() )
{
Expand Down
2 changes: 2 additions & 0 deletions src/gui/editorwidgets/qgsrelationreferencefactory.cpp
Expand Up @@ -47,6 +47,7 @@ QgsEditorWidgetConfig QgsRelationReferenceFactory::readConfig( const QDomElement
cfg.insert( "Relation", configElement.attribute( "Relation" ) );
cfg.insert( "MapIdentification", configElement.attribute( "MapIdentification" ) == "1" );
cfg.insert( "ReadOnly", configElement.attribute( "ReadOnly" ) == "1" );
cfg.insert( "AllowAddFeatures", configElement.attribute( "AllowAddFeatures" ) == "1" );

QDomNode filterNode = configElement.elementsByTagName( "FilterFields" ).at( 0 );
if ( !filterNode.isNull() )
Expand Down Expand Up @@ -78,6 +79,7 @@ void QgsRelationReferenceFactory::writeConfig( const QgsEditorWidgetConfig& conf
configElement.setAttribute( "Relation", config["Relation"].toString() );
configElement.setAttribute( "MapIdentification", config["MapIdentification"].toBool() );
configElement.setAttribute( "ReadOnly", config["ReadOnly"].toBool() );
configElement.setAttribute( "AllowAddFeatures", config["AllowAddFeatures"].toBool() );

if ( config.contains( "FilterFields" ) )
{
Expand Down
60 changes: 57 additions & 3 deletions src/gui/editorwidgets/qgsrelationreferencewidget.cpp
Expand Up @@ -78,6 +78,7 @@ QgsRelationReferenceWidget::QgsRelationReferenceWidget( QWidget* parent )
, mOrderByValue( false )
, mOpenFormButtonVisible( true )
, mChainFilters( false )
, mAllowAddFeatures( false )
{
mTopLayout = new QVBoxLayout( this );
mTopLayout->setContentsMargins( 0, 0, 0, 0 );
Expand All @@ -103,20 +104,25 @@ QgsRelationReferenceWidget::QgsRelationReferenceWidget( QWidget* parent )
chooserLayout->addWidget( mFilterContainer );

// combobox (for non-geometric relation)
mComboBox = new QComboBox( this );
mComboBox = new QComboBox();
mChooserContainer->layout()->addWidget( mComboBox );

// read-only line edit
mLineEdit = new QLineEdit( this );
mLineEdit = new QLineEdit();
mLineEdit->setReadOnly( true );
editLayout->addWidget( mLineEdit );

// open form button
mOpenFormButton = new QToolButton( this );
mOpenFormButton = new QToolButton();
mOpenFormButton->setIcon( QgsApplication::getThemeIcon( "/mActionPropertyItem.png" ) );
mOpenFormButton->setText( tr( "Open related feature form" ) );
editLayout->addWidget( mOpenFormButton );

mAddEntryButton = new QToolButton();
mAddEntryButton->setIcon( QgsApplication::getThemeIcon( "/mActionAdd.svg" ) );
mAddEntryButton->setText( tr( "Add new entry" ) );
editLayout->addWidget( mAddEntryButton );

// highlight button
mHighlightFeatureButton = new QToolButton( this );
mHighlightFeatureButton->setPopupMode( QToolButton::MenuButtonPopup );
Expand Down Expand Up @@ -173,6 +179,8 @@ QgsRelationReferenceWidget::QgsRelationReferenceWidget( QWidget* parent )
connect( mHighlightFeatureButton, SIGNAL( triggered( QAction* ) ), this, SLOT( highlightActionTriggered( QAction* ) ) );
connect( mMapIdentificationButton, SIGNAL( clicked() ), this, SLOT( mapIdentification() ) );
connect( mRemoveFKButton, SIGNAL( clicked() ), this, SLOT( deleteForeignKey() ) );
connect( mAddEntryButton, SIGNAL( clicked( bool ) ), this, SLOT( addEntry() ) );
connect( mComboBox, SIGNAL( editTextChanged( QString ) ), this, SLOT( updateAddEntryButton() ) );
}

QgsRelationReferenceWidget::~QgsRelationReferenceWidget()
Expand Down Expand Up @@ -208,6 +216,10 @@ void QgsRelationReferenceWidget::setRelation( const QgsRelation& relation, bool
mReferencedAttributeForm->hideButtonBox();
mAttributeEditorLayout->addWidget( mReferencedAttributeForm );
}

connect( mReferencedLayer, SIGNAL( editingStarted() ), this, SLOT( updateAddEntryButton() ) );
connect( mReferencedLayer, SIGNAL( editingStopped() ), this, SLOT( updateAddEntryButton() ) );
updateAddEntryButton();
}
else
{
Expand All @@ -227,6 +239,7 @@ void QgsRelationReferenceWidget::setRelationEditable( bool editable )

mFilterContainer->setEnabled( editable );
mComboBox->setEnabled( editable );
mComboBox->setEditable( true );
mMapIdentificationButton->setEnabled( editable );
mRemoveFKButton->setEnabled( editable );
mIsEditable = editable;
Expand Down Expand Up @@ -716,6 +729,17 @@ void QgsRelationReferenceWidget::updateAttributeEditorFrame( const QgsFeature& f
}
}

bool QgsRelationReferenceWidget::allowAddFeatures() const
{
return mAllowAddFeatures;
}

void QgsRelationReferenceWidget::setAllowAddFeatures( bool allowAddFeatures )
{
mAllowAddFeatures = allowAddFeatures;
updateAddEntryButton();
}

void QgsRelationReferenceWidget::featureIdentified( const QgsFeature& feature )
{
if ( mReadOnlySelector )
Expand Down Expand Up @@ -863,3 +887,33 @@ void QgsRelationReferenceWidget::filterChanged()

mFilterModel->setFilteredFeatures( featureIds );
}

void QgsRelationReferenceWidget::addEntry()
{
QgsFeature f( mReferencedLayer->fields() );
QgsAttributeMap attributes;

// if custom text is in the combobox and the displayExpression is simply a field, use the current text for the new feature
if ( mComboBox->itemText( mComboBox->currentIndex() ) != mComboBox->currentText() )
{
int fieldIdx = mReferencedLayer->fieldNameIndex( mReferencedLayer->displayExpression() );

if ( fieldIdx != -1 )
{
attributes.insert( fieldIdx, mComboBox->currentText() );
}
}

if ( mEditorContext.vectorLayerTools()->addFeature( mReferencedLayer, attributes, QgsGeometry(), &f ) )
{
int i = mComboBox->findData( f.id(), QgsAttributeTableModel::FeatureIdRole );
mComboBox->setCurrentIndex( i );
mAddEntryButton->setEnabled( false );
}
}

void QgsRelationReferenceWidget::updateAddEntryButton()
{
mAddEntryButton->setVisible( mAllowAddFeatures );
mAddEntryButton->setEnabled( mReferencedLayer && mReferencedLayer->isEditable() );
}
26 changes: 22 additions & 4 deletions src/gui/editorwidgets/qgsrelationreferencewidget.h
Expand Up @@ -67,15 +67,15 @@ class GUI_EXPORT QgsRelationReferenceWidget : public QWidget
void setEditorContext( const QgsAttributeEditorContext& context, QgsMapCanvas* canvas, QgsMessageBar* messageBar );

//! determines if the form of the related feature will be shown
bool embedForm() {return mEmbedForm;}
bool embedForm() { return mEmbedForm; }
void setEmbedForm( bool display );

//! determines if the foreign key is shown in a combox box or a read-only line edit
bool readOnlySelector() {return mReadOnlySelector;}
bool readOnlySelector() { return mReadOnlySelector; }
void setReadOnlySelector( bool readOnly );

//! determines if the widge offers the possibility to select the related feature on the map (using a dedicated map tool)
bool allowMapIdentification() {return mAllowMapIdentification;}
bool allowMapIdentification() { return mAllowMapIdentification; }
void setAllowMapIdentification( bool allowMapIdentification );

//! If the widget will order the combobox entries by value
Expand All @@ -86,7 +86,7 @@ class GUI_EXPORT QgsRelationReferenceWidget : public QWidget
void setFilterFields( const QStringList& filterFields );

//! determines the open form button is visible in the widget
bool openFormButtonVisible() {return mOpenFormButtonVisible;}
bool openFormButtonVisible() { return mOpenFormButtonVisible; }
void setOpenFormButtonVisible( bool openFormButtonVisible );

/**
Expand All @@ -113,6 +113,20 @@ class GUI_EXPORT QgsRelationReferenceWidget : public QWidget
*/
void showIndeterminateState();

/**
* Determines if a button for adding new features should be shown.
*
* @note added in QGIS 2.16
*/
bool allowAddFeatures() const;

/**
* Determines if a button for adding new features should be shown.
*
* @note added in QGIS 2.16
*/
void setAllowAddFeatures( bool allowAddFeatures );

public slots:
//! open the form of the related feature in a new dialog
void openForm();
Expand All @@ -139,6 +153,8 @@ class GUI_EXPORT QgsRelationReferenceWidget : public QWidget
void unsetMapTool();
void mapToolDeactivated();
void filterChanged();
void addEntry();
void updateAddEntryButton();

private:
void highlightFeature( QgsFeature f = QgsFeature(), CanvasExtent canvasExtent = Fixed );
Expand Down Expand Up @@ -179,13 +195,15 @@ class GUI_EXPORT QgsRelationReferenceWidget : public QWidget
bool mOrderByValue;
bool mOpenFormButtonVisible;
bool mChainFilters;
bool mAllowAddFeatures;

// UI
QVBoxLayout* mTopLayout;
QToolButton* mMapIdentificationButton;
QToolButton* mRemoveFKButton;
QToolButton* mOpenFormButton;
QToolButton* mHighlightFeatureButton;
QToolButton* mAddEntryButton;
QAction* mHighlightFeatureAction;
QAction* mScaleHighlightFeatureAction;
QAction* mPanHighlightFeatureAction;
Expand Down
Expand Up @@ -60,6 +60,7 @@ void QgsRelationReferenceWidgetWrapper::initWidget( QWidget* editor )
mWidget->setFilterFields( config( "FilterFields" ).toStringList() );
mWidget->setChainFilters( config( "ChainFilters" ).toBool() );
}
mWidget->setAllowAddFeatures( config( "AllowAddFeatures", false ).toBool() );

QgsRelation relation = QgsProject::instance()->relationManager()->relation( config( "Relation" ).toString() );

Expand Down

0 comments on commit 226339c

Please sign in to comment.