29 #include <QTableWidgetItem>
33 #include <QScrollArea>
37 #include <QDialogButtonBox>
40 #include <QVBoxLayout>
43 #include <QPushButton>
49 , mSettingsPath(
"/Windows/AttributeDialog/" )
51 , mFeature( thepFeature )
52 , mFeatureOwner( featureOwner )
55 , mShowDialogButtons( showDialogButtons )
66 QDialogButtonBox *buttonBox = NULL;
73 if (
file.open( QFile::ReadOnly ) )
78 loader.setWorkingDirectory( fi.dir() );
79 QWidget *myWidget = loader.load( &
file, parent );
82 mDialog = qobject_cast<QDialog*>( myWidget );
83 buttonBox = myWidget->findChild<QDialogButtonBox*>();
89 mDialog =
new QDialog( parent );
91 QGridLayout *gridLayout;
92 QTabWidget *tabWidget;
95 gridLayout =
new QGridLayout(
mDialog );
96 gridLayout->setObjectName( QString::fromUtf8(
"gridLayout" ) );
98 tabWidget =
new QTabWidget(
mDialog );
99 gridLayout->addWidget( tabWidget );
103 QWidget* tabPage =
new QWidget( tabWidget );
105 tabWidget->addTab( tabPage, widgDef->
name() );
106 QGridLayout *tabPageLayout =
new QGridLayout( tabPage );
114 QgsDebugMsg(
"No support for fields in attribute editor on top level" );
118 buttonBox =
new QDialogButtonBox(
mDialog );
119 buttonBox->setObjectName( QString::fromUtf8(
"buttonBox" ) );
120 gridLayout->addWidget( buttonBox );
125 mDialog =
new QDialog( parent );
127 QGridLayout *gridLayout;
131 gridLayout =
new QGridLayout(
mDialog );
132 gridLayout->setSpacing( 6 );
133 gridLayout->setMargin( 2 );
134 gridLayout->setObjectName( QString::fromUtf8(
"gridLayout" ) );
135 mFrame =
new QFrame(
mDialog );
136 mFrame->setObjectName( QString::fromUtf8(
"mFrame" ) );
137 mFrame->setFrameShape( QFrame::NoFrame );
138 mFrame->setFrameShadow( QFrame::Plain );
140 gridLayout->addWidget( mFrame, 0, 0, 1, 1 );
142 buttonBox =
new QDialogButtonBox(
mDialog );
143 buttonBox->setObjectName( QString::fromUtf8(
"buttonBox" ) );
144 gridLayout->addWidget( buttonBox, 2, 0, 1, 1 );
149 QVBoxLayout *mypOuterLayout =
new QVBoxLayout();
150 mypOuterLayout->setContentsMargins( 0, 0, 0, 0 );
153 mFrame->setLayout( mypOuterLayout );
155 QScrollArea *mypScrollArea =
new QScrollArea();
156 mypScrollArea->setFrameShape( QFrame::NoFrame );
157 mypScrollArea->setFrameShadow( QFrame::Plain );
160 mypOuterLayout->addWidget( mypScrollArea );
162 QFrame *mypInnerFrame =
new QFrame();
163 mypInnerFrame->setFrameShape( QFrame::NoFrame );
164 mypInnerFrame->setFrameShadow( QFrame::Plain );
167 mypScrollArea->setWidget( mypInnerFrame );
169 mypScrollArea->setWidgetResizable(
true );
170 QGridLayout *mypInnerLayout =
new QGridLayout( mypInnerFrame );
173 for (
int fldIdx = 0; fldIdx < theFields.
count(); ++fldIdx )
179 const QgsField &myField = theFields[fldIdx];
182 myFieldName +=
" (" + vl->
dateFormat( fldIdx ) +
")";
189 QLabel *mypLabel =
new QLabel( myFieldName, mypInnerFrame );
195 myWidget->setEnabled(
true );
199 foreach ( QWidget *w, myWidget->findChildren<QWidget *>() )
201 w->setEnabled( qobject_cast<QLabel *>( w ) ?
true :
false );
206 foreach ( QWidget *w, myWidget->findChildren<QWidget *>() )
208 if ( qobject_cast<QWebView *>( w ) )
209 w->setEnabled(
true );
210 else if ( qobject_cast<QPushButton *>( w ) && w->objectName() ==
"openUrl" )
211 w->setEnabled(
true );
213 w->setEnabled(
false );
218 myWidget->setEnabled(
false );
224 mypInnerLayout->addWidget( mypLabel, index++, 0, 1, 2 );
225 mypInnerLayout->addWidget( myWidget, index++, 0, 1, 2 );
229 mypInnerLayout->addWidget( mypLabel, index, 0 );
230 mypInnerLayout->addWidget( myWidget, index, 1 );
236 if ( mypInnerLayout->rowCount() > 0 )
238 QWidget* widget = mypInnerLayout->itemAtPosition( 0, 1 )->widget();
240 widget->setFocus( Qt::OtherFocusReason );
243 QSpacerItem *mypSpacer =
new QSpacerItem( 10, 10, QSizePolicy::Fixed, QSizePolicy::Expanding );
244 mypInnerLayout->addItem( mypSpacer, mypInnerLayout->rowCount() + 1, 0 );
252 myDa.
setEllipsoidalMode( QgisApp::instance()->mapCanvas()->mapRenderer()->hasCrsTransformEnabled() );
255 for (
int fldIdx = 0; fldIdx < theFields.
count(); ++fldIdx )
257 QList<QWidget *> myWidgets =
mDialog->findChildren<QWidget*>( theFields[fldIdx].name() );
258 if ( myWidgets.isEmpty() )
261 foreach ( QWidget *myWidget, myWidgets )
269 myWidget->setEnabled(
true );
273 foreach ( QWidget *w, myWidget->findChildren<QWidget *>() )
275 w->setEnabled( qobject_cast<QLabel *>( w ) ?
true :
false );
280 foreach ( QWidget *w, myWidget->findChildren<QWidget *>() )
282 w->setEnabled( qobject_cast<QWebView *>( w ) ?
true :
false );
287 myWidget->setEnabled(
false );
293 foreach ( QLineEdit *le,
mDialog->findChildren<QLineEdit*>() )
295 if ( !le->objectName().startsWith(
"expr_" ) )
298 le->setReadOnly(
true );
299 QString expr = le->text();
300 le->setText(
tr(
"Error" ) );
323 switch ( value.type() )
325 case QVariant::Invalid: text =
"NULL";
break;
326 case QVariant::Int: text = QString::number( value.toInt() );
break;
327 case QVariant::Double: text = QString::number( value.toDouble() );
break;
328 case QVariant::String:
329 default: text = value.toString();
342 if (
mDialog->objectName().isEmpty() )
343 mDialog->setObjectName(
"QgsAttributeDialogBase" );
345 if (
mDialog->windowTitle().isEmpty() )
346 mDialog->setWindowTitle(
tr(
"Attributes - %1" ).arg( vl->
name() ) );
357 buttonBox->setStandardButtons( QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
358 connect( buttonBox, SIGNAL( accepted() ),
mDialog, SLOT(
accept() ) );
359 connect( buttonBox, SIGNAL( accepted() ),
this, SLOT(
accept() ) );
363 buttonBox->setStandardButtons( QDialogButtonBox::Cancel );
366 connect( buttonBox, SIGNAL( rejected() ),
mDialog, SLOT( reject() ) );
373 buttonBox->setVisible(
false );
377 QMetaObject::connectSlotsByName(
mDialog );
385 vl->setProperty(
"featureForm.dialog", QVariant::fromValue( qobject_cast<QObject*>(
mDialog ) ) );
386 vl->setProperty(
"featureForm.id", QVariant( mpFeature->id() ) );
390 int pos = module.lastIndexOf(
"." );
399 QString reload = QString(
"if hasattr(%1,'DEBUGMODE') and %1.DEBUGMODE:"
400 " reload(%1)" ).arg( module.left( pos ) );
406 QString form = QString(
"_qgis_featureform_%1 = sip.wrapinstance( %2, QtGui.QDialog )" )
408 .arg((
unsigned long )
mDialog );
410 QString layer = QString(
"_qgis_layer_%1 = sip.wrapinstance( %2, qgis.core.QgsVectorLayer )" )
412 .arg((
unsigned long ) vl );
416 QDateTime dt = QDateTime::currentDateTime();
417 QString featurevarname = QString(
"_qgis_feature_%1" ).arg( dt.toString(
"yyyyMMddhhmmsszzz" ) );
418 QString
feature = QString(
"%1 = sip.wrapinstance( %2, qgis.core.QgsFeature )" )
419 .arg( featurevarname )
426 mReturnvarname = QString(
"_qgis_feature_form_%1" ).arg( dt.toString(
"yyyyMMddhhmmsszzz" ) );
427 QString expr = QString(
"%5 = %1(_qgis_featureform_%2, _qgis_layer_%3, %4)" )
431 .arg( featurevarname )
434 QgsDebugMsg( QString(
"running featureForm init: %1" ).arg( expr ) );
478 for (
int idx = 0; idx < fields.
count(); ++idx )
496 return QDialog::Accepted;
504 mDialog->setAttribute( Qt::WA_DeleteOnClose );
508 mDialog->installEventFilter(
this );
544 mLayer->setProperty(
"featureForm.dialog", QVariant() );
545 mLayer->setProperty(
"featureForm.id", QVariant() );
549 QString expr = QString(
"if locals().has_key('_qgis_featureform_%1'): del _qgis_featureform_%1\n" ).arg(
mFormNr );
555 QString expr = QString(
"if locals().has_key('%1'): del %1\n" ).arg(
mReturnvarname );
569 case QEvent::WindowActivate:
572 case QEvent::WindowDeactivate:
QgsFeatureId id() const
Get the feature id for this feature.
Class for parsing and evaluation of expressions (formerly called "search strings").
void setGeomCalculator(QgsDistanceArea &calc)
Sets the geometry calculator used in evaluation of expressions,.
bool hasEvalError() const
Returns true if an error occurred when evaluating last input.
bool fieldEditable(int idx)
is edit widget editable
bool hasParserError() const
Returns true if an error occurred when parsing the input expression.
EditorLayout editorLayout()
get the active layout for the attribute editor for this layer (added in 1.9)
void restoreGeometry()
Restores the size and position from the last time this dialog box was used.
static bool retrieveValue(QWidget *widget, QgsVectorLayer *vl, int idx, QVariant &value)
QVariant evaluate(const QgsFeature *f=NULL)
Evaluate the feature and return the result.
The attribute value should not be changed in the attribute form.
void saveGeometry()
Saves the size and position for the next time this dialog box was used.
void setSourceCrs(long srsid)
sets source spatial reference system (by QGIS CRS)
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())
Query the provider for features specified in request.
QgsGeometry * geometry() const
Get the geometry object associated with this feature.
QgsHighlight * mHighlight
Container of fields for a vector layer.
bool setAttribute(int field, const QVariant &attr)
Set an attribute by id.
void setHighlight(QgsHighlight *h)
QgsAttributeDialog(QgsVectorLayer *vl, QgsFeature *thepFeature, bool featureOwner, QgsDistanceArea myDa, QWidget *parent=0, bool showDialogButtons=true)
bool setEllipsoid(const QString &ellipsoid)
sets ellipsoid by its acronym
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)
static QWidget * createWidgetFromDef(const QgsAttributeEditorElement *widgetDef, QWidget *parent, QgsVectorLayer *vl, QgsAttributes &attrs, QMap< int, QWidget * > &proxyWidgets, bool createGroupBox)
Creates a widget form a QgsAttributeEditorElement definition.
const QString & name() const
Get the display name of the layer.
void setGeometry(const QgsGeometry &geom)
Set this feature's geometry from another QgsGeometry object (deep copy)
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
EditType editType(int idx)
get edit type
bool eventFilter(QObject *obj, QEvent *event)
A class for highlight features on the map.
This class wraps a request for features to a vector layer (or directly its vector data provider)...
QList< int > QgsAttributeList
AttributeEditorType type() const
QString & dateFormat(int idx)
access date format
const QgsAttributes & attributes() const
QString id() const
Get this layer's unique ID, this ID is used to access this layer from map layer registry.
int count() const
Return number of items.
Encapsulate a field in an attribute table or data source.
QString attributeAlias(int attributeIndex) const
Returns the alias of an attribute name or an empty string if there is no alias.
bool labelOnTop(int idx)
label widget on top
bool needsGeometry()
Returns true if the expression uses feature geometry for some computation.
General purpose distance and area calculator.
static QWidget * createAttributeEditor(QWidget *parent, QWidget *editor, QgsVectorLayer *vl, int idx, const QVariant &value, QMap< int, QWidget * > &proxyWidgets)
Creates or prepares a attributre editor widget.
QMap< int, QWidget * > mProxyWidgets
QVector< QVariant > QgsAttributes
static QgsProject * instance()
access to canonical QgsProject instance
const CORE_EXPORT QString GEO_NONE
Constant that holds the string representation for "No ellips/No CRS".
QList< QgsAttributeEditorElement * > & attributeEditorElements()
Returns a list of tabs holding groups and fields.
const QgsCoordinateReferenceSystem & crs() const
Returns layer's spatial reference system.
const QgsFields & pendingFields() const
returns field list in the to-be-committed state
QgsVectorDataProvider * dataProvider()
Returns the data provider.
QString editFormInit()
get python function for edit form initialization (added in 1.4)
bool nextFeature(QgsFeature &f)
virtual bool isEditable() const
Returns true if the provider is in editing mode.
Represents a vector layer which manages a vector based data sets.
bool isEmpty() const
Check whether the container is empty.
QString evalErrorString() const
Returns evaluation error.
void setEllipsoidalMode(bool flag)
sets whether coordinates must be projected to ellipsoid before measuring
QVariant::Type type() const
Gets variant type of the field as it will be retrieved from data source.