|
21 | 21 | #include "qgsprojectionselectionwidget.h"
|
22 | 22 | #include "qgsspinbox.h"
|
23 | 23 | #include "qgsdoublespinbox.h"
|
| 24 | +#include "qgsprocessingcontext.h" |
24 | 25 | #include <QLabel>
|
25 | 26 | #include <QHBoxLayout>
|
26 | 27 | #include <QCheckBox>
|
@@ -635,5 +636,148 @@ QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingNumericWidgetWrapper::
|
635 | 636 | return new QgsProcessingNumericWidgetWrapper( parameter, type );
|
636 | 637 | }
|
637 | 638 |
|
| 639 | +// |
| 640 | +// QgsProcessingDistanceWidgetWrapper |
| 641 | +// |
| 642 | + |
| 643 | +QgsProcessingDistanceWidgetWrapper::QgsProcessingDistanceWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent ) |
| 644 | + : QgsProcessingNumericWidgetWrapper( parameter, type, parent ) |
| 645 | +{ |
| 646 | + |
| 647 | +} |
| 648 | + |
| 649 | +QString QgsProcessingDistanceWidgetWrapper::parameterType() const |
| 650 | +{ |
| 651 | + return QgsProcessingParameterDistance::typeName(); |
| 652 | +} |
| 653 | + |
| 654 | +QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingDistanceWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type ) |
| 655 | +{ |
| 656 | + return new QgsProcessingDistanceWidgetWrapper( parameter, type ); |
| 657 | +} |
| 658 | + |
| 659 | +QWidget *QgsProcessingDistanceWidgetWrapper::createWidget() |
| 660 | +{ |
| 661 | + QWidget *spin = QgsProcessingNumericWidgetWrapper::createWidget(); |
| 662 | + |
| 663 | + mLabel = new QLabel(); |
| 664 | + mUnitsCombo = new QComboBox(); |
| 665 | + |
| 666 | + mUnitsCombo->addItem( QgsUnitTypes::toString( QgsUnitTypes::DistanceMeters ), QgsUnitTypes::DistanceMeters ); |
| 667 | + mUnitsCombo->addItem( QgsUnitTypes::toString( QgsUnitTypes::DistanceKilometers ), QgsUnitTypes::DistanceKilometers ); |
| 668 | + mUnitsCombo->addItem( QgsUnitTypes::toString( QgsUnitTypes::DistanceFeet ), QgsUnitTypes::DistanceFeet ); |
| 669 | + mUnitsCombo->addItem( QgsUnitTypes::toString( QgsUnitTypes::DistanceMiles ), QgsUnitTypes::DistanceMiles ); |
| 670 | + mUnitsCombo->addItem( QgsUnitTypes::toString( QgsUnitTypes::DistanceYards ), QgsUnitTypes::DistanceYards ); |
| 671 | + |
| 672 | + const double labelMargin = mUnitsCombo->fontMetrics().width( 'X' ); |
| 673 | + QHBoxLayout *layout = new QHBoxLayout(); |
| 674 | + layout->addWidget( spin, 1 ); |
| 675 | + layout->insertSpacing( 1, labelMargin / 2 ); |
| 676 | + layout->insertWidget( 2, mLabel ); |
| 677 | + layout->insertWidget( 3, mUnitsCombo ); |
| 678 | + layout->insertSpacing( 4, labelMargin / 2 ); |
| 679 | + |
| 680 | + mWarningLabel = new QLabel(); |
| 681 | + QIcon icon = QgsApplication::getThemeIcon( QStringLiteral( "mIconWarning.svg" ) ); |
| 682 | + const int size = static_cast< int >( std::max( 24.0, spin->height() * 0.5 ) ); |
| 683 | + mWarningLabel->setPixmap( icon.pixmap( icon.actualSize( QSize( size, size ) ) ) ); |
| 684 | + mWarningLabel->setToolTip( tr( "Distance is in geographic degrees. Consider reprojecting to a projected local coordinate system for accurate results." ) ); |
| 685 | + layout->insertWidget( 4, mWarningLabel ); |
| 686 | + layout->insertSpacing( 5, labelMargin ); |
| 687 | + |
| 688 | + setUnits( QgsUnitTypes::DistanceUnknownUnit ); |
| 689 | + |
| 690 | + QWidget *w = new QWidget(); |
| 691 | + layout->setMargin( 0 ); |
| 692 | + layout->setContentsMargins( 0, 0, 0, 0 ); |
| 693 | + w->setLayout( layout ); |
| 694 | + return w; |
| 695 | +} |
| 696 | + |
| 697 | +void QgsProcessingDistanceWidgetWrapper::postInitialize( const QList<QgsAbstractProcessingParameterWidgetWrapper *> &wrappers ) |
| 698 | +{ |
| 699 | + QgsProcessingNumericWidgetWrapper::postInitialize( wrappers ); |
| 700 | + switch ( type() ) |
| 701 | + { |
| 702 | + case QgsProcessingGui::Batch: |
| 703 | + case QgsProcessingGui::Standard: |
| 704 | + { |
| 705 | + for ( const QgsAbstractProcessingParameterWidgetWrapper *wrapper : wrappers ) |
| 706 | + { |
| 707 | + if ( wrapper->parameterDefinition()->name() == static_cast< const QgsProcessingParameterDistance * >( parameterDefinition() )->parentParameterName() ) |
| 708 | + { |
| 709 | + setUnitParameterValue( wrapper->parameterValue() ); |
| 710 | + connect( wrapper, &QgsAbstractProcessingParameterWidgetWrapper::widgetValueHasChanged, this, [ = ] |
| 711 | + { |
| 712 | + setUnitParameterValue( wrapper->parameterValue() ); |
| 713 | + } ); |
| 714 | + break; |
| 715 | + } |
| 716 | + } |
| 717 | + break; |
| 718 | + } |
| 719 | + |
| 720 | + case QgsProcessingGui::Modeler: |
| 721 | + break; |
| 722 | + } |
| 723 | +} |
| 724 | + |
| 725 | +void QgsProcessingDistanceWidgetWrapper::setUnitParameterValue( const QVariant &value ) |
| 726 | +{ |
| 727 | + QgsUnitTypes::DistanceUnit units = QgsUnitTypes::DistanceUnknownUnit; |
| 728 | + |
| 729 | + // evaluate value to layer |
| 730 | + QgsProcessingContext *context = nullptr; |
| 731 | + std::unique_ptr< QgsProcessingContext > tmpContext; |
| 732 | + if ( mProcessingContextGenerator ) |
| 733 | + context = mProcessingContextGenerator->processingContext(); |
| 734 | + |
| 735 | + if ( !context ) |
| 736 | + { |
| 737 | + tmpContext = qgis::make_unique< QgsProcessingContext >(); |
| 738 | + context = tmpContext.get(); |
| 739 | + } |
| 740 | + |
| 741 | + QgsCoordinateReferenceSystem crs = QgsProcessingParameters::parameterAsCrs( parameterDefinition(), value, *context ); |
| 742 | + if ( crs.isValid() ) |
| 743 | + { |
| 744 | + units = crs.mapUnits(); |
| 745 | + } |
| 746 | + |
| 747 | + setUnits( units ); |
| 748 | +} |
| 749 | + |
| 750 | +void QgsProcessingDistanceWidgetWrapper::setUnits( const QgsUnitTypes::DistanceUnit units ) |
| 751 | +{ |
| 752 | + mLabel->setText( QgsUnitTypes::toString( units ) ); |
| 753 | + if ( QgsUnitTypes::unitType( units ) != QgsUnitTypes::Standard ) |
| 754 | + { |
| 755 | + mUnitsCombo->hide(); |
| 756 | + mLabel->show(); |
| 757 | + } |
| 758 | + else |
| 759 | + { |
| 760 | + mUnitsCombo->setCurrentIndex( mUnitsCombo->findData( units ) ); |
| 761 | + mUnitsCombo->show(); |
| 762 | + mLabel->hide(); |
| 763 | + mWarningLabel->setVisible( units == QgsUnitTypes::DistanceDegrees ); |
| 764 | + mBaseUnit = units; |
| 765 | + } |
| 766 | +} |
| 767 | + |
| 768 | +QVariant QgsProcessingDistanceWidgetWrapper::widgetValue() const |
| 769 | +{ |
| 770 | + const QVariant val = QgsProcessingNumericWidgetWrapper::widgetValue(); |
| 771 | + if ( val.type() == QVariant::Double && mUnitsCombo->isVisible() ) |
| 772 | + { |
| 773 | + QgsUnitTypes::DistanceUnit displayUnit = static_cast<QgsUnitTypes::DistanceUnit >( mUnitsCombo->currentData().toInt() ); |
| 774 | + return val.toDouble() * QgsUnitTypes::fromUnitToUnitFactor( displayUnit, mBaseUnit ); |
| 775 | + } |
| 776 | + else |
| 777 | + { |
| 778 | + return val; |
| 779 | + } |
| 780 | +} |
| 781 | + |
638 | 782 |
|
639 | 783 | ///@endcond PRIVATE
|
0 commit comments