21#include "moc_qgsattributesformproperties.cpp"
22#include "qgsattributetypedialog.h"
23#include "qgsattributeformcontaineredit.h"
24#include "qgsattributewidgetedit.h"
63 QGridLayout *availableWidgetsWidgetLayout =
new QGridLayout;
66 availableWidgetsWidgetLayout->setContentsMargins( 0, 0, 0, 0 );
67 mAvailableWidgetsWidget->setLayout( availableWidgetsWidgetLayout );
74 QGridLayout *formLayoutWidgetLayout =
new QGridLayout;
76 mFormLayoutWidget->setLayout( formLayoutWidgetLayout );
78 formLayoutWidgetLayout->setContentsMargins( 0, 0, 0, 0 );
79 mFormLayoutTree->setHeaderLabels( QStringList() << tr(
"Form Layout" ) );
82 connect(
mAvailableWidgetsTree, &QTreeWidget::itemSelectionChanged,
this, &QgsAttributesFormProperties::onAttributeSelectionChanged );
83 connect(
mAvailableWidgetsTree, &QWidget::customContextMenuRequested,
this, &QgsAttributesFormProperties::onContextMenuRequested );
84 connect(
mFormLayoutTree, &QTreeWidget::itemSelectionChanged,
this, &QgsAttributesFormProperties::onFormLayoutSelectionChanged );
85 connect( mAddTabOrGroupButton, &QAbstractButton::clicked,
this, &QgsAttributesFormProperties::addContainer );
86 connect( mRemoveTabOrGroupButton, &QAbstractButton::clicked,
this, &QgsAttributesFormProperties::removeTabOrGroupButton );
87 connect( mInvertSelectionButton, &QAbstractButton::clicked,
this, &QgsAttributesFormProperties::onInvertSelectionButtonClicked );
88 connect( mEditorLayoutComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsAttributesFormProperties::mEditorLayoutComboBox_currentIndexChanged );
89 connect( pbnSelectEditForm, &QToolButton::clicked,
this, &QgsAttributesFormProperties::pbnSelectEditForm_clicked );
90 connect( mTbInitCode, &QPushButton::clicked,
this, &QgsAttributesFormProperties::mTbInitCode_clicked );
98 mAvailableWidgetsTreeContextMenu =
new QMenu(
this );
99 mActionCopyWidgetConfiguration =
new QAction( tr(
"Copy widget configuration" ),
this );
100 mActionPasteWidgetConfiguration =
new QAction( tr(
"Paste widget configuration" ),
this );
102 connect( mActionCopyWidgetConfiguration, &QAction::triggered,
this, &QgsAttributesFormProperties::copyWidgetConfiguration );
103 connect( mActionPasteWidgetConfiguration, &QAction::triggered,
this, &QgsAttributesFormProperties::pasteWidgetConfiguration );
105 mAvailableWidgetsTreeContextMenu->addAction( mActionCopyWidgetConfiguration );
106 mAvailableWidgetsTreeContextMenu->addAction( mActionPasteWidgetConfiguration );
109 mMessageBar->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed );
110 gridLayout->addWidget( mMessageBar, 0, 0 );
137 for (
int i = 0; i < fields.
size(); ++i )
151 if ( !field.
alias().isEmpty() )
152 tooltip = tr(
"%1 (%2)" ).arg( field.
name(), field.
alias() );
154 tooltip = field.
name();
155 item->setToolTip( 0, tooltip );
157 catitem->setExpanded(
true );
169 if ( polymorphicRelation.
isValid() )
171 name = QStringLiteral(
"%1 (%2)" ).arg( relation.name(), polymorphicRelation.
name() );
175 name = relation.
name();
182 catitem->setExpanded(
true );
190 for (
const auto &action : std::as_const( actions ) )
192 if ( action.isValid() && action.runable() && ( action.actionScopes().contains( QStringLiteral(
"Feature" ) ) || action.actionScopes().contains( QStringLiteral(
"Layer" ) ) ) )
194 const QString actionTitle { action.shortTitle().isEmpty() ? action.name() : action.shortTitle() };
221 catitem->setExpanded(
true );
229 mFormLayoutTree->setSelectionBehavior( QAbstractItemView::SelectRows );
230 mFormLayoutTree->setSelectionMode( QAbstractItemView::SelectionMode::ExtendedSelection );
267 mEditorLayoutComboBox->setCurrentIndex( mEditorLayoutComboBox->findData( QVariant::fromValue(
mLayer->
editFormConfig().
layout() ) ) );
269 mEditorLayoutComboBox_currentIndexChanged( mEditorLayoutComboBox->currentIndex() );
272 mEditFormLineEdit->setText( cfg.
uiForm() );
284 if ( mInitCode.isEmpty() )
286 mInitCode.append( tr(
"# -*- coding: utf-8 -*-\n\"\"\"\n"
287 "QGIS forms can have a Python function that is called when the form is\n"
290 "Use this function to add extra logic to your forms.\n"
292 "Enter the name of the function in the \"Python Init function\"\n"
294 "An example follows:\n"
296 "from qgis.PyQt.QtWidgets import QWidget\n\n"
297 "def my_form_open(dialog, layer, feature):\n"
298 " geom = feature.geometry()\n"
299 " control = dialog.findChild(QWidget, \"MyLineEdit\")\n" ) );
303void QgsAttributesFormProperties::loadAttributeTypeDialog()
310 const FieldConfig cfg = item->data( 0,
FieldConfigRole ).value<FieldConfig>();
311 const QString fieldName = item->data( 0,
FieldNameRole ).toString();
319 loadAttributeTypeDialogFromConfiguration( cfg );
325 mAttributeTypeFrame->layout()->setContentsMargins( 0, 0, 0, 0 );
330void QgsAttributesFormProperties::loadAttributeTypeDialogFromConfiguration(
const FieldConfig &config )
367void QgsAttributesFormProperties::storeAttributeTypeDialog()
416 cfg.mFieldConstraints = constraints;
430 QTreeWidgetItem *item = *itemIt;
431 if ( item->data( 0,
FieldNameRole ).toString() == fieldName )
432 item->setData( 0,
FieldConfigRole, QVariant::fromValue<FieldConfig>( cfg ) );
436void QgsAttributesFormProperties::storeAttributeWidgetEdit()
444void QgsAttributesFormProperties::loadAttributeWidgetEdit()
449 QTreeWidgetItem *currentItem =
mFormLayoutTree->selectedItems().at( 0 );
451 mAttributeTypeFrame->layout()->setContentsMargins( 0, 0, 0, 0 );
455void QgsAttributesFormProperties::loadInfoWidget(
const QString &infoText )
458 mAttributeTypeFrame->layout()->setContentsMargins( 0, 0, 0, 0 );
462void QgsAttributesFormProperties::storeAttributeContainerEdit()
470void QgsAttributesFormProperties::loadAttributeContainerEdit()
475 QTreeWidgetItem *currentItem =
mFormLayoutTree->selectedItems().at( 0 );
479 mAttributeTypeFrame->layout()->setContentsMargins( 0, 0, 0, 0 );
485 auto setCommonProperties = [widgetDef]( DnDTreeItemData &itemData ) {
486 itemData.setShowLabel( widgetDef->
showLabel() );
487 itemData.setLabelStyle( widgetDef->
labelStyle() );
492 QTreeWidgetItem *newWidget =
nullptr;
493 switch ( widgetDef->
type() )
498 setCommonProperties( itemData );
499 newWidget = tree->
addItem( parent, itemData );
507 if ( action.isValid() )
509 DnDTreeItemData itemData = DnDTreeItemData(
DnDTreeItemData::Action, action.id().toString(), action.shortTitle().isEmpty() ? action.name() : action.shortTitle() );
510 setCommonProperties( itemData );
511 newWidget = tree->
addItem( parent, itemData );
524 setCommonProperties( itemData );
526 RelationEditorConfiguration relEdConfig;
530 relEdConfig.nmRelationId = relationEditor->
nmRelationId();
532 relEdConfig.label = relationEditor->
label();
533 itemData.setRelationEditorConfiguration( relEdConfig );
534 newWidget = tree->
addItem( parent, itemData );
547 itemData.setContainerType( container->
type() );
551 itemData.setCollapsed( container->
collapsed() );
553 setCommonProperties( itemData );
555 newWidget = tree->
addItem( parent, itemData );
557 const QList<QgsAttributeEditorElement *> children = container->
children();
560 loadAttributeEditorTreeItem( wdg, newWidget, tree );
569 QmlElementEditorConfiguration qmlEdConfig;
570 qmlEdConfig.qmlCode = qmlElementEditor->
qmlCode();
571 itemData.setQmlElementEditorConfiguration( qmlEdConfig );
572 setCommonProperties( itemData );
573 newWidget = tree->
addItem( parent, itemData );
581 HtmlElementEditorConfiguration htmlEdConfig;
582 htmlEdConfig.htmlCode = htmlElementEditor->
htmlCode();
583 itemData.setHtmlElementEditorConfiguration( htmlEdConfig );
584 setCommonProperties( itemData );
585 newWidget = tree->
addItem( parent, itemData );
593 TextElementEditorConfiguration textEdConfig;
594 textEdConfig.text = textElementEditor->
text();
595 itemData.setTextElementEditorConfiguration( textEdConfig );
596 setCommonProperties( itemData );
597 newWidget = tree->
addItem( parent, itemData );
605 SpacerElementEditorConfiguration spacerEdConfig;
606 spacerEdConfig.drawLine = spacerElementEditor->
drawLine();
607 itemData.setSpacerElementEditorConfiguration( spacerEdConfig );
608 setCommonProperties( itemData );
609 itemData.setShowLabel(
false );
610 newWidget = tree->
addItem( parent, itemData );
616 QgsDebugError( QStringLiteral(
"Not loading invalid attribute editor type..." ) );
622 newWidget->setExpanded(
true );
628void QgsAttributesFormProperties::onAttributeSelectionChanged()
630 disconnect(
mFormLayoutTree, &QTreeWidget::itemSelectionChanged,
this, &QgsAttributesFormProperties::onFormLayoutSelectionChanged );
632 connect(
mFormLayoutTree, &QTreeWidget::itemSelectionChanged,
this, &QgsAttributesFormProperties::onFormLayoutSelectionChanged );
635void QgsAttributesFormProperties::onFormLayoutSelectionChanged()
638 disconnect(
mAvailableWidgetsTree, &QTreeWidget::itemSelectionChanged,
this, &QgsAttributesFormProperties::onAttributeSelectionChanged );
640 connect(
mAvailableWidgetsTree, &QTreeWidget::itemSelectionChanged,
this, &QgsAttributesFormProperties::onAttributeSelectionChanged );
649 storeAttributeWidgetEdit();
653 storeAttributeTypeDialog();
656 clearAttributeTypeFrame();
658 if ( emitter->selectedItems().count() != 1 )
660 receiver->clearSelection();
664 const DnDTreeItemData itemData = emitter->selectedItems().at( 0 )->data( 0,
DnDTreeRole ).value<DnDTreeItemData>();
665 switch ( itemData.type() )
672 loadAttributeWidgetEdit();
676 loadInfoWidget( tr(
"This configuration is available in the Drag and Drop Designer" ) );
685 loadAttributeWidgetEdit();
687 loadAttributeTypeDialog();
692 receiver->clearSelection();
693 loadAttributeContainerEdit();
700 loadInfoWidget( action.html() );
710 loadInfoWidget( tr(
"This configuration is available with double-click in the Drag and Drop Designer" ) );
714 loadInfoWidget( tr(
"This configuration is available with double-click" ) );
716 receiver->clearSelection();
721 receiver->clearSelection();
728void QgsAttributesFormProperties::clearAttributeTypeFrame()
756void QgsAttributesFormProperties::onInvertSelectionButtonClicked(
bool checked )
761 for (
int i = 0; i < rootItem->childCount(); ++i )
763 rootItem->child( i )->setSelected( !selectedItemList.contains( rootItem->child( i ) ) );
767void QgsAttributesFormProperties::addContainer()
769 QList<QgsAddAttributeFormContainerDialog::ContainerPair> existingContainerList;
773 const DnDTreeItemData itemData = ( *it )->data( 0,
DnDTreeRole ).value<DnDTreeItemData>();
779 QTreeWidgetItem *currentItem =
mFormLayoutTree->selectedItems().value( 0 );
782 if ( !dialog.exec() )
785 const QString name = dialog.name();
786 QTreeWidgetItem *parentContainerItem = dialog.parentContainerItem();
790void QgsAttributesFormProperties::removeTabOrGroupButton()
796 const QList<QTreeWidgetItem *> items =
mFormLayoutTree->selectedItems();
800 delete items.at( 0 );
810 switch ( itemData.
type() )
859 for (
int t = 0; t < item->childCount(); t++ )
866 widgetDef = container;
917void QgsAttributesFormProperties::mEditorLayoutComboBox_currentIndexChanged(
int )
923 mFormLayoutWidget->setVisible(
false );
924 mUiFileFrame->setVisible(
false );
925 mAddTabOrGroupButton->setVisible(
false );
926 mRemoveTabOrGroupButton->setVisible(
false );
927 mInvertSelectionButton->setVisible(
false );
931 mFormLayoutWidget->setVisible(
true );
932 mUiFileFrame->setVisible(
false );
933 mAddTabOrGroupButton->setVisible(
true );
934 mRemoveTabOrGroupButton->setVisible(
true );
935 mInvertSelectionButton->setVisible(
true );
940 mFormLayoutWidget->setVisible(
false );
941 mUiFileFrame->setVisible(
true );
942 mAddTabOrGroupButton->setVisible(
false );
943 mRemoveTabOrGroupButton->setVisible(
false );
944 mInvertSelectionButton->setVisible(
false );
949void QgsAttributesFormProperties::mTbInitCode_clicked()
958 if ( !attributesFormInitCode.exec() )
961 mInitCodeSource = attributesFormInitCode.
codeSource();
962 mInitCode = attributesFormInitCode.
initCode();
967void QgsAttributesFormProperties::pbnSelectEditForm_clicked()
970 const QString lastUsedDir = myQSettings.
value( QStringLiteral(
"style/lastUIDir" ), QDir::homePath() ).toString();
971 const QString uifilename = QFileDialog::getOpenFileName(
this, tr(
"Select edit form" ), lastUsedDir, tr(
"UI file" ) +
" (*.ui)" );
973 if ( uifilename.isNull() )
976 const QFileInfo fi( uifilename );
977 myQSettings.
setValue( QStringLiteral(
"style/lastUIDir" ), fi.path() );
978 mEditFormLineEdit->setText( uifilename );
983 storeAttributeWidgetEdit();
984 storeAttributeContainerEdit();
985 storeAttributeTypeDialog();
991 storeAttributeWidgetEdit();
992 storeAttributeContainerEdit();
993 storeAttributeTypeDialog();
999 for (
int i = 0; i < fieldContainer->childCount(); i++ )
1001 QTreeWidgetItem *fieldItem = fieldContainer->child( i );
1004 const QString fieldName { fieldItem->data( 0,
FieldNameRole ).toString() };
1057 for (
int t = 0; t <
mFormLayoutTree->invisibleRootItem()->childCount(); t++ )
1059 QTreeWidgetItem *tabItem =
mFormLayoutTree->invisibleRootItem()->child( t );
1061 if ( editorElement )
1062 editFormConfig.
addTab( editorElement );
1065 editFormConfig.
setUiForm( mEditFormLineEdit->text() );
1079 for (
int i = 0; i < relationContainer->childCount(); i++ )
1081 QTreeWidgetItem *relationItem = relationContainer->child( i );
1084 for (
int t = 0; t <
mFormLayoutTree->invisibleRootItem()->childCount(); t++ )
1086 QTreeWidgetItem *tabItem =
mFormLayoutTree->invisibleRootItem()->child( t );
1089 if ( tabItemData.
type() == itemData.
type() && tabItemData.
name() == itemData.
name() )
1127QgsAttributesFormProperties::FieldConfig::operator QVariant()
1129 return QVariant::fromValue<QgsAttributesFormProperties::FieldConfig>( *
this );
1127QgsAttributesFormProperties::FieldConfig::operator QVariant() {
…}
1136QgsAttributesFormProperties::RelationEditorConfiguration::operator QVariant()
1138 return QVariant::fromValue<QgsAttributesFormProperties::RelationEditorConfiguration>( *
this );
1136QgsAttributesFormProperties::RelationEditorConfiguration::operator QVariant() {
…}
1147 QTreeWidgetItem *newItem =
new QTreeWidgetItem( QStringList() << title );
1148 newItem->setBackground( 0, QBrush( Qt::lightGray ) );
1149 newItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled );
1154 parent->addChild( newItem );
1155 newItem->setExpanded(
true );
1160 : QTreeWidget( parent )
1163 connect(
this, &QTreeWidget::itemDoubleClicked,
this, &QgsAttributesDnDTree::onItemDoubleClicked );
1168 QTreeWidgetItem *newItem =
new QTreeWidgetItem( QStringList() << data.
name() );
1170 switch ( data.
type() )
1179 newItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled );
1185 newItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled );
1186 newItem->setBackground( 0, QBrush( Qt::lightGray ) );
1193 newItem->setIcon( 0, icon );
1200 newItem->setText( 0, tr(
"Invalid relation" ) );
1201 newItem->setForeground( 0, QColor( 255, 0, 0 ) );
1206 parent->addChild( newItem );
1208 parent->insertChild( index, newItem );
1220 const QMimeData *data =
event->mimeData();
1222 if ( data->hasFormat( QStringLiteral(
"application/x-qgsattributetabledesignerelement" ) ) )
1226 QByteArray itemData = data->data( QStringLiteral(
"application/x-qgsattributetabledesignerelement" ) );
1227 QDataStream stream( &itemData, QIODevice::ReadOnly );
1228 stream >> itemElement;
1231 if ( event->source() ==
this )
1233 event->setDropAction( Qt::MoveAction );
1241 QTreeWidget::dragMoveEvent( event );
1247 bool bDropSuccessful =
false;
1249 if ( action == Qt::IgnoreAction )
1251 bDropSuccessful =
true;
1253 else if ( data->hasFormat( QStringLiteral(
"application/x-qgsattributetabledesignerelement" ) ) )
1255 QByteArray itemData = data->data( QStringLiteral(
"application/x-qgsattributetabledesignerelement" ) );
1256 QDataStream stream( &itemData, QIODevice::ReadOnly );
1259 while ( !stream.atEnd() )
1261 stream >> itemElement;
1263 QTreeWidgetItem *newItem;
1267 newItem =
addItem( parent, itemElement, index++ );
1268 bDropSuccessful =
true;
1272 newItem =
addItem( invisibleRootItem(), itemElement, index++ );
1273 bDropSuccessful =
true;
1278 onItemDoubleClicked( newItem, 0 );
1283 onItemDoubleClicked( newItem, 0 );
1288 onItemDoubleClicked( newItem, 0 );
1293 onItemDoubleClicked( newItem, 0 );
1297 newItem->setSelected(
true );
1301 return bDropSuccessful;
1306 if ( !event->mimeData()->hasFormat( QStringLiteral(
"application/x-qgsattributetabledesignerelement" ) ) )
1309 if ( event->source() ==
this )
1311 event->setDropAction( Qt::MoveAction );
1314 QTreeWidget::dropEvent( event );
1319 return QStringList() << QStringLiteral(
"application/x-qgsattributetabledesignerelement" );
1322#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
1328 if ( items.count() <= 0 )
1331 const QStringList types = mimeTypes();
1333 if ( types.isEmpty() )
1336 QMimeData *data =
new QMimeData();
1337 const QString format = types.at( 0 );
1339 QDataStream stream( &encoded, QIODevice::WriteOnly );
1341 const auto constItems = items;
1342 for (
const QTreeWidgetItem *item : constItems )
1352 data->setData( format, encoded );
1357void QgsAttributesDnDTree::onItemDoubleClicked( QTreeWidgetItem *item,
int column )
1363 QGroupBox *baseData =
new QGroupBox( tr(
"Base configuration" ) );
1365 QFormLayout *baseLayout =
new QFormLayout();
1366 baseData->setLayout( baseLayout );
1367 QCheckBox *showLabelCheckbox =
new QCheckBox( QStringLiteral(
"Show label" ) );
1368 showLabelCheckbox->setChecked( itemData.
showLabel() );
1369 baseLayout->addRow( showLabelCheckbox );
1370 QWidget *baseWidget =
new QWidget();
1371 baseWidget->setLayout( baseLayout );
1373 switch ( itemData.
type() )
1388 dlg.setObjectName(
"QML Form Configuration Widget" );
1390 dlg.setWindowTitle( tr(
"Configure QML Widget" ) );
1392 QVBoxLayout *mainLayout =
new QVBoxLayout( &dlg );
1393 QSplitter *qmlSplitter =
new QSplitter();
1394 QWidget *qmlConfigWiget =
new QWidget();
1395 QVBoxLayout *layout =
new QVBoxLayout( qmlConfigWiget );
1396 layout->setContentsMargins( 0, 0, 0, 0 );
1397 mainLayout->addWidget( qmlSplitter );
1398 qmlSplitter->addWidget( qmlConfigWiget );
1399 layout->addWidget( baseWidget );
1401 QLineEdit *title =
new QLineEdit( itemData.
name() );
1420 QComboBox *qmlObjectTemplate =
new QComboBox();
1421 qmlObjectTemplate->addItem( tr(
"Free Text…" ) );
1422 qmlObjectTemplate->addItem( tr(
"Rectangle" ) );
1423 qmlObjectTemplate->addItem( tr(
"Pie Chart" ) );
1424 qmlObjectTemplate->addItem( tr(
"Bar Chart" ) );
1425 connect( qmlObjectTemplate, qOverload<int>( &QComboBox::activated ), qmlCode, [=](
int index ) {
1431 qmlCode->
setText( QString() );
1436 qmlCode->
setText( QStringLiteral(
"import QtQuick 2.0\n"
1441 " color: \"steelblue\"\n"
1442 " Text{ text: \"A rectangle\" }\n"
1448 qmlCode->
setText( QStringLiteral(
"import QtQuick 2.0\n"
1449 "import QtCharts 2.0\n"
1457 " PieSlice { label: \"First slice\"; value: 25 }\n"
1458 " PieSlice { label: \"Second slice\"; value: 45 }\n"
1459 " PieSlice { label: \"Third slice\"; value: 30 }\n"
1466 qmlCode->
setText( QStringLiteral(
"import QtQuick 2.0\n"
1467 "import QtCharts 2.0\n"
1470 " title: \"Bar series\"\n"
1473 " legend.alignment: Qt.AlignBottom\n"
1474 " antialiasing: true\n"
1483 " axisY: valueAxisY\n"
1484 " axisX: BarCategoryAxis { categories: [\"2007\", \"2008\", \"2009\", \"2010\", \"2011\", \"2012\" ] }\n"
1485 " BarSet { label: \"Bob\"; values: [2, 2, 3, 4, 5, 6] }\n"
1486 " BarSet { label: \"Susan\"; values: [5, 1, 2, 4, 1, 7] }\n"
1487 " BarSet { label: \"James\"; values: [3, 5, 8, 13, 5, 8] }\n"
1499 expressionWidget->registerExpressionContextGenerator(
this );
1500 expressionWidget->setLayer( mLayer );
1501 QToolButton *addFieldButton =
new QToolButton();
1504 QToolButton *editExpressionButton =
new QToolButton();
1506 editExpressionButton->setToolTip( tr(
"Insert/Edit Expression" ) );
1508 connect( addFieldButton, &QAbstractButton::clicked,
this, [=] {
1509 QString expression = expressionWidget->expression().trimmed().replace(
'"', QLatin1String(
"\\\"" ) );
1510 if ( !expression.isEmpty() )
1511 qmlCode->
insertText( QStringLiteral(
"expression.evaluate(\"%1\")" ).arg( expression ) );
1514 connect( editExpressionButton, &QAbstractButton::clicked,
this, [=] {
1516 expression.replace( QLatin1String(
"\\\"" ), QLatin1String(
"\"" ) );
1520 exprDlg.setWindowTitle( tr(
"Insert Expression" ) );
1521 if ( exprDlg.exec() == QDialog::Accepted && !exprDlg.expressionText().trimmed().isEmpty() )
1523 QString expression = exprDlg.expressionText().trimmed().replace(
'"', QLatin1String(
"\\\"" ) );
1524 if ( !expression.isEmpty() )
1525 qmlCode->
insertText( QStringLiteral(
"expression.evaluate(\"%1\")" ).arg( expression ) );
1529 layout->addWidget(
new QLabel( tr(
"Title" ) ) );
1530 layout->addWidget( title );
1531 QGroupBox *qmlCodeBox =
new QGroupBox( tr(
"QML Code" ) );
1532 qmlCodeBox->setLayout(
new QVBoxLayout );
1533 qmlCodeBox->layout()->addWidget( qmlObjectTemplate );
1534 QWidget *expressionWidgetBox =
new QWidget();
1535 qmlCodeBox->layout()->addWidget( expressionWidgetBox );
1536 expressionWidgetBox->setLayout(
new QHBoxLayout );
1537 expressionWidgetBox->layout()->setContentsMargins( 0, 0, 0, 0 );
1538 expressionWidgetBox->layout()->addWidget( expressionWidget );
1539 expressionWidgetBox->layout()->addWidget( addFieldButton );
1540 expressionWidgetBox->layout()->addWidget( editExpressionButton );
1541 expressionWidgetBox->layout()->addWidget( editExpressionButton );
1542 layout->addWidget( qmlCodeBox );
1543 layout->addWidget( qmlCode );
1545 qmlPreviewBox->setMinimumWidth( 200 );
1546 qmlPreviewBox->setWidget( qmlWrapper->
widget() );
1549 qmlSplitter->addWidget( qmlPreviewBox );
1550 qmlSplitter->setChildrenCollapsible(
false );
1551 qmlSplitter->setHandleWidth( 6 );
1552 qmlSplitter->setSizes( QList<int>() << 1 << 1 );
1554 QDialogButtonBox *buttonBox =
new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Help );
1556 connect( buttonBox, &QDialogButtonBox::accepted, &dlg, &QDialog::accept );
1557 connect( buttonBox, &QDialogButtonBox::rejected, &dlg, &QDialog::reject );
1558 connect( buttonBox, &QDialogButtonBox::helpRequested, &dlg, [=] {
1559 QgsHelp::openHelp( QStringLiteral(
"working_with_vector/vector_properties.html#other-widgets" ) );
1562 mainLayout->addWidget( buttonBox );
1567 qmlEdCfg.
qmlCode = qmlCode->text();
1568 itemData.
setName( title->text() );
1570 itemData.
setShowLabel( showLabelCheckbox->isChecked() );
1573 item->setText( 0, title->text() );
1583 dlg.setObjectName(
"HTML Form Configuration Widget" );
1585 dlg.setWindowTitle( tr(
"Configure HTML Widget" ) );
1587 QVBoxLayout *mainLayout =
new QVBoxLayout( &dlg );
1588 QSplitter *htmlSplitter =
new QSplitter();
1589 QWidget *htmlConfigWiget =
new QWidget();
1590 QVBoxLayout *layout =
new QVBoxLayout( htmlConfigWiget );
1591 layout->setContentsMargins( 0, 0, 0, 0 );
1592 mainLayout->addWidget( htmlSplitter );
1593 htmlSplitter->addWidget( htmlConfigWiget );
1594 htmlSplitter->setChildrenCollapsible(
false );
1595 htmlSplitter->setHandleWidth( 6 );
1596 htmlSplitter->setSizes( QList<int>() << 1 << 1 );
1597 layout->addWidget( baseWidget );
1599 QLineEdit *title =
new QLineEdit( itemData.
name() );
1603 htmlCode->setSizePolicy( QSizePolicy::Policy::Expanding, QSizePolicy::Policy::Expanding );
1611 connect( htmlCode, &QgsCodeEditorHTML::textChanged,
this, [=] {
1619 expressionWidget->registerExpressionContextGenerator(
this );
1620 expressionWidget->setLayer( mLayer );
1621 QToolButton *addFieldButton =
new QToolButton();
1624 QToolButton *editExpressionButton =
new QToolButton();
1626 editExpressionButton->setToolTip( tr(
"Insert/Edit Expression" ) );
1628 connect( addFieldButton, &QAbstractButton::clicked,
this, [=] {
1629 QString expression = expressionWidget->expression().trimmed().replace(
'"', QLatin1String(
"\\\"" ) );
1630 if ( !expression.isEmpty() )
1631 htmlCode->
insertText( QStringLiteral(
"<script>document.write(expression.evaluate(\"%1\"));</script>" ).arg( expression ) );
1634 connect( editExpressionButton, &QAbstractButton::clicked,
this, [=] {
1636 expression.replace( QLatin1String(
"\\\"" ), QLatin1String(
"\"" ) );
1640 exprDlg.setWindowTitle( tr(
"Insert Expression" ) );
1641 if ( exprDlg.exec() == QDialog::Accepted && !exprDlg.expressionText().trimmed().isEmpty() )
1643 QString expression = exprDlg.expressionText().trimmed().replace(
'"', QLatin1String(
"\\\"" ) );
1644 if ( !expression.isEmpty() )
1645 htmlCode->
insertText( QStringLiteral(
"<script>document.write(expression.evaluate(\"%1\"));</script>" ).arg( expression ) );
1649 layout->addWidget(
new QLabel( tr(
"Title" ) ) );
1650 layout->addWidget( title );
1651 QGroupBox *expressionWidgetBox =
new QGroupBox( tr(
"HTML Code" ) );
1652 layout->addWidget( expressionWidgetBox );
1653 expressionWidgetBox->setLayout(
new QHBoxLayout );
1654 expressionWidgetBox->layout()->addWidget( expressionWidget );
1655 expressionWidgetBox->layout()->addWidget( addFieldButton );
1656 expressionWidgetBox->layout()->addWidget( editExpressionButton );
1657 layout->addWidget( htmlCode );
1659 htmlPreviewBox->setLayout(
new QGridLayout );
1660 htmlPreviewBox->setMinimumWidth( 200 );
1661 htmlPreviewBox->layout()->addWidget( htmlWrapper->
widget() );
1663 emit htmlCode->textChanged();
1664 htmlSplitter->addWidget( htmlPreviewBox );
1665 htmlSplitter->setChildrenCollapsible(
false );
1666 htmlSplitter->setHandleWidth( 6 );
1667 htmlSplitter->setSizes( QList<int>() << 1 << 1 );
1669 QDialogButtonBox *buttonBox =
new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Help );
1671 connect( buttonBox, &QDialogButtonBox::accepted, &dlg, &QDialog::accept );
1672 connect( buttonBox, &QDialogButtonBox::rejected, &dlg, &QDialog::reject );
1673 connect( buttonBox, &QDialogButtonBox::helpRequested, &dlg, [=] {
1674 QgsHelp::openHelp( QStringLiteral(
"working_with_vector/vector_properties.html#other-widgets" ) );
1677 mainLayout->addWidget( buttonBox );
1682 htmlEdCfg.
htmlCode = htmlCode->text();
1683 itemData.
setName( title->text() );
1685 itemData.
setShowLabel( showLabelCheckbox->isChecked() );
1688 item->setText( 0, title->text() );
1698 dlg.setObjectName(
"Text Form Configuration Widget" );
1700 dlg.setWindowTitle( tr(
"Configure Text Widget" ) );
1702 QVBoxLayout *mainLayout =
new QVBoxLayout( &dlg );
1703 QSplitter *textSplitter =
new QSplitter();
1704 QWidget *textConfigWiget =
new QWidget();
1705 QVBoxLayout *layout =
new QVBoxLayout( textConfigWiget );
1706 layout->setContentsMargins( 0, 0, 0, 0 );
1707 mainLayout->addWidget( textSplitter );
1708 textSplitter->addWidget( textConfigWiget );
1709 layout->addWidget( baseWidget );
1711 QLineEdit *title =
new QLineEdit( itemData.
name() );
1714 text->setSizePolicy( QSizePolicy::Policy::Expanding, QSizePolicy::Policy::Expanding );
1722 connect( text, &QgsCodeEditorExpression::textChanged,
this, [=] {
1723 textWrapper->
setText( text->text() );
1730 expressionWidget->registerExpressionContextGenerator(
this );
1731 expressionWidget->setLayer( mLayer );
1732 QToolButton *addFieldButton =
new QToolButton();
1735 QToolButton *editExpressionButton =
new QToolButton();
1737 editExpressionButton->setToolTip( tr(
"Insert/Edit Expression" ) );
1739 connect( addFieldButton, &QAbstractButton::clicked,
this, [=] {
1740 QString expression = expressionWidget->expression().trimmed();
1741 if ( !expression.isEmpty() )
1742 text->
insertText( QStringLiteral(
"[%%1%]" ).arg( expression ) );
1744 connect( editExpressionButton, &QAbstractButton::clicked,
this, [=] {
1750 exprDlg.setWindowTitle( tr(
"Insert Expression" ) );
1751 if ( exprDlg.exec() == QDialog::Accepted && !exprDlg.expressionText().trimmed().isEmpty() )
1753 QString expression = exprDlg.expressionText().trimmed();
1754 if ( !expression.isEmpty() )
1755 text->
insertText( QStringLiteral(
"[%%1%]" ).arg( expression ) );
1759 layout->addWidget(
new QLabel( tr(
"Title" ) ) );
1760 layout->addWidget( title );
1761 QGroupBox *expressionWidgetBox =
new QGroupBox( tr(
"Text" ) );
1762 layout->addWidget( expressionWidgetBox );
1763 expressionWidgetBox->setLayout(
new QHBoxLayout );
1764 expressionWidgetBox->layout()->addWidget( expressionWidget );
1765 expressionWidgetBox->layout()->addWidget( addFieldButton );
1766 expressionWidgetBox->layout()->addWidget( editExpressionButton );
1767 layout->addWidget( text );
1769 textPreviewBox->setLayout(
new QGridLayout );
1770 textPreviewBox->setMinimumWidth( 200 );
1771 textPreviewBox->layout()->addWidget( textWrapper->
widget() );
1773 emit text->textChanged();
1774 textSplitter->addWidget( textPreviewBox );
1775 textSplitter->setChildrenCollapsible(
false );
1776 textSplitter->setHandleWidth( 6 );
1777 textSplitter->setSizes( QList<int>() << 1 << 1 );
1779 QDialogButtonBox *buttonBox =
new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Help );
1781 connect( buttonBox, &QDialogButtonBox::accepted, &dlg, &QDialog::accept );
1782 connect( buttonBox, &QDialogButtonBox::rejected, &dlg, &QDialog::reject );
1783 connect( buttonBox, &QDialogButtonBox::helpRequested, &dlg, [=] {
1784 QgsHelp::openHelp( QStringLiteral(
"working_with_vector/vector_properties.html#other-widgets" ) );
1787 mainLayout->addWidget( buttonBox );
1792 textEdCfg.
text = text->text();
1793 itemData.
setName( title->text() );
1795 itemData.
setShowLabel( showLabelCheckbox->isChecked() );
1798 item->setText( 0, title->text() );
1808 dlg.setObjectName(
"Spacer Form Configuration Widget" );
1810 dlg.setWindowTitle( tr(
"Configure Spacer Widget" ) );
1812 QVBoxLayout *mainLayout =
new QVBoxLayout();
1813 mainLayout->addWidget(
new QLabel( tr(
"Title" ) ) );
1814 QLineEdit *title =
new QLineEdit( itemData.
name() );
1815 mainLayout->addWidget( title );
1817 QHBoxLayout *cbLayout =
new QHBoxLayout();
1818 mainLayout->addLayout( cbLayout );
1819 dlg.setLayout( mainLayout );
1820 QCheckBox *cb =
new QCheckBox { &dlg };
1822 cbLayout->addWidget(
new QLabel( tr(
"Draw horizontal line" ), &dlg ) );
1823 cbLayout->addWidget( cb );
1825 QDialogButtonBox *buttonBox =
new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Help );
1827 connect( buttonBox, &QDialogButtonBox::accepted, &dlg, &QDialog::accept );
1828 connect( buttonBox, &QDialogButtonBox::rejected, &dlg, &QDialog::reject );
1829 connect( buttonBox, &QDialogButtonBox::helpRequested, &dlg, [=] {
1830 QgsHelp::openHelp( QStringLiteral(
"working_with_vector/vector_properties.html#other-widgets" ) );
1833 mainLayout->addWidget( buttonBox );
1838 spacerEdCfg.
drawLine = cb->isChecked();
1841 itemData.
setName( title->text() );
1843 item->setText( 0, title->text() );
1876 QTreeWidgetItemIterator it(
this );
1882 if ( selectedItems().count() == 1 && ( *it )->isSelected() == true )
1889 ( *it )->setSelected(
true );
1912 QString displayName;
1915 stream >> type >> name >> displayName;
1926 return mContainerType;
1931 mContainerType = type;
1941 mLabelStyle = labelStyle;
1951 mShowLabel = showLabel;
1956 return mVisibilityExpression;
1961 mVisibilityExpression = visibilityExpression;
1966 return mCollapsedExpression;
1971 mCollapsedExpression = collapsedExpression;
1976 return mRelationEditorConfiguration;
1981 mRelationEditorConfiguration = relationEditorConfiguration;
1986 return mQmlElementEditorConfiguration;
1991 mQmlElementEditorConfiguration = qmlElementEditorConfiguration;
1997 return mHtmlElementEditorConfiguration;
2002 mHtmlElementEditorConfiguration = htmlElementEditorConfiguration;
2007 return mSpacerElementEditorConfiguration;
2012 mSpacerElementEditorConfiguration = spacerElementEditorConfiguration;
2017 return mBackgroundColor;
2022 mBackgroundColor = backgroundColor;
2027 return mTextElementEditorConfiguration;
2032 mTextElementEditorConfiguration = textElementEditorConfiguration;
2035void QgsAttributesFormProperties::updatedFields()
2038 QMap<QString, FieldConfig> fieldConfigs;
2040 for (
int i = 0; i < fieldContainer->childCount(); i++ )
2042 QTreeWidgetItem *fieldItem = fieldContainer->child( i );
2043 const QString fieldName = fieldItem->data( 0,
FieldNameRole ).toString();
2045 fieldConfigs[fieldName] = cfg;
2051 for (
int i = 0; i < fieldContainer->childCount(); i++ )
2053 QTreeWidgetItem *fieldItem = fieldContainer->child( i );
2054 const QString fieldName = fieldItem->data( 0,
FieldNameRole ).toString();
2055 if ( fieldConfigs.contains( fieldName ) )
2062void QgsAttributesFormProperties::onContextMenuRequested( QPoint point )
2070 const DnDTreeItemData itemData = item->data( 0,
DnDTreeRole ).value<DnDTreeItemData>();
2073 const QClipboard *clipboard = QApplication::clipboard();
2074 const bool pasteEnabled = clipboard->mimeData()->hasFormat( QStringLiteral(
"application/x-qgsattributetabledesignerelementclipboard" ) );
2075 mActionPasteWidgetConfiguration->setEnabled( pasteEnabled );
2076 mAvailableWidgetsTreeContextMenu->popup( globalPos );
2080void QgsAttributesFormProperties::copyWidgetConfiguration()
2086 const DnDTreeItemData itemData = item->data( 0,
DnDTreeRole ).value<DnDTreeItemData>();
2090 const QString fieldName = item->data( 0,
FieldNameRole ).toString();
2100 QDomElement documentElement = doc.createElement( QStringLiteral(
"FormWidgetClipboard" ) );
2101 documentElement.setAttribute( QStringLiteral(
"name" ), field.
name() );
2106 QDomElement editWidgetElement = doc.createElement( QStringLiteral(
"editWidget" ) );
2107 documentElement.appendChild( editWidgetElement );
2108 editWidgetElement.setAttribute( QStringLiteral(
"type" ), widgetSetup.
type() );
2109 QDomElement editWidgetConfigElement = doc.createElement( QStringLiteral(
"config" ) );
2112 editWidgetElement.appendChild( editWidgetConfigElement );
2115 QDomElement splitPolicyElement = doc.createElement( QStringLiteral(
"splitPolicy" ) );
2117 documentElement.appendChild( splitPolicyElement );
2120 QDomElement duplicatePolicyElement = doc.createElement( QStringLiteral(
"duplicatePolicy" ) );
2122 documentElement.appendChild( duplicatePolicyElement );
2125 QDomElement mergePolicyElement = doc.createElement( QStringLiteral(
"mergePolicy" ) );
2127 documentElement.appendChild( mergePolicyElement );
2130 QDomElement defaultElem = doc.createElement( QStringLiteral(
"default" ) );
2133 documentElement.appendChild( defaultElem );
2136 QDomElement constraintElem = doc.createElement( QStringLiteral(
"constraint" ) );
2141 documentElement.appendChild( constraintElem );
2144 QDomElement constraintExpressionElem = doc.createElement( QStringLiteral(
"constraintExpression" ) );
2147 documentElement.appendChild( constraintExpressionElem );
2150 QDomElement widgetGeneralSettingsElem = doc.createElement( QStringLiteral(
"widgetGeneralSettings" ) );
2154 documentElement.appendChild( widgetGeneralSettingsElem );
2163 const QTreeWidgetItem *itemLayout =
mFormLayoutTree->selectedItems().at( 0 );
2164 const DnDTreeItemData itemDataLayout = itemLayout->data( 0,
DnDTreeRole ).value<DnDTreeItemData>();
2166 QDomElement displayElement = doc.createElement( QStringLiteral(
"widgetDisplay" ) );
2167 displayElement.setAttribute( QStringLiteral(
"showLabel" ), itemDataLayout.showLabel() );
2168 displayElement.setAttribute( QStringLiteral(
"horizontalStretch" ), itemDataLayout.horizontalStretch() );
2169 displayElement.setAttribute( QStringLiteral(
"verticalStretch" ), itemDataLayout.verticalStretch() );
2170 displayElement.appendChild( itemDataLayout.labelStyle().writeXml( doc ) );
2171 documentElement.appendChild( displayElement );
2174 doc.appendChild( documentElement );
2176 QMimeData *mimeData =
new QMimeData;
2177 mimeData->setData( QStringLiteral(
"application/x-qgsattributetabledesignerelementclipboard" ), doc.toByteArray() );
2178 QClipboard *clipboard = QApplication::clipboard();
2179 clipboard->setMimeData( mimeData );
2182void QgsAttributesFormProperties::pasteWidgetConfiguration()
2189 const QString fieldName = item->data( 0,
FieldNameRole ).toString();
2192 if ( fieldIndex < 0 )
2196 FieldConfig config = item->data( 0,
FieldConfigRole ).value<FieldConfig>();
2199 QClipboard *clipboard = QApplication::clipboard();
2200 if ( doc.setContent( clipboard->mimeData()->data( QStringLiteral(
"application/x-qgsattributetabledesignerelementclipboard" ) ) ) )
2202 QDomElement docElem = doc.documentElement();
2203 if ( docElem.tagName() != QLatin1String(
"FormWidgetClipboard" ) )
2212 const QDomElement fieldWidgetElement = docElem.firstChildElement( QStringLiteral(
"editWidget" ) );
2213 if ( !fieldWidgetElement.isNull() )
2215 const QString widgetType = fieldWidgetElement.attribute( QStringLiteral(
"type" ) );
2221 const QDomElement configElement = fieldWidgetElement.firstChildElement( QStringLiteral(
"config" ) );
2222 if ( !configElement.isNull() )
2224 const QDomElement optionsElem = configElement.childNodes().at( 0 ).toElement();
2228 if ( widgetType == QStringLiteral(
"ValueRelation" ) )
2230 optionsMap[QStringLiteral(
"Value" )] = context.
projectTranslator()->
translate( QStringLiteral(
"project:layers:%1:fields:%2:valuerelationvalue" ).arg(
mLayer->
id(), fieldName ), optionsMap[QStringLiteral(
"Value" )].toString() );
2232 if ( widgetType == QStringLiteral(
"ValueMap" ) )
2234 if ( optionsMap[QStringLiteral(
"map" )].canConvert<QList<QVariant>>() )
2236 QList<QVariant> translatedValueList;
2237 const QList<QVariant> valueList = optionsMap[QStringLiteral(
"map" )].toList();
2238 for (
int i = 0, row = 0; i < valueList.count(); i++, row++ )
2240 QMap<QString, QVariant> translatedValueMap;
2241 QString translatedKey = context.
projectTranslator()->
translate( QStringLiteral(
"project:layers:%1:fields:%2:valuemapdescriptions" ).arg(
mLayer->
id(), fieldName ), valueList[i].toMap().constBegin().key() );
2242 translatedValueMap.insert( translatedKey, valueList[i].toMap().constBegin().value() );
2243 translatedValueList.append( translatedValueMap );
2245 optionsMap.insert( QStringLiteral(
"map" ), translatedValueList );
2248 config.mEditorWidgetType = widgetType;
2249 config.mEditorWidgetConfig = optionsMap;
2254 mMessageBar->
pushMessage( QString(), tr(
"Unable to paste widget configuration. The target field (%1) does not support the %2 widget type." ).arg( fieldName, widgetType ),
Qgis::MessageLevel::Warning );
2259 const QDomElement splitPolicyElement = docElem.firstChildElement( QStringLiteral(
"splitPolicy" ) );
2260 if ( !splitPolicyElement.isNull() )
2263 config.mSplitPolicy = policy;
2267 const QDomElement duplicatePolicyElement = docElem.firstChildElement( QStringLiteral(
"duplicatePolicy" ) );
2268 if ( !duplicatePolicyElement.isNull() )
2271 config.mDuplicatePolicy = policy;
2275 const QDomElement mergePolicyElement = docElem.firstChildElement( QStringLiteral(
"mergePolicy" ) );
2276 if ( !mergePolicyElement.isNull() )
2279 config.mMergePolicy = policy;
2283 const QDomElement defaultElement = docElem.firstChildElement( QStringLiteral(
"default" ) );
2284 if ( !defaultElement.isNull() )
2286 mAttributeTypeDialog->setDefaultValueExpression( defaultElement.attribute( QStringLiteral(
"expression" ) ) );
2287 mAttributeTypeDialog->setApplyDefaultValueOnUpdate( defaultElement.attribute( QStringLiteral(
"applyOnUpdate" ) ).toInt() );
2293 const QDomElement constraintElement = docElem.firstChildElement( QStringLiteral(
"constraint" ) );
2294 if ( !constraintElement.isNull() )
2296 const int intConstraints = constraintElement.attribute( QStringLiteral(
"constraints" ), QStringLiteral(
"0" ) ).toInt();
2322 const int uniqueStrength = constraintElement.attribute( QStringLiteral(
"unique_strength" ), QStringLiteral(
"1" ) ).toInt();
2323 const int notNullStrength = constraintElement.attribute( QStringLiteral(
"notnull_strength" ), QStringLiteral(
"1" ) ).toInt();
2324 const int expStrength = constraintElement.attribute( QStringLiteral(
"exp_strength" ), QStringLiteral(
"1" ) ).toInt();
2335 const QDomElement constraintExpressionElement = docElem.firstChildElement( QStringLiteral(
"constraintExpression" ) );
2336 if ( !constraintExpressionElement.isNull() )
2338 QString expression = constraintExpressionElement.attribute( QStringLiteral(
"exp" ), QString() );
2339 QString description = constraintExpressionElement.attribute( QStringLiteral(
"desc" ), QString() );
2343 config.mFieldConstraints = fieldConstraints;
2345 const QDomElement widgetGeneralSettingsElement = docElem.firstChildElement( QStringLiteral(
"widgetGeneralSettings" ) );
2346 if ( !widgetGeneralSettingsElement.isNull() )
2348 const int editable = widgetGeneralSettingsElement.attribute( QStringLiteral(
"editable" ), QStringLiteral(
"0" ) ).toInt();
2349 const int reuse = widgetGeneralSettingsElement.attribute( QStringLiteral(
"reuse_last_values" ), QStringLiteral(
"0" ) ).toInt();
2350 const int labelOnTop = widgetGeneralSettingsElement.attribute( QStringLiteral(
"label_on_top" ), QStringLiteral(
"0" ) ).toInt();
2352 config.mEditable = editable;
2353 config.mReuseLastValues = reuse;
2354 config.mLabelOnTop = labelOnTop;
2357 loadAttributeTypeDialogFromConfiguration( config );
2362 const QDomElement displayElement = docElem.firstChildElement( QStringLiteral(
"widgetDisplay" ) );
2363 if ( !displayElement.isNull() )
2365 const int showLabel = displayElement.attribute( QStringLiteral(
"showLabel" ), QStringLiteral(
"0" ) ).toInt();
2366 const int horizontalStretch = displayElement.attribute( QStringLiteral(
"horizontalStretch" ), QStringLiteral(
"0" ) ).toInt();
2367 const int verticalStretch = displayElement.attribute( QStringLiteral(
"verticalStretch" ), QStringLiteral(
"0" ) ).toInt();
2369 style.
readXml( displayElement );
AttributeEditorContainerType
Attribute editor container types.
AttributeFormSuppression
Available form types for layout of the attribute form editor.
@ On
Always suppress feature form.
@ Default
Use the application-wide setting.
@ Off
Never suppress feature form.
AttributeFormLayout
Available form types for layout of the attribute form editor.
@ DragAndDrop
"Drag and drop" layout. Needs to be configured.
@ AutoGenerated
Autogenerate a simple tabular layout for the form.
@ UiFile
Load a .ui file for the layout. Needs to be configured.
FieldDomainMergePolicy
Merge policy for field domains.
@ DefaultValue
Use default field value.
@ Warning
Warning message.
FieldDomainSplitPolicy
Split policy for field domains.
@ Duplicate
Duplicate original value.
FieldDuplicatePolicy
Duplicate policy for fields.
@ Duplicate
Duplicate original value.
@ Action
A layer action element.
@ QmlElement
A QML element.
@ HtmlElement
A HTML element.
@ TextElement
A text element.
@ SpacerElement
A spacer element.
QList< QgsAction > actions(const QString &actionScope=QString()) const
Returns a list of actions that are available in the given action scope.
QgsAction action(QUuid id) const
Gets an action by its id.
Utility class that encapsulates an action based on vector attributes.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
This element will load a layer action onto the form.
const QgsAction & action(const QgsVectorLayer *layer) const
Returns the (possibly lazy loaded) action for the given layer.
A container for attribute editors, used to group them visually in the attribute form if it is set to ...
virtual void addChildElement(QgsAttributeEditorElement *element)
Add a child element to this container.
QgsOptionalExpression visibilityExpression() const
The visibility expression is used in the attribute form to show or hide this container based on an ex...
void setColumnCount(int columnCount)
Set the number of columns in this group.
void setVisibilityExpression(const QgsOptionalExpression &visibilityExpression)
The visibility expression is used in the attribute form to show or hide this container based on an ex...
QgsOptionalExpression collapsedExpression() const
The collapsed expression is used in the attribute form to set the collapsed status of the group box c...
bool collapsed() const
For group box containers returns true if this group box is collapsed.
Qgis::AttributeEditorContainerType type() const
Returns the container type.
void setType(Qgis::AttributeEditorContainerType type)
Sets the container type.
void setCollapsedExpression(const QgsOptionalExpression &collapsedExpression)
The collapsed expression is used in the attribute form to set the collapsed status of the group box o...
QList< QgsAttributeEditorElement * > children() const
Gets a list of the children elements of this container.
QColor backgroundColor() const
Returns the background color of the container.
void setCollapsed(bool collapsed)
For group box containers sets if this group box is collapsed.
int columnCount() const
Gets the number of columns in this group.
void setBackgroundColor(const QColor &backgroundColor)
Sets the background color to backgroundColor.
An abstract base class for any elements of a drag and drop form.
void setHorizontalStretch(int stretch)
Sets the horizontal stretch factor for the element.
LabelStyle labelStyle() const
Returns the label style.
void setLabelStyle(const LabelStyle &labelStyle)
Sets the labelStyle.
Qgis::AttributeEditorType type() const
The type of this element.
int verticalStretch() const
Returns the vertical stretch factor for the element.
bool showLabel() const
Controls if this element should be labeled with a title (field, relation or groupname).
QString name() const
Returns the name of this element.
void setVerticalStretch(int stretch)
Sets the vertical stretch factor for the element.
void setShowLabel(bool showLabel)
Controls if this element should be labeled with a title (field, relation or groupname).
int horizontalStretch() const
Returns the horizontal stretch factor for the element.
This element will load a field's widget onto the form.
An attribute editor widget that will represent arbitrary HTML code.
QString htmlCode() const
The Html code that will be represented within this widget.
void setHtmlCode(const QString &htmlCode)
Sets the HTML code that will be represented within this widget to htmlCode.
An attribute editor widget that will represent arbitrary QML code.
QString qmlCode() const
The QML code that will be represented within this widget.
void setQmlCode(const QString &qmlCode)
Sets the QML code that will be represented within this widget to qmlCode.
This element will load a relation editor onto the form.
void setNmRelationId(const QVariant &nmRelationId=QVariant())
Sets nmRelationId for the relation id of the second relation involved in an N:M relation.
void setRelationWidgetTypeId(const QString &relationWidgetTypeId)
Sets the relation widget type.
const QgsRelation & relation() const
Gets the id of the relation which shall be embedded.
QVariantMap relationEditorConfiguration() const
Returns the relation editor widget configuration.
void setForceSuppressFormPopup(bool forceSuppressFormPopup)
Sets force suppress form popup status to forceSuppressFormPopup.
QVariant nmRelationId() const
Determines the relation id of the second relation involved in an N:M relation.
bool forceSuppressFormPopup() const
Determines the force suppress form popup status.
QString relationWidgetTypeId() const
Returns the current relation widget type id.
void setRelationEditorConfiguration(const QVariantMap &config)
Sets the relation editor configuration.
void setLabel(const QString &label=QString())
Sets label for this element If it's empty it takes the relation id as label.
QString label() const
Determines the label of this element.
An attribute editor widget that will represent a spacer.
void setDrawLine(bool drawLine)
Sets a flag to define if the spacer element will contain an horizontal line.
bool drawLine() const
Returns true if the spacer element will contain an horizontal line.
An attribute editor widget that will represent arbitrary text code.
void setText(const QString &text)
Sets the text that will be represented within this widget to text.
QString text() const
The Text that will be represented within this widget.
Overrides mime type handling to be able to work with the drag and drop attribute editor.
void setType(QgsAttributesDnDTree::Type value)
void dropEvent(QDropEvent *event) override
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
QTreeWidgetItem * addContainer(QTreeWidgetItem *parent, const QString &title, int columnCount, Qgis::AttributeEditorContainerType type)
Adds a new container to parent.
QStringList mimeTypes() const override
QgsAttributesDnDTree(QgsVectorLayer *layer, QWidget *parent=nullptr)
QMimeData * mimeData(const QList< QTreeWidgetItem * > &items) const override
bool dropMimeData(QTreeWidgetItem *parent, int index, const QMimeData *data, Qt::DropAction action) override
void dragMoveEvent(QDragMoveEvent *event) override
Is called when mouse is moved over attributes tree before a drop event.
void selectFirstMatchingItem(const QgsAttributesFormProperties::DnDTreeItemData &data)
QTreeWidgetItem * addItem(QTreeWidgetItem *parent, const QgsAttributesFormProperties::DnDTreeItemData &data, int index=-1, const QIcon &icon=QIcon())
Adds a new item to a parent.
A HTML editor based on QScintilla2.
A text editor based on QScintilla2.
void setText(const QString &text) override
void setEditingTimeoutInterval(int timeout)
Sets the timeout (in milliseconds) threshold for the editingTimeout() signal to be emitted after an e...
void insertText(const QString &text)
Insert text at cursor position, or replace any selected text if user has made a selection.
void editingTimeout()
Emitted when either:
Provides a container for managing client side default values for fields.
A generic dialog for building expression strings.
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.
static QString findAndSelectActiveExpression(QgsCodeEditor *editor, const QString &pattern=QString())
Find the expression under the cursor in the given editor and select it.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
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.
ConstraintStrength
Strength of constraints.
@ 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.
@ ConstraintOriginLayer
Constraint was set by layer.
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().
void removeConstraint(Constraint constraint)
Removes a constraint from the field.
QString constraintDescription() const
Returns the descriptive name for the constraint expression.
void setConstraint(Constraint constraint, ConstraintOrigin origin=ConstraintOriginLayer)
Sets a constraint on the field.
QFlags< Constraint > Constraints
Encapsulate a field in an attribute table or data source.
Qgis::FieldDomainSplitPolicy splitPolicy() const
Returns the field's split policy, which indicates how field values should be handled during a split o...
Qgis::FieldDuplicatePolicy duplicatePolicy() const
Returns the field's duplicate policy, which indicates how field values should be handled during a dup...
QgsDefaultValue defaultValueDefinition
Qgis::FieldDomainMergePolicy mergePolicy() const
Returns the field's merge policy, which indicates how field values should be handled during a merge o...
QgsFieldConstraints constraints
QgsEditorWidgetSetup editorWidgetSetup() const
Gets the editor widget setup for the field.
Container of fields for a vector layer.
Q_INVOKABLE int indexOf(const QString &fieldName) const
Gets the field index from the field name.
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).
Q_INVOKABLE 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.
static void enableAutoGeometryRestore(QWidget *widget, const QString &key=QString())
Register the widget to allow its position to be automatically saved and restored when open and closed...
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
A bar for displaying non-blocking messages to the user.
void pushMessage(const QString &text, Qgis::MessageLevel level=Qgis::MessageLevel::Info, int duration=-1)
A convenience method for pushing a message with the specified text to the bar.
An expression with an additional enabled flag.
A relation where the referenced (parent) layer is calculated based on fields from the referencing (ch...
virtual QString translate(const QString &context, const QString &sourceText, const char *disambiguation=nullptr, int n=-1) const =0
Translates a string using the Qt QTranslator mechanism.
QgsRelationManager * relationManager
static QgsProject * instance()
Returns the QgsProject singleton instance.
int count() const
Returns the number of properties contained within the collection.
A container for the context for various read/write operations on objects.
const QgsProjectTranslator * projectTranslator() const
Returns the project translator.
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.
Represents a relationship between two vector layers.
QgsVectorLayer * referencedLayer
static const QgsSettingsEntryBool * settingsDigitizingDisableEnterAttributeValuesDialog
Settings entry digitizing disable enter attribute values dialog.
Stores settings for use within QGIS.
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 dataset.
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.
void removeFieldConstraint(int index, QgsFieldConstraints::Constraint constraint)
Removes a constraint for a specified field index.
void setFieldMergePolicy(int index, Qgis::FieldDomainMergePolicy policy)
Sets a merge policy for the field with the specified 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)
Sets the editor widget setup for the field at the specified index.
void setConstraintExpression(int index, const QString &expression, const QString &description=QString())
Sets the constraint expression for the specified field index.
void setFieldDuplicatePolicy(int index, Qgis::FieldDuplicatePolicy policy)
Sets a duplicate policy for the field with the specified 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.
void updatedFields()
Emitted whenever the fields available from this layer have been changed.
QgsEditFormConfig editFormConfig
void setFieldSplitPolicy(int index, Qgis::FieldDomainSplitPolicy policy)
Sets a split policy for the field with the specified index.
static QDomElement writeVariant(const QVariant &value, QDomDocument &doc)
Write a QVariant to a QDomElement.
static QVariant readVariant(const QDomElement &element)
Read a QVariant from a QDomElement.
T qgsEnumKeyToValue(const QString &key, const T &defaultValue, bool tryValueAsKey=true, bool *returnOk=nullptr)
Returns the value corresponding to the given key of an enum.
QString qgsEnumValueToKey(const T &value, bool *returnOk=nullptr)
Returns the value for the given key of an enum.
#define QgsDebugError(str)
The TabStyle struct defines color and font overrides for form fields, tabs and groups labels.
void readXml(const QDomNode &node)
Reads configuration from node.