21 #include "qgseditorwidgetregistry.h"
24 #include "qgsrelationwidgetwrapper.h"
28 #include <QFormLayout>
29 #include <QGridLayout>
33 #include <QPushButton>
34 #include <QScrollArea>
44 , mFormNr( sFormCounter++ )
46 , mIsAddDialog( false )
47 , mEditCommandMessage(
tr(
"Attributes changed" ) )
53 connect( vl, SIGNAL( attributeAdded(
int ) ),
this, SLOT(
onAttributeAdded(
int ) ) );
54 connect( vl, SIGNAL( attributeDeleted(
int ) ),
this, SLOT(
onAttributeDeleted(
int ) ) );
68 connect(
mLayer, SIGNAL( beforeModifiedCheck() ),
this, SLOT(
save() ) );
75 disconnect(
mLayer, SIGNAL( beforeModifiedCheck() ),
this, SLOT(
save() ) );
97 Q_FOREACH( QgsWidgetWrapper* ww,
mWidgets )
99 QgsEditorWidgetWrapper* eww = qobject_cast<QgsEditorWidgetWrapper*>( ww );
100 if ( eww && eww->field().name() == field )
102 eww->setValue( value );
140 bool doUpdate =
false;
150 Q_FOREACH( QgsWidgetWrapper* ww,
mWidgets )
152 QgsEditorWidgetWrapper* eww = qobject_cast<QgsEditorWidgetWrapper*>( ww );
155 QVariant dstVar = dst[eww->fieldIdx()];
156 QVariant srcVar = eww->value();
157 if ( dstVar != srcVar && srcVar.isValid() )
159 dst[eww->fieldIdx()] = srcVar;
193 for (
int i = 0; i < dst.count(); ++i )
195 if ( dst[i] == src[i] || !dst[i].isValid() )
198 QgsDebugMsg( QString(
"dst:'%1' (type:%2,isNull:%3,isValid:%4)" )
199 .arg( dst[i].toString() ).arg( dst[i].typeName() ).arg( dst[i].
isNull() ).arg( dst[i].isValid() ) );
200 QgsDebugMsg( QString(
"src:'%1' (type:%2,isNull:%3,isValid:%4)" )
201 .arg( src[i].toString() ).arg( src[i].typeName() ).arg( src[i].
isNull() ).arg( src[i].isValid() ) );
209 if ( success && n > 0 )
231 Q_FOREACH( QgsWidgetWrapper* ww,
mWidgets )
239 QgsEditorWidgetWrapper* eww = qobject_cast<QgsEditorWidgetWrapper*>( sender() );
251 Q_ASSERT( attrs.size() == idx );
252 attrs.append( QVariant() );
277 Q_FOREACH( QgsWidgetWrapper* ww,
mWidgets )
279 bool fieldEditable =
true;
280 QgsEditorWidgetWrapper* eww = qobject_cast<QgsEditorWidgetWrapper*>( ww );
285 ww->setEnabled( isEditable && fieldEditable );
288 QPushButton* okButton =
mButtonBox->button( QDialogButtonBox::Ok );
290 okButton->setEnabled( isEditable );
295 QWidget* formWidget = 0;
300 while ( QWidget* w = this->findChild<QWidget*>() )
304 delete this->layout();
307 setLayout(
new QGridLayout(
this ) );
314 if (
file.open( QFile::ReadOnly ) )
319 loader.setWorkingDirectory( fi.dir() );
320 formWidget = loader.load( &
file,
this );
321 formWidget->setWindowFlags( Qt::Widget );
322 layout()->addWidget( formWidget );
327 formWidget->installEventFilter(
this );
334 QTabWidget* tabWidget =
new QTabWidget(
this );
335 layout()->addWidget( tabWidget );
339 QWidget* tabPage =
new QWidget( tabWidget );
341 tabWidget->addTab( tabPage, widgDef->
name() );
342 QGridLayout *tabPageLayout =
new QGridLayout( tabPage );
354 QgsDebugMsg(
"No support for fields in attribute editor on top level" );
357 formWidget = tabWidget;
364 formWidget =
new QWidget(
this );
365 QGridLayout* gridLayout =
new QGridLayout( formWidget );
366 formWidget->setLayout( gridLayout );
369 QScrollArea* scrollArea =
new QScrollArea(
this );
370 scrollArea->setWidget( formWidget );
371 scrollArea->setWidgetResizable(
true );
372 scrollArea->setFrameShape( QFrame::NoFrame );
373 scrollArea->setFrameShadow( QFrame::Plain );
374 layout()->addWidget( scrollArea );
385 if ( widgetType !=
"Hidden" )
391 QWidget *l =
new QLabel( fieldName );
392 QgsEditorWidgetWrapper* eww = QgsEditorWidgetRegistry::instance()->create( widgetType,
mLayer, idx, widgetConfig, 0,
this,
mContext );
393 QWidget *w = eww ? eww->widget() :
new QLabel( QString(
"<p style=\"color: red; font-style: italic;\">Failed to create widget with type '%1'</p>" ).arg( widgetType ) );
400 gridLayout->addWidget( l, row++, 0, 1, 2 );
401 gridLayout->addWidget( w, row++, 0, 1, 2 );
405 gridLayout->addWidget( l, row, 0 );
406 gridLayout->addWidget( w, row++, 1 );
413 QgsRelationWidgetWrapper* rww =
new QgsRelationWidgetWrapper(
mLayer, rel, 0,
this );
415 gridLayout->addWidget( rww->widget(), row++, 0, 1, 2 );
424 mButtonBox =
new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
447 QString expr = QString(
"if locals().has_key('%1'): del %1\n" ).arg(
mPyFormVarName );
461 int pos = module.lastIndexOf(
"." );
470 QString reload = QString(
"if hasattr(%1,'DEBUGMODE') and %1.DEBUGMODE:"
471 " reload(%1)" ).arg( module.left( pos ) );
481 QString form = QString(
"%1 = sip.wrapinstance( %2, qgis.gui.QgsAttributeForm )" )
483 .arg((
unsigned long )
this );
490 if ( numArgs ==
"3" )
497 QString expr = QString(
"%1(%2)" )
500 QgsAttributeFormInterface* iface = QgsPythonRunner::evalToSipObject<QgsAttributeFormInterface*>( expr,
"QgsAttributeFormInterface" );
510 QWidget *newWidget = 0;
512 switch ( widgetDef->
type() )
517 int fldIdx = fieldDef->
idx();
518 if ( fldIdx < vl->pendingFields().count() && fldIdx >= 0 )
523 QgsEditorWidgetWrapper* eww = QgsEditorWidgetRegistry::instance()->create( widgetType,
mLayer, fldIdx, widgetConfig, 0,
this,
mContext );
524 newWidget = eww->widget();
537 QgsRelationWidgetWrapper* rww =
new QgsRelationWidgetWrapper(
mLayer, relDef->
relation(), 0, this );
538 rww->setContext( context );
539 newWidget = rww->widget();
541 labelText = QString::null;
549 QWidget* myContainer;
553 QGroupBox* groupBox =
new QGroupBox( parent );
554 groupBox->setTitle( container->
name() );
555 myContainer = groupBox;
556 newWidget = myContainer;
560 QScrollArea *scrollArea =
new QScrollArea( parent );
562 myContainer =
new QWidget( scrollArea );
564 scrollArea->setWidget( myContainer );
565 scrollArea->setWidgetResizable(
true );
566 scrollArea->setFrameShape( QFrame::NoFrame );
568 newWidget = scrollArea;
571 QGridLayout* gbLayout =
new QGridLayout( myContainer );
572 myContainer->setLayout( gbLayout );
576 QList<QgsAttributeEditorElement*> children = container->
children();
582 QWidget* editor =
createWidgetFromDef( childDef, myContainer, vl, context, labelText, labelOnTop );
584 if ( labelText.isNull() )
586 gbLayout->addWidget( editor, index, 0, 1, 2 );
590 QLabel* mypLabel =
new QLabel( labelText );
593 gbLayout->addWidget( mypLabel, index, 0, 1, 2 );
595 gbLayout->addWidget( editor, index, 0, 1 , 2 );
599 gbLayout->addWidget( mypLabel, index, 0 );
600 gbLayout->addWidget( editor, index, 1 );
606 gbLayout->addItem(
new QSpacerItem( 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding ), index , 0 );
608 labelText = QString::null;
614 QgsDebugMsg(
"Unknown attribute editor widget type encountered..." );
623 QList<QWidget*> myWidgets = findChildren<QWidget*>();
626 Q_FOREACH( QWidget* myWidget, myWidgets )
629 QVariant vRel = myWidget->property(
"qgisRelation" );
630 if ( vRel.isValid() )
636 QgsRelationWidgetWrapper* rww =
new QgsRelationWidgetWrapper(
mLayer, relation, myWidget,
this );
644 Q_FOREACH(
const QgsField& field, fields )
646 if ( field.
name() == myWidget->objectName() )
652 QgsEditorWidgetWrapper* eww = QgsEditorWidgetRegistry::instance()->create( widgetType,
mLayer, idx, widgetConfig, myWidget,
this,
mContext );
662 Q_FOREACH( QgsWidgetWrapper* ww,
mWidgets )
664 QgsEditorWidgetWrapper* eww = qobject_cast<QgsEditorWidgetWrapper*>( ww );
667 connect( eww, SIGNAL( valueChanged(
const QVariant& ) ),
this, SLOT(
onAttributeChanged(
const QVariant& ) ) );
676 if ( e->type() == QEvent::KeyPress )
678 QKeyEvent* keyEvent =
dynamic_cast<QKeyEvent*
>( e );
679 if ( keyEvent->key() == Qt::Key_Escape )
QList< QgsField > toList() const
Utility function to return a list of QgsField instances.
QgsFeatureId id() const
Get the feature id for this feature.
const QgsEditorWidgetConfig editorWidgetV2Config(int fieldIdx) const
Get the configuration for the editor widget used to represent the field at the given index...
const QString & name() const
Gets the name of the field.
bool isValid() const
Returns the validity of this relation.
bool fieldEditable(int idx)
is edit widget editable
EditorLayout editorLayout()
get the active layout for the attribute editor for this layer (added in 1.9)
virtual bool isGroupBox() const
bool isValid() const
Return the validity of this feature.
This class contains context information for attribute editor widgets.
void beginEditCommand(QString text)
Create edit command for undo/redo operations.
static bool eval(QString command, QString &result)
Eval a python statement.
void setAttributes(const QgsAttributes &attrs)
bool addFeature(QgsFeature &f, bool alsoUpdateExtent=true)
Adds a feature.
const QgsRelation & relation() const
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
QString editForm()
get edit form (added in 1.4)
QString attributeDisplayName(int attributeIndex) const
Convenience function that returns the attribute alias if defined or the field name else...
static bool run(QString command, QString messageOnError=QString())
execute a python statement
QgsRelation relation(const QString &id) const
const QString editorWidgetV2(int fieldIdx) const
Get the id for the editor widget used to represent the field at the given index.
AttributeEditorType type() const
void destroyEditCommand()
Destroy active command and reverts all changes in it.
Q_DECL_DEPRECATED bool changeAttributeValue(QgsFeatureId fid, int field, QVariant value, bool emitSignal)
Changes an attribute value (but does not commit it)
const QgsAttributes & attributes() const
Encapsulate a field in an attribute table or data source.
void setFields(const QgsFields *fields, bool initAttributes=false)
Assign a field map with the feature to allow attribute access by attribute name.
void endEditCommand()
Finish edit command and add it to undo/redo stack.
bool labelOnTop(int idx)
label widget on top
QList< QgsAttributeEditorElement * > children() const
void setValid(bool validity)
Set the validity of the feature.
QVector< QVariant > QgsAttributes
virtual void setIsGroupBox(bool isGroupBox)
This class manages a set of relations between layers.
static QgsProject * instance()
access to canonical QgsProject instance
QList< QgsAttributeEditorElement * > & attributeEditorElements()
Returns a list of tabs holding groups and fields.
const QgsFields & pendingFields() const
returns field list in the to-be-committed state
QString editFormInit()
get python function for edit form initialization (added in 1.4)
virtual bool isEditable() const
Returns true if the provider is in editing mode.
Represents a vector layer which manages a vector based data sets.
int fieldNameIndex(const QString &fieldName) const
Returns the index of a field name or -1 if the field does not exist.
QgsRelationManager * relationManager() const
bool isNull(const QVariant &v)