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 "\tgeom = feature.geometry()\n"
249 "\tcontrol = dialog.findChild(QWidget, \"MyLineEdit\")\n" ) );
253 void 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 );
307 void 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 ) );
374 void QgsAttributesFormProperties::storeAttributeWidgetEdit()
382 void QgsAttributesFormProperties::loadAttributeWidgetEdit()
387 QTreeWidgetItem *currentItem =
mFormLayoutTree->selectedItems().at( 0 );
389 mAttributeTypeFrame->layout()->setContentsMargins( 0, 0, 0, 0 );
393 void QgsAttributesFormProperties::loadInfoWidget(
const QString &infoText )
396 mAttributeTypeFrame->layout()->setContentsMargins( 0, 0, 0, 0 );
400 void QgsAttributesFormProperties::storeAttributeContainerEdit()
408 void QgsAttributesFormProperties::loadAttributeContainerEdit()
413 QTreeWidgetItem *currentItem =
mFormLayoutTree->selectedItems().at( 0 );
417 mAttributeTypeFrame->layout()->setContentsMargins( 0, 0, 0, 0 );
423 QTreeWidgetItem *newWidget =
nullptr;
424 switch ( widgetDef->
type() )
429 itemData.setShowLabel( widgetDef->
showLabel() );
430 newWidget = tree->
addItem( parent, itemData );
438 if ( action.isValid() )
440 DnDTreeItemData itemData = DnDTreeItemData(
DnDTreeItemData::Action, action.id().toString(), action.shortTitle().isEmpty() ? action.name() : action.shortTitle() );
441 itemData.setShowLabel( widgetDef->
showLabel() );
442 newWidget = tree->
addItem( parent, itemData );
446 QgsDebugMsg( QStringLiteral(
"Invalid form action" ) );
455 itemData.setShowLabel( widgetDef->
showLabel() );
457 RelationEditorConfiguration relEdConfig;
461 relEdConfig.nmRelationId = relationEditor->
nmRelationId();
463 relEdConfig.label = relationEditor->
label();
464 itemData.setRelationEditorConfiguration( relEdConfig );
465 newWidget = tree->
addItem( parent, itemData );
472 itemData.setShowLabel( widgetDef->
showLabel() );
479 itemData.setShowAsGroupBox( container->
isGroupBox() );
482 newWidget = tree->
addItem( parent, itemData );
484 const QList<QgsAttributeEditorElement *> children = container->
children();
487 loadAttributeEditorTreeItem( wdg, newWidget, tree );
496 itemData.setShowLabel( widgetDef->
showLabel() );
497 QmlElementEditorConfiguration qmlEdConfig;
498 qmlEdConfig.qmlCode = qmlElementEditor->
qmlCode();
499 itemData.setQmlElementEditorConfiguration( qmlEdConfig );
500 newWidget = tree->
addItem( parent, itemData );
508 itemData.setShowLabel( widgetDef->
showLabel() );
509 HtmlElementEditorConfiguration htmlEdConfig;
510 htmlEdConfig.htmlCode = htmlElementEditor->
htmlCode();
511 itemData.setHtmlElementEditorConfiguration( htmlEdConfig );
512 newWidget = tree->
addItem( parent, itemData );
518 QgsDebugMsg( QStringLiteral(
"Not loading invalid attribute editor type..." ) );
527 void QgsAttributesFormProperties::onAttributeSelectionChanged()
529 disconnect(
mFormLayoutTree, &QTreeWidget::itemSelectionChanged,
this, &QgsAttributesFormProperties::onFormLayoutSelectionChanged );
531 connect(
mFormLayoutTree, &QTreeWidget::itemSelectionChanged,
this, &QgsAttributesFormProperties::onFormLayoutSelectionChanged );
534 void QgsAttributesFormProperties::onFormLayoutSelectionChanged()
537 disconnect(
mAvailableWidgetsTree, &QTreeWidget::itemSelectionChanged,
this, &QgsAttributesFormProperties::onAttributeSelectionChanged );
539 connect(
mAvailableWidgetsTree, &QTreeWidget::itemSelectionChanged,
this, &QgsAttributesFormProperties::onAttributeSelectionChanged );
546 if ( layout == QgsEditFormConfig::EditorLayout::TabLayout )
547 storeAttributeWidgetEdit();
548 storeAttributeTypeDialog();
549 storeAttributeContainerEdit();
551 clearAttributeTypeFrame();
553 if ( emitter->selectedItems().count() != 1 )
555 receiver->clearSelection();
559 const DnDTreeItemData itemData = emitter->selectedItems().at( 0 )->data( 0,
DnDTreeRole ).value<DnDTreeItemData>();
560 switch ( itemData.type() )
565 if ( layout == QgsEditFormConfig::EditorLayout::TabLayout )
567 loadAttributeWidgetEdit();
571 loadInfoWidget( tr(
"This configuration is available in the Drag and Drop Designer" ) );
578 if ( layout == QgsEditFormConfig::EditorLayout::TabLayout )
579 loadAttributeWidgetEdit();
580 loadAttributeTypeDialog();
585 receiver->clearSelection();
586 loadAttributeContainerEdit();
593 loadInfoWidget( action.html() );
599 if ( layout != QgsEditFormConfig::EditorLayout::TabLayout )
601 loadInfoWidget( tr(
"This configuration is available with double-click in the Drag and Drop Designer" ) );
605 loadInfoWidget( tr(
"This configuration is available with double-click" ) );
607 receiver->clearSelection();
612 receiver->clearSelection();
619 void QgsAttributesFormProperties::clearAttributeTypeFrame()
647 void QgsAttributesFormProperties::onInvertSelectionButtonClicked(
bool checked )
652 for (
int i = 0; i < rootItem->childCount(); ++i )
654 rootItem->child( i )->setSelected( ! selectedItemList.contains( rootItem->child( i ) ) );
658 void QgsAttributesFormProperties::addTabOrGroupButton()
660 QList<QgsAddTabOrGroup::TabPair> tabList;
664 const DnDTreeItemData itemData = ( *it )->data( 0,
DnDTreeRole ).value<DnDTreeItemData>();
670 QTreeWidgetItem *currentItem =
mFormLayoutTree->selectedItems().value( 0 );
673 if ( !addTabOrGroup.exec() )
676 const QString name = addTabOrGroup.name();
677 if ( addTabOrGroup.tabButtonIsChecked() )
683 QTreeWidgetItem *tabItem = addTabOrGroup.tab();
688 void QgsAttributesFormProperties::removeTabOrGroupButton()
700 switch ( itemData.
type() )
739 for (
int t = 0; t < item->childCount(); t++ )
746 widgetDef = container;
777 void QgsAttributesFormProperties::mEditorLayoutComboBox_currentIndexChanged(
int index )
784 case QgsEditFormConfig::EditorLayout::GeneratedLayout:
785 mFormLayoutWidget->setVisible(
false );
786 mUiFileFrame->setVisible(
false );
787 mAddTabOrGroupButton->setVisible(
false );
788 mRemoveTabOrGroupButton->setVisible(
false );
789 mInvertSelectionButton->setVisible(
false );
792 case QgsEditFormConfig::EditorLayout::TabLayout:
793 mFormLayoutWidget->setVisible(
true );
794 mUiFileFrame->setVisible(
false );
795 mAddTabOrGroupButton->setVisible(
true );
796 mRemoveTabOrGroupButton->setVisible(
true );
797 mInvertSelectionButton->setVisible(
true );
800 case QgsEditFormConfig::EditorLayout::UiFileLayout:
802 mFormLayoutWidget->setVisible(
false );
803 mUiFileFrame->setVisible(
true );
804 mAddTabOrGroupButton->setVisible(
false );
805 mRemoveTabOrGroupButton->setVisible(
false );
806 mInvertSelectionButton->setVisible(
false );
811 void QgsAttributesFormProperties::mTbInitCode_clicked()
820 if ( !attributesFormInitCode.exec() )
823 mInitCodeSource = attributesFormInitCode.
codeSource();
824 mInitCode = attributesFormInitCode.
initCode();
830 void QgsAttributesFormProperties::pbnSelectEditForm_clicked()
833 const QString lastUsedDir = myQSettings.
value( QStringLiteral(
"style/lastUIDir" ), QDir::homePath() ).toString();
834 const QString uifilename = QFileDialog::getOpenFileName(
this, tr(
"Select edit form" ), lastUsedDir, tr(
"UI file" ) +
" (*.ui)" );
836 if ( uifilename.isNull() )
839 const QFileInfo fi( uifilename );
840 myQSettings.
setValue( QStringLiteral(
"style/lastUIDir" ), fi.path() );
841 mEditFormLineEdit->setText( uifilename );
846 storeAttributeWidgetEdit();
847 storeAttributeContainerEdit();
848 storeAttributeTypeDialog();
854 for (
int i = 0; i < fieldContainer->childCount(); i++ )
856 QTreeWidgetItem *fieldItem = fieldContainer->child( i );
859 const QString fieldName { fieldItem->data( 0,
FieldNameRole ).toString() };
909 for (
int t = 0; t <
mFormLayoutTree->invisibleRootItem()->childCount(); t++ )
911 QTreeWidgetItem *tabItem =
mFormLayoutTree->invisibleRootItem()->child( t );
914 editFormConfig.
addTab( editorElement );
917 editFormConfig.
setUiForm( mEditFormLineEdit->text() );
931 for (
int i = 0; i < relationContainer->childCount(); i++ )
933 QTreeWidgetItem *relationItem = relationContainer->child( i );
936 for (
int t = 0; t <
mFormLayoutTree->invisibleRootItem()->childCount(); t++ )
938 QTreeWidgetItem *tabItem =
mFormLayoutTree->invisibleRootItem()->child( t );
941 if ( tabItemData.
type() == itemData.
type() && tabItemData.
name() == itemData.
name() )
977 QgsAttributesFormProperties::FieldConfig::operator QVariant()
979 return QVariant::fromValue<QgsAttributesFormProperties::FieldConfig>( *
this );
986 QgsAttributesFormProperties::RelationEditorConfiguration::operator QVariant()
988 return QVariant::fromValue<QgsAttributesFormProperties::RelationEditorConfiguration>( *
this );
997 QTreeWidgetItem *newItem =
new QTreeWidgetItem( QStringList() << title );
998 newItem->setBackground( 0, QBrush( Qt::lightGray ) );
999 newItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled );
1003 parent->addChild( newItem );
1004 newItem->setExpanded(
true );
1009 : QTreeWidget( parent )
1012 connect(
this, &QTreeWidget::itemDoubleClicked,
this, &QgsAttributesDnDTree::onItemDoubleClicked );
1017 QTreeWidgetItem *newItem =
new QTreeWidgetItem( QStringList() << data.
name() );
1019 switch ( data.
type() )
1026 newItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled );
1032 newItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled );
1033 newItem->setBackground( 0, QBrush( Qt::lightGray ) );
1040 newItem->setIcon( 0, icon );
1043 parent->addChild( newItem );
1045 parent->insertChild( index, newItem );
1057 const QMimeData *data =
event->mimeData();
1059 if ( data->hasFormat( QStringLiteral(
"application/x-qgsattributetabledesignerelement" ) ) )
1063 QByteArray itemData = data->data( QStringLiteral(
"application/x-qgsattributetabledesignerelement" ) );
1064 QDataStream stream( &itemData, QIODevice::ReadOnly );
1065 stream >> itemElement;
1068 if ( event->source() ==
this )
1070 event->setDropAction( Qt::MoveAction );
1078 QTreeWidget::dragMoveEvent( event );
1084 bool bDropSuccessful =
false;
1086 if ( action == Qt::IgnoreAction )
1088 bDropSuccessful =
true;
1090 else if ( data->hasFormat( QStringLiteral(
"application/x-qgsattributetabledesignerelement" ) ) )
1092 QByteArray itemData = data->data( QStringLiteral(
"application/x-qgsattributetabledesignerelement" ) );
1093 QDataStream stream( &itemData, QIODevice::ReadOnly );
1096 while ( !stream.atEnd() )
1098 stream >> itemElement;
1100 QTreeWidgetItem *newItem;
1104 newItem =
addItem( parent, itemElement, index++ );
1105 bDropSuccessful =
true;
1109 newItem =
addItem( invisibleRootItem(), itemElement, index++ );
1110 bDropSuccessful =
true;
1115 onItemDoubleClicked( newItem, 0 );
1120 onItemDoubleClicked( newItem, 0 );
1123 newItem->setSelected(
true );
1127 return bDropSuccessful;
1132 if ( !event->mimeData()->hasFormat( QStringLiteral(
"application/x-qgsattributetabledesignerelement" ) ) )
1135 if ( event->source() ==
this )
1137 event->setDropAction( Qt::MoveAction );
1140 QTreeWidget::dropEvent( event );
1145 return QStringList() << QStringLiteral(
"application/x-qgsattributetabledesignerelement" );
1148 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1154 if ( items.count() <= 0 )
1157 const QStringList types = mimeTypes();
1159 if ( types.isEmpty() )
1162 QMimeData *data =
new QMimeData();
1163 const QString format = types.at( 0 );
1165 QDataStream stream( &encoded, QIODevice::WriteOnly );
1167 const auto constItems = items;
1168 for (
const QTreeWidgetItem *item : constItems )
1178 data->setData( format, encoded );
1183 void QgsAttributesDnDTree::onItemDoubleClicked( QTreeWidgetItem *item,
int column )
1189 QGroupBox *baseData =
new QGroupBox( tr(
"Base configuration" ) );
1191 QFormLayout *baseLayout =
new QFormLayout();
1192 baseData->setLayout( baseLayout );
1193 QCheckBox *showLabelCheckbox =
new QCheckBox( QStringLiteral(
"Show label" ) );
1194 showLabelCheckbox->setChecked( itemData.
showLabel() );
1195 baseLayout->addRow( showLabelCheckbox );
1196 QWidget *baseWidget =
new QWidget();
1197 baseWidget->setLayout( baseLayout );
1199 switch ( itemData.
type() )
1210 if ( mType == QgsAttributesDnDTree::Type::Drag )
1214 dlg.setWindowTitle( tr(
"Configure QML Widget" ) );
1216 QVBoxLayout *mainLayout =
new QVBoxLayout();
1217 QHBoxLayout *qmlLayout =
new QHBoxLayout();
1218 QVBoxLayout *layout =
new QVBoxLayout();
1219 mainLayout->addLayout( qmlLayout );
1220 qmlLayout->addLayout( layout );
1221 dlg.setLayout( mainLayout );
1222 layout->addWidget( baseWidget );
1224 QLineEdit *title =
new QLineEdit( itemData.
name() );
1228 qmlCode->setPlaceholderText( tr(
"Insert QML code here…" ) );
1235 connect( qmlCode, &QPlainTextEdit::textChanged,
this, [ = ]
1237 qmlWrapper->
setQmlCode( qmlCode->toPlainText() );
1243 QComboBox *qmlObjectTemplate =
new QComboBox();
1244 qmlObjectTemplate->addItem( tr(
"Free Text…" ) );
1245 qmlObjectTemplate->addItem( tr(
"Rectangle" ) );
1246 qmlObjectTemplate->addItem( tr(
"Pie Chart" ) );
1247 qmlObjectTemplate->addItem( tr(
"Bar Chart" ) );
1248 connect( qmlObjectTemplate, qOverload<int>( &QComboBox::activated ), qmlCode, [ = ](
int index )
1255 qmlCode->setPlaceholderText( tr(
"Insert QML code here…" ) );
1260 qmlCode->insertPlainText( QStringLiteral(
"import QtQuick 2.0\n"
1265 " color: \"steelblue\"\n"
1266 " Text{ text: \"A rectangle\" }\n"
1272 qmlCode->insertPlainText( QStringLiteral(
"import QtQuick 2.0\n"
1273 "import QtCharts 2.0\n"
1281 " PieSlice { label: \"First slice\"; value: 25 }\n"
1282 " PieSlice { label: \"Second slice\"; value: 45 }\n"
1283 " PieSlice { label: \"Third slice\"; value: 30 }\n"
1290 qmlCode->insertPlainText( QStringLiteral(
"import QtQuick 2.0\n"
1291 "import QtCharts 2.0\n"
1294 " title: \"Bar series\"\n"
1297 " legend.alignment: Qt.AlignBottom\n"
1298 " antialiasing: true\n"
1307 " axisY: valueAxisY\n"
1308 " axisX: BarCategoryAxis { categories: [\"2007\", \"2008\", \"2009\", \"2010\", \"2011\", \"2012\" ] }\n"
1309 " BarSet { label: \"Bob\"; values: [2, 2, 3, 4, 5, 6] }\n"
1310 " BarSet { label: \"Susan\"; values: [5, 1, 2, 4, 1, 7] }\n"
1311 " BarSet { label: \"James\"; values: [3, 5, 8, 13, 5, 8] }\n"
1322 expressionWidget->
setLayer( mLayer );
1323 QToolButton *addExpressionButton =
new QToolButton();
1326 connect( addExpressionButton, &QAbstractButton::clicked,
this, [ = ]
1328 qmlCode->insertPlainText( QStringLiteral(
"expression.evaluate(\"%1\")" ).arg( expressionWidget->expression().replace(
'"', QLatin1String(
"\\\"" ) ) ) );
1331 layout->addWidget(
new QLabel( tr(
"Title" ) ) );
1332 layout->addWidget( title );
1333 QGroupBox *qmlCodeBox =
new QGroupBox( tr(
"QML Code" ) );
1334 qmlCodeBox->setLayout(
new QGridLayout );
1335 qmlCodeBox->layout()->addWidget( qmlObjectTemplate );
1336 QGroupBox *expressionWidgetBox =
new QGroupBox();
1337 qmlCodeBox->layout()->addWidget( expressionWidgetBox );
1338 expressionWidgetBox->setLayout(
new QHBoxLayout );
1339 expressionWidgetBox->layout()->addWidget( expressionWidget );
1340 expressionWidgetBox->layout()->addWidget( addExpressionButton );
1341 qmlCodeBox->layout()->addWidget( qmlCode );
1342 layout->addWidget( qmlCodeBox );
1343 QScrollArea *qmlPreviewBox =
new QScrollArea();
1344 qmlPreviewBox->setLayout(
new QGridLayout );
1345 qmlPreviewBox->setMinimumWidth( 400 );
1346 qmlPreviewBox->layout()->addWidget( qmlWrapper->
widget() );
1348 emit qmlCode->textChanged();
1349 qmlLayout->addWidget( qmlPreviewBox );
1351 QDialogButtonBox *buttonBox =
new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
1353 connect( buttonBox, &QDialogButtonBox::accepted, &dlg, &QDialog::accept );
1354 connect( buttonBox, &QDialogButtonBox::rejected, &dlg, &QDialog::reject );
1356 mainLayout->addWidget( buttonBox );
1361 qmlEdCfg.
qmlCode = qmlCode->toPlainText();
1362 itemData.
setName( title->text() );
1364 itemData.
setShowLabel( showLabelCheckbox->isChecked() );
1367 item->setText( 0, title->text() );
1374 if ( mType == QgsAttributesDnDTree::Type::Drag )
1377 dlg.setWindowTitle( tr(
"Configure HTML Widget" ) );
1379 QVBoxLayout *mainLayout =
new QVBoxLayout();
1380 QHBoxLayout *htmlLayout =
new QHBoxLayout();
1381 QVBoxLayout *layout =
new QVBoxLayout();
1382 mainLayout->addLayout( htmlLayout );
1383 htmlLayout->addLayout( layout );
1384 dlg.setLayout( mainLayout );
1385 layout->addWidget( baseWidget );
1387 QLineEdit *title =
new QLineEdit( itemData.
name() );
1391 htmlCode->setSizePolicy( QSizePolicy::Policy::Expanding, QSizePolicy::Policy::Expanding );
1399 connect( htmlCode, &QgsCodeEditorHTML::textChanged,
this, [ = ]
1407 expressionWidget->
setLayer( mLayer );
1408 QToolButton *addExpressionButton =
new QToolButton();
1411 connect( addExpressionButton, &QAbstractButton::clicked,
this, [ = ]
1413 htmlCode->
insertText( QStringLiteral(
"<script>document.write(expression.evaluate(\"%1\"));</script>" ).arg( expressionWidget->expression().replace(
'"', QLatin1String(
"\\\"" ) ) ) );
1416 layout->addWidget(
new QLabel( tr(
"Title" ) ) );
1417 layout->addWidget( title );
1418 QGroupBox *expressionWidgetBox =
new QGroupBox( tr(
"HTML Code" ) );
1419 layout->addWidget( expressionWidgetBox );
1420 expressionWidgetBox->setLayout(
new QHBoxLayout );
1421 expressionWidgetBox->layout()->addWidget( expressionWidget );
1422 expressionWidgetBox->layout()->addWidget( addExpressionButton );
1423 layout->addWidget( htmlCode );
1424 QScrollArea *htmlPreviewBox =
new QScrollArea();
1425 htmlPreviewBox->setLayout(
new QGridLayout );
1426 htmlPreviewBox->setMinimumWidth( 400 );
1427 htmlPreviewBox->layout()->addWidget( htmlWrapper->
widget() );
1429 emit htmlCode->textChanged();
1430 htmlLayout->addWidget( htmlPreviewBox );
1432 QDialogButtonBox *buttonBox =
new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
1434 connect( buttonBox, &QDialogButtonBox::accepted, &dlg, &QDialog::accept );
1435 connect( buttonBox, &QDialogButtonBox::rejected, &dlg, &QDialog::reject );
1437 mainLayout->addWidget( buttonBox );
1442 htmlEdCfg.
htmlCode = htmlCode->text();
1443 itemData.
setName( title->text() );
1445 itemData.
setShowLabel( showLabelCheckbox->isChecked() );
1448 item->setText( 0, title->text() );
1467 QTreeWidgetItemIterator it(
this );
1473 if ( selectedItems().count() == 1 && ( *it )->isSelected() == true )
1480 ( *it )->setSelected(
true );
1503 QString displayName;
1506 stream >> type >> name >> displayName;
1517 return mShowAsGroupBox;
1522 mShowAsGroupBox = showAsGroupBox;
1532 mShowLabel = showLabel;
1537 return mVisibilityExpression;
1542 mVisibilityExpression = visibilityExpression;
1547 return mRelationEditorConfiguration;
1552 mRelationEditorConfiguration = relationEditorConfiguration;
1557 return mQmlElementEditorConfiguration;
1562 mQmlElementEditorConfiguration = qmlElementEditorConfiguration;
1568 return mHtmlElementEditorConfiguration;
1573 mHtmlElementEditorConfiguration = htmlElementEditorConfiguration;
1578 return mBackgroundColor;
1583 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 rendered as 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...
virtual void setIsGroupBox(bool isGroupBox)
Determines if this container is rendered as collapsible group box or tab in a tabwidget.
QColor backgroundColor() const
backgroundColor
int columnCount() const
Gets the number of columns in this group.
QList< QgsAttributeEditorElement * > children() const
Gets a list of the children elements of this container.
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.
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.
QgsActionManager * actions()
Returns all layer actions defined on this layer.
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.
void setFieldAlias(int index, const QString &aliasString)
Sets an alias (a display name) for attributes to display in dialogs.
QgsEditFormConfig editFormConfig