Also permit drag and drop onto multi layer line edit

We supported drag and drop onto the full expanded panel, now
also support dropping onto the summary line edit widget too
This commit is contained in:
Nyall Dawson 2024-06-27 11:03:24 +10:00
parent 7ec94dc2c3
commit b0929e4ced
6 changed files with 101 additions and 22 deletions

View File

@ -214,6 +214,7 @@ Constructor for QgsProcessingMultipleInputPanelWidget.
Sets the project associated with the widget.
%End
protected:
virtual void dragEnterEvent( QDragEnterEvent *event );

View File

@ -214,6 +214,7 @@ Constructor for QgsProcessingMultipleInputPanelWidget.
Sets the project associated with the widget.
%End
protected:
virtual void dragEnterEvent( QDragEnterEvent *event );

View File

@ -447,7 +447,7 @@ QList< int> QgsProcessingMultipleInputPanelWidget::existingMapLayerFromMimeData(
}
QStringList QgsProcessingMultipleInputPanelWidget::compatibleUrisFromMimeData( const QMimeData *data, const QgsMimeDataUtils::UriList &skipUrls ) const
QStringList QgsProcessingMultipleInputPanelWidget::compatibleUrisFromMimeData( const QgsProcessingParameterMultipleLayers *parameter, const QMimeData *data, const QgsMimeDataUtils::UriList &skipUrls )
{
QStringList skipUrlData;
skipUrlData.reserve( skipUrls.size() );
@ -466,12 +466,12 @@ QStringList QgsProcessingMultipleInputPanelWidget::compatibleUrisFromMimeData( c
// clang analyzer is not happy because of the multiple duplicate return branches, but it makes the code more readable
// NOLINTBEGIN(bugprone-branch-clone)
if ( ( mParameter->layerType() == Qgis::ProcessingSourceType::MapLayer
|| mParameter->layerType() == Qgis::ProcessingSourceType::Vector
|| mParameter->layerType() == Qgis::ProcessingSourceType::VectorAnyGeometry
|| mParameter->layerType() == Qgis::ProcessingSourceType::VectorLine
|| mParameter->layerType() == Qgis::ProcessingSourceType::VectorPoint
|| mParameter->layerType() == Qgis::ProcessingSourceType::VectorPolygon )
if ( ( parameter->layerType() == Qgis::ProcessingSourceType::MapLayer
|| parameter->layerType() == Qgis::ProcessingSourceType::Vector
|| parameter->layerType() == Qgis::ProcessingSourceType::VectorAnyGeometry
|| parameter->layerType() == Qgis::ProcessingSourceType::VectorLine
|| parameter->layerType() == Qgis::ProcessingSourceType::VectorPoint
|| parameter->layerType() == Qgis::ProcessingSourceType::VectorPolygon )
&& u.layerType == QLatin1String( "vector" ) )
{
bool acceptable = false;
@ -482,38 +482,38 @@ QStringList QgsProcessingMultipleInputPanelWidget::compatibleUrisFromMimeData( c
break;
case Qgis::GeometryType::Point:
if ( mParameter->layerType() == Qgis::ProcessingSourceType::MapLayer || mParameter->layerType() == Qgis::ProcessingSourceType::Vector || mParameter->layerType() == Qgis::ProcessingSourceType::VectorAnyGeometry || mParameter->layerType() == Qgis::ProcessingSourceType::VectorPoint )
if ( parameter->layerType() == Qgis::ProcessingSourceType::MapLayer || parameter->layerType() == Qgis::ProcessingSourceType::Vector || parameter->layerType() == Qgis::ProcessingSourceType::VectorAnyGeometry || parameter->layerType() == Qgis::ProcessingSourceType::VectorPoint )
acceptable = true;
break;
case Qgis::GeometryType::Line:
if ( mParameter->layerType() == Qgis::ProcessingSourceType::MapLayer || mParameter->layerType() == Qgis::ProcessingSourceType::Vector || mParameter->layerType() == Qgis::ProcessingSourceType::VectorAnyGeometry || mParameter->layerType() == Qgis::ProcessingSourceType::VectorLine )
if ( parameter->layerType() == Qgis::ProcessingSourceType::MapLayer || parameter->layerType() == Qgis::ProcessingSourceType::Vector || parameter->layerType() == Qgis::ProcessingSourceType::VectorAnyGeometry || parameter->layerType() == Qgis::ProcessingSourceType::VectorLine )
acceptable = true;
break;
case Qgis::GeometryType::Polygon:
if ( mParameter->layerType() == Qgis::ProcessingSourceType::MapLayer || mParameter->layerType() == Qgis::ProcessingSourceType::Vector || mParameter->layerType() == Qgis::ProcessingSourceType::VectorAnyGeometry || mParameter->layerType() == Qgis::ProcessingSourceType::VectorPolygon )
if ( parameter->layerType() == Qgis::ProcessingSourceType::MapLayer || parameter->layerType() == Qgis::ProcessingSourceType::Vector || parameter->layerType() == Qgis::ProcessingSourceType::VectorAnyGeometry || parameter->layerType() == Qgis::ProcessingSourceType::VectorPolygon )
acceptable = true;
break;
case Qgis::GeometryType::Null:
if ( mParameter->layerType() == Qgis::ProcessingSourceType::MapLayer || mParameter->layerType() == Qgis::ProcessingSourceType::Vector )
if ( parameter->layerType() == Qgis::ProcessingSourceType::MapLayer || parameter->layerType() == Qgis::ProcessingSourceType::Vector )
acceptable = true;
break;
}
if ( acceptable )
res.append( u.providerKey != QLatin1String( "ogr" ) ? QgsProcessingUtils::encodeProviderKeyAndUri( u.providerKey, u.uri ) : u.uri );
}
else if ( ( mParameter->layerType() == Qgis::ProcessingSourceType::MapLayer || mParameter->layerType() == Qgis::ProcessingSourceType::Raster )
else if ( ( parameter->layerType() == Qgis::ProcessingSourceType::MapLayer || parameter->layerType() == Qgis::ProcessingSourceType::Raster )
&& u.layerType == QLatin1String( "raster" ) && u.providerKey == QLatin1String( "gdal" ) )
res.append( u.uri );
else if ( ( mParameter->layerType() == Qgis::ProcessingSourceType::MapLayer || mParameter->layerType() == Qgis::ProcessingSourceType::Mesh )
else if ( ( parameter->layerType() == Qgis::ProcessingSourceType::MapLayer || parameter->layerType() == Qgis::ProcessingSourceType::Mesh )
&& u.layerType == QLatin1String( "mesh" ) && u.providerKey == QLatin1String( "mdal" ) )
res.append( u.uri );
else if ( ( mParameter->layerType() == Qgis::ProcessingSourceType::MapLayer || mParameter->layerType() == Qgis::ProcessingSourceType::PointCloud )
else if ( ( parameter->layerType() == Qgis::ProcessingSourceType::MapLayer || parameter->layerType() == Qgis::ProcessingSourceType::PointCloud )
&& u.layerType == QLatin1String( "pointcloud" ) )
res.append( u.uri );
else if ( ( mParameter->layerType() == Qgis::ProcessingSourceType::MapLayer || mParameter->layerType() == Qgis::ProcessingSourceType::VectorTile )
else if ( ( parameter->layerType() == Qgis::ProcessingSourceType::MapLayer || parameter->layerType() == Qgis::ProcessingSourceType::VectorTile )
&& u.layerType == QLatin1String( "vector-tile" ) )
res.append( u.uri );
// NOLINTEND(bugprone-branch-clone)
@ -567,7 +567,7 @@ void QgsProcessingMultipleInputPanelWidget::dragEnterEvent( QDragEnterEvent *eve
}
// maybe dragging layers from browser or file explorer
const QStringList uris = compatibleUrisFromMimeData( event->mimeData(), handledUris );
const QStringList uris = compatibleUrisFromMimeData( mParameter, event->mimeData(), handledUris );
if ( !uris.isEmpty() )
{
// dragged an acceptable layer, phew
@ -598,7 +598,7 @@ void QgsProcessingMultipleInputPanelWidget::dropEvent( QDropEvent *event )
}
// maybe dragging layers from browser or file explorer
const QStringList uris = compatibleUrisFromMimeData( event->mimeData(), handledUris );
const QStringList uris = compatibleUrisFromMimeData( mParameter, event->mimeData(), handledUris );
if ( !uris.isEmpty() )
{
for ( const QString &uri : uris )

View File

@ -251,6 +251,16 @@ class GUI_EXPORT QgsProcessingMultipleInputPanelWidget : public QgsProcessingMul
*/
void setProject( QgsProject *project );
/**
* Returns a list of layer URIs compatible with the \a parameter, from mime data.
*
* \since QGIS 3.40
*/
static QStringList compatibleUrisFromMimeData(
const QgsProcessingParameterMultipleLayers *parameter,
const QMimeData *data,
const QgsMimeDataUtils::UriList &skipUrls ) SIP_SKIP;
private slots:
void addFiles();
@ -267,7 +277,6 @@ class GUI_EXPORT QgsProcessingMultipleInputPanelWidget : public QgsProcessingMul
* the specified mime \a data (if possible!).
*/
QList<int> existingMapLayerFromMimeData( const QMimeData *data, QgsMimeDataUtils::UriList &handledUrls ) const;
QStringList compatibleUrisFromMimeData( const QMimeData *data, const QgsMimeDataUtils::UriList &skipUrls ) const;
void populateFromProject( QgsProject *project );
const QgsProcessingParameterMultipleLayers *mParameter = nullptr;

View File

@ -7124,7 +7124,54 @@ QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingBandWidgetWrapper::
return new QgsProcessingBandParameterDefinitionWidget( context, widgetContext, definition, algorithm );
}
//
// QgsProcessingMultipleLayerLineEdit
//
QgsProcessingMultipleLayerLineEdit::QgsProcessingMultipleLayerLineEdit( QWidget *parent, const QgsProcessingParameterMultipleLayers *param )
: QgsHighlightableLineEdit( parent )
, mParam( param )
{
setAcceptDrops( true );
}
void QgsProcessingMultipleLayerLineEdit::dragEnterEvent( QDragEnterEvent *event )
{
const QStringList uris = QgsProcessingMultipleInputPanelWidget::compatibleUrisFromMimeData( mParam, event->mimeData(), {} );
if ( !uris.isEmpty() )
{
event->setDropAction( Qt::CopyAction );
event->accept();
setHighlighted( true );
}
else
{
event->ignore();
}
}
void QgsProcessingMultipleLayerLineEdit::dragLeaveEvent( QDragLeaveEvent *event )
{
QgsHighlightableLineEdit::dragLeaveEvent( event );
event->accept();
setHighlighted( false );
}
void QgsProcessingMultipleLayerLineEdit::dropEvent( QDropEvent *event )
{
const QStringList uris = QgsProcessingMultipleInputPanelWidget::compatibleUrisFromMimeData( mParam, event->mimeData(), {} );
if ( !uris.isEmpty() )
{
event->acceptProposedAction();
QVariantList uriList;
uriList.reserve( uris.size() );
for ( const QString &uri : uris )
uriList.append( QVariant( uri ) );
emit layersDropped( uriList );
}
setHighlighted( false );
}
//
// QgsProcessingMultipleLayerPanelWidget
@ -7137,9 +7184,12 @@ QgsProcessingMultipleLayerPanelWidget::QgsProcessingMultipleLayerPanelWidget( QW
QHBoxLayout *hl = new QHBoxLayout();
hl->setContentsMargins( 0, 0, 0, 0 );
mLineEdit = new QLineEdit();
mLineEdit->setEnabled( false );
mLineEdit = new QgsProcessingMultipleLayerLineEdit( nullptr, param );
mLineEdit->setEnabled( true );
mLineEdit->setReadOnly( true );
hl->addWidget( mLineEdit, 1 );
connect( mLineEdit, &QgsProcessingMultipleLayerLineEdit::layersDropped, this, &QgsProcessingMultipleLayerPanelWidget::setValue );
mToolButton = new QToolButton();
mToolButton->setText( QString( QChar( 0x2026 ) ) );

View File

@ -28,7 +28,7 @@
#include "qgspointcloudlayer.h"
#include "qgsprocessingmodelchildparametersource.h"
#include "qobjectuniqueptr.h"
#include "qgshighlightablelineedit.h"
#include <QAbstractButton>
class QCheckBox;
@ -74,6 +74,7 @@ class QgsMapLayerComboBox;
class QgsProcessingPointCloudExpressionLineEdit;
class QgsProcessingRasterCalculatorExpressionLineEdit;
class QgsRubberBand;
class QgsHighlightableLineEdit;
///@cond PRIVATE
@ -2057,6 +2058,23 @@ class GUI_EXPORT QgsProcessingBandWidgetWrapper : public QgsAbstractProcessingPa
};
class GUI_EXPORT QgsProcessingMultipleLayerLineEdit: public QgsHighlightableLineEdit
{
Q_OBJECT
public:
QgsProcessingMultipleLayerLineEdit( QWidget *parent = nullptr, const QgsProcessingParameterMultipleLayers *param = nullptr );
void dragEnterEvent( QDragEnterEvent *event ) override;
void dragLeaveEvent( QDragLeaveEvent *event ) override;
void dropEvent( QDropEvent *event ) override;
signals:
void layersDropped( const QVariantList &value );
private:
const QgsProcessingParameterMultipleLayers *mParam = nullptr;
};
class GUI_EXPORT QgsProcessingMultipleLayerPanelWidget : public QWidget
{
@ -2085,7 +2103,7 @@ class GUI_EXPORT QgsProcessingMultipleLayerPanelWidget : public QWidget
void updateSummaryText();
const QgsProcessingParameterMultipleLayers *mParam = nullptr;
QLineEdit *mLineEdit = nullptr;
QgsProcessingMultipleLayerLineEdit *mLineEdit = nullptr;
QToolButton *mToolButton = nullptr;
QVariantList mValue;