1 /***************************************************************************
2 qgsprocessingparameterdxflayers.cpp
3 ---------------------
4 Date : September 2020
5 Copyright : (C) 2020 by Alexander Bruy
6 Email : alexander dot bruy at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
16 #include "qgsprocessingparameterdxflayers.h"
17 #include "qgsvectorlayer.h"
18
19
QgsProcessingParameterDxfLayers(const QString & name,const QString & description)20 QgsProcessingParameterDxfLayers::QgsProcessingParameterDxfLayers( const QString &name, const QString &description )
21 : QgsProcessingParameterDefinition( name, description, QVariant(), false )
22 {
23 }
24
clone() const25 QgsProcessingParameterDefinition *QgsProcessingParameterDxfLayers::clone() const
26 {
27 return new QgsProcessingParameterDxfLayers( *this );
28 }
29
type() const30 QString QgsProcessingParameterDxfLayers::type() const
31 {
32 return typeName();
33 }
34
checkValueIsAcceptable(const QVariant & input,QgsProcessingContext * context) const35 bool QgsProcessingParameterDxfLayers::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context ) const
36 {
37 if ( !input.isValid() )
38 return mFlags & FlagOptional;
39
40 if ( qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( input ) ) )
41 {
42 return true;
43 }
44
45 if ( input.type() == QVariant::String )
46 {
47 if ( input.toString().isEmpty() )
48 return mFlags & FlagOptional;
49
50 if ( !context )
51 return true;
52
53 QgsMapLayer *mapLayer = QgsProcessingUtils::mapLayerFromString( input.toString(), *context );
54 return mapLayer && ( mapLayer->type() == QgsMapLayerType::VectorLayer );
55 }
56 else if ( input.type() == QVariant::List )
57 {
58 if ( input.toList().isEmpty() )
59 return mFlags & FlagOptional;;
60
61 const QVariantList layerList = input.toList();
62 for ( const QVariant &variantLayer : layerList )
63 {
64 if ( qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( variantLayer ) ) )
65 continue;
66
67 if ( variantLayer.type() == QVariant::String )
68 {
69 if ( !context )
70 return true;
71
72 QgsMapLayer *mapLayer = QgsProcessingUtils::mapLayerFromString( variantLayer.toString(), *context );
73 if ( !mapLayer || mapLayer->type() != QgsMapLayerType::VectorLayer )
74 return false;
75 }
76 else if ( variantLayer.type() == QVariant::Map )
77 {
78 const QVariantMap layerMap = variantLayer.toMap();
79
80 if ( !layerMap.contains( QStringLiteral( "layer" ) ) && !layerMap.contains( QStringLiteral( "attributeIndex" ) ) )
81 return false;
82
83 if ( !context )
84 return true;
85
86 QgsMapLayer *mapLayer = QgsProcessingUtils::mapLayerFromString( layerMap.value( QStringLiteral( "layer" ) ).toString(), *context );
87 if ( !mapLayer || mapLayer->type() != QgsMapLayerType::VectorLayer )
88 return false;
89
90 QgsVectorLayer *vectorLayer = static_cast<QgsVectorLayer *>( mapLayer );
91
92 if ( !vectorLayer )
93 return false;
94
95 if ( layerMap.value( QStringLiteral( "attributeIndex" ) ).toInt() >= vectorLayer->fields().count() )
96 return false;
97 }
98 else
99 {
100 return false;
101 }
102 }
103 return true;
104 }
105 else if ( input.type() == QVariant::StringList )
106 {
107 const auto constToStringList = input.toStringList();
108 if ( constToStringList.isEmpty() )
109 return mFlags & FlagOptional;
110
111 if ( !context )
112 return true;
113
114 for ( const QString &v : constToStringList )
115 {
116 if ( !QgsProcessingUtils::mapLayerFromString( v, *context ) )
117 return false;
118 }
119 return true;
120 }
121
122 return false;
123 }
124
valueAsPythonString(const QVariant & value,QgsProcessingContext & context) const125 QString QgsProcessingParameterDxfLayers::valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const
126 {
127 QStringList parts;
128 const QList<QgsDxfExport::DxfLayer> layers = parameterAsLayers( value, context );
129 for ( const QgsDxfExport::DxfLayer &layer : layers )
130 {
131 QStringList layerDefParts;
132 layerDefParts << QStringLiteral( "'layer': " ) + QgsProcessingUtils::stringToPythonLiteral( QgsProcessingUtils::normalizeLayerSource( layer.layer()->source() ) );
133 if ( layer.layerOutputAttributeIndex() >= -1 )
134 layerDefParts << QStringLiteral( "'attributeIndex': " ) + QgsProcessingUtils::variantToPythonLiteral( layer.layerOutputAttributeIndex() );
135
136 const QString layerDef = QStringLiteral( "{%1}" ).arg( layerDefParts.join( ',' ) );
137 parts << layerDef;
138 }
139 return parts.join( ',' ).prepend( '[' ).append( ']' );
140 }
141
asPythonString(QgsProcessing::PythonOutputType outputType) const142 QString QgsProcessingParameterDxfLayers::asPythonString( QgsProcessing::PythonOutputType outputType ) const
143 {
144 switch ( outputType )
145 {
146 case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
147 {
148 QString code = QStringLiteral( "QgsProcessingParameterDxfLayers('%1', %2)" )
149 .arg( name(), QgsProcessingUtils::stringToPythonLiteral( description() ) );
150 return code;
151 }
152 }
153 return QString();
154 }
155
parameterAsLayers(const QVariant & layersVariant,QgsProcessingContext & context)156 QList<QgsDxfExport::DxfLayer> QgsProcessingParameterDxfLayers::parameterAsLayers( const QVariant &layersVariant, QgsProcessingContext &context )
157 {
158 QList<QgsDxfExport::DxfLayer> layers;
159
160 if ( QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( layersVariant ) ) )
161 {
162 layers << QgsDxfExport::DxfLayer( layer );
163 }
164
165 if ( layersVariant.type() == QVariant::String )
166 {
167 QgsMapLayer *mapLayer = QgsProcessingUtils::mapLayerFromString( layersVariant.toString(), context );
168 layers << QgsDxfExport::DxfLayer( static_cast<QgsVectorLayer *>( mapLayer ) );
169 }
170 else if ( layersVariant.type() == QVariant::List )
171 {
172 const QVariantList layersVariantList = layersVariant.toList();
173 for ( const QVariant &layerItem : layersVariantList )
174 {
175 if ( layerItem.type() == QVariant::Map )
176 {
177 const QVariantMap layerVariantMap = layerItem.toMap();
178 layers << variantMapAsLayer( layerVariantMap, context );
179 }
180 else if ( layerItem.type() == QVariant::String )
181 {
182 QgsMapLayer *mapLayer = QgsProcessingUtils::mapLayerFromString( layerItem.toString(), context );
183 layers << QgsDxfExport::DxfLayer( static_cast<QgsVectorLayer *>( mapLayer ) );
184 }
185 }
186 }
187 else if ( layersVariant.type() == QVariant::StringList )
188 {
189 const auto layersStringList = layersVariant.toStringList();
190 for ( const QString &layerItem : layersStringList )
191 {
192 QgsMapLayer *mapLayer = QgsProcessingUtils::mapLayerFromString( layerItem, context );
193 layers << QgsDxfExport::DxfLayer( static_cast<QgsVectorLayer *>( mapLayer ) );
194 }
195 }
196
197 return layers;
198 }
199
variantMapAsLayer(const QVariantMap & layerVariantMap,QgsProcessingContext & context)200 QgsDxfExport::DxfLayer QgsProcessingParameterDxfLayers::variantMapAsLayer( const QVariantMap &layerVariantMap, QgsProcessingContext &context )
201 {
202 const QVariant layerVariant = layerVariantMap[ QStringLiteral( "layer" ) ];
203
204 QgsVectorLayer *inputLayer = nullptr;
205 if ( ( inputLayer = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( layerVariant ) ) ) )
206 {
207 // good
208 }
209 else if ( ( inputLayer = qobject_cast< QgsVectorLayer * >( QgsProcessingUtils::mapLayerFromString( layerVariant.toString(), context ) ) ) )
210 {
211 // good
212 }
213 else
214 {
215 // bad
216 }
217
218 QgsDxfExport::DxfLayer dxfLayer( inputLayer, layerVariantMap[ QStringLiteral( "attributeIndex" ) ].toInt() );
219 return dxfLayer;
220 }
221
layerAsVariantMap(const QgsDxfExport::DxfLayer & layer)222 QVariantMap QgsProcessingParameterDxfLayers::layerAsVariantMap( const QgsDxfExport::DxfLayer &layer )
223 {
224 QVariantMap vm;
225 if ( !layer.layer() )
226 return vm;
227
228 vm[ QStringLiteral( "layer" )] = layer.layer()->id();
229 vm[ QStringLiteral( "attributeIndex" ) ] = layer.layerOutputAttributeIndex();
230 return vm;
231 }
232