31 #include <QScrollArea>
32 #include <QPushButton>
35 #include <QFileDialog>
37 #include <QListWidget>
41 #include <QHBoxLayout>
42 #include <QPlainTextEdit>
44 #include <QCalendarWidget>
45 #include <QDialogButtonBox>
52 #include <QDesktopServices>
56 QPushButton *pb = qobject_cast<QPushButton *>( sender() );
60 QWidget *hbox = qobject_cast<QWidget *>( pb->parent() );
64 QLineEdit *le = hbox->findChild<QLineEdit *>();
68 QString fileName = QFileDialog::getOpenFileName( 0 ,
tr(
"Select a file" ), QFileInfo( le->text() ).absolutePath() );
69 if ( fileName.isNull() )
72 le->setText( QDir::toNativeSeparators( fileName ) );
77 QPushButton *pb = qobject_cast<QPushButton *>( sender() );
81 QWidget *hbox = qobject_cast<QWidget *>( pb->parent() );
85 QLineEdit *le = hbox->findChild<QLineEdit *>();
89 QDialog *dlg =
new QDialog();
90 dlg->setWindowTitle(
tr(
"Select a date" ) );
91 QVBoxLayout *vl =
new QVBoxLayout( dlg );
94 QString dateFormat = v ? v->
dateFormat() :
"yyyy-MM-dd";
96 QCalendarWidget *cw =
new QCalendarWidget( dlg );
97 QString prevValue = le->text();
98 cw->setSelectedDate( QDate::fromString( prevValue, dateFormat ) );
101 QDialogButtonBox *buttonBox =
new QDialogButtonBox( dlg );
102 buttonBox->addButton( QDialogButtonBox::Ok );
103 buttonBox->addButton( QDialogButtonBox::Cancel );
104 vl->addWidget( buttonBox );
106 connect( buttonBox, SIGNAL( accepted() ), dlg, SLOT( accept() ) );
107 connect( buttonBox, SIGNAL( rejected() ), dlg, SLOT( reject() ) );
109 if ( dlg->exec() == QDialog::Accepted )
111 QString newValue = cw->selectedDate().toString( dateFormat );
112 le->setText( newValue );
113 le->setModified( newValue != prevValue );
119 QLineEdit *le = qobject_cast<QLineEdit *>( sender() );
123 QWidget *hbox = qobject_cast<QWidget *>( le->parent() );
127 QWebView *ww = hbox->findChild<QWebView *>();
136 QLineEdit *le = qobject_cast<QLineEdit *>( sender() );
140 QWidget *hbox = qobject_cast<QWidget *>( le->parent() );
144 QLabel *lw = hbox->findChild<QLabel *>();
153 if (
size.width() == 0 &&
size.height() > 0 )
155 size.setWidth(
size.height() * pm.size().width() / pm.size().height() );
157 else if (
size.width() > 0 &&
size.height() == 0 )
159 size.setHeight(
size.width() * pm.size().height() / pm.size().width() );
162 pm = pm.scaled(
size, Qt::KeepAspectRatio, Qt::SmoothTransformation );
165 lw->setMinimumSize(
size );
170 QPushButton *pb = qobject_cast<QPushButton *>( sender() );
174 QWidget *hbox = qobject_cast<QWidget *>( pb->parent() );
178 QWebView *ww = hbox->findChild<QWebView *>();
182 QLineEdit *le = hbox->findChild<QLineEdit *>();
186 le->blockSignals(
true );
187 le->setText( ww->url().toString() );
188 le->blockSignals(
false );
193 QPushButton *pb = qobject_cast<QPushButton *>( sender() );
197 QWidget *hbox = qobject_cast<QWidget *>( pb->parent() );
201 QWebView *ww = hbox->findChild<QWebView *>();
212 QLineEdit *sle = qobject_cast<QLineEdit *>( sender() );
217 QWidget *hbox = qobject_cast<QWidget *>( sender()->parent() );
225 QLineEdit *le = hbox->findChild<QLineEdit *>();
231 le->blockSignals(
true );
232 le->setText( scb->
color().name() );
233 le->blockSignals(
false );
238 cb->blockSignals(
true );
239 cb->
setColor( QColor( sle->text() ) );
240 cb->blockSignals(
false );
248 cb = qobject_cast<QComboBox *>( editor );
250 cb =
new QComboBox( parent );
259 lw = qobject_cast<QListWidget *>( editor );
261 lw =
new QListWidget( parent );
268 QMap<int, QWidget*> dummyProxyWidgets;
277 QWidget *myWidget = 0;
280 QVariant::Type myFieldType = field.
type();
282 bool synchronized =
false;
288 QList<QVariant> values;
291 QComboBox *cb =
comboBox( editor, parent );
294 cb->setEditable(
false );
296 for ( QList<QVariant>::iterator it = values.begin(); it != values.end(); it++ )
297 cb->addItem( it->toString(), it->toString() );
307 QStringList enumValues;
310 QComboBox *cb =
comboBox( editor, parent );
313 QStringList::const_iterator s_it = enumValues.constBegin();
314 for ( ; s_it != enumValues.constEnd(); ++s_it )
316 cb->addItem( *s_it, *s_it );
326 const QMap<QString, QVariant> &map = vl->
valueMap( idx );
328 QComboBox *cb =
comboBox( editor, parent );
331 for ( QMap<QString, QVariant>::const_iterator it = map.begin(); it != map.end(); it++ )
333 cb->addItem( it.key(), it.value() );
346 QMap< QString, QString > map;
361 if ( ki >= 0 && vi >= 0 )
363 QSet<int> attributes;
364 attributes << ki << vi;
386 if ( e && !e->
evaluate( &f ).toBool() )
396 QComboBox *cb =
comboBox( editor, parent );
402 cb->addItem(
tr(
"(no selection)" ), settings.value(
"qgis/nullValue",
"NULL" ).toString() );
405 for ( QMap< QString, QString >::const_iterator it = map.begin(); it != map.end(); it++ )
408 cb->addItem( it.key(), it.value() );
410 cb->addItem( it.value(), it.key() );
418 QListWidget *lw =
listWidget( editor, parent );
421 QStringList checkList = value.toString().remove( QChar(
'{' ) ).remove( QChar(
'}' ) ).split(
"," );
423 for ( QMap< QString, QString >::const_iterator it = map.begin(); it != map.end(); it++ )
425 QListWidgetItem *item;
428 item =
new QListWidgetItem( it.key() );
429 item->setData( Qt::UserRole, it.value() );
430 item->setCheckState( checkList.contains( it.value() ) ? Qt::Checked : Qt::Unchecked );
434 item =
new QListWidgetItem( it.value() );
435 item->setData( Qt::UserRole, it.key() );
436 item->setCheckState( checkList.contains( it.key() ) ? Qt::Checked : Qt::Unchecked );
449 QMap<QString, QString> classes;
455 for (
int i = 0; i < categories.size(); i++ )
457 QString label = categories[i].label();
458 QString value = categories[i].value().toString();
459 if ( label.isEmpty() )
461 classes.insert( value, label );
465 QComboBox *cb =
comboBox( editor, parent );
468 for ( QMap<QString, QString>::const_iterator it = classes.begin(); it != classes.end(); it++ )
470 cb->addItem( it.value(), it.key() );
482 if ( myFieldType == QVariant::Int )
493 sb = qobject_cast<QSpinBox *>( editor );
495 sb =
new QSpinBox( parent );
499 sb->setRange( min, max );
500 sb->setSingleStep( step );
507 QAbstractSlider *sl = 0;
511 sl = qobject_cast<QAbstractSlider*>( editor );
515 sl =
new QDial( parent );
519 sl =
new QSlider( Qt::Horizontal, parent );
524 sl->setRange( min, max );
525 sl->setSingleStep( step );
532 else if ( myFieldType == QVariant::Double )
534 QDoubleSpinBox *dsb = 0;
536 dsb = qobject_cast<QDoubleSpinBox*>( editor );
538 dsb =
new QDoubleSpinBox( parent );
544 double step = vl->
range( idx ).
mStep.toDouble();
546 dsb->setRange( min, max );
547 dsb->setSingleStep( step );
561 gb = qobject_cast<QGroupBox *>( editor );
562 cb = qobject_cast<QCheckBox*>( editor );
565 cb =
new QCheckBox( parent );
589 QPlainTextEdit *pte = 0;
594 le = qobject_cast<QLineEdit *>( editor );
595 te = qobject_cast<QTextEdit *>( editor );
596 pte = qobject_cast<QPlainTextEdit *>( editor );
597 cb = qobject_cast<QComboBox *>( editor );
601 pte =
new QPlainTextEdit( parent );
612 QList<QVariant> values;
616 for ( QList<QVariant>::const_iterator it = values.begin(); it != values.end(); it++ )
617 svalues << it->toString();
619 QCompleter *c =
new QCompleter( svalues );
620 c->setCompletionMode( QCompleter::PopupCompletion );
621 le->setCompleter( c );
626 le->setReadOnly(
true );
636 te->setAcceptRichText(
true );
647 if ( cb->isEditable() )
656 myWidget->setDisabled(
true );
661 QMap<int, QWidget*>::const_iterator it = proxyWidgets.find( idx );
662 if ( it != proxyWidgets.end() )
664 QObject* obj = qvariant_cast<QObject*>(( *it )->property(
"QgisAttrEditProxy" ) );
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 ) );
678 rSlot = SLOT( changeText() );
679 wSig = SIGNAL( textChanged() );
683 wSlot = SLOT( setPlainText( QString ) );
685 if ( cb && cb->isEditable() )
687 wSlot = SLOT( setEditText( QString ) );
688 wSig = SIGNAL( editTextChanged( QString ) );
691 synchronized = connect( relay, rSig, myWidget, wSlot );
692 synchronized &= connect( myWidget, wSig, relay, rSlot );
697 if ( !cb || cb->isEditable() )
699 myWidget->setProperty(
"QgisAttrEditSlot", QVariant( QByteArray( wSlot ) ) );
700 myWidget->setProperty(
"QgisAttrEditProxy", QVariant( QMetaType::QObjectStar, &relay ) );
716 QCalendarWidget *cw = qobject_cast<QCalendarWidget *>( editor );
723 QWebView *ww = qobject_cast<QWebView *>( editor );
728 ww->settings()->setAttribute( QWebSettings::LocalContentCanAccessRemoteUrls,
true );
729 ww->settings()->setAttribute( QWebSettings::JavascriptCanOpenWindows,
true );
731 ww->settings()->setAttribute( QWebSettings::DeveloperExtrasEnabled,
true );
735 if (
size.width() > 0 ||
size.height() > 0 )
737 if (
size.width() == 0 )
739 if (
size.height() == 0 )
741 ww->setMinimumSize(
size );
748 QLabel *lw = qobject_cast<QLabel *>( editor );
762 QPushButton *pb0 = 0;
763 QPushButton *pb1 = 0;
764 QLineEdit *le = qobject_cast<QLineEdit *>( editor );
770 if ( editor->parent() )
772 pb0 = editor->parent()->findChild<QPushButton *>();
777 myWidget =
new QWidget( parent );
778 myWidget->setBackgroundRole( QPalette::Window );
779 myWidget->setAutoFillBackground(
true );
787 pb0 =
new QPushButton(
tr(
"..." ), myWidget );
791 pb0 =
new QPushButton(
tr(
"<" ), myWidget );
792 pb0->setObjectName(
"saveUrl" );
793 pb1 =
new QPushButton(
tr(
"..." ), myWidget );
794 pb1->setObjectName(
"openUrl" );
807 QGridLayout *layout =
new QGridLayout( myWidget );
810 lw =
new QLabel( myWidget );
811 layout->addWidget( lw, 0, 0, 1, 2 );
816 ww =
new QWebView( myWidget );
817 ww->setObjectName(
"webview" );
820 ww->settings()->setAttribute( QWebSettings::LocalContentCanAccessRemoteUrls,
true );
821 ww->settings()->setAttribute( QWebSettings::JavascriptCanOpenWindows,
true );
823 ww->settings()->setAttribute( QWebSettings::DeveloperExtrasEnabled,
true );
827 if (
size.width() > 0 ||
size.height() > 0 )
829 if (
size.width() == 0 )
831 if (
size.height() == 0 )
833 ww->setMinimumSize(
size );
836 layout->addWidget( ww, 0, 0, 1, 2 );
840 layout->addWidget( le, row, 0 );
841 layout->addWidget( pb0, row, 1 );
843 layout->addWidget( pb1, row, 2 );
845 myWidget->setLayout( layout );
853 connect( le, SIGNAL( textChanged(
const QString & ) ),
new QgsAttributeEditor( le, vl, idx ), SLOT(
loadUrl(
const QString & ) ) );
865 pb0->setToolTip(
tr(
"Select filename..." ) );
870 pb0->setToolTip(
tr(
"Save current page url in attribute" ) );
875 pb0->setToolTip(
tr(
"Select date in calendar" ) );
880 pb0->setToolTip(
tr(
"Select color in browser" ) );
889 pb1->setToolTip(
tr(
"Open current page in default browser" ) );
896 QMap<int, QWidget*>::const_iterator it = proxyWidgets.find( idx );
897 if ( it != proxyWidgets.end() )
901 myWidget->setEnabled(
false );
906 proxyWidgets.insert( idx, myWidget );
909 setValue( myWidget, vl, idx, value );
921 bool modified =
false;
925 QString nullValue = settings.value(
"qgis/nullValue",
"NULL" ).toString();
927 QLineEdit *le = qobject_cast<QLineEdit *>( widget );
931 modified = le->isModified();
932 if ( text == nullValue )
934 text = QString::null;
938 QTextEdit *te = qobject_cast<QTextEdit *>( widget );
942 modified = te->document()->isModified();
943 if ( text == nullValue )
945 text = QString::null;
949 QPlainTextEdit *pte = qobject_cast<QPlainTextEdit *>( widget );
952 text = pte->toPlainText();
953 modified = pte->document()->isModified();
954 if ( text == nullValue )
956 text = QString::null;
960 QComboBox *cb = qobject_cast<QComboBox *>( widget );
968 text = cb->itemData( cb->currentIndex() ).toString();
969 if ( text == nullValue )
971 text = QString::null;
976 text = cb->currentText();
981 QListWidget *lw = qobject_cast<QListWidget *>( widget );
987 for (
int i = 0, n = 0; i < lw->count(); i++ )
989 if ( lw->item( i )->checkState() == Qt::Checked )
995 text.append( lw->item( i )->data( Qt::UserRole ).toString() );
1003 text = QString::null;
1008 QSpinBox *sb = qobject_cast<QSpinBox *>( widget );
1011 text = QString::number( sb->value() );
1014 QAbstractSlider *slider = qobject_cast<QAbstractSlider *>( widget );
1017 text = QString::number( slider->value() );
1020 QDoubleSpinBox *dsb = qobject_cast<QDoubleSpinBox *>( widget );
1023 text = QString::number( dsb->value() );
1026 QCheckBox *ckb = qobject_cast<QCheckBox *>( widget );
1029 QPair<QString, QString> states = vl->
checkedState( idx );
1030 text = ckb->isChecked() ? states.first : states.second;
1033 QGroupBox *gb = qobject_cast<QGroupBox *>( widget );
1036 QPair<QString, QString> states = vl->
checkedState( idx );
1037 text = gb->isChecked() ? states.first : states.second;
1040 QCalendarWidget *cw = qobject_cast<QCalendarWidget *>( widget );
1043 text = cw->selectedDate().toString( vl->
dateFormat( idx ) );
1046 le = widget->findChild<QLineEdit *>();
1049 if ( !cw && !gb && le )
1052 modified = le->isModified();
1053 if ( text == nullValue )
1055 text = QString::null;
1059 switch ( theField.
type() )
1064 int myIntValue = text.toInt( &ok );
1065 if ( ok && !text.isEmpty() )
1067 value = QVariant( myIntValue );
1070 else if ( modified )
1076 case QVariant::LongLong:
1079 qlonglong myLongValue = text.toLong( &ok );
1080 if ( ok && !text.isEmpty() )
1082 value = QVariant( myLongValue );
1085 else if ( modified )
1090 case QVariant::Double:
1093 double myDblValue = text.toDouble( &ok );
1094 if ( ok && !text.isEmpty() )
1096 value = QVariant( myDblValue );
1099 else if ( modified )
1105 case QVariant::Date:
1107 QDate myDateValue = QDate::fromString( text, vl->
dateFormat( idx ) );
1108 if ( myDateValue.isValid() && !text.isEmpty() )
1110 value = myDateValue;
1113 else if ( modified )
1121 if ( text.isNull() )
1122 value = QVariant( theField.
type() );
1124 value = QVariant( text );
1138 QVariant::Type myFieldType = field.
type();
1141 QString nullValue = settings.value(
"qgis/nullValue",
"NULL" ).toString();
1152 QComboBox *cb = qobject_cast<QComboBox *>( editor );
1161 int idx = cb->findData( v );
1165 cb->setCurrentIndex( idx );
1173 if ( myFieldType == QVariant::Int )
1177 QSpinBox *sb = qobject_cast<QSpinBox *>( editor );
1180 sb->setValue( value.toInt() );
1184 QAbstractSlider *sl = qobject_cast<QAbstractSlider *>( editor );
1187 sl->setValue( value.toInt() );
1191 else if ( myFieldType == QVariant::Double )
1193 QDoubleSpinBox *dsb = qobject_cast<QDoubleSpinBox *>( editor );
1196 dsb->setValue( value.toDouble() );
1202 QGroupBox *gb = qobject_cast<QGroupBox *>( editor );
1205 QPair<QString, QString> states = vl->
checkedState( idx );
1206 gb->setChecked( value == states.first );
1210 QCheckBox *cb = qobject_cast<QCheckBox *>( editor );
1213 QPair<QString, QString> states = vl->
checkedState( idx );
1214 cb->setChecked( value == states.first );
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 )
1235 if ( fle && !( myFieldType == QVariant::Int || myFieldType == QVariant::Double || myFieldType == QVariant::LongLong || myFieldType == QVariant::Date ) )
1241 if ( value.isNull() )
1243 if ( myFieldType == QVariant::Int || myFieldType == QVariant::Double || myFieldType == QVariant::LongLong || myFieldType == QVariant::Date )
1246 text = QUuid::createUuid().toString();
1256 le->setText( text );
1257 if ( cb && cb->isEditable() )
1258 cb->setEditText( text );
1260 te->setHtml( text );
1262 pte->setPlainText( text );
1272 QCalendarWidget *cw = qobject_cast<QCalendarWidget *>( editor );
1275 cw->setSelectedDate( value.toDate() );
1279 QWebView *ww = qobject_cast<QWebView *>( editor );
1282 ww->load( value.toString() );
1286 QLabel *lw = qobject_cast<QLabel *>( editor );
1293 cb->
setColor( QColor( value.toString() ) );
1298 QLineEdit *le = qobject_cast<QLineEdit*>( editor );
1301 le = editor->findChild<QLineEdit *>();
1307 if ( fle && !( myFieldType == QVariant::Int || myFieldType == QVariant::Double || myFieldType == QVariant::LongLong || myFieldType == QVariant::Date ) )
1313 if ( value.isNull() )
1315 if ( myFieldType == QVariant::Int || myFieldType == QVariant::Double || myFieldType == QVariant::LongLong || myFieldType == QVariant::Date )
1322 text = value.toDate().toString( vl->
dateFormat( idx ) );
1326 text = value.toString();
1329 le->setText( text );
1342 QWidget *newWidget = 0;
1344 switch ( widgetDef->
type() )
1349 int fldIdx = fieldDef->
idx();
1350 newWidget =
createAttributeEditor( parent, 0, vl, fldIdx, attrs.value( fldIdx, QVariant() ), proxyWidgets );
1358 newWidget->setEnabled(
true );
1362 foreach ( QWidget *w, newWidget->findChildren<QWidget *>() )
1364 w->setEnabled( qobject_cast<QLabel *>( w ) ?
true :
false );
1369 foreach ( QWidget *w, newWidget->findChildren<QWidget *>() )
1371 if ( qobject_cast<QWebView *>( w ) )
1372 w->setEnabled(
true );
1373 else if ( qobject_cast<QPushButton *>( w ) && w->objectName() ==
"openUrl" )
1374 w->setEnabled(
true );
1376 w->setEnabled(
false );
1381 newWidget->setEnabled(
false );
1392 QWidget* myContainer;
1394 if ( createGroupBox )
1396 QGroupBox* groupBox =
new QGroupBox( parent );
1397 groupBox->setTitle( container->
name() );
1398 myContainer = groupBox;
1399 newWidget = myContainer;
1403 QScrollArea *scrollArea =
new QScrollArea( parent );
1405 myContainer =
new QWidget( scrollArea );
1407 scrollArea->setWidget( myContainer );
1408 scrollArea->setWidgetResizable(
true );
1409 scrollArea->setFrameShape( QFrame::NoFrame );
1411 newWidget = scrollArea;
1414 QGridLayout* gbLayout =
new QGridLayout( myContainer );
1415 myContainer->setLayout( gbLayout );
1419 QList<QgsAttributeEditorElement*> children = container->
children();
1421 for ( QList<QgsAttributeEditorElement*>::const_iterator it = children.begin(); it != children.end(); ++it )
1424 QWidget* editor =
createWidgetFromDef( childDef, myContainer, vl, attrs, proxyWidgets,
true );
1428 gbLayout->addWidget( editor, index, 0, 1, 2 );
1436 QLabel *mypLabel =
new QLabel( myFieldName, myContainer );
1440 gbLayout->addWidget( mypLabel, index++, 0, 1, 2 );
1441 gbLayout->addWidget( editor, index, 0, 1 , 2 );
1445 gbLayout->addWidget( mypLabel, index, 0 );
1446 gbLayout->addWidget( editor, index, 1 );
1452 gbLayout->addItem(
new QSpacerItem( 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding ), index , 0 );
1458 QgsDebugMsg(
"Unknown attribute editor widget type encountered..." );
1467 QObject* sObj = QObject::sender();
1468 QTextEdit *te = qobject_cast<QTextEdit *>( sObj );
1469 QPlainTextEdit *pte = qobject_cast<QPlainTextEdit *>( sObj );
1479 QObject* sObj = QObject::sender();
1480 const char* sSlot = sObj->property(
"QgisAttrEditSlot" ).toByteArray().constData();
1483 disconnect(
this, SIGNAL(
textChanged( QString ) ), sObj, sSlot );
1486 QList<bool> oldBlockSigs;
1487 for (
int i = 0; i <
mProxyList.size(); ++i )
1489 oldBlockSigs << (
mProxyList[i] )->blockSignals(
true );
1496 connect(
this, SIGNAL(
textChanged( QString ) ), sObj, sSlot );
1497 for (
int i = 0; i <
mProxyList.size(); ++i )
1499 mProxyList[i]->blockSignals( oldBlockSigs[i] );