|
20 | 20 | #include "qgisapp.h"
|
21 | 21 | #include "qgsfieldcombobox.h"
|
22 | 22 | #include "qgsqmlwidgetwrapper.h"
|
| 23 | +#include "qgshtmlwidgetwrapper.h" |
23 | 24 | #include "qgsapplication.h"
|
24 | 25 | #include "qgscolorbutton.h"
|
| 26 | +#include "qgscodeeditorhtml.h" |
25 | 27 |
|
26 | 28 | QgsAttributesFormProperties::QgsAttributesFormProperties( QgsVectorLayer *layer, QWidget *parent )
|
27 | 29 | : QWidget( parent )
|
@@ -140,14 +142,17 @@ void QgsAttributesFormProperties::initAvailableWidgetsTree()
|
140 | 142 | }
|
141 | 143 | catitem->setExpanded( true );
|
142 | 144 |
|
143 |
| - // QML widget |
| 145 | + // QML/HTML widget |
144 | 146 | catItemData = DnDTreeItemData( DnDTreeItemData::Container, QStringLiteral( "Other" ), tr( "Other Widgets" ) );
|
145 | 147 | catitem = mAvailableWidgetsTree->addItem( mAvailableWidgetsTree->invisibleRootItem(), catItemData );
|
146 | 148 |
|
147 | 149 | DnDTreeItemData itemData = DnDTreeItemData( DnDTreeItemData::QmlWidget, QStringLiteral( "QmlWidget" ), tr( "QML Widget" ) );
|
148 | 150 | itemData.setShowLabel( true );
|
149 |
| - |
150 | 151 | mAvailableWidgetsTree->addItem( catitem, itemData );
|
| 152 | + |
| 153 | + auto itemDataHtml { DnDTreeItemData( DnDTreeItemData::HtmlWidget, QStringLiteral( "HtmlWidget" ), tr( "HTML Widget" ) ) }; |
| 154 | + itemDataHtml.setShowLabel( true ); |
| 155 | + mAvailableWidgetsTree->addItem( catitem, itemDataHtml ); |
151 | 156 | catitem ->setExpanded( true );
|
152 | 157 | }
|
153 | 158 |
|
@@ -479,6 +484,19 @@ QTreeWidgetItem *QgsAttributesFormProperties::loadAttributeEditorTreeItem( QgsAt
|
479 | 484 | newWidget = tree->addItem( parent, itemData );
|
480 | 485 | break;
|
481 | 486 | }
|
| 487 | + |
| 488 | + case QgsAttributeEditorElement::AeTypeHtmlElement: |
| 489 | + { |
| 490 | + const QgsAttributeEditorHtmlElement *htmlElementEditor = static_cast<const QgsAttributeEditorHtmlElement *>( widgetDef ); |
| 491 | + DnDTreeItemData itemData = DnDTreeItemData( DnDTreeItemData::HtmlWidget, widgetDef->name(), widgetDef->name() ); |
| 492 | + itemData.setShowLabel( widgetDef->showLabel() ); |
| 493 | + HtmlElementEditorConfiguration htmlEdConfig; |
| 494 | + htmlEdConfig.htmlCode = htmlElementEditor->htmlCode(); |
| 495 | + itemData.setHtmlElementEditorConfiguration( htmlEdConfig ); |
| 496 | + newWidget = tree->addItem( parent, itemData ); |
| 497 | + break; |
| 498 | + } |
| 499 | + |
482 | 500 | case QgsAttributeEditorElement::AeTypeInvalid:
|
483 | 501 | {
|
484 | 502 | QgsDebugMsg( QStringLiteral( "Not loading invalid attribute editor type..." ) );
|
@@ -520,6 +538,12 @@ void QgsAttributesFormProperties::onAttributeSelectionChanged()
|
520 | 538 | mAttributeTypeDialog->setVisible( false );
|
521 | 539 | break;
|
522 | 540 | }
|
| 541 | + case DnDTreeItemData::HtmlWidget: |
| 542 | + { |
| 543 | + mAttributeRelationEdit->setVisible( false ); |
| 544 | + mAttributeTypeDialog->setVisible( false ); |
| 545 | + break; |
| 546 | + } |
523 | 547 |
|
524 | 548 | }
|
525 | 549 | }
|
@@ -620,6 +644,15 @@ QgsAttributeEditorElement *QgsAttributesFormProperties::createAttributeEditorWid
|
620 | 644 | widgetDef = element;
|
621 | 645 | break;
|
622 | 646 | }
|
| 647 | + |
| 648 | + case DnDTreeItemData::HtmlWidget: |
| 649 | + { |
| 650 | + QgsAttributeEditorHtmlElement *element = new QgsAttributeEditorHtmlElement( item->text( 0 ), parent ); |
| 651 | + element->setHtmlCode( itemData.htmlElementEditorConfiguration().htmlCode ); |
| 652 | + widgetDef = element; |
| 653 | + break; |
| 654 | + } |
| 655 | + |
623 | 656 | }
|
624 | 657 |
|
625 | 658 | widgetDef->setShowLabel( itemData.showLabel() );
|
@@ -875,6 +908,10 @@ QTreeWidgetItem *DnDTree::addItem( QTreeWidgetItem *parent, QgsAttributesFormPro
|
875 | 908 | case QgsAttributesFormProperties::DnDTreeItemData::QmlWidget:
|
876 | 909 | //no icon for QmlWidget
|
877 | 910 | break;
|
| 911 | + |
| 912 | + case QgsAttributesFormProperties::DnDTreeItemData::HtmlWidget: |
| 913 | + //no icon for HtmlWidget |
| 914 | + break; |
878 | 915 | }
|
879 | 916 | }
|
880 | 917 | newItem->setData( 0, QgsAttributesFormProperties::DnDTreeRole, data );
|
@@ -955,6 +992,11 @@ bool DnDTree::dropMimeData( QTreeWidgetItem *parent, int index, const QMimeData
|
955 | 992 | {
|
956 | 993 | onItemDoubleClicked( newItem, 0 );
|
957 | 994 | }
|
| 995 | + |
| 996 | + if ( itemElement.type() == QgsAttributesFormProperties::DnDTreeItemData::HtmlWidget ) |
| 997 | + { |
| 998 | + onItemDoubleClicked( newItem, 0 ); |
| 999 | + } |
958 | 1000 | }
|
959 | 1001 | }
|
960 | 1002 |
|
@@ -1295,6 +1337,85 @@ void DnDTree::onItemDoubleClicked( QTreeWidgetItem *item, int column )
|
1295 | 1337 | }
|
1296 | 1338 | break;
|
1297 | 1339 |
|
| 1340 | + case QgsAttributesFormProperties::DnDTreeItemData::HtmlWidget: |
| 1341 | + { |
| 1342 | + QDialog dlg; |
| 1343 | + dlg.setWindowTitle( tr( "Configure HTML Widget" ) ); |
| 1344 | + |
| 1345 | + QVBoxLayout *mainLayout = new QVBoxLayout(); |
| 1346 | + QHBoxLayout *htmlLayout = new QHBoxLayout(); |
| 1347 | + QVBoxLayout *layout = new QVBoxLayout(); |
| 1348 | + mainLayout->addLayout( htmlLayout ); |
| 1349 | + htmlLayout->addLayout( layout ); |
| 1350 | + dlg.setLayout( mainLayout ); |
| 1351 | + layout->addWidget( baseWidget ); |
| 1352 | + |
| 1353 | + QLineEdit *title = new QLineEdit( itemData.name() ); |
| 1354 | + |
| 1355 | + //htmlCode |
| 1356 | + QgsCodeEditorHTML *htmlCode = new QgsCodeEditorHTML( ); |
| 1357 | + htmlCode->setSizePolicy( QSizePolicy::Policy::Expanding, QSizePolicy::Policy::Expanding ); |
| 1358 | + htmlCode->setText( itemData.htmlElementEditorConfiguration().htmlCode ); |
| 1359 | + |
| 1360 | + QgsHtmlWidgetWrapper *htmlWrapper = new QgsHtmlWidgetWrapper( mLayer, nullptr, this ); |
| 1361 | + QgsFeature previewFeature; |
| 1362 | + mLayer->getFeatures().nextFeature( previewFeature ); |
| 1363 | + |
| 1364 | + //update preview on text change |
| 1365 | + connect( htmlCode, &QgsCodeEditorHTML::textChanged, this, [ = ] |
| 1366 | + { |
| 1367 | + htmlWrapper->setHtmlCode( htmlCode->text( ) ); |
| 1368 | + htmlWrapper->reinitWidget(); |
| 1369 | + htmlWrapper->setFeature( previewFeature ); |
| 1370 | + } ); |
| 1371 | + |
| 1372 | + QgsFieldExpressionWidget *expressionWidget = new QgsFieldExpressionWidget; |
| 1373 | + expressionWidget->setLayer( mLayer ); |
| 1374 | + QToolButton *addExpressionButton = new QToolButton(); |
| 1375 | + addExpressionButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/symbologyAdd.svg" ) ) ); |
| 1376 | + |
| 1377 | + connect( addExpressionButton, &QAbstractButton::clicked, this, [ = ] |
| 1378 | + { |
| 1379 | + htmlCode->insertText( QStringLiteral( "<script>document.write(expression.evaluate(\"%1\"));</script>" ).arg( expressionWidget->expression().replace( '"', QLatin1String( "\\\"" ) ) ) ); |
| 1380 | + } ); |
| 1381 | + |
| 1382 | + layout->addWidget( new QLabel( tr( "Title" ) ) ); |
| 1383 | + layout->addWidget( title ); |
| 1384 | + QGroupBox *expressionWidgetBox = new QGroupBox( tr( "HTML Code" ) ); |
| 1385 | + layout->addWidget( expressionWidgetBox ); |
| 1386 | + expressionWidgetBox->setLayout( new QHBoxLayout ); |
| 1387 | + expressionWidgetBox->layout()->addWidget( expressionWidget ); |
| 1388 | + expressionWidgetBox->layout()->addWidget( addExpressionButton ); |
| 1389 | + layout->addWidget( htmlCode ); |
| 1390 | + QScrollArea *htmlPreviewBox = new QScrollArea(); |
| 1391 | + htmlPreviewBox->setLayout( new QGridLayout ); |
| 1392 | + htmlPreviewBox->setMinimumWidth( 400 ); |
| 1393 | + htmlPreviewBox->layout()->addWidget( htmlWrapper->widget() ); |
| 1394 | + //emit to load preview for the first time |
| 1395 | + emit htmlCode->textChanged(); |
| 1396 | + htmlLayout->addWidget( htmlPreviewBox ); |
| 1397 | + |
| 1398 | + QDialogButtonBox *buttonBox = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel ); |
| 1399 | + |
| 1400 | + connect( buttonBox, &QDialogButtonBox::accepted, &dlg, &QDialog::accept ); |
| 1401 | + connect( buttonBox, &QDialogButtonBox::rejected, &dlg, &QDialog::reject ); |
| 1402 | + |
| 1403 | + mainLayout->addWidget( buttonBox ); |
| 1404 | + |
| 1405 | + if ( dlg.exec() ) |
| 1406 | + { |
| 1407 | + QgsAttributesFormProperties::HtmlElementEditorConfiguration htmlEdCfg; |
| 1408 | + htmlEdCfg.htmlCode = htmlCode->text(); |
| 1409 | + itemData.setName( title->text() ); |
| 1410 | + itemData.setHtmlElementEditorConfiguration( htmlEdCfg ); |
| 1411 | + itemData.setShowLabel( showLabelCheckbox->isChecked() ); |
| 1412 | + |
| 1413 | + item->setData( 0, QgsAttributesFormProperties::DnDTreeRole, itemData ); |
| 1414 | + item->setText( 0, title->text() ); |
| 1415 | + } |
| 1416 | + } |
| 1417 | + break; |
| 1418 | + |
1298 | 1419 | case QgsAttributesFormProperties::DnDTreeItemData::Field:
|
1299 | 1420 | {
|
1300 | 1421 | QDialog dlg;
|
@@ -1407,6 +1528,17 @@ void QgsAttributesFormProperties::DnDTreeItemData::setQmlElementEditorConfigurat
|
1407 | 1528 | mQmlElementEditorConfiguration = qmlElementEditorConfiguration;
|
1408 | 1529 | }
|
1409 | 1530 |
|
| 1531 | + |
| 1532 | +QgsAttributesFormProperties::HtmlElementEditorConfiguration QgsAttributesFormProperties::DnDTreeItemData::htmlElementEditorConfiguration() const |
| 1533 | +{ |
| 1534 | + return mHtmlElementEditorConfiguration; |
| 1535 | +} |
| 1536 | + |
| 1537 | +void QgsAttributesFormProperties::DnDTreeItemData::setHtmlElementEditorConfiguration( QgsAttributesFormProperties::HtmlElementEditorConfiguration htmlElementEditorConfiguration ) |
| 1538 | +{ |
| 1539 | + mHtmlElementEditorConfiguration = htmlElementEditorConfiguration; |
| 1540 | +} |
| 1541 | + |
1410 | 1542 | QColor QgsAttributesFormProperties::DnDTreeItemData::backgroundColor() const
|
1411 | 1543 | {
|
1412 | 1544 | return mBackgroundColor;
|
|
0 commit comments