19#include "qgsattributetypedialog.h"
20#include "qgsattributeformcontaineredit.h"
21#include "qgsattributewidgetedit.h"
47 mEditorLayoutComboBox->addItem( tr(
"Autogenerate" ), QgsEditFormConfig::EditorLayout::GeneratedLayout );
48 mEditorLayoutComboBox->addItem( tr(
"Drag and Drop Designer" ), QgsEditFormConfig::EditorLayout::TabLayout );
49 mEditorLayoutComboBox->addItem( tr(
"Provide ui-file" ), QgsEditFormConfig::EditorLayout::UiFileLayout );
52 QGridLayout *availableWidgetsWidgetLayout =
new QGridLayout;
55 availableWidgetsWidgetLayout->setContentsMargins( 0, 0, 0, 0 );
56 mAvailableWidgetsWidget->setLayout( availableWidgetsWidgetLayout );
62 QGridLayout *formLayoutWidgetLayout =
new QGridLayout;
64 mFormLayoutWidget->setLayout( formLayoutWidgetLayout );
66 formLayoutWidgetLayout->setContentsMargins( 0, 0, 0, 0 );
67 mFormLayoutTree->setHeaderLabels( QStringList() << tr(
"Form Layout" ) );
70 connect(
mAvailableWidgetsTree, &QTreeWidget::itemSelectionChanged,
this, &QgsAttributesFormProperties::onAttributeSelectionChanged );
71 connect(
mFormLayoutTree, &QTreeWidget::itemSelectionChanged,
this, &QgsAttributesFormProperties::onFormLayoutSelectionChanged );
72 connect( mAddTabOrGroupButton, &QAbstractButton::clicked,
this, &QgsAttributesFormProperties::addTabOrGroupButton );
73 connect( mRemoveTabOrGroupButton, &QAbstractButton::clicked,
this, &QgsAttributesFormProperties::removeTabOrGroupButton );
74 connect( mInvertSelectionButton, &QAbstractButton::clicked,
this, &QgsAttributesFormProperties::onInvertSelectionButtonClicked );
75 connect( mEditorLayoutComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsAttributesFormProperties::mEditorLayoutComboBox_currentIndexChanged );
76 connect( pbnSelectEditForm, &QToolButton::clicked,
this, &QgsAttributesFormProperties::pbnSelectEditForm_clicked );
77 connect( mTbInitCode, &QPushButton::clicked,
this, &QgsAttributesFormProperties::mTbInitCode_clicked );
104 for (
int i = 0; i < fields.
size(); ++i )
122 item->setToolTip( 0, tooltip );
124 catitem->setExpanded(
true );
139 catitem->setExpanded(
true );
147 for (
const auto &action : std::as_const( actions ) )
149 if ( action.isValid() && action.runable() &&
150 ( action.actionScopes().contains( QStringLiteral(
"Feature" ) ) ||
151 action.actionScopes().contains( QStringLiteral(
"Layer" ) ) ) )
153 const QString actionTitle { action.shortTitle().isEmpty() ? action.name() : action.shortTitle() };
171 catitem ->setExpanded(
true );
179 mFormLayoutTree->setSelectionBehavior( QAbstractItemView::SelectRows );
180 mFormLayoutTree->setSelectionMode( QAbstractItemView::SelectionMode::ExtendedSelection );
196 mFormSuppressCmbBx->addItem( tr(
"Hide Form on Add Feature (global settings)" ) );
200 mFormSuppressCmbBx->addItem( tr(
"Show Form on Add Feature (global settings)" ) );
202 mFormSuppressCmbBx->addItem( tr(
"Hide Form on Add Feature" ) );
203 mFormSuppressCmbBx->addItem( tr(
"Show Form on Add Feature" ) );
219 mEditorLayoutComboBox_currentIndexChanged( mEditorLayoutComboBox->currentIndex() );
222 mEditFormLineEdit->setText( cfg.
uiForm() );
234 if ( mInitCode.isEmpty() )
236 mInitCode.append( tr(
"# -*- coding: utf-8 -*-\n\"\"\"\n"
237 "QGIS forms can have a Python function that is called when the form is\n"
240 "Use this function to add extra logic to your forms.\n"
242 "Enter the name of the function in the \"Python Init function\"\n"
244 "An example follows:\n"
246 "from qgis.PyQt.QtWidgets import QWidget\n\n"
247 "def my_form_open(dialog, layer, feature):\n"
248 " geom = feature.geometry()\n"
249 " control = dialog.findChild(QWidget, \"MyLineEdit\")\n" ) );
253void QgsAttributesFormProperties::loadAttributeTypeDialog()
260 const FieldConfig cfg = item->data( 0,
FieldConfigRole ).value<FieldConfig>();
261 const QString fieldName = item->data( 0,
FieldNameRole ).toString();
282 QgsFieldConstraints::Constraints providerConstraints = QgsFieldConstraints::Constraints();
301 mAttributeTypeFrame->layout()->setContentsMargins( 0, 0, 0, 0 );
307void QgsAttributesFormProperties::storeAttributeTypeDialog()
357 cfg.mFieldConstraints = constraints;
368 QTreeWidgetItem *item = *itemIt;
369 if ( item->data( 0,
FieldNameRole ).toString() == fieldName )
370 item->setData( 0,
FieldConfigRole, QVariant::fromValue<FieldConfig>( cfg ) );
374void QgsAttributesFormProperties::storeAttributeWidgetEdit()
382void QgsAttributesFormProperties::loadAttributeWidgetEdit()
387 QTreeWidgetItem *currentItem =
mFormLayoutTree->selectedItems().at( 0 );
389 mAttributeTypeFrame->layout()->setContentsMargins( 0, 0, 0, 0 );
393void QgsAttributesFormProperties::loadInfoWidget(
const QString &infoText )
396 mAttributeTypeFrame->layout()->setContentsMargins( 0, 0, 0, 0 );
400void QgsAttributesFormProperties::storeAttributeContainerEdit()
408void QgsAttributesFormProperties::loadAttributeContainerEdit()
413 QTreeWidgetItem *currentItem =
mFormLayoutTree->selectedItems().at( 0 );
417 mAttributeTypeFrame->layout()->setContentsMargins( 0, 0, 0, 0 );
424 QTreeWidgetItem *newWidget =
nullptr;
425 switch ( widgetDef->
type() )
430 itemData.setShowLabel( widgetDef->
showLabel() );
431 itemData.setLabelStyle( widgetDef->
labelStyle() );
432 newWidget = tree->
addItem( parent, itemData );
440 if ( action.isValid() )
442 DnDTreeItemData itemData = DnDTreeItemData(
DnDTreeItemData::Action, action.id().toString(), action.shortTitle().isEmpty() ? action.name() : action.shortTitle() );
443 itemData.setShowLabel( widgetDef->
showLabel() );
444 itemData.setLabelStyle( widgetDef->
labelStyle() );
445 newWidget = tree->
addItem( parent, itemData );
449 QgsDebugMsg( QStringLiteral(
"Invalid form action" ) );
458 itemData.setShowLabel( widgetDef->
showLabel() );
459 itemData.setLabelStyle( widgetDef->
labelStyle() );
461 RelationEditorConfiguration relEdConfig;
465 relEdConfig.nmRelationId = relationEditor->
nmRelationId();
467 relEdConfig.label = relationEditor->
label();
468 itemData.setRelationEditorConfiguration( relEdConfig );
469 newWidget = tree->
addItem( parent, itemData );
476 itemData.setShowLabel( widgetDef->
showLabel() );
483 itemData.setShowAsGroupBox( container->
isGroupBox() );
487 itemData.setCollapsed( container->
collapsed() );
488 itemData.setLabelStyle( widgetDef->
labelStyle() );
489 newWidget = tree->
addItem( parent, itemData );
491 const QList<QgsAttributeEditorElement *> children = container->
children();
494 loadAttributeEditorTreeItem( wdg, newWidget, tree );
503 itemData.setShowLabel( widgetDef->
showLabel() );
504 QmlElementEditorConfiguration qmlEdConfig;
505 qmlEdConfig.qmlCode = qmlElementEditor->
qmlCode();
506 itemData.setQmlElementEditorConfiguration( qmlEdConfig );
507 itemData.setLabelStyle( widgetDef->
labelStyle() );
508 newWidget = tree->
addItem( parent, itemData );
516 itemData.setShowLabel( widgetDef->
showLabel() );
517 HtmlElementEditorConfiguration htmlEdConfig;
518 htmlEdConfig.htmlCode = htmlElementEditor->
htmlCode();
519 itemData.setHtmlElementEditorConfiguration( htmlEdConfig );
520 itemData.setLabelStyle( widgetDef->
labelStyle() );
521 newWidget = tree->
addItem( parent, itemData );
527 QgsDebugMsg( QStringLiteral(
"Not loading invalid attribute editor type..." ) );
536void QgsAttributesFormProperties::onAttributeSelectionChanged()
538 disconnect(
mFormLayoutTree, &QTreeWidget::itemSelectionChanged,
this, &QgsAttributesFormProperties::onFormLayoutSelectionChanged );
540 connect(
mFormLayoutTree, &QTreeWidget::itemSelectionChanged,
this, &QgsAttributesFormProperties::onFormLayoutSelectionChanged );
543void QgsAttributesFormProperties::onFormLayoutSelectionChanged()
546 disconnect(
mAvailableWidgetsTree, &QTreeWidget::itemSelectionChanged,
this, &QgsAttributesFormProperties::onAttributeSelectionChanged );
548 connect(
mAvailableWidgetsTree, &QTreeWidget::itemSelectionChanged,
this, &QgsAttributesFormProperties::onAttributeSelectionChanged );
555 if ( layout == QgsEditFormConfig::EditorLayout::TabLayout )
556 storeAttributeWidgetEdit();
557 storeAttributeTypeDialog();
558 storeAttributeContainerEdit();
560 clearAttributeTypeFrame();
562 if ( emitter->selectedItems().count() != 1 )
564 receiver->clearSelection();
568 const DnDTreeItemData itemData = emitter->selectedItems().at( 0 )->data( 0,
DnDTreeRole ).value<DnDTreeItemData>();
569 switch ( itemData.type() )
574 if ( layout == QgsEditFormConfig::EditorLayout::TabLayout )
576 loadAttributeWidgetEdit();
580 loadInfoWidget( tr(
"This configuration is available in the Drag and Drop Designer" ) );
587 if ( layout == QgsEditFormConfig::EditorLayout::TabLayout )
588 loadAttributeWidgetEdit();
589 loadAttributeTypeDialog();
594 receiver->clearSelection();
595 loadAttributeContainerEdit();
602 loadInfoWidget( action.html() );
608 if ( layout != QgsEditFormConfig::EditorLayout::TabLayout )
610 loadInfoWidget( tr(
"This configuration is available with double-click in the Drag and Drop Designer" ) );
614 loadInfoWidget( tr(
"This configuration is available with double-click" ) );
616 receiver->clearSelection();
621 receiver->clearSelection();
628void QgsAttributesFormProperties::clearAttributeTypeFrame()
656void QgsAttributesFormProperties::onInvertSelectionButtonClicked(
bool checked )
661 for (
int i = 0; i < rootItem->childCount(); ++i )
663 rootItem->child( i )->setSelected( ! selectedItemList.contains( rootItem->child( i ) ) );
667void QgsAttributesFormProperties::addTabOrGroupButton()
669 QList<QgsAddTabOrGroup::TabPair> tabList;
673 const DnDTreeItemData itemData = ( *it )->data( 0,
DnDTreeRole ).value<DnDTreeItemData>();
679 QTreeWidgetItem *currentItem =
mFormLayoutTree->selectedItems().value( 0 );
682 if ( !addTabOrGroup.exec() )
685 const QString name = addTabOrGroup.name();
686 if ( addTabOrGroup.tabButtonIsChecked() )
692 QTreeWidgetItem *tabItem = addTabOrGroup.tab();
697void QgsAttributesFormProperties::removeTabOrGroupButton()
709 switch ( itemData.
type() )
750 for (
int t = 0; t < item->childCount(); t++ )
757 widgetDef = container;
791void QgsAttributesFormProperties::mEditorLayoutComboBox_currentIndexChanged(
int index )
798 case QgsEditFormConfig::EditorLayout::GeneratedLayout:
799 mFormLayoutWidget->setVisible(
false );
800 mUiFileFrame->setVisible(
false );
801 mAddTabOrGroupButton->setVisible(
false );
802 mRemoveTabOrGroupButton->setVisible(
false );
803 mInvertSelectionButton->setVisible(
false );
806 case QgsEditFormConfig::EditorLayout::TabLayout:
807 mFormLayoutWidget->setVisible(
true );
808 mUiFileFrame->setVisible(
false );
809 mAddTabOrGroupButton->setVisible(
true );
810 mRemoveTabOrGroupButton->setVisible(
true );
811 mInvertSelectionButton->setVisible(
true );
814 case QgsEditFormConfig::EditorLayout::UiFileLayout:
816 mFormLayoutWidget->setVisible(
false );
817 mUiFileFrame->setVisible(
true );
818 mAddTabOrGroupButton->setVisible(
false );
819 mRemoveTabOrGroupButton->setVisible(
false );
820 mInvertSelectionButton->setVisible(
false );
825void QgsAttributesFormProperties::mTbInitCode_clicked()
834 if ( !attributesFormInitCode.exec() )
837 mInitCodeSource = attributesFormInitCode.
codeSource();
838 mInitCode = attributesFormInitCode.
initCode();
844void QgsAttributesFormProperties::pbnSelectEditForm_clicked()
847 const QString lastUsedDir = myQSettings.
value( QStringLiteral(
"style/lastUIDir" ), QDir::homePath() ).toString();
848 const QString uifilename = QFileDialog::getOpenFileName(
this, tr(
"Select edit form" ), lastUsedDir, tr(
"UI file" ) +
" (*.ui)" );
850 if ( uifilename.isNull() )
853 const QFileInfo fi( uifilename );
854 myQSettings.
setValue( QStringLiteral(
"style/lastUIDir" ), fi.path() );
855 mEditFormLineEdit->setText( uifilename );
860 storeAttributeWidgetEdit();
861 storeAttributeContainerEdit();
862 storeAttributeTypeDialog();
868 for (
int i = 0; i < fieldContainer->childCount(); i++ )
870 QTreeWidgetItem *fieldItem = fieldContainer->child( i );
873 const QString fieldName { fieldItem->data( 0,
FieldNameRole ).toString() };
923 for (
int t = 0; t <
mFormLayoutTree->invisibleRootItem()->childCount(); t++ )
925 QTreeWidgetItem *tabItem =
mFormLayoutTree->invisibleRootItem()->child( t );
928 editFormConfig.
addTab( editorElement );
931 editFormConfig.
setUiForm( mEditFormLineEdit->text() );
945 for (
int i = 0; i < relationContainer->childCount(); i++ )
947 QTreeWidgetItem *relationItem = relationContainer->child( i );
950 for (
int t = 0; t <
mFormLayoutTree->invisibleRootItem()->childCount(); t++ )
952 QTreeWidgetItem *tabItem =
mFormLayoutTree->invisibleRootItem()->child( t );
955 if ( tabItemData.
type() == itemData.
type() && tabItemData.
name() == itemData.
name() )
991QgsAttributesFormProperties::FieldConfig::operator QVariant()
993 return QVariant::fromValue<QgsAttributesFormProperties::FieldConfig>( *
this );
1000QgsAttributesFormProperties::RelationEditorConfiguration::operator QVariant()
1002 return QVariant::fromValue<QgsAttributesFormProperties::RelationEditorConfiguration>( *
this );
1011 QTreeWidgetItem *newItem =
new QTreeWidgetItem( QStringList() << title );
1012 newItem->setBackground( 0, QBrush( Qt::lightGray ) );
1013 newItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled );
1017 parent->addChild( newItem );
1018 newItem->setExpanded(
true );
1023 : QTreeWidget( parent )
1026 connect(
this, &QTreeWidget::itemDoubleClicked,
this, &QgsAttributesDnDTree::onItemDoubleClicked );
1031 QTreeWidgetItem *newItem =
new QTreeWidgetItem( QStringList() << data.
name() );
1033 switch ( data.
type() )
1040 newItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled );
1046 newItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled );
1047 newItem->setBackground( 0, QBrush( Qt::lightGray ) );
1054 newItem->setIcon( 0, icon );
1057 parent->addChild( newItem );
1059 parent->insertChild( index, newItem );
1071 const QMimeData *data =
event->mimeData();
1073 if ( data->hasFormat( QStringLiteral(
"application/x-qgsattributetabledesignerelement" ) ) )
1077 QByteArray itemData = data->data( QStringLiteral(
"application/x-qgsattributetabledesignerelement" ) );
1078 QDataStream stream( &itemData, QIODevice::ReadOnly );
1079 stream >> itemElement;
1082 if ( event->source() ==
this )
1084 event->setDropAction( Qt::MoveAction );
1092 QTreeWidget::dragMoveEvent( event );
1098 bool bDropSuccessful =
false;
1100 if ( action == Qt::IgnoreAction )
1102 bDropSuccessful =
true;
1104 else if ( data->hasFormat( QStringLiteral(
"application/x-qgsattributetabledesignerelement" ) ) )
1106 QByteArray itemData = data->data( QStringLiteral(
"application/x-qgsattributetabledesignerelement" ) );
1107 QDataStream stream( &itemData, QIODevice::ReadOnly );
1110 while ( !stream.atEnd() )
1112 stream >> itemElement;
1114 QTreeWidgetItem *newItem;
1118 newItem =
addItem( parent, itemElement, index++ );
1119 bDropSuccessful =
true;
1123 newItem =
addItem( invisibleRootItem(), itemElement, index++ );
1124 bDropSuccessful =
true;
1129 onItemDoubleClicked( newItem, 0 );
1134 onItemDoubleClicked( newItem, 0 );
1137 newItem->setSelected(
true );
1141 return bDropSuccessful;
1146 if ( !event->mimeData()->hasFormat( QStringLiteral(
"application/x-qgsattributetabledesignerelement" ) ) )
1149 if ( event->source() ==
this )
1151 event->setDropAction( Qt::MoveAction );
1154 QTreeWidget::dropEvent( event );
1159 return QStringList() << QStringLiteral(
"application/x-qgsattributetabledesignerelement" );
1162#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1168 if ( items.count() <= 0 )
1171 const QStringList types = mimeTypes();
1173 if ( types.isEmpty() )
1176 QMimeData *data =
new QMimeData();
1177 const QString format = types.at( 0 );
1179 QDataStream stream( &encoded, QIODevice::WriteOnly );
1181 const auto constItems = items;
1182 for (
const QTreeWidgetItem *item : constItems )
1192 data->setData( format, encoded );
1197void QgsAttributesDnDTree::onItemDoubleClicked( QTreeWidgetItem *item,
int column )
1203 QGroupBox *baseData =
new QGroupBox( tr(
"Base configuration" ) );
1205 QFormLayout *baseLayout =
new QFormLayout();
1206 baseData->setLayout( baseLayout );
1207 QCheckBox *showLabelCheckbox =
new QCheckBox( QStringLiteral(
"Show label" ) );
1208 showLabelCheckbox->setChecked( itemData.
showLabel() );
1209 baseLayout->addRow( showLabelCheckbox );
1210 QWidget *baseWidget =
new QWidget();
1211 baseWidget->setLayout( baseLayout );
1213 switch ( itemData.
type() )
1224 if ( mType == QgsAttributesDnDTree::Type::Drag )
1228 dlg.setWindowTitle( tr(
"Configure QML Widget" ) );
1230 QVBoxLayout *mainLayout =
new QVBoxLayout();
1231 QHBoxLayout *qmlLayout =
new QHBoxLayout();
1232 QVBoxLayout *layout =
new QVBoxLayout();
1233 mainLayout->addLayout( qmlLayout );
1234 qmlLayout->addLayout( layout );
1235 dlg.setLayout( mainLayout );
1236 layout->addWidget( baseWidget );
1238 QLineEdit *title =
new QLineEdit( itemData.
name() );
1242 qmlCode->setPlaceholderText( tr(
"Insert QML code here…" ) );
1249 connect( qmlCode, &QPlainTextEdit::textChanged,
this, [ = ]
1251 qmlWrapper->
setQmlCode( qmlCode->toPlainText() );
1257 QComboBox *qmlObjectTemplate =
new QComboBox();
1258 qmlObjectTemplate->addItem( tr(
"Free Text…" ) );
1259 qmlObjectTemplate->addItem( tr(
"Rectangle" ) );
1260 qmlObjectTemplate->addItem( tr(
"Pie Chart" ) );
1261 qmlObjectTemplate->addItem( tr(
"Bar Chart" ) );
1262 connect( qmlObjectTemplate, qOverload<int>( &QComboBox::activated ), qmlCode, [ = ](
int index )
1269 qmlCode->setPlaceholderText( tr(
"Insert QML code here…" ) );
1274 qmlCode->insertPlainText( QStringLiteral(
"import QtQuick 2.0\n"
1279 " color: \"steelblue\"\n"
1280 " Text{ text: \"A rectangle\" }\n"
1286 qmlCode->insertPlainText( QStringLiteral(
"import QtQuick 2.0\n"
1287 "import QtCharts 2.0\n"
1295 " PieSlice { label: \"First slice\"; value: 25 }\n"
1296 " PieSlice { label: \"Second slice\"; value: 45 }\n"
1297 " PieSlice { label: \"Third slice\"; value: 30 }\n"
1304 qmlCode->insertPlainText( QStringLiteral(
"import QtQuick 2.0\n"
1305 "import QtCharts 2.0\n"
1308 " title: \"Bar series\"\n"
1311 " legend.alignment: Qt.AlignBottom\n"
1312 " antialiasing: true\n"
1321 " axisY: valueAxisY\n"
1322 " axisX: BarCategoryAxis { categories: [\"2007\", \"2008\", \"2009\", \"2010\", \"2011\", \"2012\" ] }\n"
1323 " BarSet { label: \"Bob\"; values: [2, 2, 3, 4, 5, 6] }\n"
1324 " BarSet { label: \"Susan\"; values: [5, 1, 2, 4, 1, 7] }\n"
1325 " BarSet { label: \"James\"; values: [3, 5, 8, 13, 5, 8] }\n"
1336 expressionWidget->
setLayer( mLayer );
1337 QToolButton *addExpressionButton =
new QToolButton();
1340 connect( addExpressionButton, &QAbstractButton::clicked,
this, [ = ]
1342 qmlCode->insertPlainText( QStringLiteral(
"expression.evaluate(\"%1\")" ).arg( expressionWidget->expression().replace(
'"', QLatin1String(
"\\\"" ) ) ) );
1345 layout->addWidget(
new QLabel( tr(
"Title" ) ) );
1346 layout->addWidget( title );
1347 QGroupBox *qmlCodeBox =
new QGroupBox( tr(
"QML Code" ) );
1348 qmlCodeBox->setLayout(
new QGridLayout );
1349 qmlCodeBox->layout()->addWidget( qmlObjectTemplate );
1350 QGroupBox *expressionWidgetBox =
new QGroupBox();
1351 qmlCodeBox->layout()->addWidget( expressionWidgetBox );
1352 expressionWidgetBox->setLayout(
new QHBoxLayout );
1353 expressionWidgetBox->layout()->addWidget( expressionWidget );
1354 expressionWidgetBox->layout()->addWidget( addExpressionButton );
1355 qmlCodeBox->layout()->addWidget( qmlCode );
1356 layout->addWidget( qmlCodeBox );
1358 qmlPreviewBox->setLayout(
new QGridLayout );
1359 qmlPreviewBox->setMinimumWidth( 400 );
1360 qmlPreviewBox->layout()->addWidget( qmlWrapper->
widget() );
1362 emit qmlCode->textChanged();
1363 qmlLayout->addWidget( qmlPreviewBox );
1365 QDialogButtonBox *buttonBox =
new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
1367 connect( buttonBox, &QDialogButtonBox::accepted, &dlg, &QDialog::accept );
1368 connect( buttonBox, &QDialogButtonBox::rejected, &dlg, &QDialog::reject );
1370 mainLayout->addWidget( buttonBox );
1375 qmlEdCfg.
qmlCode = qmlCode->toPlainText();
1376 itemData.
setName( title->text() );
1378 itemData.
setShowLabel( showLabelCheckbox->isChecked() );
1381 item->setText( 0, title->text() );
1388 if ( mType == QgsAttributesDnDTree::Type::Drag )
1391 dlg.setWindowTitle( tr(
"Configure HTML Widget" ) );
1393 QVBoxLayout *mainLayout =
new QVBoxLayout();
1394 QHBoxLayout *htmlLayout =
new QHBoxLayout();
1395 QVBoxLayout *layout =
new QVBoxLayout();
1396 mainLayout->addLayout( htmlLayout );
1397 htmlLayout->addLayout( layout );
1398 dlg.setLayout( mainLayout );
1399 layout->addWidget( baseWidget );
1401 QLineEdit *title =
new QLineEdit( itemData.
name() );
1405 htmlCode->setSizePolicy( QSizePolicy::Policy::Expanding, QSizePolicy::Policy::Expanding );
1413 connect( htmlCode, &QgsCodeEditorHTML::textChanged,
this, [ = ]
1421 expressionWidget->
setLayer( mLayer );
1422 QToolButton *addExpressionButton =
new QToolButton();
1425 connect( addExpressionButton, &QAbstractButton::clicked,
this, [ = ]
1427 htmlCode->
insertText( QStringLiteral(
"<script>document.write(expression.evaluate(\"%1\"));</script>" ).arg( expressionWidget->expression().replace(
'"', QLatin1String(
"\\\"" ) ) ) );
1430 layout->addWidget(
new QLabel( tr(
"Title" ) ) );
1431 layout->addWidget( title );
1432 QGroupBox *expressionWidgetBox =
new QGroupBox( tr(
"HTML Code" ) );
1433 layout->addWidget( expressionWidgetBox );
1434 expressionWidgetBox->setLayout(
new QHBoxLayout );
1435 expressionWidgetBox->layout()->addWidget( expressionWidget );
1436 expressionWidgetBox->layout()->addWidget( addExpressionButton );
1437 layout->addWidget( htmlCode );
1439 htmlPreviewBox->setLayout(
new QGridLayout );
1440 htmlPreviewBox->setMinimumWidth( 400 );
1441 htmlPreviewBox->layout()->addWidget( htmlWrapper->
widget() );
1443 emit htmlCode->textChanged();
1444 htmlLayout->addWidget( htmlPreviewBox );
1446 QDialogButtonBox *buttonBox =
new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
1448 connect( buttonBox, &QDialogButtonBox::accepted, &dlg, &QDialog::accept );
1449 connect( buttonBox, &QDialogButtonBox::rejected, &dlg, &QDialog::reject );
1451 mainLayout->addWidget( buttonBox );
1456 htmlEdCfg.
htmlCode = htmlCode->text();
1457 itemData.
setName( title->text() );
1459 itemData.
setShowLabel( showLabelCheckbox->isChecked() );
1462 item->setText( 0, title->text() );
1481 QTreeWidgetItemIterator it(
this );
1487 if ( selectedItems().count() == 1 && ( *it )->isSelected() == true )
1494 ( *it )->setSelected(
true );
1517 QString displayName;
1520 stream >> type >> name >> displayName;
1531 return mShowAsGroupBox;
1536 mShowAsGroupBox = showAsGroupBox;
1546 mLabelStyle = labelStyle;
1556 mShowLabel = showLabel;
1561 return mVisibilityExpression;
1566 mVisibilityExpression = visibilityExpression;
1571 return mCollapsedExpression;
1576 mCollapsedExpression = collapsedExpression;
1581 return mRelationEditorConfiguration;
1586 mRelationEditorConfiguration = relationEditorConfiguration;
1591 return mQmlElementEditorConfiguration;
1596 mQmlElementEditorConfiguration = qmlElementEditorConfiguration;
1602 return mHtmlElementEditorConfiguration;
1607 mHtmlElementEditorConfiguration = htmlElementEditorConfiguration;
1612 return mBackgroundColor;
1617 mBackgroundColor = backgroundColor;
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.
Dialog to add a tab or group of attributes.
QPair< QString, QTreeWidgetItem * > TabPair
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.
virtual bool isGroupBox() const
Returns if this container is going to be a group box.
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 if this group box is collapsed.
void setCollapsedExpression(const QgsOptionalExpression &collapsedExpression)
The collapsed expression is used in the attribute form to set the collapsed status of the group box o...
virtual void setIsGroupBox(bool isGroupBox)
Determines if this container is rendered as collapsible group box or tab in a tabwidget.
QList< QgsAttributeEditorElement * > children() const
Gets a list of the children elements of this container.
QColor backgroundColor() const
backgroundColor
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.
LabelStyle labelStyle() const
Returns the label style.
void setLabelStyle(const LabelStyle &labelStyle)
Sets the labelStyle.
AttributeEditorType type() const
The type of this 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 setShowLabel(bool showLabel)
Controls if this element should be labeled with a title (field, relation or groupname).
@ AeTypeHtmlElement
A HTML element.
@ AeTypeQmlElement
A QML element.
@ AeTypeContainer
A container.
@ AeTypeRelation
A relation.
@ AeTypeAction
A layer action element (since QGIS 3.22)
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.
This class overrides mime type handling to be able to work with the drag and drop attribute editor.
void setType(QgsAttributesDnDTree::Type value)
QTreeWidgetItem * addContainer(QTreeWidgetItem *parent, const QString &title, int columnCount)
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
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 QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
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.
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.
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
The TabStyle struct defines color and font overrides for form fields, tabs and groups labels.