21#include "qgsattributetypedialog.h"
22#include "qgsattributeformcontaineredit.h"
23#include "qgsattributewidgetedit.h"
51 mEditorLayoutComboBox->addItem( tr(
"Autogenerate" ), QVariant::fromValue( Qgis::AttributeFormLayout::AutoGenerated ) );
52 mEditorLayoutComboBox->addItem( tr(
"Drag and Drop Designer" ), QVariant::fromValue( Qgis::AttributeFormLayout::DragAndDrop ) );
53 mEditorLayoutComboBox->addItem( tr(
"Provide ui-file" ), QVariant::fromValue( Qgis::AttributeFormLayout::UiFile ) );
56 QGridLayout *availableWidgetsWidgetLayout =
new QGridLayout;
59 availableWidgetsWidgetLayout->setContentsMargins( 0, 0, 0, 0 );
60 mAvailableWidgetsWidget->setLayout( availableWidgetsWidgetLayout );
66 QGridLayout *formLayoutWidgetLayout =
new QGridLayout;
68 mFormLayoutWidget->setLayout( formLayoutWidgetLayout );
70 formLayoutWidgetLayout->setContentsMargins( 0, 0, 0, 0 );
71 mFormLayoutTree->setHeaderLabels( QStringList() << tr(
"Form Layout" ) );
74 connect(
mAvailableWidgetsTree, &QTreeWidget::itemSelectionChanged,
this, &QgsAttributesFormProperties::onAttributeSelectionChanged );
75 connect(
mFormLayoutTree, &QTreeWidget::itemSelectionChanged,
this, &QgsAttributesFormProperties::onFormLayoutSelectionChanged );
76 connect( mAddTabOrGroupButton, &QAbstractButton::clicked,
this, &QgsAttributesFormProperties::addContainer );
77 connect( mRemoveTabOrGroupButton, &QAbstractButton::clicked,
this, &QgsAttributesFormProperties::removeTabOrGroupButton );
78 connect( mInvertSelectionButton, &QAbstractButton::clicked,
this, &QgsAttributesFormProperties::onInvertSelectionButtonClicked );
79 connect( mEditorLayoutComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsAttributesFormProperties::mEditorLayoutComboBox_currentIndexChanged );
80 connect( pbnSelectEditForm, &QToolButton::clicked,
this, &QgsAttributesFormProperties::pbnSelectEditForm_clicked );
81 connect( mTbInitCode, &QPushButton::clicked,
this, &QgsAttributesFormProperties::mTbInitCode_clicked );
108 for (
int i = 0; i < fields.
size(); ++i )
126 item->setToolTip( 0, tooltip );
128 catitem->setExpanded(
true );
143 catitem->setExpanded(
true );
151 for (
const auto &action : std::as_const( actions ) )
153 if ( action.isValid() && action.runable() &&
154 ( action.actionScopes().contains( QStringLiteral(
"Feature" ) ) ||
155 action.actionScopes().contains( QStringLiteral(
"Layer" ) ) ) )
157 const QString actionTitle { action.shortTitle().isEmpty() ? action.name() : action.shortTitle() };
184 catitem ->setExpanded(
true );
192 mFormLayoutTree->setSelectionBehavior( QAbstractItemView::SelectRows );
193 mFormLayoutTree->setSelectionMode( QAbstractItemView::SelectionMode::ExtendedSelection );
209 mFormSuppressCmbBx->addItem( tr(
"Hide Form on Add Feature (global settings)" ), QVariant::fromValue( Qgis::AttributeFormSuppression::Default ) );
213 mFormSuppressCmbBx->addItem( tr(
"Show Form on Add Feature (global settings)" ), QVariant::fromValue( Qgis::AttributeFormSuppression::Default ) );
215 mFormSuppressCmbBx->addItem( tr(
"Hide Form on Add Feature" ), QVariant::fromValue( Qgis::AttributeFormSuppression::On ) );
216 mFormSuppressCmbBx->addItem( tr(
"Show Form on Add Feature" ), QVariant::fromValue( Qgis::AttributeFormSuppression::Off ) );
230 mEditorLayoutComboBox->setCurrentIndex( mEditorLayoutComboBox->findData( QVariant::fromValue(
mLayer->
editFormConfig().
layout() ) ) );
232 mEditorLayoutComboBox_currentIndexChanged( mEditorLayoutComboBox->currentIndex() );
235 mEditFormLineEdit->setText( cfg.
uiForm() );
247 if ( mInitCode.isEmpty() )
249 mInitCode.append( tr(
"# -*- coding: utf-8 -*-\n\"\"\"\n"
250 "QGIS forms can have a Python function that is called when the form is\n"
253 "Use this function to add extra logic to your forms.\n"
255 "Enter the name of the function in the \"Python Init function\"\n"
257 "An example follows:\n"
259 "from qgis.PyQt.QtWidgets import QWidget\n\n"
260 "def my_form_open(dialog, layer, feature):\n"
261 " geom = feature.geometry()\n"
262 " control = dialog.findChild(QWidget, \"MyLineEdit\")\n" ) );
266void QgsAttributesFormProperties::loadAttributeTypeDialog()
273 const FieldConfig cfg = item->data( 0,
FieldConfigRole ).value<FieldConfig>();
274 const QString fieldName = item->data( 0,
FieldNameRole ).toString();
296 QgsFieldConstraints::Constraints providerConstraints = QgsFieldConstraints::Constraints();
315 mAttributeTypeFrame->layout()->setContentsMargins( 0, 0, 0, 0 );
321void QgsAttributesFormProperties::storeAttributeTypeDialog()
371 cfg.mFieldConstraints = constraints;
384 QTreeWidgetItem *item = *itemIt;
385 if ( item->data( 0,
FieldNameRole ).toString() == fieldName )
386 item->setData( 0,
FieldConfigRole, QVariant::fromValue<FieldConfig>( cfg ) );
390void QgsAttributesFormProperties::storeAttributeWidgetEdit()
398void QgsAttributesFormProperties::loadAttributeWidgetEdit()
403 QTreeWidgetItem *currentItem =
mFormLayoutTree->selectedItems().at( 0 );
405 mAttributeTypeFrame->layout()->setContentsMargins( 0, 0, 0, 0 );
409void QgsAttributesFormProperties::loadInfoWidget(
const QString &infoText )
412 mAttributeTypeFrame->layout()->setContentsMargins( 0, 0, 0, 0 );
416void QgsAttributesFormProperties::storeAttributeContainerEdit()
424void QgsAttributesFormProperties::loadAttributeContainerEdit()
429 QTreeWidgetItem *currentItem =
mFormLayoutTree->selectedItems().at( 0 );
433 mAttributeTypeFrame->layout()->setContentsMargins( 0, 0, 0, 0 );
440 auto setCommonProperties = [widgetDef]( DnDTreeItemData & itemData )
442 itemData.setShowLabel( widgetDef->
showLabel() );
443 itemData.setLabelStyle( widgetDef->
labelStyle() );
448 QTreeWidgetItem *newWidget =
nullptr;
449 switch ( widgetDef->
type() )
451 case Qgis::AttributeEditorType::Field:
454 setCommonProperties( itemData );
455 newWidget = tree->
addItem( parent, itemData );
459 case Qgis::AttributeEditorType::Action:
463 if ( action.isValid() )
465 DnDTreeItemData itemData = DnDTreeItemData(
DnDTreeItemData::Action, action.id().toString(), action.shortTitle().isEmpty() ? action.name() : action.shortTitle() );
466 setCommonProperties( itemData );
467 newWidget = tree->
addItem( parent, itemData );
476 case Qgis::AttributeEditorType::Relation:
480 setCommonProperties( itemData );
482 RelationEditorConfiguration relEdConfig;
486 relEdConfig.nmRelationId = relationEditor->
nmRelationId();
488 relEdConfig.label = relationEditor->
label();
489 itemData.setRelationEditorConfiguration( relEdConfig );
490 newWidget = tree->
addItem( parent, itemData );
494 case Qgis::AttributeEditorType::Container:
503 itemData.setContainerType( container->
type() );
507 itemData.setCollapsed( container->
collapsed() );
509 setCommonProperties( itemData );
511 newWidget = tree->
addItem( parent, itemData );
513 const QList<QgsAttributeEditorElement *> children = container->
children();
516 loadAttributeEditorTreeItem( wdg, newWidget, tree );
521 case Qgis::AttributeEditorType::QmlElement:
525 QmlElementEditorConfiguration qmlEdConfig;
526 qmlEdConfig.qmlCode = qmlElementEditor->
qmlCode();
527 itemData.setQmlElementEditorConfiguration( qmlEdConfig );
528 setCommonProperties( itemData );
529 newWidget = tree->
addItem( parent, itemData );
533 case Qgis::AttributeEditorType::HtmlElement:
537 HtmlElementEditorConfiguration htmlEdConfig;
538 htmlEdConfig.htmlCode = htmlElementEditor->
htmlCode();
539 itemData.setHtmlElementEditorConfiguration( htmlEdConfig );
540 setCommonProperties( itemData );
541 newWidget = tree->
addItem( parent, itemData );
545 case Qgis::AttributeEditorType::TextElement:
549 TextElementEditorConfiguration textEdConfig;
550 textEdConfig.text = textElementEditor->
text();
551 itemData.setTextElementEditorConfiguration( textEdConfig );
552 setCommonProperties( itemData );
553 newWidget = tree->
addItem( parent, itemData );
557 case Qgis::AttributeEditorType::SpacerElement:
561 SpacerElementEditorConfiguration spacerEdConfig;
562 spacerEdConfig.drawLine = spacerElementEditor->
drawLine();
563 itemData.setSpacerElementEditorConfiguration( spacerEdConfig );
564 setCommonProperties( itemData );
565 itemData.setShowLabel(
false );
566 newWidget = tree->
addItem( parent, itemData );
570 case Qgis::AttributeEditorType::Invalid:
572 QgsDebugError( QStringLiteral(
"Not loading invalid attribute editor type..." ) );
578 newWidget->setExpanded(
true );
584void QgsAttributesFormProperties::onAttributeSelectionChanged()
586 disconnect(
mFormLayoutTree, &QTreeWidget::itemSelectionChanged,
this, &QgsAttributesFormProperties::onFormLayoutSelectionChanged );
588 connect(
mFormLayoutTree, &QTreeWidget::itemSelectionChanged,
this, &QgsAttributesFormProperties::onFormLayoutSelectionChanged );
591void QgsAttributesFormProperties::onFormLayoutSelectionChanged()
594 disconnect(
mAvailableWidgetsTree, &QTreeWidget::itemSelectionChanged,
this, &QgsAttributesFormProperties::onAttributeSelectionChanged );
596 connect(
mAvailableWidgetsTree, &QTreeWidget::itemSelectionChanged,
this, &QgsAttributesFormProperties::onAttributeSelectionChanged );
603 if ( layout == Qgis::AttributeFormLayout::DragAndDrop )
604 storeAttributeWidgetEdit();
605 storeAttributeTypeDialog();
606 storeAttributeContainerEdit();
608 clearAttributeTypeFrame();
610 if ( emitter->selectedItems().count() != 1 )
612 receiver->clearSelection();
616 const DnDTreeItemData itemData = emitter->selectedItems().at( 0 )->data( 0,
DnDTreeRole ).value<DnDTreeItemData>();
617 switch ( itemData.type() )
622 if ( layout == Qgis::AttributeFormLayout::DragAndDrop )
624 loadAttributeWidgetEdit();
628 loadInfoWidget( tr(
"This configuration is available in the Drag and Drop Designer" ) );
635 if ( layout == Qgis::AttributeFormLayout::DragAndDrop )
636 loadAttributeWidgetEdit();
637 loadAttributeTypeDialog();
642 receiver->clearSelection();
643 loadAttributeContainerEdit();
650 loadInfoWidget( action.html() );
658 if ( layout != Qgis::AttributeFormLayout::DragAndDrop )
660 loadInfoWidget( tr(
"This configuration is available with double-click in the Drag and Drop Designer" ) );
664 loadInfoWidget( tr(
"This configuration is available with double-click" ) );
666 receiver->clearSelection();
671 receiver->clearSelection();
678void QgsAttributesFormProperties::clearAttributeTypeFrame()
706void QgsAttributesFormProperties::onInvertSelectionButtonClicked(
bool checked )
711 for (
int i = 0; i < rootItem->childCount(); ++i )
713 rootItem->child( i )->setSelected( ! selectedItemList.contains( rootItem->child( i ) ) );
717void QgsAttributesFormProperties::addContainer()
719 QList<QgsAddAttributeFormContainerDialog::ContainerPair> existingContainerList;
723 const DnDTreeItemData itemData = ( *it )->data( 0,
DnDTreeRole ).value<DnDTreeItemData>();
729 QTreeWidgetItem *currentItem =
mFormLayoutTree->selectedItems().value( 0 );
732 if ( !dialog.exec() )
735 const QString name = dialog.name();
736 QTreeWidgetItem *parentContainerItem = dialog.parentContainerItem();
739 dialog.columnCount(),
740 dialog.containerType() );
743void QgsAttributesFormProperties::removeTabOrGroupButton()
749 const QList<QTreeWidgetItem *> items =
mFormLayoutTree->selectedItems();
753 delete items.at( 0 );
764 switch ( itemData.
type() )
812 for (
int t = 0; t < item->childCount(); t++ )
819 widgetDef = container;
871void QgsAttributesFormProperties::mEditorLayoutComboBox_currentIndexChanged(
int )
876 case Qgis::AttributeFormLayout::AutoGenerated:
877 mFormLayoutWidget->setVisible(
false );
878 mUiFileFrame->setVisible(
false );
879 mAddTabOrGroupButton->setVisible(
false );
880 mRemoveTabOrGroupButton->setVisible(
false );
881 mInvertSelectionButton->setVisible(
false );
884 case Qgis::AttributeFormLayout::DragAndDrop:
885 mFormLayoutWidget->setVisible(
true );
886 mUiFileFrame->setVisible(
false );
887 mAddTabOrGroupButton->setVisible(
true );
888 mRemoveTabOrGroupButton->setVisible(
true );
889 mInvertSelectionButton->setVisible(
true );
892 case Qgis::AttributeFormLayout::UiFile:
894 mFormLayoutWidget->setVisible(
false );
895 mUiFileFrame->setVisible(
true );
896 mAddTabOrGroupButton->setVisible(
false );
897 mRemoveTabOrGroupButton->setVisible(
false );
898 mInvertSelectionButton->setVisible(
false );
903void QgsAttributesFormProperties::mTbInitCode_clicked()
912 if ( !attributesFormInitCode.exec() )
915 mInitCodeSource = attributesFormInitCode.
codeSource();
916 mInitCode = attributesFormInitCode.
initCode();
922void QgsAttributesFormProperties::pbnSelectEditForm_clicked()
925 const QString lastUsedDir = myQSettings.
value( QStringLiteral(
"style/lastUIDir" ), QDir::homePath() ).toString();
926 const QString uifilename = QFileDialog::getOpenFileName(
this, tr(
"Select edit form" ), lastUsedDir, tr(
"UI file" ) +
" (*.ui)" );
928 if ( uifilename.isNull() )
931 const QFileInfo fi( uifilename );
932 myQSettings.
setValue( QStringLiteral(
"style/lastUIDir" ), fi.path() );
933 mEditFormLineEdit->setText( uifilename );
938 storeAttributeWidgetEdit();
939 storeAttributeContainerEdit();
940 storeAttributeTypeDialog();
946 for (
int i = 0; i < fieldContainer->childCount(); i++ )
948 QTreeWidgetItem *fieldItem = fieldContainer->child( i );
951 const QString fieldName { fieldItem->data( 0,
FieldNameRole ).toString() };
1002 for (
int t = 0; t <
mFormLayoutTree->invisibleRootItem()->childCount(); t++ )
1004 QTreeWidgetItem *tabItem =
mFormLayoutTree->invisibleRootItem()->child( t );
1006 if ( editorElement )
1007 editFormConfig.
addTab( editorElement );
1010 editFormConfig.
setUiForm( mEditFormLineEdit->text() );
1024 for (
int i = 0; i < relationContainer->childCount(); i++ )
1026 QTreeWidgetItem *relationItem = relationContainer->child( i );
1029 for (
int t = 0; t <
mFormLayoutTree->invisibleRootItem()->childCount(); t++ )
1031 QTreeWidgetItem *tabItem =
mFormLayoutTree->invisibleRootItem()->child( t );
1034 if ( tabItemData.
type() == itemData.
type() && tabItemData.
name() == itemData.
name() )
1071QgsAttributesFormProperties::FieldConfig::operator QVariant()
1073 return QVariant::fromValue<QgsAttributesFormProperties::FieldConfig>( *
this );
1080QgsAttributesFormProperties::RelationEditorConfiguration::operator QVariant()
1082 return QVariant::fromValue<QgsAttributesFormProperties::RelationEditorConfiguration>( *
this );
1091 QTreeWidgetItem *newItem =
new QTreeWidgetItem( QStringList() << title );
1092 newItem->setBackground( 0, QBrush( Qt::lightGray ) );
1093 newItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled );
1098 parent->addChild( newItem );
1099 newItem->setExpanded(
true );
1104 : QTreeWidget( parent )
1107 connect(
this, &QTreeWidget::itemDoubleClicked,
this, &QgsAttributesDnDTree::onItemDoubleClicked );
1112 QTreeWidgetItem *newItem =
new QTreeWidgetItem( QStringList() << data.
name() );
1114 switch ( data.
type() )
1123 newItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled );
1129 newItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled );
1130 newItem->setBackground( 0, QBrush( Qt::lightGray ) );
1137 newItem->setIcon( 0, icon );
1140 parent->addChild( newItem );
1142 parent->insertChild( index, newItem );
1154 const QMimeData *data =
event->mimeData();
1156 if ( data->hasFormat( QStringLiteral(
"application/x-qgsattributetabledesignerelement" ) ) )
1160 QByteArray itemData = data->data( QStringLiteral(
"application/x-qgsattributetabledesignerelement" ) );
1161 QDataStream stream( &itemData, QIODevice::ReadOnly );
1162 stream >> itemElement;
1165 if ( event->source() ==
this )
1167 event->setDropAction( Qt::MoveAction );
1175 QTreeWidget::dragMoveEvent( event );
1181 bool bDropSuccessful =
false;
1183 if ( action == Qt::IgnoreAction )
1185 bDropSuccessful =
true;
1187 else if ( data->hasFormat( QStringLiteral(
"application/x-qgsattributetabledesignerelement" ) ) )
1189 QByteArray itemData = data->data( QStringLiteral(
"application/x-qgsattributetabledesignerelement" ) );
1190 QDataStream stream( &itemData, QIODevice::ReadOnly );
1193 while ( !stream.atEnd() )
1195 stream >> itemElement;
1197 QTreeWidgetItem *newItem;
1201 newItem =
addItem( parent, itemElement, index++ );
1202 bDropSuccessful =
true;
1206 newItem =
addItem( invisibleRootItem(), itemElement, index++ );
1207 bDropSuccessful =
true;
1212 onItemDoubleClicked( newItem, 0 );
1217 onItemDoubleClicked( newItem, 0 );
1222 onItemDoubleClicked( newItem, 0 );
1227 onItemDoubleClicked( newItem, 0 );
1231 newItem->setSelected(
true );
1235 return bDropSuccessful;
1240 if ( !event->mimeData()->hasFormat( QStringLiteral(
"application/x-qgsattributetabledesignerelement" ) ) )
1243 if ( event->source() ==
this )
1245 event->setDropAction( Qt::MoveAction );
1248 QTreeWidget::dropEvent( event );
1253 return QStringList() << QStringLiteral(
"application/x-qgsattributetabledesignerelement" );
1256#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1262 if ( items.count() <= 0 )
1265 const QStringList types = mimeTypes();
1267 if ( types.isEmpty() )
1270 QMimeData *data =
new QMimeData();
1271 const QString format = types.at( 0 );
1273 QDataStream stream( &encoded, QIODevice::WriteOnly );
1275 const auto constItems = items;
1276 for (
const QTreeWidgetItem *item : constItems )
1286 data->setData( format, encoded );
1291void QgsAttributesDnDTree::onItemDoubleClicked( QTreeWidgetItem *item,
int column )
1297 QGroupBox *baseData =
new QGroupBox( tr(
"Base configuration" ) );
1299 QFormLayout *baseLayout =
new QFormLayout();
1300 baseData->setLayout( baseLayout );
1301 QCheckBox *showLabelCheckbox =
new QCheckBox( QStringLiteral(
"Show label" ) );
1302 showLabelCheckbox->setChecked( itemData.
showLabel() );
1303 baseLayout->addRow( showLabelCheckbox );
1304 QWidget *baseWidget =
new QWidget();
1305 baseWidget->setLayout( baseLayout );
1307 switch ( itemData.
type() )
1318 if ( mType == QgsAttributesDnDTree::Type::Drag )
1322 dlg.setWindowTitle( tr(
"Configure QML Widget" ) );
1324 QVBoxLayout *mainLayout =
new QVBoxLayout();
1325 QHBoxLayout *qmlLayout =
new QHBoxLayout();
1326 QVBoxLayout *layout =
new QVBoxLayout();
1327 mainLayout->addLayout( qmlLayout );
1328 qmlLayout->addLayout( layout );
1329 dlg.setLayout( mainLayout );
1330 layout->addWidget( baseWidget );
1332 QLineEdit *title =
new QLineEdit( itemData.
name() );
1336 qmlCode->setPlaceholderText( tr(
"Insert QML code here…" ) );
1343 connect( qmlCode, &QPlainTextEdit::textChanged,
this, [ = ]
1345 qmlWrapper->
setQmlCode( qmlCode->toPlainText() );
1351 QComboBox *qmlObjectTemplate =
new QComboBox();
1352 qmlObjectTemplate->addItem( tr(
"Free Text…" ) );
1353 qmlObjectTemplate->addItem( tr(
"Rectangle" ) );
1354 qmlObjectTemplate->addItem( tr(
"Pie Chart" ) );
1355 qmlObjectTemplate->addItem( tr(
"Bar Chart" ) );
1356 connect( qmlObjectTemplate, qOverload<int>( &QComboBox::activated ), qmlCode, [ = ](
int index )
1363 qmlCode->setPlaceholderText( tr(
"Insert QML code here…" ) );
1368 qmlCode->insertPlainText( QStringLiteral(
"import QtQuick 2.0\n"
1373 " color: \"steelblue\"\n"
1374 " Text{ text: \"A rectangle\" }\n"
1380 qmlCode->insertPlainText( QStringLiteral(
"import QtQuick 2.0\n"
1381 "import QtCharts 2.0\n"
1389 " PieSlice { label: \"First slice\"; value: 25 }\n"
1390 " PieSlice { label: \"Second slice\"; value: 45 }\n"
1391 " PieSlice { label: \"Third slice\"; value: 30 }\n"
1398 qmlCode->insertPlainText( QStringLiteral(
"import QtQuick 2.0\n"
1399 "import QtCharts 2.0\n"
1402 " title: \"Bar series\"\n"
1405 " legend.alignment: Qt.AlignBottom\n"
1406 " antialiasing: true\n"
1415 " axisY: valueAxisY\n"
1416 " axisX: BarCategoryAxis { categories: [\"2007\", \"2008\", \"2009\", \"2010\", \"2011\", \"2012\" ] }\n"
1417 " BarSet { label: \"Bob\"; values: [2, 2, 3, 4, 5, 6] }\n"
1418 " BarSet { label: \"Susan\"; values: [5, 1, 2, 4, 1, 7] }\n"
1419 " BarSet { label: \"James\"; values: [3, 5, 8, 13, 5, 8] }\n"
1430 expressionWidget->
setLayer( mLayer );
1431 QToolButton *addExpressionButton =
new QToolButton();
1434 connect( addExpressionButton, &QAbstractButton::clicked,
this, [ = ]
1436 qmlCode->insertPlainText( QStringLiteral(
"expression.evaluate(\"%1\")" ).arg( expressionWidget->expression().replace(
'"', QLatin1String(
"\\\"" ) ) ) );
1439 layout->addWidget(
new QLabel( tr(
"Title" ) ) );
1440 layout->addWidget( title );
1441 QGroupBox *qmlCodeBox =
new QGroupBox( tr(
"QML Code" ) );
1442 qmlCodeBox->setLayout(
new QGridLayout );
1443 qmlCodeBox->layout()->addWidget( qmlObjectTemplate );
1444 QGroupBox *expressionWidgetBox =
new QGroupBox();
1445 qmlCodeBox->layout()->addWidget( expressionWidgetBox );
1446 expressionWidgetBox->setLayout(
new QHBoxLayout );
1447 expressionWidgetBox->layout()->addWidget( expressionWidget );
1448 expressionWidgetBox->layout()->addWidget( addExpressionButton );
1449 qmlCodeBox->layout()->addWidget( qmlCode );
1450 layout->addWidget( qmlCodeBox );
1452 qmlPreviewBox->setLayout(
new QGridLayout );
1453 qmlPreviewBox->setMinimumWidth( 400 );
1454 qmlPreviewBox->layout()->addWidget( qmlWrapper->
widget() );
1456 emit qmlCode->textChanged();
1457 qmlLayout->addWidget( qmlPreviewBox );
1459 QDialogButtonBox *buttonBox =
new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
1461 connect( buttonBox, &QDialogButtonBox::accepted, &dlg, &QDialog::accept );
1462 connect( buttonBox, &QDialogButtonBox::rejected, &dlg, &QDialog::reject );
1464 mainLayout->addWidget( buttonBox );
1469 qmlEdCfg.
qmlCode = qmlCode->toPlainText();
1470 itemData.
setName( title->text() );
1472 itemData.
setShowLabel( showLabelCheckbox->isChecked() );
1475 item->setText( 0, title->text() );
1482 if ( mType == QgsAttributesDnDTree::Type::Drag )
1485 dlg.setWindowTitle( tr(
"Configure HTML Widget" ) );
1487 QVBoxLayout *mainLayout =
new QVBoxLayout();
1488 QHBoxLayout *htmlLayout =
new QHBoxLayout();
1489 QVBoxLayout *layout =
new QVBoxLayout();
1490 mainLayout->addLayout( htmlLayout );
1491 htmlLayout->addLayout( layout );
1492 dlg.setLayout( mainLayout );
1493 layout->addWidget( baseWidget );
1495 QLineEdit *title =
new QLineEdit( itemData.
name() );
1499 htmlCode->setSizePolicy( QSizePolicy::Policy::Expanding, QSizePolicy::Policy::Expanding );
1507 connect( htmlCode, &QgsCodeEditorHTML::textChanged,
this, [ = ]
1516 expressionWidget->setLayer( mLayer );
1517 QToolButton *addExpressionButton =
new QToolButton();
1520 connect( addExpressionButton, &QAbstractButton::clicked,
this, [ = ]
1522 htmlCode->
insertText( QStringLiteral(
"<script>document.write(expression.evaluate(\"%1\"));</script>" ).arg( expressionWidget->expression().replace(
'"', QLatin1String(
"\\\"" ) ) ) );
1525 layout->addWidget(
new QLabel( tr(
"Title" ) ) );
1526 layout->addWidget( title );
1527 QGroupBox *expressionWidgetBox =
new QGroupBox( tr(
"HTML Code" ) );
1528 layout->addWidget( expressionWidgetBox );
1529 expressionWidgetBox->setLayout(
new QHBoxLayout );
1530 expressionWidgetBox->layout()->addWidget( expressionWidget );
1531 expressionWidgetBox->layout()->addWidget( addExpressionButton );
1532 layout->addWidget( htmlCode );
1534 htmlPreviewBox->setLayout(
new QGridLayout );
1535 htmlPreviewBox->setMinimumWidth( 400 );
1536 htmlPreviewBox->layout()->addWidget( htmlWrapper->
widget() );
1538 emit htmlCode->textChanged();
1539 htmlLayout->addWidget( htmlPreviewBox );
1541 QDialogButtonBox *buttonBox =
new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
1543 connect( buttonBox, &QDialogButtonBox::accepted, &dlg, &QDialog::accept );
1544 connect( buttonBox, &QDialogButtonBox::rejected, &dlg, &QDialog::reject );
1546 mainLayout->addWidget( buttonBox );
1551 htmlEdCfg.
htmlCode = htmlCode->text();
1552 itemData.
setName( title->text() );
1554 itemData.
setShowLabel( showLabelCheckbox->isChecked() );
1557 item->setText( 0, title->text() );
1564 if ( mType == QgsAttributesDnDTree::Type::Drag )
1567 dlg.setWindowTitle( tr(
"Configure Text Widget" ) );
1569 QVBoxLayout *mainLayout =
new QVBoxLayout();
1570 QHBoxLayout *textLayout =
new QHBoxLayout();
1571 QVBoxLayout *layout =
new QVBoxLayout();
1572 mainLayout->addLayout( textLayout );
1573 textLayout->addLayout( layout );
1574 dlg.setLayout( mainLayout );
1575 layout->addWidget( baseWidget );
1577 QLineEdit *title =
new QLineEdit( itemData.
name() );
1580 text->setSizePolicy( QSizePolicy::Policy::Expanding, QSizePolicy::Policy::Expanding );
1588 connect( text, &QgsCodeEditorExpression::textChanged,
this, [ = ]
1590 textWrapper->
setText( text->text( ) );
1596 expressionWidget->
setLayer( mLayer );
1597 QToolButton *addExpressionButton =
new QToolButton();
1600 connect( addExpressionButton, &QAbstractButton::clicked,
this, [ = ]
1602 text->
insertText( expressionWidget->expression().prepend( QStringLiteral(
"[% " ) ).append( QStringLiteral(
" %]" ) ) );
1605 layout->addWidget(
new QLabel( tr(
"Title" ) ) );
1606 layout->addWidget( title );
1607 QGroupBox *expressionWidgetBox =
new QGroupBox( tr(
"Text" ) );
1608 layout->addWidget( expressionWidgetBox );
1609 expressionWidgetBox->setLayout(
new QHBoxLayout );
1610 expressionWidgetBox->layout()->addWidget( expressionWidget );
1611 expressionWidgetBox->layout()->addWidget( addExpressionButton );
1612 layout->addWidget( text );
1614 textPreviewBox->setLayout(
new QGridLayout );
1615 textPreviewBox->setMinimumWidth( 400 );
1616 textPreviewBox->layout()->addWidget( textWrapper->
widget() );
1618 emit text->textChanged();
1619 textLayout->addWidget( textPreviewBox );
1621 QDialogButtonBox *buttonBox =
new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
1623 connect( buttonBox, &QDialogButtonBox::accepted, &dlg, &QDialog::accept );
1624 connect( buttonBox, &QDialogButtonBox::rejected, &dlg, &QDialog::reject );
1626 mainLayout->addWidget( buttonBox );
1631 textEdCfg.
text = text->text();
1632 itemData.
setName( title->text() );
1634 itemData.
setShowLabel( showLabelCheckbox->isChecked() );
1637 item->setText( 0, title->text() );
1644 if ( mType == QgsAttributesDnDTree::Type::Drag )
1647 dlg.setWindowTitle( tr(
"Configure Spacer Widget" ) );
1649 QVBoxLayout *mainLayout =
new QVBoxLayout();
1650 mainLayout->addWidget(
new QLabel( tr(
"Title" ) ) );
1651 QLineEdit *title =
new QLineEdit( itemData.
name() );
1652 mainLayout->addWidget( title );
1654 QHBoxLayout *cbLayout =
new QHBoxLayout( );
1655 mainLayout->addLayout( cbLayout );
1656 dlg.setLayout( mainLayout );
1657 QCheckBox *cb =
new QCheckBox { &dlg };
1659 cbLayout->addWidget(
new QLabel( tr(
"Draw horizontal line" ), &dlg ) );
1660 cbLayout->addWidget( cb );
1663 QDialogButtonBox *buttonBox =
new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
1665 connect( buttonBox, &QDialogButtonBox::accepted, &dlg, &QDialog::accept );
1666 connect( buttonBox, &QDialogButtonBox::rejected, &dlg, &QDialog::reject );
1668 mainLayout->addWidget( buttonBox );
1673 spacerEdCfg.
drawLine = cb->isChecked();
1676 itemData.
setName( title->text() );
1678 item->setText( 0, title->text() );
1711 QTreeWidgetItemIterator it(
this );
1717 if ( selectedItems().count() == 1 && ( *it )->isSelected() == true )
1724 ( *it )->setSelected(
true );
1747 QString displayName;
1750 stream >> type >> name >> displayName;
1761 return mContainerType;
1766 mContainerType = type;
1776 mLabelStyle = labelStyle;
1786 mShowLabel = showLabel;
1791 return mVisibilityExpression;
1796 mVisibilityExpression = visibilityExpression;
1801 return mCollapsedExpression;
1806 mCollapsedExpression = collapsedExpression;
1811 return mRelationEditorConfiguration;
1816 mRelationEditorConfiguration = relationEditorConfiguration;
1821 return mQmlElementEditorConfiguration;
1826 mQmlElementEditorConfiguration = qmlElementEditorConfiguration;
1832 return mHtmlElementEditorConfiguration;
1837 mHtmlElementEditorConfiguration = htmlElementEditorConfiguration;
1842 return mSpacerElementEditorConfiguration;
1847 mSpacerElementEditorConfiguration = spacerElementEditorConfiguration;
1852 return mBackgroundColor;
1857 mBackgroundColor = backgroundColor;
1862 return mTextElementEditorConfiguration;
1867 mTextElementEditorConfiguration = textElementEditorConfiguration;
AttributeEditorContainerType
Attribute editor container types.
AttributeFormSuppression
Available form types for layout of the attribute form editor.
AttributeFormLayout
Available form types for layout of the attribute form editor.
QList< QgsAction > actions(const QString &actionScope=QString()) const
Returns a list of actions that are available in the given action scope.
QgsAction action(QUuid id) const
Gets an action by its id.
Utility class that encapsulates an action based on vector attributes.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
This element will load a layer action onto the form.
const QgsAction & action(const QgsVectorLayer *layer) const
Returns the (possibly lazy loaded) action for the given layer.
This is a container for attribute editors, used to group them visually in the attribute form if it is...
virtual void addChildElement(QgsAttributeEditorElement *element)
Add a child element to this container.
QgsOptionalExpression visibilityExpression() const
The visibility expression is used in the attribute form to show or hide this container based on an ex...
void setColumnCount(int columnCount)
Set the number of columns in this group.
void setVisibilityExpression(const QgsOptionalExpression &visibilityExpression)
The visibility expression is used in the attribute form to show or hide this container based on an ex...
QgsOptionalExpression collapsedExpression() const
The collapsed expression is used in the attribute form to set the collapsed status of the group box c...
bool collapsed() const
For group box containers returns true if this group box is collapsed.
Qgis::AttributeEditorContainerType type() const
Returns the container type.
void setType(Qgis::AttributeEditorContainerType type)
Sets the container type.
void setCollapsedExpression(const QgsOptionalExpression &collapsedExpression)
The collapsed expression is used in the attribute form to set the collapsed status of the group box o...
QList< QgsAttributeEditorElement * > children() const
Gets a list of the children elements of this container.
QColor backgroundColor() const
Returns the background color of the container.
void setCollapsed(bool collapsed)
For group box containers sets if this group box is collapsed.
int columnCount() const
Gets the number of columns in this group.
void setBackgroundColor(const QColor &backgroundColor)
Sets the background color to backgroundColor.
This is an abstract base class for any elements of a drag and drop form.
void setHorizontalStretch(int stretch)
Sets the horizontal stretch factor for the element.
LabelStyle labelStyle() const
Returns the label style.
void setLabelStyle(const LabelStyle &labelStyle)
Sets the labelStyle.
Qgis::AttributeEditorType type() const
The type of this element.
int verticalStretch() const
Returns the vertical stretch factor for the element.
bool showLabel() const
Controls if this element should be labeled with a title (field, relation or groupname).
QString name() const
Returns the name of this element.
void setVerticalStretch(int stretch)
Sets the vertical stretch factor for the element.
void setShowLabel(bool showLabel)
Controls if this element should be labeled with a title (field, relation or groupname).
int horizontalStretch() const
Returns the horizontal stretch factor for the element.
This element will load a field's widget onto the form.
An attribute editor widget that will represent arbitrary HTML code.
QString htmlCode() const
The Html code that will be represented within this widget.
void setHtmlCode(const QString &htmlCode)
Sets the HTML code that will be represented within this widget to htmlCode.
An attribute editor widget that will represent arbitrary QML code.
QString qmlCode() const
The QML code that will be represented within this widget.
void setQmlCode(const QString &qmlCode)
Sets the QML code that will be represented within this widget to qmlCode.
This element will load a relation editor onto the form.
void setNmRelationId(const QVariant &nmRelationId=QVariant())
Sets nmRelationId for the relation id of the second relation involved in an N:M relation.
void setRelationWidgetTypeId(const QString &relationWidgetTypeId)
Sets the relation widget type.
const QgsRelation & relation() const
Gets the id of the relation which shall be embedded.
QVariantMap relationEditorConfiguration() const
Returns the relation editor widget configuration.
void setForceSuppressFormPopup(bool forceSuppressFormPopup)
Sets force suppress form popup status to forceSuppressFormPopup.
QVariant nmRelationId() const
Determines the relation id of the second relation involved in an N:M relation.
bool forceSuppressFormPopup() const
Determines the force suppress form popup status.
QString relationWidgetTypeId() const
Returns the current relation widget type id.
void setRelationEditorConfiguration(const QVariantMap &config)
Sets the relation editor configuration.
void setLabel(const QString &label=QString())
Sets label for this element If it's empty it takes the relation id as label.
QString label() const
Determines the label of this element.
An attribute editor widget that will represent a spacer.
void setDrawLine(bool drawLine)
Sets a flag to define if the spacer element will contain an horizontal line.
bool drawLine() const
Returns true if the spacer element will contain an horizontal line.
An attribute editor widget that will represent arbitrary text code.
void setText(const QString &text)
Sets the text that will be represented within this widget to text.
QString text() const
The Text that will be represented within this widget.
This class overrides mime type handling to be able to work with the drag and drop attribute editor.
void setType(QgsAttributesDnDTree::Type value)
QTreeWidgetItem * addItem(QTreeWidgetItem *parent, QgsAttributesFormProperties::DnDTreeItemData data, int index=-1, const QIcon &icon=QIcon())
Adds a new item to a parent.
void dropEvent(QDropEvent *event) override
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
QTreeWidgetItem * addContainer(QTreeWidgetItem *parent, const QString &title, int columnCount, Qgis::AttributeEditorContainerType type)
Adds a new container to parent.
QStringList mimeTypes() const override
QgsAttributesDnDTree(QgsVectorLayer *layer, QWidget *parent=nullptr)
QMimeData * mimeData(const QList< QTreeWidgetItem * > &items) const override
bool dropMimeData(QTreeWidgetItem *parent, int index, const QMimeData *data, Qt::DropAction action) override
void dragMoveEvent(QDragMoveEvent *event) override
Is called when mouse is moved over attributes tree before a drop event.
void selectFirstMatchingItem(const QgsAttributesFormProperties::DnDTreeItemData &data)
A HTML editor based on QScintilla2.
void insertText(const QString &text)
Insert text at cursor position, or replace any selected text if user has made a selection.
The QgsDefaultValue class provides a container for managing client side default values for fields.
Q_GADGET QString expression
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
static QgsExpressionContextScope * formScope(const QgsFeature &formFeature=QgsFeature(), const QString &formMode=QString())
Creates a new scope which contains functions and variables from the current attribute form/table form...
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
void appendScopes(const QList< QgsExpressionContextScope * > &scopes)
Appends a list of scopes to the end of the context.
bool nextFeature(QgsFeature &f)
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Stores information about constraints which may be present on a field.
@ ConstraintStrengthSoft
User is warned if constraint is violated but feature can still be accepted.
@ ConstraintStrengthHard
Constraint must be honored before feature can be accepted.
void setConstraintStrength(Constraint constraint, ConstraintStrength strength)
Sets the strength of a constraint.
void setConstraintExpression(const QString &expression, const QString &description=QString())
Set the constraint expression for the field.
@ ConstraintOriginProvider
Constraint was set at data provider.
ConstraintStrength constraintStrength(Constraint constraint) const
Returns the strength of a field constraint, or ConstraintStrengthNotSet if the constraint is not pres...
ConstraintOrigin constraintOrigin(Constraint constraint) const
Returns the origin of a field constraint, or ConstraintOriginNotSet if the constraint is not present ...
QString constraintExpression() const
Returns the constraint expression for the field, if set.
@ ConstraintNotNull
Field may not be null.
@ ConstraintUnique
Field must have a unique value.
@ ConstraintExpression
Field has an expression constraint set. See constraintExpression().
QString constraintDescription() const
Returns the descriptive name for the constraint expression.
Q_GADGET Constraints constraints
void setConstraint(Constraint constraint, ConstraintOrigin origin=ConstraintOriginLayer)
Sets a constraint on the field.
Encapsulate a field in an attribute table or data source.
Qgis::FieldDomainSplitPolicy splitPolicy() const
Returns the field's split policy, which indicates how field values should be handled during a split o...
QgsFieldConstraints constraints
Container of fields for a vector layer.
int indexOf(const QString &fieldName) const
Gets the field index from the field name.
@ OriginExpression
Field is calculated from an expression.
@ OriginJoin
Field comes from a joined layer (originIndex / 1000 = index of the join, originIndex % 1000 = index w...
int count() const
Returns number of items.
FieldOrigin fieldOrigin(int fieldIdx) const
Returns the field's origin (value from an enumeration).
QgsField field(int fieldIdx) const
Returns the field at particular index (must be in range 0..N-1).
int size() const
Returns number of items.
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
QIcon iconForField(int fieldIdx, bool considerOrigin=false) const
Returns an icon corresponding to a field index, based on the field's type and source.
static QgsEditorWidgetRegistry * editorWidgetRegistry()
Returns the global editor widget registry, used for managing all known edit widget factories.
An expression with an additional enabled flag.
QgsRelationManager * relationManager
static QgsProject * instance()
Returns the QgsProject singleton instance.
int count() const
Returns the number of properties contained within the collection.
QList< QgsRelation > referencedRelations(const QgsVectorLayer *layer=nullptr) const
Gets all relations where this layer is the referenced part (i.e.
Q_INVOKABLE QgsRelation relation(const QString &id) const
Gets access to a relation by its id.
static const QgsSettingsEntryBool * settingsDigitizingDisableEnterAttributeValuesDialog
Settings entry digitizing disable enter attribute values dialog.
This class is a composition of two QSettings instances:
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
Wraps a label widget to display text.
void setText(const QString &text)
Sets the text code to htmlCode.
void reinitWidget()
Clears the content and makes new initialization.
void setFeature(const QgsFeature &feature) override
Represents a vector layer which manages a vector based data sets.
QgsDefaultValue defaultValueDefinition(int index) const
Returns the definition of the expression used when calculating the default value for a field.
void setFieldConstraint(int index, QgsFieldConstraints::Constraint constraint, QgsFieldConstraints::ConstraintStrength strength=QgsFieldConstraints::ConstraintStrengthHard)
Sets a constraint for a specified field index.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
void removeFieldConstraint(int index, QgsFieldConstraints::Constraint constraint)
Removes a constraint for a specified field index.
void setDefaultValueDefinition(int index, const QgsDefaultValue &definition)
Sets the definition of the expression to use when calculating the default value for a field.
void setEditFormConfig(const QgsEditFormConfig &editFormConfig)
Sets the editFormConfig (configuration) of the form used to represent this vector layer.
void setEditorWidgetSetup(int index, const QgsEditorWidgetSetup &setup)
The editor widget setup defines which QgsFieldFormatter and editor widget will be used for the field ...
void setConstraintExpression(int index, const QString &expression, const QString &description=QString())
Sets the constraint expression for the specified field index.
QgsActionManager * actions()
Returns all layer actions defined on this layer.
void setFieldAlias(int index, const QString &aliasString)
Sets an alias (a display name) for attributes to display in dialogs.
QgsEditFormConfig editFormConfig
void setFieldSplitPolicy(int index, Qgis::FieldDomainSplitPolicy policy)
Sets a split policy for the field with the specified index.
#define QgsDebugError(str)
The TabStyle struct defines color and font overrides for form fields, tabs and groups labels.