Skip to content

Commit

Permalink
Pass attribute editor context for widgets on the attribute table
Browse files Browse the repository at this point in the history
Fixes relation reference widget in attribute table
  • Loading branch information
m-kuhn committed Sep 16, 2014
1 parent d05d83e commit ab3ff17
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 29 deletions.
23 changes: 16 additions & 7 deletions python/gui/qgsattributeeditorcontext.sip
Expand Up @@ -15,19 +15,26 @@ class QgsAttributeEditorContext
*/
enum RelationMode
{
Undefined, //!< This context is not defined by a relation
EmbedMultiple, //!< When embedding a list of features (e.g. houses as an embedded form in a district form)
EmbedSingle, //!< When embedding a single feature (e.g. district information when looking at the form of a house)
StandaloneSingle //!< When showing a new dialog for a single feature (e.g. district information when looking at the form of a house)
Undefined, //!< This context is not defined by a relation
Multiple, //!< When showing a list of features (e.g. houses as an embedded form in a district form)
Single //!< When showing a single feature (e.g. district information when looking at the form of a house)
};

enum FormMode
{
Embed,
StandaloneDialog,
Popup
};

QgsAttributeEditorContext();

QgsAttributeEditorContext( const QgsAttributeEditorContext& parentContext, const QgsRelation& relation, RelationMode mode );

void setDistanceArea( const QgsDistanceArea& distanceArea );
QgsAttributeEditorContext( const QgsAttributeEditorContext& parentContext, FormMode formMode );

const QgsDistanceArea& distanceArea();
QgsAttributeEditorContext( const QgsAttributeEditorContext& parentContext, const QgsRelation& relation, RelationMode relationMode, FormMode formMode );

void setDistanceArea( const QgsDistanceArea& distanceArea );

void setVectorLayerTools( QgsVectorLayerTools* vlTools );
const QgsVectorLayerTools* vectorLayerTools() const;
Expand All @@ -36,5 +43,7 @@ class QgsAttributeEditorContext
const QgsRelation& relation() const;
RelationMode relationMode() const;

FormMode formMode() const;

const QgsAttributeEditorContext* parentContext() const;
};
1 change: 0 additions & 1 deletion src/app/qgsattributetabledialog.h
Expand Up @@ -40,7 +40,6 @@ class QSignalMapper;

class QgsAttributeTableModel;
class QgsAttributeTableFilterModel;
class QgsAttributeTableView;

