mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-25 00:58:06 -05:00
[processing] Refine behavior of "Use filename as layer name" option to
always avoid using temporary file names, and then set this option as enabled by default. Also change the setting key so that existing users will also get the new default value. Fixes #32591
This commit is contained in:
parent
8edfcf1d02
commit
6b82917715
@ -160,6 +160,13 @@ Ownership of ``processor`` is transferred.
|
||||
.. seealso:: :py:func:`postProcessor`
|
||||
|
||||
.. versionadded:: 3.2
|
||||
%End
|
||||
|
||||
void setOutputLayerName( QgsMapLayer *layer ) const;
|
||||
%Docstring
|
||||
Sets a ``layer`` name to match this output, respecting any local user settings which affect this name.
|
||||
|
||||
.. versionadded:: 3.10.1
|
||||
%End
|
||||
|
||||
QgsProject *project;
|
||||
|
@ -49,7 +49,7 @@ class ProcessingConfig:
|
||||
VECTOR_LINE_STYLE = 'VECTOR_LINE_STYLE'
|
||||
VECTOR_POLYGON_STYLE = 'VECTOR_POLYGON_STYLE'
|
||||
FILTER_INVALID_GEOMETRIES = 'FILTER_INVALID_GEOMETRIES'
|
||||
USE_FILENAME_AS_LAYER_NAME = 'USE_FILENAME_AS_LAYER_NAME'
|
||||
PREFER_FILENAME_AS_LAYER_NAME = 'PREFER_FILENAME_AS_LAYER_NAME'
|
||||
KEEP_DIALOG_OPEN = 'KEEP_DIALOG_OPEN'
|
||||
PRE_EXECUTION_SCRIPT = 'PRE_EXECUTION_SCRIPT'
|
||||
POST_EXECUTION_SCRIPT = 'POST_EXECUTION_SCRIPT'
|
||||
@ -74,8 +74,8 @@ class ProcessingConfig:
|
||||
ProcessingConfig.tr('Keep dialog open after running an algorithm'), True))
|
||||
ProcessingConfig.addSetting(Setting(
|
||||
ProcessingConfig.tr('General'),
|
||||
ProcessingConfig.USE_FILENAME_AS_LAYER_NAME,
|
||||
ProcessingConfig.tr('Use filename as layer name'), False))
|
||||
ProcessingConfig.PREFER_FILENAME_AS_LAYER_NAME,
|
||||
ProcessingConfig.tr('Prefer output filename for layer names'), True))
|
||||
ProcessingConfig.addSetting(Setting(
|
||||
ProcessingConfig.tr('General'),
|
||||
ProcessingConfig.SHOW_PROVIDERS_TOOLTIP,
|
||||
|
@ -17,7 +17,6 @@
|
||||
***************************************************************************
|
||||
"""
|
||||
|
||||
|
||||
__author__ = 'Victor Olaya'
|
||||
__date__ = 'August 2012'
|
||||
__copyright__ = '(C) 2012, Victor Olaya'
|
||||
@ -41,30 +40,6 @@ from processing.core.ProcessingConfig import ProcessingConfig
|
||||
from processing.gui.RenderingStyles import RenderingStyles
|
||||
|
||||
|
||||
def set_layer_name(layer, context_layer_details):
|
||||
"""
|
||||
Sets the name for the given layer, either using the layer's file name
|
||||
(or database layer name), or the name specified by the parameter definition.
|
||||
"""
|
||||
use_filename_as_layer_name = ProcessingConfig.getSetting(ProcessingConfig.USE_FILENAME_AS_LAYER_NAME)
|
||||
|
||||
if use_filename_as_layer_name or not context_layer_details.name:
|
||||
source_parts = QgsProviderRegistry.instance().decodeUri(layer.dataProvider().name(), layer.source())
|
||||
layer_name = source_parts.get('layerName', '')
|
||||
# if source layer name exists, use that -- else use
|
||||
if layer_name:
|
||||
layer.setName(layer_name)
|
||||
else:
|
||||
path = source_parts.get('path', '')
|
||||
if path:
|
||||
layer.setName(os.path.splitext(os.path.basename(path))[0])
|
||||
elif context_layer_details.name:
|
||||
# fallback to parameter's name -- shouldn't happen!
|
||||
layer.setName(context_layer_details.name)
|
||||
else:
|
||||
layer.setName(context_layer_details.name)
|
||||
|
||||
|
||||
def handleAlgorithmResults(alg, context, feedback=None, showResults=True, parameters={}):
|
||||
wrongLayers = []
|
||||
if feedback is None:
|
||||
@ -82,7 +57,7 @@ def handleAlgorithmResults(alg, context, feedback=None, showResults=True, parame
|
||||
try:
|
||||
layer = QgsProcessingUtils.mapLayerFromString(l, context, typeHint=details.layerTypeHint)
|
||||
if layer is not None:
|
||||
set_layer_name(layer, details)
|
||||
details.setOutputLayerName(layer)
|
||||
|
||||
'''If running a model, the execution will arrive here when an algorithm that is part of
|
||||
that model is executed. We check if its output is a final otuput of the model, and
|
||||
@ -126,7 +101,9 @@ def handleAlgorithmResults(alg, context, feedback=None, showResults=True, parame
|
||||
else:
|
||||
wrongLayers.append(str(l))
|
||||
except Exception:
|
||||
QgsMessageLog.logMessage(QCoreApplication.translate('Postprocessing', "Error loading result layer:") + "\n" + traceback.format_exc(), 'Processing', Qgis.Critical)
|
||||
QgsMessageLog.logMessage(QCoreApplication.translate('Postprocessing',
|
||||
"Error loading result layer:") + "\n" + traceback.format_exc(),
|
||||
'Processing', Qgis.Critical)
|
||||
wrongLayers.append(str(l))
|
||||
i += 1
|
||||
|
||||
@ -135,7 +112,8 @@ def handleAlgorithmResults(alg, context, feedback=None, showResults=True, parame
|
||||
if wrongLayers:
|
||||
msg = QCoreApplication.translate('Postprocessing', "The following layers were not correctly generated.")
|
||||
msg += "<ul>" + "".join(["<li>%s</li>" % lay for lay in wrongLayers]) + "</ul>"
|
||||
msg += QCoreApplication.translate('Postprocessing', "You can check the 'Log Messages Panel' in QGIS main window to find more information about the execution of the algorithm.")
|
||||
msg += QCoreApplication.translate('Postprocessing',
|
||||
"You can check the 'Log Messages Panel' in QGIS main window to find more information about the execution of the algorithm.")
|
||||
feedback.reportError(msg)
|
||||
|
||||
return len(wrongLayers) == 0
|
||||
|
@ -17,6 +17,8 @@
|
||||
|
||||
#include "qgsprocessingcontext.h"
|
||||
#include "qgsprocessingutils.h"
|
||||
#include "qgsproviderregistry.h"
|
||||
#include "qgssettings.h"
|
||||
|
||||
QgsProcessingContext::QgsProcessingContext()
|
||||
: mPreferredVectorFormat( QgsProcessingUtils::defaultVectorExtension() )
|
||||
@ -119,3 +121,39 @@ void QgsProcessingContext::LayerDetails::setPostProcessor( QgsProcessingLayerPos
|
||||
|
||||
mPostProcessor = processor;
|
||||
}
|
||||
|
||||
void QgsProcessingContext::LayerDetails::setOutputLayerName( QgsMapLayer *layer ) const
|
||||
{
|
||||
if ( !layer )
|
||||
return;
|
||||
|
||||
const bool preferFilenameAsLayerName = QgsSettings().value( QStringLiteral( "Processing/Configuration/PREFER_FILENAME_AS_LAYER_NAME" ), true ).toBool();
|
||||
|
||||
// note - for temporary layers, we don't use the filename, regardless of user setting (it will be meaningless!)
|
||||
if ( ( preferFilenameAsLayerName && !layer->isTemporary() ) || name.isEmpty() )
|
||||
{
|
||||
const QVariantMap sourceParts = QgsProviderRegistry::instance()->decodeUri( layer->providerType(), layer->source() );
|
||||
const QString layerName = sourceParts.value( QStringLiteral( "layerName" ) ).toString();
|
||||
// if output layer name exists, use that!
|
||||
if ( !layerName.isEmpty() )
|
||||
layer->setName( layerName );
|
||||
else
|
||||
{
|
||||
const QString path = sourceParts.value( QStringLiteral( "path" ) ).toString();
|
||||
if ( !path.isEmpty() )
|
||||
{
|
||||
const QFileInfo fi( path );
|
||||
layer->setName( fi.baseName() );
|
||||
}
|
||||
else if ( !name.isEmpty() )
|
||||
{
|
||||
// fallback to parameter's name -- shouldn't happen!
|
||||
layer->setName( name );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
layer->setName( name );
|
||||
}
|
||||
}
|
||||
|
@ -172,10 +172,17 @@ class CORE_EXPORT QgsProcessingContext
|
||||
//! Default constructor
|
||||
LayerDetails() = default;
|
||||
|
||||
//! Friendly name for layer, to use when loading layer into project.
|
||||
/**
|
||||
* Friendly name for layer, possibly for use when loading layer into project.
|
||||
*
|
||||
* \warning Instead of directly using this value, prefer to call setOutputLayerName() to
|
||||
* generate a layer name which respects the user's local Processing settings.
|
||||
*/
|
||||
QString name;
|
||||
|
||||
//! Associated output name from algorithm which generated the layer.
|
||||
/**
|
||||
* Associated output name from algorithm which generated the layer.
|
||||
*/
|
||||
QString outputName;
|
||||
|
||||
/**
|
||||
@ -202,6 +209,13 @@ class CORE_EXPORT QgsProcessingContext
|
||||
*/
|
||||
void setPostProcessor( QgsProcessingLayerPostProcessorInterface *processor SIP_TRANSFER );
|
||||
|
||||
/**
|
||||
* Sets a \a layer name to match this output, respecting any local user settings which affect this name.
|
||||
*
|
||||
* \since QGIS 3.10.1
|
||||
*/
|
||||
void setOutputLayerName( QgsMapLayer *layer ) const;
|
||||
|
||||
//! Destination project
|
||||
QgsProject *project = nullptr;
|
||||
|
||||
|
@ -1938,6 +1938,27 @@ void TestQgsProcessing::parameters()
|
||||
QCOMPARE( context2.layersToLoadOnCompletion().keys().at( 0 ), destId );
|
||||
QCOMPARE( context2.layersToLoadOnCompletion().values().at( 0 ).name, QStringLiteral( "my_dest" ) );
|
||||
QCOMPARE( context2.layersToLoadOnCompletion().values().at( 0 ).outputName, QStringLiteral( "fs" ) );
|
||||
|
||||
// setting layer name to match...
|
||||
context2.layersToLoadOnCompletion().values().at( 0 ).setOutputLayerName( nullptr );
|
||||
std::unique_ptr< QgsVectorLayer > vl = qgis::make_unique< QgsVectorLayer >( QStringLiteral( "Point" ), QString(), QStringLiteral( "memory" ) );
|
||||
QVERIFY( vl->isValid() );
|
||||
context2.layersToLoadOnCompletion().values().at( 0 ).setOutputLayerName( vl.get() );
|
||||
// temporary layer, must use output name as layer name
|
||||
QCOMPARE( vl->name(), QStringLiteral( "my_dest" ) );
|
||||
// otherwise expect to use path
|
||||
std::unique_ptr< QgsRasterLayer > rl = qgis::make_unique< QgsRasterLayer >( QStringLiteral( TEST_DATA_DIR ) + "/landsat.tif", QString() );
|
||||
context2.layersToLoadOnCompletion().values().at( 0 ).setOutputLayerName( rl.get() );
|
||||
QCOMPARE( rl->name(), QStringLiteral( "landsat" ) );
|
||||
// unless setting prohibits it...
|
||||
QgsSettings().setValue( QStringLiteral( "Processing/Configuration/PREFER_FILENAME_AS_LAYER_NAME" ), false );
|
||||
context2.layersToLoadOnCompletion().values().at( 0 ).setOutputLayerName( rl.get() );
|
||||
QCOMPARE( rl->name(), QStringLiteral( "my_dest" ) );
|
||||
// if layer has a layername, we should use that instead of the base file name...
|
||||
QgsSettings().setValue( QStringLiteral( "Processing/Configuration/PREFER_FILENAME_AS_LAYER_NAME" ), true );
|
||||
vl = qgis::make_unique< QgsVectorLayer >( QStringLiteral( TEST_DATA_DIR ) + "/points_gpkg.gpkg|layername=points_small", QString() );
|
||||
context2.layersToLoadOnCompletion().values().at( 0 ).setOutputLayerName( vl.get() );
|
||||
QCOMPARE( vl->name(), QStringLiteral( "points_small" ) );
|
||||
}
|
||||
|
||||
void TestQgsProcessing::algorithmParameters()
|
||||
|
Loading…
x
Reference in New Issue
Block a user