21#include "qgsattributetypedialog.h"
22#include "qgsattributeformcontaineredit.h"
23#include "qgsattributewidgetedit.h"
50 mEditorLayoutComboBox->addItem( tr(
"Autogenerate" ), QgsEditFormConfig::EditorLayout::GeneratedLayout );
51 mEditorLayoutComboBox->addItem( tr(
"Drag and Drop Designer" ), QgsEditFormConfig::EditorLayout::TabLayout );
52 mEditorLayoutComboBox->addItem( tr(
"Provide ui-file" ), QgsEditFormConfig::EditorLayout::UiFileLayout );
55 QGridLayout *availableWidgetsWidgetLayout =
new QGridLayout;
58 availableWidgetsWidgetLayout->setContentsMargins( 0, 0, 0, 0 );
59 mAvailableWidgetsWidget->setLayout( availableWidgetsWidgetLayout );
65 QGridLayout *formLayoutWidgetLayout =
new QGridLayout;
67 mFormLayoutWidget->setLayout( formLayoutWidgetLayout );
69 formLayoutWidgetLayout->setContentsMargins( 0, 0, 0, 0 );
70 mFormLayoutTree->setHeaderLabels( QStringList() << tr(
"Form Layout" ) );
73 connect(
mAvailableWidgetsTree, &QTreeWidget::itemSelectionChanged,
this, &QgsAttributesFormProperties::onAttributeSelectionChanged );
74 connect(
mFormLayoutTree, &QTreeWidget::itemSelectionChanged,
this, &QgsAttributesFormProperties::onFormLayoutSelectionChanged );
75 connect( mAddTabOrGroupButton, &QAbstractButton::clicked,
this, &QgsAttributesFormProperties::addTabOrGroupButton );
76 connect( mRemoveTabOrGroupButton, &QAbstractButton::clicked,
this, &QgsAttributesFormProperties::removeTabOrGroupButton );
77 connect( mInvertSelectionButton, &QAbstractButton::clicked,
this, &QgsAttributesFormProperties::onInvertSelectionButtonClicked );
78 connect( mEditorLayoutComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsAttributesFormProperties::mEditorLayoutComboBox_currentIndexChanged );
79 connect( pbnSelectEditForm, &QToolButton::clicked,
this, &QgsAttributesFormProperties::pbnSelectEditForm_clicked );
80 connect( mTbInitCode, &QPushButton::clicked,
this, &QgsAttributesFormProperties::mTbInitCode_clicked );
107 for (
int i = 0; i < fields.
size(); ++i )
125 item->setToolTip( 0, tooltip );
127 catitem->setExpanded(
true );
142 catitem->setExpanded(
true );
150 for (
const auto &action : std::as_const( actions ) )
152 if ( action.isValid() && action.runable() &&
153 ( action.actionScopes().contains( QStringLiteral(
"Feature" ) ) ||
154 action.actionScopes().contains( QStringLiteral(
"Layer" ) ) ) )
156 const QString actionTitle { action.shortTitle().isEmpty() ? action.name() : action.shortTitle() };
183 catitem ->setExpanded(
true );
191 mFormLayoutTree->setSelectionBehavior( QAbstractItemView::SelectRows );
192 mFormLayoutTree->setSelectionMode( QAbstractItemView::SelectionMode::ExtendedSelection );
208 mFormSuppressCmbBx->addItem( tr(
"Hide Form on Add Feature (global settings)" ) );
212 mFormSuppressCmbBx->addItem( tr(
"Show Form on Add Feature (global settings)" ) );
214 mFormSuppressCmbBx->addItem( tr(
"Hide Form on Add Feature" ) );
215 mFormSuppressCmbBx->addItem( tr(
"Show Form on Add Feature" ) );
231 mEditorLayoutComboBox_currentIndexChanged( mEditorLayoutComboBox->currentIndex() );
234 mEditFormLineEdit->setText( cfg.
uiForm() );
246 if ( mInitCode.isEmpty() )
248 mInitCode.append( tr(
"# -*- coding: utf-8 -*-\n\"\"\"\n"
249 "QGIS forms can have a Python function that is called when the form is\n"
252 "Use this function to add extra logic to your forms.\n"
254 "Enter the name of the function in the \"Python Init function\"\n"
256 "An example follows:\n"
258 "from qgis.PyQt.QtWidgets import QWidget\n\n"
259 "def my_form_open(dialog, layer, feature):\n"
260 " geom = feature.geometry()\n"
261 " control = dialog.findChild(QWidget, \"MyLineEdit\")\n" ) );
265void QgsAttributesFormProperties::loadAttributeTypeDialog()
272 const FieldConfig cfg = item->data( 0,
FieldConfigRole ).value<FieldConfig>();
273 const QString fieldName = item->data( 0,
FieldNameRole ).toString();
294 QgsFieldConstraints::Constraints providerConstraints = QgsFieldConstraints::Constraints();
313 mAttributeTypeFrame->layout()->setContentsMargins( 0, 0, 0, 0 );
319void QgsAttributesFormProperties::storeAttributeTypeDialog()
369 cfg.mFieldConstraints = constraints;
380 QTreeWidgetItem *item = *itemIt;
381 if ( item->data( 0,
FieldNameRole ).toString() == fieldName )
382 item->setData( 0,
FieldConfigRole, QVariant::fromValue<FieldConfig>( cfg ) );
386void QgsAttributesFormProperties::storeAttributeWidgetEdit()
394void QgsAttributesFormProperties::loadAttributeWidgetEdit()
399 QTreeWidgetItem *currentItem =
mFormLayoutTree->selectedItems().at( 0 );
401 mAttributeTypeFrame->layout()->setContentsMargins( 0, 0, 0, 0 );
405void QgsAttributesFormProperties::loadInfoWidget(
const QString &infoText )
408 mAttributeTypeFrame->layout()->setContentsMargins( 0, 0, 0, 0 );
412void QgsAttributesFormProperties::storeAttributeContainerEdit()
420void QgsAttributesFormProperties::loadAttributeContainerEdit()
425 QTreeWidgetItem *currentItem =
mFormLayoutTree->selectedItems().at( 0 );
429 mAttributeTypeFrame->layout()->setContentsMargins( 0, 0, 0, 0 );
436 QTreeWidgetItem *newWidget =
nullptr;
437 switch ( widgetDef->
type() )
442 itemData.setShowLabel( widgetDef->
showLabel() );
443 itemData.setLabelStyle( widgetDef->
labelStyle() );
444 newWidget = tree->
addItem( parent, itemData );
452 if ( action.isValid() )
454 DnDTreeItemData itemData = DnDTreeItemData(
DnDTreeItemData::Action, action.id().toString(), action.shortTitle().isEmpty() ? action.name() : action.shortTitle() );
455 itemData.setShowLabel( widgetDef->
showLabel() );
456 itemData.setLabelStyle( widgetDef->
labelStyle() );
457 newWidget = tree->
addItem( parent, itemData );
461 QgsDebugMsg( QStringLiteral(
"Invalid form action" ) );
470 itemData.setShowLabel( widgetDef->
showLabel() );
471 itemData.setLabelStyle( widgetDef->
labelStyle() );
473 RelationEditorConfiguration relEdConfig;
477 relEdConfig.nmRelationId = relationEditor->
nmRelationId();
479 relEdConfig.label = relationEditor->
label();
480 itemData.setRelationEditorConfiguration( relEdConfig );
481 newWidget = tree->
addItem( parent, itemData );
488 itemData.setShowLabel( widgetDef->
showLabel() );
495 itemData.setShowAsGroupBox( container->
isGroupBox() );
499 itemData.setCollapsed( container->
collapsed() );
500 itemData.setLabelStyle( widgetDef->
labelStyle() );
501 newWidget = tree->
addItem( parent, itemData );
503 const QList<QgsAttributeEditorElement *> children = container->
children();
506 loadAttributeEditorTreeItem( wdg, newWidget, tree );
515 itemData.setShowLabel( widgetDef->
showLabel() );
516 QmlElementEditorConfiguration qmlEdConfig;
517 qmlEdConfig.qmlCode = qmlElementEditor->
qmlCode();
518 itemData.setQmlElementEditorConfiguration( qmlEdConfig );
519 itemData.setLabelStyle( widgetDef->
labelStyle() );
520 newWidget = tree->
addItem( parent, itemData );
528 itemData.setShowLabel( widgetDef->
showLabel() );
529 HtmlElementEditorConfiguration htmlEdConfig;
530 htmlEdConfig.htmlCode = htmlElementEditor->
htmlCode();
531 itemData.setHtmlElementEditorConfiguration( htmlEdConfig );
532 itemData.setLabelStyle( widgetDef->
labelStyle() );
533 newWidget = tree->
addItem( parent, itemData );
541 itemData.setShowLabel( widgetDef->
showLabel() );
542 TextElementEditorConfiguration textEdConfig;
543 textEdConfig.text = textElementEditor->
text();
544 itemData.setTextElementEditorConfiguration( textEdConfig );
545 itemData.setLabelStyle( widgetDef->
labelStyle() );
546 newWidget = tree->
addItem( parent, itemData );
554 itemData.setShowLabel( widgetDef->
showLabel() );
555 SpacerElementEditorConfiguration spacerEdConfig;
556 spacerEdConfig.drawLine = spacerElementEditor->
drawLine();
557 itemData.setSpacerElementEditorConfiguration( spacerEdConfig );
558 itemData.setLabelStyle( widgetDef->
labelStyle() );
559 itemData.setShowLabel(
false );
560 newWidget = tree->
addItem( parent, itemData );
566 QgsDebugMsg( QStringLiteral(
"Not loading invalid attribute editor type..." ) );
575void QgsAttributesFormProperties::onAttributeSelectionChanged()
577 disconnect(
mFormLayoutTree, &QTreeWidget::itemSelectionChanged,
this, &QgsAttributesFormProperties::onFormLayoutSelectionChanged );
579 connect(
mFormLayoutTree, &QTreeWidget::itemSelectionChanged,
this, &QgsAttributesFormProperties::onFormLayoutSelectionChanged );
582void QgsAttributesFormProperties::onFormLayoutSelectionChanged()
585 disconnect(
mAvailableWidgetsTree, &QTreeWidget::itemSelectionChanged,
this, &QgsAttributesFormProperties::onAttributeSelectionChanged );
587 connect(
mAvailableWidgetsTree, &QTreeWidget::itemSelectionChanged,
this, &QgsAttributesFormProperties::onAttributeSelectionChanged );
594 if ( layout == QgsEditFormConfig::EditorLayout::TabLayout )
595 storeAttributeWidgetEdit();
596 storeAttributeTypeDialog();
597 storeAttributeContainerEdit();
599 clearAttributeTypeFrame();
601 if ( emitter->selectedItems().count() != 1 )
603 receiver->clearSelection();
607 const DnDTreeItemData itemData = emitter->selectedItems().at( 0 )->data( 0,
DnDTreeRole ).value<DnDTreeItemData>();
608 switch ( itemData.type() )
613 if ( layout == QgsEditFormConfig::EditorLayout::TabLayout )
615 loadAttributeWidgetEdit();
619 loadInfoWidget( tr(
"This configuration is available in the Drag and Drop Designer" ) );
626 if ( layout == QgsEditFormConfig::EditorLayout::TabLayout )
627 loadAttributeWidgetEdit();
628 loadAttributeTypeDialog();
633 receiver->clearSelection();
634 loadAttributeContainerEdit();
641 loadInfoWidget( action.html() );
649 if ( layout != QgsEditFormConfig::EditorLayout::TabLayout )
651 loadInfoWidget( tr(
"This configuration is available with double-click in the Drag and Drop Designer" ) );
655 loadInfoWidget( tr(
"This configuration is available with double-click" ) );
657 receiver->clearSelection();
662 receiver->clearSelection();
669void QgsAttributesFormProperties::clearAttributeTypeFrame()
697void QgsAttributesFormProperties::onInvertSelectionButtonClicked(
bool checked )
702 for (
int i = 0; i < rootItem->childCount(); ++i )
704 rootItem->child( i )->setSelected( ! selectedItemList.contains( rootItem->child( i ) ) );
708void QgsAttributesFormProperties::addTabOrGroupButton()
710 QList<QgsAddTabOrGroup::TabPair> tabList;
714 const DnDTreeItemData itemData = ( *it )->data( 0,
DnDTreeRole ).value<DnDTreeItemData>();
720 QTreeWidgetItem *currentItem =
mFormLayoutTree->selectedItems().value( 0 );
723 if ( !addTabOrGroup.exec() )
726 const QString name = addTabOrGroup.name();
727 if ( addTabOrGroup.tabButtonIsChecked() )
733 QTreeWidgetItem *tabItem = addTabOrGroup.tab();
738void QgsAttributesFormProperties::removeTabOrGroupButton()
750 switch ( itemData.
type() )
791 for (
int t = 0; t < item->childCount(); t++ )
798 widgetDef = container;
848void QgsAttributesFormProperties::mEditorLayoutComboBox_currentIndexChanged(
int index )
855 case QgsEditFormConfig::EditorLayout::GeneratedLayout:
856 mFormLayoutWidget->setVisible(
false );
857 mUiFileFrame->setVisible(
false );
858 mAddTabOrGroupButton->setVisible(
false );
859 mRemoveTabOrGroupButton->setVisible(
false );
860 mInvertSelectionButton->setVisible(
false );
863 case QgsEditFormConfig::EditorLayout::TabLayout:
864 mFormLayoutWidget->setVisible(
true );
865 mUiFileFrame->setVisible(
false );
866 mAddTabOrGroupButton->setVisible(
true );
867 mRemoveTabOrGroupButton->setVisible(
true );
868 mInvertSelectionButton->setVisible(
true );
871 case QgsEditFormConfig::EditorLayout::UiFileLayout:
873 mFormLayoutWidget->setVisible(
false );
874 mUiFileFrame->setVisible(
true );
875 mAddTabOrGroupButton->setVisible(
false );
876 mRemoveTabOrGroupButton->setVisible(
false );
877 mInvertSelectionButton->setVisible(
false );
882void QgsAttributesFormProperties::mTbInitCode_clicked()
891 if ( !attributesFormInitCode.exec() )
894 mInitCodeSource = attributesFormInitCode.
codeSource();
895 mInitCode = attributesFormInitCode.
initCode();
901void QgsAttributesFormProperties::pbnSelectEditForm_clicked()
904 const QString lastUsedDir = myQSettings.
value( QStringLiteral(
"style/lastUIDir" ), QDir::homePath() ).toString();
905 const QString uifilename = QFileDialog::getOpenFileName(
this, tr(
"Select edit form" ), lastUsedDir, tr(
"UI file" ) +
" (*.ui)" );
907 if ( uifilename.isNull() )
910 const QFileInfo fi( uifilename );
911 myQSettings.
setValue( QStringLiteral(
"style/lastUIDir" ), fi.path() );
912 mEditFormLineEdit->setText( uifilename );
917 storeAttributeWidgetEdit();
918 storeAttributeContainerEdit();
919 storeAttributeTypeDialog();
925 for (
int i = 0; i < fieldContainer->childCount(); i++ )
927 QTreeWidgetItem *fieldItem = fieldContainer->child( i );
930 const QString fieldName { fieldItem->data( 0,
FieldNameRole ).toString() };
980 for (
int t = 0; t <
mFormLayoutTree->invisibleRootItem()->childCount(); t++ )
982 QTreeWidgetItem *tabItem =
mFormLayoutTree->invisibleRootItem()->child( t );
985 editFormConfig.
addTab( editorElement );
988 editFormConfig.
setUiForm( mEditFormLineEdit->text() );
1002 for (
int i = 0; i < relationContainer->childCount(); i++ )
1004 QTreeWidgetItem *relationItem = relationContainer->child( i );
1007 for (
int t = 0; t <
mFormLayoutTree->invisibleRootItem()->childCount(); t++ )
1009 QTreeWidgetItem *tabItem =
mFormLayoutTree->invisibleRootItem()->child( t );
1012 if ( tabItemData.
type() == itemData.
type() && tabItemData.
name() == itemData.
name() )
1048QgsAttributesFormProperties::FieldConfig::operator QVariant()
1050 return QVariant::fromValue<QgsAttributesFormProperties::FieldConfig>( *
this );
1057QgsAttributesFormProperties::RelationEditorConfiguration::operator QVariant()
1059 return QVariant::fromValue<QgsAttributesFormProperties::RelationEditorConfiguration>( *
this );
1068 QTreeWidgetItem *newItem =
new QTreeWidgetItem( QStringList() << title );
1069 newItem->setBackground( 0, QBrush( Qt::lightGray ) );
1070 newItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled );
1074 parent->addChild( newItem );
1075 newItem->setExpanded(
true );
1080 : QTreeWidget( parent )
1083 connect(
this, &QTreeWidget::itemDoubleClicked,
this, &QgsAttributesDnDTree::onItemDoubleClicked );
1088 QTreeWidgetItem *newItem =
new QTreeWidgetItem( QStringList() << data.
name() );
1090 switch ( data.
type() )
1099 newItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled );
1105 newItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled );
1106 newItem->setBackground( 0, QBrush( Qt::lightGray ) );
1113 newItem->setIcon( 0, icon );
1116 parent->addChild( newItem );
1118 parent->insertChild( index, newItem );
1130 const QMimeData *data =
event->mimeData();
1132 if ( data->hasFormat( QStringLiteral(
"application/x-qgsattributetabledesignerelement" ) ) )
1136 QByteArray itemData = data->data( QStringLiteral(
"application/x-qgsattributetabledesignerelement" ) );
1137 QDataStream stream( &itemData, QIODevice::ReadOnly );
1138 stream >> itemElement;
1141 if ( event->source() ==
this )
1143 event->setDropAction( Qt::MoveAction );
1151 QTreeWidget::dragMoveEvent( event );
1157 bool bDropSuccessful =
false;
1159 if ( action == Qt::IgnoreAction )
1161 bDropSuccessful =
true;
1163 else if ( data->hasFormat( QStringLiteral(
"application/x-qgsattributetabledesignerelement" ) ) )
1165 QByteArray itemData = data->data( QStringLiteral(
"application/x-qgsattributetabledesignerelement" ) );
1166 QDataStream stream( &itemData, QIODevice::ReadOnly );
1169 while ( !stream.atEnd() )
1171 stream >> itemElement;
1173 QTreeWidgetItem *newItem;
1177 newItem =
addItem( parent, itemElement, index++ );
1178 bDropSuccessful =
true;
1182 newItem =
addItem( invisibleRootItem(), itemElement, index++ );
1183 bDropSuccessful =
true;
1188 onItemDoubleClicked( newItem, 0 );
1193 onItemDoubleClicked( newItem, 0 );
1198 onItemDoubleClicked( newItem, 0 );
1203 onItemDoubleClicked( newItem, 0 );
1207 newItem->setSelected(
true );
1211 return bDropSuccessful;
1216 if ( !event->mimeData()->hasFormat( QStringLiteral(
"application/x-qgsattributetabledesignerelement" ) ) )
1219 if ( event->source() ==
this )
1221 event->setDropAction( Qt::MoveAction );
1224 QTreeWidget::dropEvent( event );
1229 return QStringList() << QStringLiteral(
"application/x-qgsattributetabledesignerelement" );
1232#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1238 if ( items.count() <= 0 )
1241 const QStringList types = mimeTypes();
1243 if ( types.isEmpty() )
1246 QMimeData *data =
new QMimeData();
1247 const QString format = types.at( 0 );
1249 QDataStream stream( &encoded, QIODevice::WriteOnly );
1251 const auto constItems = items;
1252 for (
const QTreeWidgetItem *item : constItems )
1262 data->setData( format, encoded );
1267void QgsAttributesDnDTree::onItemDoubleClicked( QTreeWidgetItem *item,
int column )
1273 QGroupBox *baseData =
new QGroupBox( tr(
"Base configuration" ) );
1275 QFormLayout *baseLayout =
new QFormLayout();
1276 baseData->setLayout( baseLayout );
1277 QCheckBox *showLabelCheckbox =
new QCheckBox( QStringLiteral(
"Show label" ) );
1278 showLabelCheckbox->setChecked( itemData.
showLabel() );
1279 baseLayout->addRow( showLabelCheckbox );
1280 QWidget *baseWidget =
new QWidget();
1281 baseWidget->setLayout( baseLayout );
1283 switch ( itemData.
type() )
1294 if ( mType == QgsAttributesDnDTree::Type::Drag )
1298 dlg.setWindowTitle( tr(
"Configure QML Widget" ) );
1300 QVBoxLayout *mainLayout =
new QVBoxLayout();
1301 QHBoxLayout *qmlLayout =
new QHBoxLayout();
1302 QVBoxLayout *layout =
new QVBoxLayout();
1303 mainLayout->addLayout( qmlLayout );
1304 qmlLayout->addLayout( layout );
1305 dlg.setLayout( mainLayout );
1306 layout->addWidget( baseWidget );
1308 QLineEdit *title =
new QLineEdit( itemData.
name() );
1312 qmlCode->setPlaceholderText( tr(
"Insert QML code here…" ) );
1319 connect( qmlCode, &QPlainTextEdit::textChanged,
this, [ = ]
1321 qmlWrapper->
setQmlCode( qmlCode->toPlainText() );
1327 QComboBox *qmlObjectTemplate =
new QComboBox();
1328 qmlObjectTemplate->addItem( tr(
"Free Text…" ) );
1329 qmlObjectTemplate->addItem( tr(
"Rectangle" ) );
1330 qmlObjectTemplate->addItem( tr(
"Pie Chart" ) );
1331 qmlObjectTemplate->addItem( tr(
"Bar Chart" ) );
1332 connect( qmlObjectTemplate, qOverload<int>( &QComboBox::activated ), qmlCode, [ = ](
int index )
1339 qmlCode->setPlaceholderText( tr(
"Insert QML code here…" ) );
1344 qmlCode->insertPlainText( QStringLiteral(
"import QtQuick 2.0\n"
1349 " color: \"steelblue\"\n"
1350 " Text{ text: \"A rectangle\" }\n"
1356 qmlCode->insertPlainText( QStringLiteral(
"import QtQuick 2.0\n"
1357 "import QtCharts 2.0\n"
1365 " PieSlice { label: \"First slice\"; value: 25 }\n"
1366 " PieSlice { label: \"Second slice\"; value: 45 }\n"
1367 " PieSlice { label: \"Third slice\"; value: 30 }\n"
1374 qmlCode->insertPlainText( QStringLiteral(
"import QtQuick 2.0\n"
1375 "import QtCharts 2.0\n"
1378 " title: \"Bar series\"\n"
1381 " legend.alignment: Qt.AlignBottom\n"
1382 " antialiasing: true\n"
1391 " axisY: valueAxisY\n"
1392 " axisX: BarCategoryAxis { categories: [\"2007\", \"2008\", \"2009\", \"2010\", \"2011\", \"2012\" ] }\n"
1393 " BarSet { label: \"Bob\"; values: [2, 2, 3, 4, 5, 6] }\n"
1394 " BarSet { label: \"Susan\"; values: [5, 1, 2, 4, 1, 7] }\n"
1395 " BarSet { label: \"James\"; values: [3, 5, 8, 13, 5, 8] }\n"
1406 expressionWidget->
setLayer( mLayer );
1407 QToolButton *addExpressionButton =
new QToolButton();
1410 connect( addExpressionButton, &QAbstractButton::clicked,
this, [ = ]
1412 qmlCode->insertPlainText( QStringLiteral(
"expression.evaluate(\"%1\")" ).arg( expressionWidget->expression().replace(
'"', QLatin1String(
"\\\"" ) ) ) );
1415 layout->addWidget(
new QLabel( tr(
"Title" ) ) );
1416 layout->addWidget( title );
1417 QGroupBox *qmlCodeBox =
new QGroupBox( tr(
"QML Code" ) );
1418 qmlCodeBox->setLayout(
new QGridLayout );
1419 qmlCodeBox->layout()->addWidget( qmlObjectTemplate );
1420 QGroupBox *expressionWidgetBox =
new QGroupBox();
1421 qmlCodeBox->layout()->addWidget( expressionWidgetBox );
1422 expressionWidgetBox->setLayout(
new QHBoxLayout );
1423 expressionWidgetBox->layout()->addWidget( expressionWidget );
1424 expressionWidgetBox->layout()->addWidget( addExpressionButton );
1425 qmlCodeBox->layout()->addWidget( qmlCode );
1426 layout->addWidget( qmlCodeBox );
1428 qmlPreviewBox->setLayout(
new QGridLayout );
1429 qmlPreviewBox->setMinimumWidth( 400 );
1430 qmlPreviewBox->layout()->addWidget( qmlWrapper->
widget() );
1432 emit qmlCode->textChanged();
1433 qmlLayout->addWidget( qmlPreviewBox );
1435 QDialogButtonBox *buttonBox =
new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
1437 connect( buttonBox, &QDialogButtonBox::accepted, &dlg, &QDialog::accept );
1438 connect( buttonBox, &QDialogButtonBox::rejected, &dlg, &QDialog::reject );
1440 mainLayout->addWidget( buttonBox );
1445 qmlEdCfg.
qmlCode = qmlCode->toPlainText();
1446 itemData.
setName( title->text() );
1448 itemData.
setShowLabel( showLabelCheckbox->isChecked() );
1451 item->setText( 0, title->text() );
1458 if ( mType == QgsAttributesDnDTree::Type::Drag )
1461 dlg.setWindowTitle( tr(
"Configure HTML Widget" ) );
1463 QVBoxLayout *mainLayout =
new QVBoxLayout();
1464 QHBoxLayout *htmlLayout =
new QHBoxLayout();
1465 QVBoxLayout *layout =
new QVBoxLayout();
1466 mainLayout->addLayout( htmlLayout );
1467 htmlLayout->addLayout( layout );
1468 dlg.setLayout( mainLayout );
1469 layout->addWidget( baseWidget );
1471 QLineEdit *title =
new QLineEdit( itemData.
name() );
1475 htmlCode->setSizePolicy( QSizePolicy::Policy::Expanding, QSizePolicy::Policy::Expanding );
1483 connect( htmlCode, &QgsCodeEditorHTML::textChanged,
this, [ = ]
1492 expressionWidget->setLayer( mLayer );
1493 QToolButton *addExpressionButton =
new QToolButton();
1496 connect( addExpressionButton, &QAbstractButton::clicked,
this, [ = ]
1498 htmlCode->
insertText( QStringLiteral(
"<script>document.write(expression.evaluate(\"%1\"));</script>" ).arg( expressionWidget->expression().replace(
'"', QLatin1String(
"\\\"" ) ) ) );
1501 layout->addWidget(
new QLabel( tr(
"Title" ) ) );
1502 layout->addWidget( title );
1503 QGroupBox *expressionWidgetBox =
new QGroupBox( tr(
"HTML Code" ) );
1504 layout->addWidget( expressionWidgetBox );
1505 expressionWidgetBox->setLayout(
new QHBoxLayout );
1506 expressionWidgetBox->layout()->addWidget( expressionWidget );
1507 expressionWidgetBox->layout()->addWidget( addExpressionButton );
1508 layout->addWidget( htmlCode );
1510 htmlPreviewBox->setLayout(
new QGridLayout );
1511 htmlPreviewBox->setMinimumWidth( 400 );
1512 htmlPreviewBox->layout()->addWidget( htmlWrapper->
widget() );
1514 emit htmlCode->textChanged();
1515 htmlLayout->addWidget( htmlPreviewBox );
1517 QDialogButtonBox *buttonBox =
new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
1519 connect( buttonBox, &QDialogButtonBox::accepted, &dlg, &QDialog::accept );
1520 connect( buttonBox, &QDialogButtonBox::rejected, &dlg, &QDialog::reject );
1522 mainLayout->addWidget( buttonBox );
1527 htmlEdCfg.
htmlCode = htmlCode->text();
1528 itemData.
setName( title->text() );
1530 itemData.
setShowLabel( showLabelCheckbox->isChecked() );
1533 item->setText( 0, title->text() );
1540 if ( mType == QgsAttributesDnDTree::Type::Drag )
1543 dlg.setWindowTitle( tr(
"Configure Text Widget" ) );
1545 QVBoxLayout *mainLayout =
new QVBoxLayout();
1546 QHBoxLayout *textLayout =
new QHBoxLayout();
1547 QVBoxLayout *layout =
new QVBoxLayout();
1548 mainLayout->addLayout( textLayout );
1549 textLayout->addLayout( layout );
1550 dlg.setLayout( mainLayout );
1551 layout->addWidget( baseWidget );
1553 QLineEdit *title =
new QLineEdit( itemData.
name() );
1556 text->setSizePolicy( QSizePolicy::Policy::Expanding, QSizePolicy::Policy::Expanding );
1564 connect( text, &QgsCodeEditorExpression::textChanged,
this, [ = ]
1566 textWrapper->
setText( text->text( ) );
1572 expressionWidget->
setLayer( mLayer );
1573 QToolButton *addExpressionButton =
new QToolButton();
1576 connect( addExpressionButton, &QAbstractButton::clicked,
this, [ = ]
1578 text->
insertText( expressionWidget->expression().prepend( QStringLiteral(
"[% " ) ).append( QStringLiteral(
" %]" ) ) );
1581 layout->addWidget(
new QLabel( tr(
"Title" ) ) );
1582 layout->addWidget( title );
1583 QGroupBox *expressionWidgetBox =
new QGroupBox( tr(
"Text" ) );
1584 layout->addWidget( expressionWidgetBox );
1585 expressionWidgetBox->setLayout(
new QHBoxLayout );
1586 expressionWidgetBox->layout()->addWidget( expressionWidget );
1587 expressionWidgetBox->layout()->addWidget( addExpressionButton );
1588 layout->addWidget( text );
1590 textPreviewBox->setLayout(
new QGridLayout );
1591 textPreviewBox->setMinimumWidth( 400 );
1592 textPreviewBox->layout()->addWidget( textWrapper->
widget() );
1594 emit text->textChanged();
1595 textLayout->addWidget( textPreviewBox );
1597 QDialogButtonBox *buttonBox =
new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
1599 connect( buttonBox, &QDialogButtonBox::accepted, &dlg, &QDialog::accept );
1600 connect( buttonBox, &QDialogButtonBox::rejected, &dlg, &QDialog::reject );
1602 mainLayout->addWidget( buttonBox );
1607 textEdCfg.
text = text->text();
1608 itemData.
setName( title->text() );
1610 itemData.
setShowLabel( showLabelCheckbox->isChecked() );
1613 item->setText( 0, title->text() );
1620 if ( mType == QgsAttributesDnDTree::Type::Drag )
1623 dlg.setWindowTitle( tr(
"Configure Spacer Widget" ) );
1625 QVBoxLayout *mainLayout =
new QVBoxLayout();
1626 mainLayout->addWidget(
new QLabel( tr(
"Title" ) ) );
1627 QLineEdit *title =
new QLineEdit( itemData.
name() );
1628 mainLayout->addWidget( title );
1630 QHBoxLayout *cbLayout =
new QHBoxLayout( );
1631 mainLayout->addLayout( cbLayout );
1632 dlg.setLayout( mainLayout );
1633 QCheckBox *cb =
new QCheckBox { &dlg };
1635 cbLayout->addWidget(
new QLabel( tr(
"Draw horizontal line" ), &dlg ) );
1636 cbLayout->addWidget( cb );
1639 QDialogButtonBox *buttonBox =
new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
1641 connect( buttonBox, &QDialogButtonBox::accepted, &dlg, &QDialog::accept );
1642 connect( buttonBox, &QDialogButtonBox::rejected, &dlg, &QDialog::reject );
1644 mainLayout->addWidget( buttonBox );
1649 spacerEdCfg.
drawLine = cb->isChecked();
1652 itemData.
setName( title->text() );
1654 item->setText( 0, title->text() );
1687 QTreeWidgetItemIterator it(
this );
1693 if ( selectedItems().count() == 1 && ( *it )->isSelected() == true )
1700 ( *it )->setSelected(
true );
1723 QString displayName;
1726 stream >> type >> name >> displayName;
1737 return mShowAsGroupBox;
1742 mShowAsGroupBox = showAsGroupBox;
1752 mLabelStyle = labelStyle;
1762 mShowLabel = showLabel;
1767 return mVisibilityExpression;
1772 mVisibilityExpression = visibilityExpression;
1777 return mCollapsedExpression;
1782 mCollapsedExpression = collapsedExpression;
1787 return mRelationEditorConfiguration;
1792 mRelationEditorConfiguration = relationEditorConfiguration;
1797 return mQmlElementEditorConfiguration;
1802 mQmlElementEditorConfiguration = qmlElementEditorConfiguration;
1808 return mHtmlElementEditorConfiguration;
1813 mHtmlElementEditorConfiguration = htmlElementEditorConfiguration;
1818 return mSpacerElementEditorConfiguration;
1823 mSpacerElementEditorConfiguration = spacerElementEditorConfiguration;
1828 return mBackgroundColor;
1833 mBackgroundColor = backgroundColor;
1838 return mTextElementEditorConfiguration;
1843 mTextElementEditorConfiguration = textElementEditorConfiguration;
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).
@ AeTypeTextElement
A text element (since QGIS 3.30)
@ AeTypeHtmlElement
A HTML element.
@ AeTypeSpacerElement
A spacer element (since QGIS 3.30)
@ 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.
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 * 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
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
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.
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
The TabStyle struct defines color and font overrides for form fields, tabs and groups labels.