QGIS API Documentation  2.0.1-Dufour
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
qgsattributeeditor.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsattributeeditor.cpp - description
3  -------------------
4  begin : July 2009
5  copyright : (C) 2009 by Jürgen E. Fischer
6  email : jef@norbit.de
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #include "qgsattributeeditor.h"
19 #include <qgsvectorlayer.h>
20 #include <qgsvectordataprovider.h>
22 #include <qgslonglongvalidator.h>
23 #include <qgsfieldvalidator.h>
24 #include <qgsmaplayerregistry.h>
25 #include <qgslogger.h>
26 #include <qgsexpression.h>
27 #include <qgsfilterlineedit.h>
28 #include <qgscolorbutton.h>
30 
31 #include <QScrollArea>
32 #include <QPushButton>
33 #include <QLineEdit>
34 #include <QTextEdit>
35 #include <QFileDialog>
36 #include <QComboBox>
37 #include <QListWidget>
38 #include <QCheckBox>
39 #include <QSpinBox>
40 #include <QCompleter>
41 #include <QHBoxLayout>
42 #include <QPlainTextEdit>
43 #include <QDial>
44 #include <QCalendarWidget>
45 #include <QDialogButtonBox>
46 #include <QSettings>
47 #include <QDir>
48 #include <QUuid>
49 #include <QGroupBox>
50 #include <QLabel>
51 #include <QWebView>
52 #include <QDesktopServices>
53 
55 {
56  QPushButton *pb = qobject_cast<QPushButton *>( sender() );
57  if ( !pb )
58  return;
59 
60  QWidget *hbox = qobject_cast<QWidget *>( pb->parent() );
61  if ( !hbox )
62  return;
63 
64  QLineEdit *le = hbox->findChild<QLineEdit *>();
65  if ( !le )
66  return;
67 
68  QString fileName = QFileDialog::getOpenFileName( 0 , tr( "Select a file" ), QFileInfo( le->text() ).absolutePath() );
69  if ( fileName.isNull() )
70  return;
71 
72  le->setText( QDir::toNativeSeparators( fileName ) );
73 }
74 
76 {
77  QPushButton *pb = qobject_cast<QPushButton *>( sender() );
78  if ( !pb )
79  return;
80 
81  QWidget *hbox = qobject_cast<QWidget *>( pb->parent() );
82  if ( !hbox )
83  return;
84 
85  QLineEdit *le = hbox->findChild<QLineEdit *>();
86  if ( !le )
87  return;
88 
89  QDialog *dlg = new QDialog();
90  dlg->setWindowTitle( tr( "Select a date" ) );
91  QVBoxLayout *vl = new QVBoxLayout( dlg );
92 
93  const QgsFieldValidator *v = dynamic_cast<const QgsFieldValidator *>( le->validator() );
94  QString dateFormat = v ? v->dateFormat() : "yyyy-MM-dd";
95 
96  QCalendarWidget *cw = new QCalendarWidget( dlg );
97  QString prevValue = le->text();
98  cw->setSelectedDate( QDate::fromString( prevValue, dateFormat ) );
99  vl->addWidget( cw );
100 
101  QDialogButtonBox *buttonBox = new QDialogButtonBox( dlg );
102  buttonBox->addButton( QDialogButtonBox::Ok );
103  buttonBox->addButton( QDialogButtonBox::Cancel );
104  vl->addWidget( buttonBox );
105 
106  connect( buttonBox, SIGNAL( accepted() ), dlg, SLOT( accept() ) );
107  connect( buttonBox, SIGNAL( rejected() ), dlg, SLOT( reject() ) );
108 
109  if ( dlg->exec() == QDialog::Accepted )
110  {
111  QString newValue = cw->selectedDate().toString( dateFormat );
112  le->setText( newValue );
113  le->setModified( newValue != prevValue );
114  }
115 }
116 
117 void QgsAttributeEditor::loadUrl( const QString &url )
118 {
119  QLineEdit *le = qobject_cast<QLineEdit *>( sender() );
120  if ( !le )
121  return;
122 
123  QWidget *hbox = qobject_cast<QWidget *>( le->parent() );
124  if ( !hbox )
125  return;
126 
127  QWebView *ww = hbox->findChild<QWebView *>();
128  if ( !ww )
129  return;
130 
131  ww->load( url );
132 }
133 
134 void QgsAttributeEditor::loadPixmap( const QString &name )
135 {
136  QLineEdit *le = qobject_cast<QLineEdit *>( sender() );
137  if ( !le )
138  return;
139 
140  QWidget *hbox = qobject_cast<QWidget *>( le->parent() );
141  if ( !hbox )
142  return;
143 
144  QLabel *lw = hbox->findChild<QLabel *>();
145  if ( !lw )
146  return;
147 
148  QPixmap pm( name );
149  if ( pm.isNull() )
150  return;
151 
152  QSize size( mLayer->widgetSize( mIdx ) );
153  if ( size.width() == 0 && size.height() > 0 )
154  {
155  size.setWidth( size.height() * pm.size().width() / pm.size().height() );
156  }
157  else if ( size.width() > 0 && size.height() == 0 )
158  {
159  size.setHeight( size.width() * pm.size().height() / pm.size().width() );
160  }
161 
162  pm = pm.scaled( size, Qt::KeepAspectRatio, Qt::SmoothTransformation );
163 
164  lw->setPixmap( pm );
165  lw->setMinimumSize( size );
166 }
167 
169 {
170  QPushButton *pb = qobject_cast<QPushButton *>( sender() );
171  if ( !pb )
172  return;
173 
174  QWidget *hbox = qobject_cast<QWidget *>( pb->parent() );
175  if ( !hbox )
176  return;
177 
178  QWebView *ww = hbox->findChild<QWebView *>();
179  if ( !ww )
180  return;
181 
182  QLineEdit *le = hbox->findChild<QLineEdit *>();
183  if ( !le )
184  return;
185 
186  le->blockSignals( true );
187  le->setText( ww->url().toString() );
188  le->blockSignals( false );
189 }
190 
192 {
193  QPushButton *pb = qobject_cast<QPushButton *>( sender() );
194  if ( !pb )
195  return;
196 
197  QWidget *hbox = qobject_cast<QWidget *>( pb->parent() );
198  if ( !hbox )
199  return;
200 
201  QWebView *ww = hbox->findChild<QWebView *>();
202  if ( !ww )
203  return;
204 
205  QDesktopServices::openUrl( ww->url().toString() );
206 }
207 
209 {
210  QString color;
211  QgsColorButton *scb = qobject_cast<QgsColorButton *>( sender() );
212  QLineEdit *sle = qobject_cast<QLineEdit *>( sender() );
213 
214  if ( !scb && !sle )
215  return;
216 
217  QWidget *hbox = qobject_cast<QWidget *>( sender()->parent() );
218  if ( !hbox )
219  return;
220 
221  QgsColorButton *cb = hbox->findChild<QgsColorButton *>();
222  if ( !cb )
223  return;
224 
225  QLineEdit *le = hbox->findChild<QLineEdit *>();
226  if ( !le )
227  return;
228 
229  if ( scb )
230  {
231  le->blockSignals( true );
232  le->setText( scb->color().name() );
233  le->blockSignals( false );
234  }
235 
236  if ( sle )
237  {
238  cb->blockSignals( true );
239  cb->setColor( QColor( sle->text() ) );
240  cb->blockSignals( false );
241  }
242 }
243 
244 QComboBox *QgsAttributeEditor::comboBox( QWidget *editor, QWidget *parent )
245 {
246  QComboBox *cb = 0;
247  if ( editor )
248  cb = qobject_cast<QComboBox *>( editor );
249  else
250  cb = new QComboBox( parent );
251 
252  return cb;
253 }
254 
255 QListWidget *QgsAttributeEditor::listWidget( QWidget *editor, QWidget *parent )
256 {
257  QListWidget *lw = 0;
258  if ( editor )
259  lw = qobject_cast<QListWidget *>( editor );
260  else
261  lw = new QListWidget( parent );
262 
263  return lw;
264 }
265 
266 QWidget *QgsAttributeEditor::createAttributeEditor( QWidget *parent, QWidget *editor, QgsVectorLayer *vl, int idx, const QVariant &value )
267 {
268  QMap<int, QWidget*> dummyProxyWidgets;
269  return createAttributeEditor( parent, editor, vl, idx, value, dummyProxyWidgets );
270 }
271 
272 QWidget *QgsAttributeEditor::createAttributeEditor( QWidget *parent, QWidget *editor, QgsVectorLayer *vl, int idx, const QVariant &value, QMap<int, QWidget*> &proxyWidgets )
273 {
274  if ( !vl )
275  return 0;
276 
277  QWidget *myWidget = 0;
278  QgsVectorLayer::EditType editType = vl->editType( idx );
279  const QgsField &field = vl->pendingFields()[idx];
280  QVariant::Type myFieldType = field.type();
281 
282  bool synchronized = false;
283 
284  switch ( editType )
285  {
287  {
288  QList<QVariant> values;
289  vl->dataProvider()->uniqueValues( idx, values );
290 
291  QComboBox *cb = comboBox( editor, parent );
292  if ( cb )
293  {
294  cb->setEditable( false );
295 
296  for ( QList<QVariant>::iterator it = values.begin(); it != values.end(); it++ )
297  cb->addItem( it->toString(), it->toString() );
298 
299  myWidget = cb;
300  }
301 
302  }
303  break;
304 
306  {
307  QStringList enumValues;
308  vl->dataProvider()->enumValues( idx, enumValues );
309 
310  QComboBox *cb = comboBox( editor, parent );
311  if ( cb )
312  {
313  QStringList::const_iterator s_it = enumValues.constBegin();
314  for ( ; s_it != enumValues.constEnd(); ++s_it )
315  {
316  cb->addItem( *s_it, *s_it );
317  }
318 
319  myWidget = cb;
320  }
321  }
322  break;
323 
325  {
326  const QMap<QString, QVariant> &map = vl->valueMap( idx );
327 
328  QComboBox *cb = comboBox( editor, parent );
329  if ( cb )
330  {
331  for ( QMap<QString, QVariant>::const_iterator it = map.begin(); it != map.end(); it++ )
332  {
333  cb->addItem( it.key(), it.value() );
334  }
335 
336  myWidget = cb;
337  }
338  }
339  break;
340 
342  {
343  const QgsVectorLayer::ValueRelationData &data = vl->valueRelation( idx );
344 
345  QgsVectorLayer *layer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( data.mLayer ) );
346  QMap< QString, QString > map;
347 
348  if ( layer )
349  {
350  int ki = layer->fieldNameIndex( data.mOrderByValue ? data.mValue : data.mKey );
351  int vi = layer->fieldNameIndex( data.mOrderByValue ? data.mKey : data.mValue );
352 
353  QgsExpression *e = 0;
354  if ( !data.mFilterExpression.isEmpty() )
355  {
356  e = new QgsExpression( data.mFilterExpression );
357  if ( e->hasParserError() || !e->prepare( layer->pendingFields() ) )
358  ki = -1;
359  }
360 
361  if ( ki >= 0 && vi >= 0 )
362  {
363  QSet<int> attributes;
364  attributes << ki << vi;
365 
367 
368  if ( e )
369  {
370  if ( e->needsGeometry() )
372 
373  foreach ( const QString &field, e->referencedColumns() )
374  {
375  int idx = layer->fieldNameIndex( field );
376  if ( idx < 0 )
377  continue;
378  attributes << idx;
379  }
380  }
381 
382  QgsFeatureIterator fit = layer->getFeatures( QgsFeatureRequest().setFlags( flags ).setSubsetOfAttributes( attributes.toList() ) );
383  QgsFeature f;
384  while ( fit.nextFeature( f ) )
385  {
386  if ( e && !e->evaluate( &f ).toBool() )
387  continue;
388 
389  map.insert( f.attribute( ki ).toString(), f.attribute( vi ).toString() );
390  }
391  }
392  }
393 
394  if ( !data.mAllowMulti )
395  {
396  QComboBox *cb = comboBox( editor, parent );
397  if ( cb )
398  {
399  if ( data.mAllowNull )
400  {
401  QSettings settings;
402  cb->addItem( tr( "(no selection)" ), settings.value( "qgis/nullValue", "NULL" ).toString() );
403  }
404 
405  for ( QMap< QString, QString >::const_iterator it = map.begin(); it != map.end(); it++ )
406  {
407  if ( data.mOrderByValue )
408  cb->addItem( it.key(), it.value() );
409  else
410  cb->addItem( it.value(), it.key() );
411  }
412 
413  myWidget = cb;
414  }
415  }
416  else
417  {
418  QListWidget *lw = listWidget( editor, parent );
419  if ( lw )
420  {
421  QStringList checkList = value.toString().remove( QChar( '{' ) ).remove( QChar( '}' ) ).split( "," );
422 
423  for ( QMap< QString, QString >::const_iterator it = map.begin(); it != map.end(); it++ )
424  {
425  QListWidgetItem *item;
426  if ( data.mOrderByValue )
427  {
428  item = new QListWidgetItem( it.key() );
429  item->setData( Qt::UserRole, it.value() );
430  item->setCheckState( checkList.contains( it.value() ) ? Qt::Checked : Qt::Unchecked );
431  }
432  else
433  {
434  item = new QListWidgetItem( it.value() );
435  item->setData( Qt::UserRole, it.key() );
436  item->setCheckState( checkList.contains( it.key() ) ? Qt::Checked : Qt::Unchecked );
437  }
438  lw->addItem( item );
439  }
440 
441  myWidget = lw;
442  }
443  }
444  }
445  break;
446 
448  {
449  QMap<QString, QString> classes;
450 
451  const QgsCategorizedSymbolRendererV2 *csr = dynamic_cast<const QgsCategorizedSymbolRendererV2 *>( vl->rendererV2() );
452  if ( csr )
453  {
454  const QgsCategoryList &categories = (( QgsCategorizedSymbolRendererV2 * )csr )->categories(); // FIXME: QgsCategorizedSymbolRendererV2::categories() should be const
455  for ( int i = 0; i < categories.size(); i++ )
456  {
457  QString label = categories[i].label();
458  QString value = categories[i].value().toString();
459  if ( label.isEmpty() )
460  label = value;
461  classes.insert( value, label );
462  }
463  }
464 
465  QComboBox *cb = comboBox( editor, parent );
466  if ( cb )
467  {
468  for ( QMap<QString, QString>::const_iterator it = classes.begin(); it != classes.end(); it++ )
469  {
470  cb->addItem( it.value(), it.key() );
471  }
472 
473  myWidget = cb;
474  }
475  }
476  break;
477 
481  {
482  if ( myFieldType == QVariant::Int )
483  {
484  int min = vl->range( idx ).mMin.toInt();
485  int max = vl->range( idx ).mMax.toInt();
486  int step = vl->range( idx ).mStep.toInt();
487 
488  if ( editType == QgsVectorLayer::EditRange )
489  {
490  QSpinBox *sb = 0;
491 
492  if ( editor )
493  sb = qobject_cast<QSpinBox *>( editor );
494  else
495  sb = new QSpinBox( parent );
496 
497  if ( sb )
498  {
499  sb->setRange( min, max );
500  sb->setSingleStep( step );
501 
502  myWidget = sb;
503  }
504  }
505  else
506  {
507  QAbstractSlider *sl = 0;
508 
509  if ( editor )
510  {
511  sl = qobject_cast<QAbstractSlider*>( editor );
512  }
513  else if ( editType == QgsVectorLayer::DialRange )
514  {
515  sl = new QDial( parent );
516  }
517  else
518  {
519  sl = new QSlider( Qt::Horizontal, parent );
520  }
521 
522  if ( sl )
523  {
524  sl->setRange( min, max );
525  sl->setSingleStep( step );
526 
527  myWidget = sl;
528  }
529  }
530  break;
531  }
532  else if ( myFieldType == QVariant::Double )
533  {
534  QDoubleSpinBox *dsb = 0;
535  if ( editor )
536  dsb = qobject_cast<QDoubleSpinBox*>( editor );
537  else
538  dsb = new QDoubleSpinBox( parent );
539 
540  if ( dsb )
541  {
542  double min = vl->range( idx ).mMin.toDouble();
543  double max = vl->range( idx ).mMax.toDouble();
544  double step = vl->range( idx ).mStep.toDouble();
545 
546  dsb->setRange( min, max );
547  dsb->setSingleStep( step );
548 
549  myWidget = dsb;
550  }
551  break;
552  }
553  }
554 
556  {
557  QCheckBox *cb = 0;
558  QGroupBox *gb = 0;
559  if ( editor )
560  {
561  gb = qobject_cast<QGroupBox *>( editor );
562  cb = qobject_cast<QCheckBox*>( editor );
563  }
564  else
565  cb = new QCheckBox( parent );
566 
567  if ( cb )
568  {
569  myWidget = cb;
570  break;
571  }
572  else if ( gb )
573  {
574  myWidget = gb;
575  break;
576  }
577  }
578 
579  // fall-through
580 
586  {
587  QLineEdit *le = 0;
588  QTextEdit *te = 0;
589  QPlainTextEdit *pte = 0;
590  QComboBox * cb = 0;
591 
592  if ( editor )
593  {
594  le = qobject_cast<QLineEdit *>( editor );
595  te = qobject_cast<QTextEdit *>( editor );
596  pte = qobject_cast<QPlainTextEdit *>( editor );
597  cb = qobject_cast<QComboBox *>( editor );
598  }
599  else if ( editType == QgsVectorLayer::TextEdit )
600  {
601  pte = new QPlainTextEdit( parent );
602  }
603  else
604  {
605  le = new QgsFilterLineEdit( parent );
606  }
607 
608  if ( le )
609  {
610  if ( editType == QgsVectorLayer::UniqueValuesEditable )
611  {
612  QList<QVariant> values;
613  vl->dataProvider()->uniqueValues( idx, values );
614 
615  QStringList svalues;
616  for ( QList<QVariant>::const_iterator it = values.begin(); it != values.end(); it++ )
617  svalues << it->toString();
618 
619  QCompleter *c = new QCompleter( svalues );
620  c->setCompletionMode( QCompleter::PopupCompletion );
621  le->setCompleter( c );
622  }
623 
624  if ( editType == QgsVectorLayer::UuidGenerator )
625  {
626  le->setReadOnly( true );
627  }
628 
629  le->setValidator( new QgsFieldValidator( le, field, vl->dateFormat( idx ) ) );
630 
631  myWidget = le;
632  }
633 
634  if ( te )
635  {
636  te->setAcceptRichText( true );
637  myWidget = te;
638  }
639 
640  if ( pte )
641  {
642  myWidget = pte;
643  }
644 
645  if ( cb )
646  {
647  if ( cb->isEditable() )
648  cb->setValidator( new QgsFieldValidator( cb, field, vl->dateFormat( idx ) ) );
649  myWidget = cb;
650  }
651 
652  if ( myWidget )
653  {
654  if ( editType == QgsVectorLayer::Immutable )
655  {
656  myWidget->setDisabled( true );
657  }
658 
659  QgsStringRelay* relay = NULL;
660 
661  QMap<int, QWidget*>::const_iterator it = proxyWidgets.find( idx );
662  if ( it != proxyWidgets.end() )
663  {
664  QObject* obj = qvariant_cast<QObject*>(( *it )->property( "QgisAttrEditProxy" ) );
665  relay = qobject_cast<QgsStringRelay*>( obj );
666  }
667  else
668  {
669  relay = new QgsStringRelay( myWidget );
670  }
671 
672  const char* rSlot = SLOT( changeText( QString ) );
673  const char* rSig = SIGNAL( textChanged( QString ) );
674  const char* wSlot = SLOT( setText( QString ) );
675  const char* wSig = SIGNAL( textChanged( QString ) );
676  if ( te || pte )
677  {
678  rSlot = SLOT( changeText() );
679  wSig = SIGNAL( textChanged() );
680  }
681  if ( pte )
682  {
683  wSlot = SLOT( setPlainText( QString ) );
684  }
685  if ( cb && cb->isEditable() )
686  {
687  wSlot = SLOT( setEditText( QString ) );
688  wSig = SIGNAL( editTextChanged( QString ) );
689  }
690 
691  synchronized = connect( relay, rSig, myWidget, wSlot );
692  synchronized &= connect( myWidget, wSig, relay, rSlot );
693 
694  // store list of proxies in relay
695  relay->appendProxy( myWidget );
696 
697  if ( !cb || cb->isEditable() )
698  {
699  myWidget->setProperty( "QgisAttrEditSlot", QVariant( QByteArray( wSlot ) ) );
700  myWidget->setProperty( "QgisAttrEditProxy", QVariant( QMetaType::QObjectStar, &relay ) );
701  }
702  }
703  }
704  break;
705 
707  myWidget = 0;
708  break;
709 
715  {
716  QCalendarWidget *cw = qobject_cast<QCalendarWidget *>( editor );
717  if ( cw )
718  {
719  myWidget = cw;
720  break;
721  }
722 
723  QWebView *ww = qobject_cast<QWebView *>( editor );
724  if ( ww )
725  {
726  ww->page()->setNetworkAccessManager( QgsNetworkAccessManager::instance() );
727  // ww->page()->setLinkDelegationPolicy( QWebPage::DelegateAllLinks );
728  ww->settings()->setAttribute( QWebSettings::LocalContentCanAccessRemoteUrls, true );
729  ww->settings()->setAttribute( QWebSettings::JavascriptCanOpenWindows, true );
730 #ifdef QGISDEBUG
731  ww->settings()->setAttribute( QWebSettings::DeveloperExtrasEnabled, true );
732 #endif
733 
734  QSize size( vl->widgetSize( idx ) );
735  if ( size.width() > 0 || size.height() > 0 )
736  {
737  if ( size.width() == 0 )
738  size.setWidth( 1 );
739  if ( size.height() == 0 )
740  size.setHeight( 1 );
741  ww->setMinimumSize( size );
742  }
743 
744  myWidget = ww;
745  break;
746  }
747 
748  QLabel *lw = qobject_cast<QLabel *>( editor );
749  if ( lw )
750  {
751  myWidget = lw;
752  break;
753  }
754 
755  QgsColorButton *cb = qobject_cast<QgsColorButton *>( editor );
756  if ( cb )
757  {
758  myWidget = cb;
759  break;
760  }
761 
762  QPushButton *pb0 = 0;
763  QPushButton *pb1 = 0;
764  QLineEdit *le = qobject_cast<QLineEdit *>( editor );
765  if ( le )
766  {
767  if ( le )
768  myWidget = le;
769 
770  if ( editor->parent() )
771  {
772  pb0 = editor->parent()->findChild<QPushButton *>();
773  }
774  }
775  else
776  {
777  myWidget = new QWidget( parent );
778  myWidget->setBackgroundRole( QPalette::Window );
779  myWidget->setAutoFillBackground( true );
780 
781  le = new QgsFilterLineEdit( myWidget );
782  switch ( editType )
783  {
787  pb0 = new QPushButton( tr( "..." ), myWidget );
788  break;
789 
791  pb0 = new QPushButton( tr( "<" ), myWidget );
792  pb0->setObjectName( "saveUrl" );
793  pb1 = new QPushButton( tr( "..." ), myWidget );
794  pb1->setObjectName( "openUrl" );
795  break;
796 
798  pb0 = new QgsColorButton( myWidget );
799  break;
800 
801  default:
802  break;
803  }
804 
805 
806  int row = 0;
807  QGridLayout *layout = new QGridLayout( myWidget );
808  if ( editType == QgsVectorLayer::Photo )
809  {
810  lw = new QLabel( myWidget );
811  layout->addWidget( lw, 0, 0, 1, 2 );
812  row++;
813  }
814  else if ( editType == QgsVectorLayer::WebView )
815  {
816  ww = new QWebView( myWidget );
817  ww->setObjectName( "webview" );
818  ww->page()->setNetworkAccessManager( QgsNetworkAccessManager::instance() );
819  // ww->page()->setLinkDelegationPolicy( QWebPage::DelegateAllLinks );
820  ww->settings()->setAttribute( QWebSettings::LocalContentCanAccessRemoteUrls, true );
821  ww->settings()->setAttribute( QWebSettings::JavascriptCanOpenWindows, true );
822 #ifdef QGISDEBUG
823  ww->settings()->setAttribute( QWebSettings::DeveloperExtrasEnabled, true );
824 #endif
825 
826  QSize size( vl->widgetSize( idx ) );
827  if ( size.width() > 0 || size.height() > 0 )
828  {
829  if ( size.width() == 0 )
830  size.setWidth( 1 );
831  if ( size.height() == 0 )
832  size.setHeight( 1 );
833  ww->setMinimumSize( size );
834  }
835 
836  layout->addWidget( ww, 0, 0, 1, 2 );
837  row++;
838  }
839 
840  layout->addWidget( le, row, 0 );
841  layout->addWidget( pb0, row, 1 );
842  if ( pb1 )
843  layout->addWidget( pb1, row, 2 );
844 
845  myWidget->setLayout( layout );
846  }
847 
848  if ( le )
849  {
850  le->setValidator( new QgsFieldValidator( le, field, vl->dateFormat( idx ) ) );
851 
852  if ( ww )
853  connect( le, SIGNAL( textChanged( const QString & ) ), new QgsAttributeEditor( le, vl, idx ), SLOT( loadUrl( const QString & ) ) );
854  if ( lw )
855  connect( le, SIGNAL( textChanged( const QString & ) ), new QgsAttributeEditor( le, vl, idx ), SLOT( loadPixmap( const QString & ) ) );
856  if ( editType == QgsVectorLayer::Color )
857  connect( le, SIGNAL( textChanged( const QString & ) ), new QgsAttributeEditor( le ), SLOT( updateColor() ) );
858  }
859 
860  if ( pb0 )
861  {
862  if ( editType == QgsVectorLayer::FileName || editType == QgsVectorLayer::Photo )
863  {
864  connect( pb0, SIGNAL( clicked() ), new QgsAttributeEditor( pb0 ), SLOT( selectFileName() ) );
865  pb0->setToolTip( tr( "Select filename..." ) );
866  }
867  if ( editType == QgsVectorLayer::WebView )
868  {
869  connect( pb0, SIGNAL( clicked() ), new QgsAttributeEditor( pb0 ), SLOT( updateUrl() ) );
870  pb0->setToolTip( tr( "Save current page url in attribute" ) );
871  }
872  if ( editType == QgsVectorLayer::Calendar )
873  {
874  connect( pb0, SIGNAL( clicked() ), new QgsAttributeEditor( pb0 ), SLOT( selectDate() ) );
875  pb0->setToolTip( tr( "Select date in calendar" ) );
876  }
877  if ( editType == QgsVectorLayer::Color )
878  {
879  connect( pb0, SIGNAL( colorChanged( const QColor & ) ), new QgsAttributeEditor( pb0 ), SLOT( updateColor() ) );
880  pb0->setToolTip( tr( "Select color in browser" ) );
881  }
882  }
883 
884  if ( pb1 )
885  {
886  if ( editType == QgsVectorLayer::WebView )
887  {
888  connect( pb1, SIGNAL( clicked() ), new QgsAttributeEditor( pb1 ), SLOT( openUrl() ) );
889  pb1->setToolTip( tr( "Open current page in default browser" ) );
890  }
891  }
892  }
893  break;
894  }
895 
896  QMap<int, QWidget*>::const_iterator it = proxyWidgets.find( idx );
897  if ( it != proxyWidgets.end() )
898  {
899  if ( !synchronized )
900  {
901  myWidget->setEnabled( false );
902  }
903  }
904  else
905  {
906  proxyWidgets.insert( idx, myWidget );
907  }
908 
909  setValue( myWidget, vl, idx, value );
910 
911  return myWidget;
912 }
913 
914 bool QgsAttributeEditor::retrieveValue( QWidget *widget, QgsVectorLayer *vl, int idx, QVariant &value )
915 {
916  if ( !widget )
917  return false;
918 
919  const QgsField &theField = vl->pendingFields()[idx];
920  QgsVectorLayer::EditType editType = vl->editType( idx );
921  bool modified = false;
922  QString text;
923 
924  QSettings settings;
925  QString nullValue = settings.value( "qgis/nullValue", "NULL" ).toString();
926 
927  QLineEdit *le = qobject_cast<QLineEdit *>( widget );
928  if ( le )
929  {
930  text = le->text();
931  modified = le->isModified();
932  if ( text == nullValue )
933  {
934  text = QString::null;
935  }
936  }
937 
938  QTextEdit *te = qobject_cast<QTextEdit *>( widget );
939  if ( te )
940  {
941  text = te->toHtml();
942  modified = te->document()->isModified();
943  if ( text == nullValue )
944  {
945  text = QString::null;
946  }
947  }
948 
949  QPlainTextEdit *pte = qobject_cast<QPlainTextEdit *>( widget );
950  if ( pte )
951  {
952  text = pte->toPlainText();
953  modified = pte->document()->isModified();
954  if ( text == nullValue )
955  {
956  text = QString::null;
957  }
958  }
959 
960  QComboBox *cb = qobject_cast<QComboBox *>( widget );
961  if ( cb )
962  {
963  if ( editType == QgsVectorLayer::UniqueValues ||
964  editType == QgsVectorLayer::ValueMap ||
965  editType == QgsVectorLayer::Classification ||
966  editType == QgsVectorLayer::ValueRelation )
967  {
968  text = cb->itemData( cb->currentIndex() ).toString();
969  if ( text == nullValue )
970  {
971  text = QString::null;
972  }
973  }
974  else
975  {
976  text = cb->currentText();
977  }
978  modified = true;
979  }
980 
981  QListWidget *lw = qobject_cast<QListWidget *>( widget );
982  if ( lw )
983  {
984  if ( editType == QgsVectorLayer::ValueRelation )
985  {
986  text = '{';
987  for ( int i = 0, n = 0; i < lw->count(); i++ )
988  {
989  if ( lw->item( i )->checkState() == Qt::Checked )
990  {
991  if ( n > 0 )
992  {
993  text.append( ',' );
994  }
995  text.append( lw->item( i )->data( Qt::UserRole ).toString() );
996  n++;
997  }
998  }
999  text.append( '}' );
1000  }
1001  else
1002  {
1003  text = QString::null;
1004  }
1005  modified = true;
1006  }
1007 
1008  QSpinBox *sb = qobject_cast<QSpinBox *>( widget );
1009  if ( sb )
1010  {
1011  text = QString::number( sb->value() );
1012  }
1013 
1014  QAbstractSlider *slider = qobject_cast<QAbstractSlider *>( widget );
1015  if ( slider )
1016  {
1017  text = QString::number( slider->value() );
1018  }
1019 
1020  QDoubleSpinBox *dsb = qobject_cast<QDoubleSpinBox *>( widget );
1021  if ( dsb )
1022  {
1023  text = QString::number( dsb->value() );
1024  }
1025 
1026  QCheckBox *ckb = qobject_cast<QCheckBox *>( widget );
1027  if ( ckb )
1028  {
1029  QPair<QString, QString> states = vl->checkedState( idx );
1030  text = ckb->isChecked() ? states.first : states.second;
1031  }
1032 
1033  QGroupBox *gb = qobject_cast<QGroupBox *>( widget );
1034  if ( gb )
1035  {
1036  QPair<QString, QString> states = vl->checkedState( idx );
1037  text = gb->isChecked() ? states.first : states.second;
1038  }
1039 
1040  QCalendarWidget *cw = qobject_cast<QCalendarWidget *>( widget );
1041  if ( cw )
1042  {
1043  text = cw->selectedDate().toString( vl->dateFormat( idx ) );
1044  }
1045 
1046  le = widget->findChild<QLineEdit *>();
1047  // QCalendarWidget and QGroupBox have an internal QLineEdit which returns the year
1048  // part of the date so we need to skip this if we have a QCalendarWidget
1049  if ( !cw && !gb && le )
1050  {
1051  text = le->text();
1052  modified = le->isModified();
1053  if ( text == nullValue )
1054  {
1055  text = QString::null;
1056  }
1057  }
1058 
1059  switch ( theField.type() )
1060  {
1061  case QVariant::Int:
1062  {
1063  bool ok;
1064  int myIntValue = text.toInt( &ok );
1065  if ( ok && !text.isEmpty() )
1066  {
1067  value = QVariant( myIntValue );
1068  modified = true;
1069  }
1070  else if ( modified )
1071  {
1072  value = QVariant();
1073  }
1074  }
1075  break;
1076  case QVariant::LongLong:
1077  {
1078  bool ok;
1079  qlonglong myLongValue = text.toLong( &ok );
1080  if ( ok && !text.isEmpty() )
1081  {
1082  value = QVariant( myLongValue );
1083  modified = true;
1084  }
1085  else if ( modified )
1086  {
1087  value = QVariant();
1088  }
1089  }
1090  case QVariant::Double:
1091  {
1092  bool ok;
1093  double myDblValue = text.toDouble( &ok );
1094  if ( ok && !text.isEmpty() )
1095  {
1096  value = QVariant( myDblValue );
1097  modified = true;
1098  }
1099  else if ( modified )
1100  {
1101  value = QVariant();
1102  }
1103  }
1104  break;
1105  case QVariant::Date:
1106  {
1107  QDate myDateValue = QDate::fromString( text, vl->dateFormat( idx ) );
1108  if ( myDateValue.isValid() && !text.isEmpty() )
1109  {
1110  value = myDateValue;
1111  modified = true;
1112  }
1113  else if ( modified )
1114  {
1115  value = QVariant();
1116  }
1117  }
1118  break;
1119  default: //string
1120  modified = true;
1121  if ( text.isNull() )
1122  value = QVariant( theField.type() );
1123  else
1124  value = QVariant( text );
1125  break;
1126  }
1127 
1128  return modified;
1129 }
1130 
1131 bool QgsAttributeEditor::setValue( QWidget *editor, QgsVectorLayer *vl, int idx, const QVariant &value )
1132 {
1133  if ( !editor )
1134  return false;
1135 
1136  QgsVectorLayer::EditType editType = vl->editType( idx );
1137  const QgsField &field = vl->pendingFields()[idx];
1138  QVariant::Type myFieldType = field.type();
1139 
1140  QSettings settings;
1141  QString nullValue = settings.value( "qgis/nullValue", "NULL" ).toString();
1142 
1143  switch ( editType )
1144  {
1150  {
1151  QVariant v = value;
1152  QComboBox *cb = qobject_cast<QComboBox *>( editor );
1153  if ( !cb )
1154  return false;
1155 
1156  if ( v.isNull() )
1157  {
1158  v = nullValue;
1159  }
1160 
1161  int idx = cb->findData( v );
1162  if ( idx < 0 )
1163  return false;
1164 
1165  cb->setCurrentIndex( idx );
1166  }
1167  break;
1168 
1172  {
1173  if ( myFieldType == QVariant::Int )
1174  {
1175  if ( editType == QgsVectorLayer::EditRange )
1176  {
1177  QSpinBox *sb = qobject_cast<QSpinBox *>( editor );
1178  if ( !sb )
1179  return false;
1180  sb->setValue( value.toInt() );
1181  }
1182  else
1183  {
1184  QAbstractSlider *sl = qobject_cast<QAbstractSlider *>( editor );
1185  if ( !sl )
1186  return false;
1187  sl->setValue( value.toInt() );
1188  }
1189  break;
1190  }
1191  else if ( myFieldType == QVariant::Double )
1192  {
1193  QDoubleSpinBox *dsb = qobject_cast<QDoubleSpinBox *>( editor );
1194  if ( !dsb )
1195  return false;
1196  dsb->setValue( value.toDouble() );
1197  }
1198  }
1199 
1201  {
1202  QGroupBox *gb = qobject_cast<QGroupBox *>( editor );
1203  if ( gb )
1204  {
1205  QPair<QString, QString> states = vl->checkedState( idx );
1206  gb->setChecked( value == states.first );
1207  break;
1208  }
1209 
1210  QCheckBox *cb = qobject_cast<QCheckBox *>( editor );
1211  if ( cb )
1212  {
1213  QPair<QString, QString> states = vl->checkedState( idx );
1214  cb->setChecked( value == states.first );
1215  break;
1216  }
1217  }
1218 
1219  // fall-through
1220 
1226  {
1227  QgsFilterLineEdit *fle = qobject_cast<QgsFilterLineEdit *>( editor );
1228  QLineEdit *le = qobject_cast<QLineEdit *>( editor );
1229  QComboBox *cb = qobject_cast<QComboBox *>( editor );
1230  QTextEdit *te = qobject_cast<QTextEdit *>( editor );
1231  QPlainTextEdit *pte = qobject_cast<QPlainTextEdit *>( editor );
1232  if ( !le && ! cb && !te && !pte )
1233  return false;
1234 
1235  if ( fle && !( myFieldType == QVariant::Int || myFieldType == QVariant::Double || myFieldType == QVariant::LongLong || myFieldType == QVariant::Date ) )
1236  {
1237  fle->setNullValue( nullValue );
1238  }
1239 
1240  QString text;
1241  if ( value.isNull() )
1242  {
1243  if ( myFieldType == QVariant::Int || myFieldType == QVariant::Double || myFieldType == QVariant::LongLong || myFieldType == QVariant::Date )
1244  text = "";
1245  else if ( editType == QgsVectorLayer::UuidGenerator )
1246  text = QUuid::createUuid().toString();
1247  else
1248  text = nullValue;
1249  }
1250  else
1251  {
1252  text = field.displayString( value );
1253  }
1254 
1255  if ( le )
1256  le->setText( text );
1257  if ( cb && cb->isEditable() )
1258  cb->setEditText( text );
1259  if ( te )
1260  te->setHtml( text );
1261  if ( pte )
1262  pte->setPlainText( text );
1263  }
1264  break;
1265 
1268  case QgsVectorLayer::Photo:
1270  case QgsVectorLayer::Color:
1271  {
1272  QCalendarWidget *cw = qobject_cast<QCalendarWidget *>( editor );
1273  if ( cw )
1274  {
1275  cw->setSelectedDate( value.toDate() );
1276  break;
1277  }
1278 
1279  QWebView *ww = qobject_cast<QWebView *>( editor );
1280  if ( ww )
1281  {
1282  ww->load( value.toString() );
1283  break;
1284  }
1285 
1286  QLabel *lw = qobject_cast<QLabel *>( editor );
1287  if ( lw )
1288  break;
1289 
1290  QgsColorButton *cb = qobject_cast<QgsColorButton *>( editor );
1291  if ( cb )
1292  {
1293  cb->setColor( QColor( value.toString() ) );
1294  break;
1295  }
1296 
1297  QgsFilterLineEdit *fle = qobject_cast<QgsFilterLineEdit*>( editor );
1298  QLineEdit *le = qobject_cast<QLineEdit*>( editor );
1299  if ( !le )
1300  {
1301  le = editor->findChild<QLineEdit *>();
1302  fle = qobject_cast<QgsFilterLineEdit *>( le );
1303  }
1304  if ( !le )
1305  return false;
1306 
1307  if ( fle && !( myFieldType == QVariant::Int || myFieldType == QVariant::Double || myFieldType == QVariant::LongLong || myFieldType == QVariant::Date ) )
1308  {
1309  fle->setNullValue( nullValue );
1310  }
1311 
1312  QString text;
1313  if ( value.isNull() )
1314  {
1315  if ( myFieldType == QVariant::Int || myFieldType == QVariant::Double || myFieldType == QVariant::LongLong || myFieldType == QVariant::Date )
1316  text = "";
1317  else
1318  text = nullValue;
1319  }
1320  else if ( editType == QgsVectorLayer::Calendar && value.canConvert( QVariant::Date ) )
1321  {
1322  text = value.toDate().toString( vl->dateFormat( idx ) );
1323  }
1324  else
1325  {
1326  text = value.toString();
1327  }
1328 
1329  le->setText( text );
1330  }
1331  break;
1332 
1334  break;
1335  }
1336 
1337  return true;
1338 }
1339 
1340 QWidget* QgsAttributeEditor::createWidgetFromDef( const QgsAttributeEditorElement* widgetDef, QWidget* parent, QgsVectorLayer* vl, QgsAttributes &attrs, QMap<int, QWidget*> &proxyWidgets, bool createGroupBox )
1341 {
1342  QWidget *newWidget = 0;
1343 
1344  switch ( widgetDef->type() )
1345  {
1347  {
1348  const QgsAttributeEditorField* fieldDef = dynamic_cast<const QgsAttributeEditorField*>( widgetDef );
1349  int fldIdx = fieldDef->idx();
1350  newWidget = createAttributeEditor( parent, 0, vl, fldIdx, attrs.value( fldIdx, QVariant() ), proxyWidgets );
1351 
1352  if ( newWidget )
1353  {
1354  if ( vl->editType( fldIdx ) != QgsVectorLayer::Immutable )
1355  {
1356  if ( newWidget->isEnabled() && vl->isEditable() && vl->fieldEditable( fldIdx ) )
1357  {
1358  newWidget->setEnabled( true );
1359  }
1360  else if ( vl->editType( fldIdx ) == QgsVectorLayer::Photo )
1361  {
1362  foreach ( QWidget *w, newWidget->findChildren<QWidget *>() )
1363  {
1364  w->setEnabled( qobject_cast<QLabel *>( w ) ? true : false );
1365  }
1366  }
1367  else if ( vl->editType( fldIdx ) == QgsVectorLayer::WebView )
1368  {
1369  foreach ( QWidget *w, newWidget->findChildren<QWidget *>() )
1370  {
1371  if ( qobject_cast<QWebView *>( w ) )
1372  w->setEnabled( true );
1373  else if ( qobject_cast<QPushButton *>( w ) && w->objectName() == "openUrl" )
1374  w->setEnabled( true );
1375  else
1376  w->setEnabled( false );
1377  }
1378  }
1379  else
1380  {
1381  newWidget->setEnabled( false );
1382  }
1383  }
1384  }
1385 
1386  break;
1387  }
1388 
1390  {
1391  const QgsAttributeEditorContainer* container = dynamic_cast<const QgsAttributeEditorContainer*>( widgetDef );
1392  QWidget* myContainer;
1393 
1394  if ( createGroupBox )
1395  {
1396  QGroupBox* groupBox = new QGroupBox( parent );
1397  groupBox->setTitle( container->name() );
1398  myContainer = groupBox;
1399  newWidget = myContainer;
1400  }
1401  else
1402  {
1403  QScrollArea *scrollArea = new QScrollArea( parent );
1404 
1405  myContainer = new QWidget( scrollArea );
1406 
1407  scrollArea->setWidget( myContainer );
1408  scrollArea->setWidgetResizable( true );
1409  scrollArea->setFrameShape( QFrame::NoFrame );
1410 
1411  newWidget = scrollArea;
1412  }
1413 
1414  QGridLayout* gbLayout = new QGridLayout( myContainer );
1415  myContainer->setLayout( gbLayout );
1416 
1417  int index = 0;
1418 
1419  QList<QgsAttributeEditorElement*> children = container->children();
1420 
1421  for ( QList<QgsAttributeEditorElement*>::const_iterator it = children.begin(); it != children.end(); ++it )
1422  {
1423  QgsAttributeEditorElement* childDef = *it;
1424  QWidget* editor = createWidgetFromDef( childDef, myContainer, vl, attrs, proxyWidgets, true );
1425 
1426  if ( childDef->type() == QgsAttributeEditorElement::AeTypeContainer )
1427  {
1428  gbLayout->addWidget( editor, index, 0, 1, 2 );
1429  }
1430  else
1431  {
1432  const QgsAttributeEditorField* fieldDef = dynamic_cast<const QgsAttributeEditorField*>( childDef );
1433 
1434  //show attribute alias if available
1435  QString myFieldName = vl->attributeDisplayName( fieldDef->idx() );
1436  QLabel *mypLabel = new QLabel( myFieldName, myContainer );
1437 
1438  if ( vl->labelOnTop( fieldDef->idx() ) )
1439  {
1440  gbLayout->addWidget( mypLabel, index++, 0, 1, 2 );
1441  gbLayout->addWidget( editor, index, 0, 1 , 2 );
1442  }
1443  else
1444  {
1445  gbLayout->addWidget( mypLabel, index, 0 );
1446  gbLayout->addWidget( editor, index, 1 );
1447  }
1448  }
1449 
1450  ++index;
1451  }
1452  gbLayout->addItem( new QSpacerItem( 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding ), index , 0 );
1453 
1454  break;
1455  }
1456 
1457  default:
1458  QgsDebugMsg( "Unknown attribute editor widget type encountered..." );
1459  break;
1460  }
1461 
1462  return newWidget;
1463 }
1464 
1466 {
1467  QObject* sObj = QObject::sender();
1468  QTextEdit *te = qobject_cast<QTextEdit *>( sObj );
1469  QPlainTextEdit *pte = qobject_cast<QPlainTextEdit *>( sObj );
1470 
1471  if ( te )
1472  changeText( te->toPlainText() );
1473  if ( pte )
1474  changeText( pte->toPlainText() );
1475 }
1476 
1477 void QgsStringRelay::changeText( QString str )
1478 {
1479  QObject* sObj = QObject::sender();
1480  const char* sSlot = sObj->property( "QgisAttrEditSlot" ).toByteArray().constData();
1481 
1482  // disconnect widget being edited from relay's signal
1483  disconnect( this, SIGNAL( textChanged( QString ) ), sObj, sSlot );
1484 
1485  // block all proxies' signals
1486  QList<bool> oldBlockSigs;
1487  for ( int i = 0; i < mProxyList.size(); ++i )
1488  {
1489  oldBlockSigs << ( mProxyList[i] )->blockSignals( true );
1490  }
1491 
1492  // update all proxies not being edited without creating cyclical signals/slots
1493  emit textChanged( str );
1494 
1495  // reconnect widget being edited and reset blockSignals state
1496  connect( this, SIGNAL( textChanged( QString ) ), sObj, sSlot );
1497  for ( int i = 0; i < mProxyList.size(); ++i )
1498  {
1499  mProxyList[i]->blockSignals( oldBlockSigs[i] );
1500  }
1501 }
Class for parsing and evaluation of expressions (formerly called "search strings").
Definition: qgsexpression.h:88
QMap< QString, QVariant > & valueMap(int idx)
access value map
Wrapper for iterator of features from vector data provider or vector layer.
void appendProxy(QWidget *proxy)
QgsFeatureRendererV2 * rendererV2()
Return renderer V2.
bool fieldEditable(int idx)
is edit widget editable
bool hasParserError() const
Returns true if an error occurred when parsing the input expression.
Definition: qgsexpression.h:95
QList< QWidget * > mProxyList
RangeData & range(int idx)
access range
static bool retrieveValue(QWidget *widget, QgsVectorLayer *vl, int idx, QVariant &value)
QVariant evaluate(const QgsFeature *f=NULL)
Evaluate the feature and return the result.
virtual void enumValues(int index, QStringList &enumList)
Returns the possible enum values of an attribute.
bool prepare(const QgsFields &fields)
Get the expression ready for evaluation - find out column indexes.
QString displayString(const QVariant &v) const
Formats string for display.
Definition: qgsfield.cpp:114
The attribute value should not be changed in the attribute form.
#define QgsDebugMsg(str)
Definition: qgslogger.h:36
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())
Query the provider for features specified in request.
void textChanged(QString)
static QListWidget * listWidget(QWidget *editor, QWidget *parent)
QgsAttributeEditor(QObject *parent, QgsVectorLayer *vl=0, int idx=-1)
A cross platform button subclass for selecting colors. Will open a color chooser dialog when clicked...
virtual void uniqueValues(int index, QList< QVariant > &uniqueValues, int limit=-1)
Return unique values of an attribute.
QColor color() const
Return the currently selected color.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:114
QgsVectorLayer * mLayer
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.
double ANALYSIS_EXPORT max(double x, double y)
returns the maximum of two doubles or the first argument if both are equal
QList< QgsRendererCategoryV2 > QgsCategoryList
QSize & widgetSize(int idx)
access widget size for photo and webview widget
QString dateFormat() const
QString attributeDisplayName(int attributeIndex) const
Convenience function that returns the attribute alias if defined or the field name else...
The attribute value should not be shown in the attribute form.
EditType editType(int idx)
get edit type
QStringList referencedColumns()
Get list of columns referenced by the expression.
static bool setValue(QWidget *widget, QgsVectorLayer *vl, int idx, const QVariant &value)
This class wraps a request for features to a vector layer (or directly its vector data provider)...
AttributeEditorType type() const
QString & dateFormat(int idx)
access date format
Lineedit with builtin clear button.
QPair< QString, QString > checkedState(int idx)
return string representing 'true' for a checkbox (added in 1.4)
static QComboBox * comboBox(QWidget *editor, QWidget *parent)
void setNullValue(QString nullValue)
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:29
ValueRelationData & valueRelation(int idx)
access relations
void loadPixmap(const QString &)
bool labelOnTop(int idx)
label widget on top
QList< QgsAttributeEditorElement * > children() const
bool needsGeometry()
Returns true if the expression uses feature geometry for some computation.
uuid generator - readonly and automatically intialized
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.
static QgsMapLayerRegistry * instance()
Returns the instance pointer, creating the object on the first call.
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
Definition: qgsfeature.cpp:231
static QgsNetworkAccessManager * instance()
returns a pointer to the single instance
QVector< QVariant > QgsAttributes
Definition: qgsfeature.h:100
void setColor(const QColor &color)
Specify the current color.
QgsMapLayer * mapLayer(QString theLayerId)
Retrieve a pointer to a loaded layer by id.
const QgsFields & pendingFields() const
returns field list in the to-be-committed state
QgsVectorDataProvider * dataProvider()
Returns the data provider.
double ANALYSIS_EXPORT min(double x, double y)
returns the minimum of two doubles or the first argument if both are equal
bool nextFeature(QgsFeature &f)
Do not fetch geometry.
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.
double size
Definition: qgssvgcache.cpp:75
void loadUrl(const QString &)
value map from an table
QVariant::Type type() const
Gets variant type of the field as it will be retrieved from data source.
Definition: qgsfield.cpp:60
#define tr(sourceText)