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() ) );
82 disconnect( mButtonBox, SIGNAL( accepted() ),
this, SLOT(
accept() ) );
83 disconnect( mButtonBox, SIGNAL( rejected() ),
this, SLOT(
resetValues() ) );
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;
165 QVariant dstVar = dst[eww->
fieldIdx()];
166 QVariant srcVar = eww->
value();
169 if (( dstVar != srcVar || dstVar.isNull() != srcVar.isNull() ) && srcVar.isValid() && mLayer->
fieldEditable( eww->
fieldIdx() ) )
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() )
218 QgsDebugMsg( QString(
"Updating field %1" ).arg( i ) );
219 QgsDebugMsg( QString(
"dst:'%1' (type:%2, isNull:%3, isValid:%4)" )
220 .arg( dst[i].toString() ).arg( dst[i].typeName() ).arg( dst[i].
isNull() ).arg( dst[i].isValid() ) );
221 QgsDebugMsg( QString(
"src:'%1' (type:%2, isNull:%3, isValid:%4)" )
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() )
280 Q_ASSERT( attrs.size() == idx );
281 attrs.append( QVariant(
layer()->pendingFields()[idx].type() ) );
289 void QgsAttributeForm::onAttributeDeleted(
int idx )
302 void QgsAttributeForm::synchronizeEnabledState()
304 bool isEditable = ( mFeature.
isValid() || mIsAddDialog ) && mLayer->
isEditable();
308 bool fieldEditable =
true;
314 ww->
setEnabled( isEditable && fieldEditable );
317 QPushButton* okButton = mButtonBox->button( QDialogButtonBox::Ok );
319 okButton->setEnabled( isEditable );
322 void QgsAttributeForm::init()
324 QApplication::setOverrideCursor( QCursor( Qt::WaitCursor ) );
327 QWidget* formWidget = 0;
329 bool buttonBoxVisible =
true;
333 buttonBoxVisible = mButtonBox->isVisible();
338 qDeleteAll( mWidgets );
341 while ( QWidget* w = this->findChild<QWidget*>() )
348 setLayout(
new QGridLayout(
this ) );
355 if (
file.open( QFile::ReadOnly ) )
360 loader.setWorkingDirectory( fi.dir() );
361 formWidget = loader.load( &
file,
this );
362 formWidget->setWindowFlags( Qt::Widget );
363 layout()->addWidget( formWidget );
366 mButtonBox = findChild<QDialogButtonBox*>();
369 formWidget->installEventFilter(
this );
376 QTabWidget* tabWidget =
new QTabWidget(
this );
377 layout()->addWidget( tabWidget );
381 QWidget* tabPage =
new QWidget( tabWidget );
383 tabWidget->addTab( tabPage, widgDef->
name() );
384 QGridLayout *tabPageLayout =
new QGridLayout( tabPage );
395 tabPageLayout->addWidget( createWidgetFromDef( widgDef, tabPage, mLayer, mContext, dummy1, dummy2 ) );
399 QgsDebugMsg(
"No support for fields in attribute editor on top level" );
402 formWidget = tabWidget;
409 formWidget =
new QWidget(
this );
410 QGridLayout* gridLayout =
new QGridLayout( formWidget );
411 formWidget->setLayout( gridLayout );
415 QScrollArea* scrollArea =
new QScrollArea(
this );
416 scrollArea->setWidget( formWidget );
417 scrollArea->setWidgetResizable(
true );
418 scrollArea->setFrameShape( QFrame::NoFrame );
419 scrollArea->setFrameShadow( QFrame::Plain );
420 scrollArea->setFocusProxy(
this );
421 layout()->addWidget( scrollArea );
435 if ( widgetType ==
"Hidden" )
442 QWidget *l =
new QLabel( fieldName );
444 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 ) );
447 w->setObjectName( field.
name() );
450 addWidgetWrapper( eww );
454 gridLayout->addWidget( l, row++, 0, 1, 2 );
455 gridLayout->addWidget( w, row++, 0, 1, 2 );
459 gridLayout->addWidget( l, row, 0 );
460 gridLayout->addWidget( w, row++, 1 );
468 gridLayout->addWidget( rww->
widget(), row++, 0, 1, 2 );
469 mWidgets.append( rww );
475 mButtonBox =
new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
476 mButtonBox->setObjectName(
"buttonBox" );
477 layout()->addWidget( mButtonBox );
480 mButtonBox->setVisible( buttonBoxVisible );
484 connect( mButtonBox, SIGNAL( accepted() ),
this, SLOT(
accept() ) );
485 connect( mButtonBox, SIGNAL( rejected() ),
this, SLOT(
resetValues() ) );
487 connect( mLayer, SIGNAL( editingStarted() ),
this, SLOT( synchronizeEnabledState() ) );
488 connect( mLayer, SIGNAL( editingStopped() ),
this, SLOT( synchronizeEnabledState() ) );
494 QApplication::restoreOverrideCursor();
497 void QgsAttributeForm::cleanPython()
499 if ( !mPyFormVarName.isNull() )
501 QString expr = QString(
"if locals().has_key('%1'): del %1\n" ).arg( mPyFormVarName );
506 void QgsAttributeForm::initPython()
515 int pos = module.lastIndexOf(
"." );
524 QString reload = QString(
"if hasattr(%1,'DEBUGMODE') and %1.DEBUGMODE:"
525 " reload(%1)" ).arg( module.left( pos ) );
533 mPyFormVarName = QString(
"_qgis_featureform_%1" ).arg( mFormNr );
535 QString form = QString(
"%1 = sip.wrapinstance( %2, qgis.gui.QgsAttributeForm )" )
536 .arg( mPyFormVarName )
537 .arg((
unsigned long )
this );
541 QgsDebugMsg( QString(
"running featureForm init: %1" ).arg( mPyFormVarName ) );
544 if ( numArgs ==
"3" )
551 QString expr = QString(
"%1(%2)" )
553 .arg( mPyFormVarName );
554 QgsAttributeFormInterface* iface = QgsPythonRunner::evalToSipObject<QgsAttributeFormInterface*>( expr,
"QgsAttributeFormInterface" );
564 QWidget *newWidget = 0;
566 switch ( widgetDef->
type() )
575 if ( fldIdx < vl->pendingFields().count() && fldIdx >= 0 )
581 newWidget = eww->
widget();
582 addWidgetWrapper( eww );
584 newWidget->setObjectName( mLayer->
pendingFields()[ fldIdx ].name() );
599 newWidget = rww->
widget();
600 mWidgets.append( rww );
601 labelText = QString::null;
612 QWidget* myContainer;
615 QGroupBox* groupBox =
new QGroupBox( parent );
616 groupBox->setTitle( container->
name() );
617 myContainer = groupBox;
618 newWidget = myContainer;
622 QScrollArea *scrollArea =
new QScrollArea( parent );
624 myContainer =
new QWidget( scrollArea );
626 scrollArea->setWidget( myContainer );
627 scrollArea->setWidgetResizable(
true );
628 scrollArea->setFrameShape( QFrame::NoFrame );
630 newWidget = scrollArea;
633 QGridLayout* gbLayout =
new QGridLayout( myContainer );
634 myContainer->setLayout( gbLayout );
638 QList<QgsAttributeEditorElement*> children = container->
children();
644 QWidget* editor = createWidgetFromDef( childDef, myContainer, vl, context, labelText, labelOnTop );
646 if ( labelText.isNull() )
648 gbLayout->addWidget( editor, index, 0, 1, 2 );
652 QLabel* mypLabel =
new QLabel( labelText );
655 gbLayout->addWidget( mypLabel, index, 0, 1, 2 );
657 gbLayout->addWidget( editor, index, 0, 1, 2 );
661 gbLayout->addWidget( mypLabel, index, 0 );
662 gbLayout->addWidget( editor, index, 1 );
668 gbLayout->addItem(
new QSpacerItem( 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding ), index, 0 );
670 labelText = QString::null;
676 QgsDebugMsg(
"Unknown attribute editor widget type encountered..." );
692 connect( meww, SIGNAL( valueChanged( QVariant ) ), eww, SLOT( setValue( QVariant ) ) );
693 connect( eww, SIGNAL( valueChanged( QVariant ) ), meww, SLOT( setValue( QVariant ) ) );
699 mWidgets.append( eww );
702 void QgsAttributeForm::createWrappers()
704 QList<QWidget*> myWidgets = findChildren<QWidget*>();
707 Q_FOREACH ( QWidget* myWidget, myWidgets )
710 QVariant vRel = myWidget->property(
"qgisRelation" );
711 if ( vRel.isValid() )
721 mWidgets.append( rww );
726 Q_FOREACH (
const QgsField& field, fields )
728 if ( field.
name() == myWidget->objectName() )
735 addWidgetWrapper( eww );
742 void QgsAttributeForm::connectWrappers()
744 bool isFirstEww =
true;
754 setFocusProxy( eww->
widget() );
758 connect( eww, SIGNAL( valueChanged(
const QVariant& ) ),
this, SLOT( onAttributeChanged(
const QVariant& ) ) );
768 if ( e->type() == QEvent::KeyPress )
770 QKeyEvent* keyEvent =
dynamic_cast<QKeyEvent*
>( e );
771 if ( keyEvent && keyEvent->key() == Qt::Key_Escape )