class APP_EXPORT QgsAttributeTableDialog : public QDialog, private Ui::QgsAttributeTableDialog
{
Expand Down
23 changes: 17 additions & 6 deletions src/gui/attributetable/qgsattributetabledelegate.cpp
Expand Up @@ -29,10 +29,7 @@
#include "qgsvectordataprovider.h"



// TODO: Remove this casting orgy

QgsVectorLayer *QgsAttributeTableDelegate::layer( const QAbstractItemModel *model ) const
QgsVectorLayer* QgsAttributeTableDelegate::layer( const QAbstractItemModel *model )
{
const QgsAttributeTableModel *tm = qobject_cast<const QgsAttributeTableModel *>( model );
if ( tm )
Expand All @@ -42,7 +39,20 @@ QgsVectorLayer *QgsAttributeTableDelegate::layer( const QAbstractItemModel *mode
if ( fm )
return fm->layer();

return NULL;
return 0;
}

const QgsAttributeTableModel* QgsAttributeTableDelegate::masterModel( const QAbstractItemModel* model )
{
const QgsAttributeTableModel *tm = qobject_cast<const QgsAttributeTableModel *>( model );
if ( tm )
return tm;

const QgsAttributeTableFilterModel *fm = dynamic_cast<const QgsAttributeTableFilterModel *>( model );
if ( fm )
return fm->masterModel();

return 0;
}

QWidget *QgsAttributeTableDelegate::createEditor(
Expand All @@ -59,7 +69,8 @@ QWidget *QgsAttributeTableDelegate::createEditor(

QString widgetType = vl->editorWidgetV2( fieldIdx );
QgsEditorWidgetConfig cfg = vl->editorWidgetV2Config( fieldIdx );
QgsEditorWidgetWrapper* eww = QgsEditorWidgetRegistry::instance()->create( widgetType, vl, fieldIdx, cfg, 0, parent );
QgsAttributeEditorContext context( masterModel( index.model() )->editorContext(), QgsAttributeEditorContext::Popup );
QgsEditorWidgetWrapper* eww = QgsEditorWidgetRegistry::instance()->create( widgetType, vl, fieldIdx, cfg, 0, parent, context );
QWidget* w = eww->widget();

w->setAutoFillBackground( true );
Expand Down
10 changes: 6 additions & 4 deletions src/gui/attributetable/qgsattributetabledelegate.h
Expand Up @@ -22,7 +22,7 @@
class QgsFeatureSelectionModel;
class QPainter;
class QgsVectorLayer;
class QgsAttributeTableView;
class QgsAttributeTableModel;

/** \ingroup app
* A delegate item class for QgsAttributeTable (see Qt documentation for
Expand All @@ -31,16 +31,18 @@ class QgsAttributeTableView;

class GUI_EXPORT QgsAttributeTableDelegate : public QItemDelegate
{
Q_OBJECT;
Q_OBJECT

QgsVectorLayer *layer( const QAbstractItemModel *model ) const;
static QgsVectorLayer* layer( const QAbstractItemModel* model );
static const QgsAttributeTableModel* masterModel( const QAbstractItemModel* model );

public:
/** Constructor
* @param parent parent object
*/
QgsAttributeTableDelegate( QObject* parent = NULL ) :
QItemDelegate( parent ) {};
QItemDelegate( parent ) {}

/** Used to create an editor for when the user tries to
* change the contents of a cell */
QWidget * createEditor(
Expand Down
26 changes: 26 additions & 0 deletions src/gui/attributetable/qgsattributetablemodel.h
Expand Up @@ -26,6 +26,7 @@

#include "qgsvectorlayer.h" // QgsAttributeList
#include "qgsvectorlayercache.h"
#include "qgsattributeeditorcontext.h"

class QgsMapCanvas;
class QgsMapLayerAction;
Expand Down Expand Up @@ -193,8 +194,31 @@ class GUI_EXPORT QgsAttributeTableModel: public QAbstractTableModel
*/
void prefetchColumnData( int column );

/**
* Set a request that will be used to fill this attribute table model.
* In contrast to a filter, the request will constrain the data shown without the possibility
* to dynamically adjust it.
*
* @param request The request to use to fill this table model.
*/
void setRequest( const QgsFeatureRequest& request );

/**
* Sets the context in which this table is shown.
* Will be forwarded to any editor widget created when editing data on this model.
*
* @param context The context
*/
void setEditorContext( const QgsAttributeEditorContext& context ) { mEditorContext = context; }

/**
* Returns the context in which this table is shown.
* Will be forwarded to any editor widget created when editing data on this model.
*
* @return The context
*/
const QgsAttributeEditorContext& editorContext() const { return mEditorContext; }

signals:
/**
* Model has been changed
Expand Down Expand Up @@ -291,6 +315,8 @@ class GUI_EXPORT QgsAttributeTableModel: public QAbstractTableModel
* right = max column
*/
QRect mChangedCellBounds;

QgsAttributeEditorContext mEditorContext;
};


Expand Down
3 changes: 2 additions & 1 deletion src/gui/attributetable/qgsdualview.cpp
Expand Up @@ -114,7 +114,7 @@ void QgsDualView::columnBoxInit()
// ... If there are primary key(s) defined
QStringList pkFields;

Q_FOREACH ( int attr, pkAttrs )
Q_FOREACH( int attr, pkAttrs )
{
pkFields.append( "COALESCE(\"" + fields[attr].name() + "\", '<NULL>')" );
}
Expand Down Expand Up @@ -224,6 +224,7 @@ void QgsDualView::initModels( QgsMapCanvas* mapCanvas, const QgsFeatureRequest&
{
mMasterModel = new QgsAttributeTableModel( mLayerCache, this );
mMasterModel->setRequest( request );
mMasterModel->setEditorContext( mEditorContext );

connect( mMasterModel, SIGNAL( progress( int, bool & ) ), this, SLOT( progress( int, bool & ) ) );
connect( mMasterModel, SIGNAL( finished() ), this, SLOT( finished() ) );
Expand Down
4 changes: 2 additions & 2 deletions src/gui/editorwidgets/qgsrelationreferencewidget.cpp
Expand Up @@ -152,7 +152,7 @@ void QgsRelationReferenceWidget::setRelation( QgsRelation relation, bool allowNu
mFkeyFieldIdx = mReferencedLayer->fieldNameIndex( relation.fieldPairs().first().second );


QgsAttributeEditorContext context( mEditorContext, relation, QgsAttributeEditorContext::EmbedSingle );
QgsAttributeEditorContext context( mEditorContext, relation, QgsAttributeEditorContext::Single, QgsAttributeEditorContext::Embed );

if ( mEmbedForm )
{
Expand Down Expand Up @@ -430,7 +430,7 @@ void QgsRelationReferenceWidget::openForm()
if ( !feat.isValid() )
return;

QgsAttributeEditorContext context( mEditorContext, mRelation, QgsAttributeEditorContext::StandaloneSingle );
QgsAttributeEditorContext context( mEditorContext, mRelation, QgsAttributeEditorContext::Single, QgsAttributeEditorContext::StandaloneDialog );
QgsAttributeDialog attributeDialog( mReferencedLayer, new QgsFeature( feat ), true, this, true, context );
attributeDialog.exec();
}
Expand Down
4 changes: 2 additions & 2 deletions src/gui/editorwidgets/qgsrelationwidgetwrapper.cpp
Expand Up @@ -48,15 +48,15 @@ void QgsRelationWidgetWrapper::initWidget( QWidget* editor )
w = new QgsRelationEditorWidget( editor );
}

QgsAttributeEditorContext myContext( QgsAttributeEditorContext( context(), mRelation, QgsAttributeEditorContext::EmbedMultiple ) );
QgsAttributeEditorContext myContext( QgsAttributeEditorContext( context(), mRelation, QgsAttributeEditorContext::Multiple, QgsAttributeEditorContext::Embed ) );

w->setEditorContext( myContext );

// If this widget is already embedded by the same relation, reduce functionality
const QgsAttributeEditorContext* ctx = &context();
do
{
if ( ctx->relation().name() == mRelation.name() && ctx->relationMode() == QgsAttributeEditorContext::EmbedMultiple )
if ( ctx->relation().name() == mRelation.name() && ctx->relationMode() == QgsAttributeEditorContext::Multiple )
{
w->setSaveCollapsedState( false );
w->setCollapsed( true );
Expand Down
33 changes: 27 additions & 6 deletions src/gui/qgsattributeeditorcontext.h
Expand Up @@ -38,10 +38,16 @@ class GUI_EXPORT QgsAttributeEditorContext
*/
enum RelationMode
{
Undefined, //!< This context is not defined by a relation
EmbedMultiple, //!< When embedding a list of features (e.g. houses as an embedded form in a district form)
EmbedSingle, //!< When embedding a single feature (e.g. district information when looking at the form of a house)
StandaloneSingle //!< When showing a new dialog for a single feature (e.g. district information when looking at the form of a house)
Undefined, //!< This context is not defined by a relation
Multiple, //!< When showing a list of features (e.g. houses as an embedded form in a district form)
Single //!< When showing a single feature (e.g. district information when looking at the form of a house)
};

enum FormMode
{
Embed, //!< A form was embedded as a widget on another form
StandaloneDialog, //!< A form was opened as a new dialog
Popup //!< A widget was opened as a popup (e.g. attribute table editor widget)
};

QgsAttributeEditorContext()
Expand All @@ -51,13 +57,25 @@ class GUI_EXPORT QgsAttributeEditorContext
, mRelationMode( Undefined )
{}

QgsAttributeEditorContext( const QgsAttributeEditorContext& parentContext, const QgsRelation& relation, RelationMode mode )
QgsAttributeEditorContext( const QgsAttributeEditorContext& parentContext, FormMode formMode )
: mParentContext( &parentContext )
, mLayer( 0 )
, mVectorLayerTools( parentContext.mVectorLayerTools )
, mDistanceArea( parentContext.mDistanceArea )
, mRelationMode( Undefined )
, mFormMode( formMode )
{
Q_ASSERT( parentContext.vectorLayerTools() );
}

QgsAttributeEditorContext( const QgsAttributeEditorContext& parentContext, const QgsRelation& relation, RelationMode relationMode, FormMode widgetMode )
: mParentContext( &parentContext )
, mLayer( 0 )
, mVectorLayerTools( parentContext.mVectorLayerTools )
, mDistanceArea( parentContext.mDistanceArea )
, mRelation( relation )
, mRelationMode( mode )
, mRelationMode( relationMode )
, mFormMode( widgetMode )
{
Q_ASSERT( parentContext.vectorLayerTools() );
}
Expand All @@ -80,6 +98,8 @@ class GUI_EXPORT QgsAttributeEditorContext
inline const QgsRelation& relation() const { return mRelation; }
inline RelationMode relationMode() const { return mRelationMode; }

inline FormMode formMode() const { return mFormMode; }

inline const QgsAttributeEditorContext* parentContext() const { return mParentContext; }

private:
Expand All @@ -89,6 +109,7 @@ class GUI_EXPORT QgsAttributeEditorContext
QgsDistanceArea mDistanceArea;
QgsRelation mRelation;
RelationMode mRelationMode;
FormMode mFormMode;
};

#endif // QGSATTRIBUTEEDITORCONTEXT_H

0 comments on commit ab3ff17

Please sign in to comment.