28 #include <QFormLayout>
29 #include <QGridLayout>
33 #include <QPushButton>
34 #include <QScrollArea>
38 int QgsAttributeForm::sFormCounter = 0;
45 , mFormNr( sFormCounter++ )
47 , mIsAddDialog( false )
48 , mEditCommandMessage(
tr(
"Attributes changed" ) )
54 connect( vl, SIGNAL( attributeAdded(
int ) ),
this, SLOT( onAttributeAdded(
int ) ) );
55 connect( vl, SIGNAL( attributeDeleted(
int ) ),
this, SLOT( onAttributeDeleted(
int ) ) );
61 qDeleteAll( mInterfaces );
70 connect( mLayer, SIGNAL( beforeModifiedCheck() ),
this, SLOT(
save() ) );
77 disconnect( mLayer, SIGNAL( beforeModifiedCheck() ),
this, SLOT(
save() ) );
88 mInterfaces.
append( iface );
98 mIsAddDialog = isAddDialog;
100 synchronizeEnabledState();
108 if ( eww && eww->
field().
name() == field )
121 synchronizeEnabledState();
136 bool changedLayer =
false;
148 if ( mFeature.
isValid() || mIsAddDialog )
150 bool doUpdate =
false;
194 bool res = mLayer->
addFeature( updatedFeature );
209 for (
int i = 0; i < dst.
count(); ++i )
211 if (( dst[i] == src[i] && dst[i].
isNull() == src[i].
isNull() )
220 .arg( dst[i].toString() ).arg( dst[i].typeName() ).arg( dst[i].
isNull() ).arg( dst[i].isValid() ) );
222 .arg( src[i].toString() ).arg( src[i].typeName() ).arg( src[i].
isNull() ).arg( src[i].isValid() ) );
228 if ( success && n > 0 )
265 void QgsAttributeForm::onAttributeChanged(
const QVariant& value )
274 void QgsAttributeForm::onAttributeAdded(
int idx )
277 if ( mFeature.isValid() )
288 void QgsAttributeForm::onAttributeDeleted(
int idx )
315 void QgsAttributeForm::synchronizeEnabledState()
317 bool isEditable = ( mFeature.
isValid() || mIsAddDialog ) && mLayer->
isEditable();
321 bool fieldEditable =
true;
327 ww->
setEnabled( isEditable && fieldEditable );
335 void QgsAttributeForm::init()
342 bool buttonBoxVisible =
true;
346 buttonBoxVisible = mButtonBox->
isVisible();
351 qDeleteAll( mWidgets );
354 while (
QWidget* w = this->findChild<QWidget*>() )
368 if ( file.open( QFile::ReadOnly ) )
374 formWidget = loader.
load( &file,
this );
379 mButtonBox = findChild<QDialogButtonBox*>();
396 tabWidget->
addTab( tabPage, widgDef->
name() );
409 tabPageLayout->
addWidget( createWidgetFromDef( widgDef, tabPage, mLayer, mContext, dummy1, dummy2 ) );
413 QgsDebugMsg(
"No support for fields in attribute editor on top level" );
416 formWidget = tabWidget;
423 formWidget =
new QWidget(
this );
449 if ( widgetType ==
"Hidden" )
458 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 ) );
464 addWidgetWrapper( eww );
468 gridLayout->
addWidget( l, row++, 0, 1, 2 );
469 gridLayout->
addWidget( w, row++, 0, 1, 2 );
489 mButtonBox =
new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
498 connect( mButtonBox, SIGNAL( accepted() ),
this, SLOT(
accept() ) );
501 connect( mLayer, SIGNAL( editingStarted() ),
this, SLOT( synchronizeEnabledState() ) );
502 connect( mLayer, SIGNAL( editingStopped() ),
this, SLOT( synchronizeEnabledState() ) );
511 void QgsAttributeForm::cleanPython()
513 if ( !mPyFormVarName.
isNull() )
515 QString expr =
QString(
"if locals().has_key('%1'): del %1\n" ).
arg( mPyFormVarName );
520 void QgsAttributeForm::initPython()
538 QString reload =
QString(
"if hasattr(%1,'DEBUGMODE') and %1.DEBUGMODE:"
539 " reload(%1)" ).
arg( module.
left( pos ) );
547 static int sFormId = 0;
548 mPyFormVarName =
QString(
"_qgis_featureform_%1_%2" ).
arg( mFormNr ).
arg( sFormId++ );
550 QString form =
QString(
"%1 = sip.wrapinstance( %2, qgis.gui.QgsAttributeForm )" )
551 .
arg( mPyFormVarName )
552 .
arg((
unsigned long )
this );
559 if ( numArgs ==
"3" )
568 .arg( mPyFormVarName );
569 QgsAttributeFormInterface* iface = QgsPythonRunner::evalToSipObject<QgsAttributeFormInterface*>( expr,
"QgsAttributeFormInterface" );
581 switch ( widgetDef->
type() )
590 if ( fldIdx < vl->pendingFields().count() && fldIdx >= 0 )
596 newWidget = eww->
widget();
597 addWidgetWrapper( eww );
614 newWidget = rww->
widget();
616 labelText = QString::null;
632 myContainer = groupBox;
633 newWidget = myContainer;
639 myContainer =
new QWidget( scrollArea );
645 newWidget = scrollArea;
659 QWidget* editor = createWidgetFromDef( childDef, myContainer, vl, context, labelText, labelOnTop );
663 gbLayout->
addWidget( editor, index, 0, 1, 2 );
670 gbLayout->
addWidget( mypLabel, index, 0, 1, 2 );
672 gbLayout->
addWidget( editor, index, 0, 1, 2 );
676 gbLayout->
addWidget( mypLabel, index, 0 );
684 spacer->
setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Preferred );
687 labelText = QString::null;
693 QgsDebugMsg(
"Unknown attribute editor widget type encountered..." );
719 void QgsAttributeForm::createWrappers()
724 Q_FOREACH (
QWidget* myWidget, myWidgets )
743 Q_FOREACH (
const QgsField& field, fields )
752 addWidgetWrapper( eww );
759 void QgsAttributeForm::connectWrappers()
761 bool isFirstEww =
true;
775 connect( eww, SIGNAL( valueChanged(
const QVariant& ) ),
this, SLOT( onAttributeChanged(
const QVariant& ) ) );
785 if ( e->
type() == QEvent::KeyPress )
788 if ( keyEvent && 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
This is an abstract base class for any elements of a drag and drop form.
EditorLayout editorLayout()
get the active layout for the attribute editor for this layer
virtual bool isGroupBox() const
Returns if this ccontainer is going to be rendered as a group box.
bool isValid() const
Returns the validity of this feature.
void setFrameShape(Shape)
This class contains context information for attribute editor widgets.
void beginEditCommand(QString text)
Create edit command for undo/redo operations.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())
Query the provider for features specified in request.
const QObjectList & children() const
void insert(int i, const T &value)
static bool eval(QString command, QString &result)
Eval a python statement.
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
This element will load a field's widget onto the form.
This element will load a relation editor onto the form.
bool addFeature(QgsFeature &f, bool alsoUpdateExtent=true)
Adds a feature.
const QgsRelation & relation() const
Get the id of the relation which shall be embedded.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
void setWorkingDirectory(const QDir &dir)
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
virtual bool isEditable() const override
Returns true if the provider is in editing mode.
int idx() const
Return the index of the field.
int lastIndexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
QString name() const
Return the name of this element.
QString editForm()
get edit form
void append(const T &value)
QVariant property(const char *name) const
void installEventFilter(QObject *filterObj)
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
Get access to a relation by its id.
QgsAttributes attributes() const
Returns the feature's attributes.
const QString editorWidgetV2(int fieldIdx) const
Get the id for the editor widget used to represent the field at the given index.
void setObjectName(const QString &name)
void triggerRepaint()
Will advice the map canvas (and any other interested party) that this layer requires to be repainted...
This class wraps a request for features to a vector layer (or directly its vector data provider)...
void setOverrideCursor(const QCursor &cursor)
AttributeEditorType type() const
The type of this element.
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)
void restoreOverrideCursor()
Encapsulate a field in an attribute table or data source.
Q_DECL_DEPRECATED 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
Get a list of the children elements of this container.
void setFrameShadow(Shadow)
void setValid(bool validity)
Sets the validity of the feature.
void setTitle(const QString &title)
virtual void setIsGroupBox(bool isGroupBox)
Determines if this container is rendered as collapsible group box or tab in a tabwidget.
This class manages a set of relations between layers.
static QgsProject * instance()
access to canonical QgsProject instance
int count(const T &value) const
QList< QgsAttributeEditorElement * > & attributeEditorElements()
Returns a list of tabs holding groups and fields.
This is a container for attribute editors, used to group them visually in the attribute form if it is...
QWidget * load(QIODevice *device, QWidget *parentWidget)
QString left(int n) const
const QgsFields & pendingFields() const
returns field list in the to-be-committed state
QString editFormInit()
get python function for edit form initialization
bool nextFeature(QgsFeature &f)
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
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
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
bool isNull(const QVariant &v)