Add UI to select which insertion method should be used when adding new layers

This commit is contained in:
Mathieu Pellerin 2022-09-27 17:04:26 +07:00
parent 9b0dda7733
commit a17ab8f03b
11 changed files with 237 additions and 244 deletions

View File

@ -2045,6 +2045,7 @@ Qgis.CoordinateDisplayType.__doc__ = 'Formats for displaying coordinates\n\n.. v
# --
Qgis.CoordinateDisplayType.baseClass = Qgis
# monkey patching scoped based enum
<<<<<<< HEAD
Qgis.ScriptLanguage.Css.__doc__ = "CSS"
Qgis.ScriptLanguage.QgisExpression.__doc__ = "QGIS expressions"
Qgis.ScriptLanguage.Html.__doc__ = "HTML"
@ -2057,3 +2058,11 @@ Qgis.ScriptLanguage.Unknown.__doc__ = "Unknown/other language"
Qgis.ScriptLanguage.__doc__ = 'Scripting languages.\n\n.. versionadded:: 3.30\n\n' + '* ``Css``: ' + Qgis.ScriptLanguage.Css.__doc__ + '\n' + '* ``QgisExpression``: ' + Qgis.ScriptLanguage.QgisExpression.__doc__ + '\n' + '* ``Html``: ' + Qgis.ScriptLanguage.Html.__doc__ + '\n' + '* ``JavaScript``: ' + Qgis.ScriptLanguage.JavaScript.__doc__ + '\n' + '* ``Json``: ' + Qgis.ScriptLanguage.Json.__doc__ + '\n' + '* ``Python``: ' + Qgis.ScriptLanguage.Python.__doc__ + '\n' + '* ``R``: ' + Qgis.ScriptLanguage.R.__doc__ + '\n' + '* ``Sql``: ' + Qgis.ScriptLanguage.Sql.__doc__ + '\n' + '* ``Unknown``: ' + Qgis.ScriptLanguage.Unknown.__doc__
# --
Qgis.ScriptLanguage.baseClass = Qgis
=======
Qgis.LayerTreeInsertionMethod.AboveInsertionPoint.__doc__ = "Layers are added in the tree above the insertion point"
Qgis.LayerTreeInsertionMethod.TopOfTree.__doc__ = "Layers are added at the top of the layer tree"
Qgis.LayerTreeInsertionMethod.OptimalInInsertionGroup.__doc__ = "Layers are added at optimal locations across the insertion point's group"
Qgis.LayerTreeInsertionMethod.__doc__ = 'Layer tree insertion methods\n\n.. versionadded:: 3.30\n\n' + '* ``AboveInsertionPoint``: ' + Qgis.LayerTreeInsertionMethod.AboveInsertionPoint.__doc__ + '\n' + '* ``TopOfTree``: ' + Qgis.LayerTreeInsertionMethod.TopOfTree.__doc__ + '\n' + '* ``OptimalInInsertionGroup``: ' + Qgis.LayerTreeInsertionMethod.OptimalInInsertionGroup.__doc__
# --
Qgis.LayerTreeInsertionMethod.baseClass = Qgis
>>>>>>> 4a95e2b0a8 (Add UI to select which insertion method should be used when adding new layers)

View File

@ -67,6 +67,20 @@ Set where the new layers should be inserted - can be used to follow current sele
By default it is root group with zero index.
.. versionadded:: 3.10
%End
void setLayerInsertionMethod( Qgis::LayerTreeInsertionMethod method );
%Docstring
Sets the insertion ``method`` used to add layers to the tree
.. versionadded:: 3.30
%End
Qgis::LayerTreeInsertionMethod layerInsertionMethod() const;
%Docstring
Returns the insertion method used to add layers to the tree
.. versionadded:: 3.30
%End
signals:

View File

@ -1327,6 +1327,7 @@ The development version
CustomCrs,
};
<<<<<<< HEAD
enum class ScriptLanguage
{
Css,
@ -1338,6 +1339,13 @@ The development version
R,
Sql,
Unknown,
=======
enum class LayerTreeInsertionMethod
{
AboveInsertionPoint,
TopOfTree,
OptimalInInsertionGroup,
>>>>>>> 4a95e2b0a8 (Add UI to select which insertion method should be used when adding new layers)
};
static const double DEFAULT_SEARCH_RADIUS_MM;

View File

@ -214,7 +214,18 @@ void QgsAppLayerHandling::addSortedLayersToLegend( QList<QgsMapLayer *> &layers
for ( QgsMapLayer *layer : layers )
{
parent->insertLayer( currentIndex, layer );
switch ( QgsProject::instance()->layerTreeRegistryBridge()->layerInsertionMethod() )
{
case Qgis::LayerTreeInsertionMethod::AboveInsertionPoint:
parent->insertLayer( currentIndex, layer );
break;
case Qgis::LayerTreeInsertionMethod::TopOfTree:
QgsProject::instance()->layerTreeRoot()->insertLayer( 0, layer );
break;
case Qgis::LayerTreeInsertionMethod::OptimalInInsertionGroup:
QgsLayerTreeUtils::insertLayerAtOptimalPlacement( parent, layer );
break;
}
}
QgisApp::instance()->layerTreeView()->setCurrentLayer( layers.at( 0 ) );
}

View File

@ -711,6 +711,11 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl, const QList<QgsOpti
cmbLegendDoubleClickAction->setCurrentIndex( mSettings->value( QStringLiteral( "/qgis/legendDoubleClickAction" ), 0 ).toInt() );
mLayerTreeInsertionMethod->addItem( tr( "Above currently currently selected layer" ), QVariant::fromValue( Qgis::LayerTreeInsertionMethod::AboveInsertionPoint ) );
mLayerTreeInsertionMethod->addItem( tr( "Always on top of the layer tree" ), QVariant::fromValue( Qgis::LayerTreeInsertionMethod::TopOfTree ) );
mLayerTreeInsertionMethod->addItem( tr( "Optimal index within current layer tree group" ), QVariant::fromValue( Qgis::LayerTreeInsertionMethod::OptimalInInsertionGroup ) );
mLayerTreeInsertionMethod->setCurrentIndex( mLayerTreeInsertionMethod->findData( QVariant::fromValue( mSettings->enumValue( QStringLiteral( "/qgis/layerTreeInsertionMethod" ), Qgis::LayerTreeInsertionMethod::AboveInsertionPoint ) ) ) );
// Legend symbol minimum / maximum values
mLegendSymbolMinimumSizeSpinBox->setClearValue( 0.0, tr( "none" ) );
mLegendSymbolMaximumSizeSpinBox->setClearValue( 0.0, tr( "none" ) );
@ -1586,6 +1591,7 @@ void QgsOptions::saveOptions()
QgisApp::instance()->setMapTipsDelay( mMapTipsDelaySpinBox->value() );
mSettings->setValue( QStringLiteral( "/qgis/legendDoubleClickAction" ), cmbLegendDoubleClickAction->currentIndex() );
mSettings->setEnumValue( QStringLiteral( "/qgis/layerTreeInsertionMethod" ), mLayerTreeInsertionMethod->currentData().value<Qgis::LayerTreeInsertionMethod>() );
// project
mSettings->setValue( QStringLiteral( "/qgis/projOpenAtLaunch" ), mProjectOnLaunchCmbBx->currentIndex() );

View File

@ -5577,6 +5577,7 @@ bool QgisApp::fileNew( bool promptToSaveFlag, bool forceBlank )
QgsProject *prj = QgsProject::instance();
prj->layerTreeRegistryBridge()->setNewLayersVisible( settings.value( QStringLiteral( "qgis/new_layers_visible" ), true ).toBool() );
prj->layerTreeRegistryBridge()->setLayerInsertionMethod( settings.enumValue( QStringLiteral( "qgis/layerTreeInsertionMethod" ), Qgis::LayerTreeInsertionMethod::AboveInsertionPoint ) );
//set the canvas to the default project background color
mOverviewCanvas->setBackgroundColor( prj->backgroundColor() );
@ -12333,6 +12334,7 @@ void QgisApp::showOptionsDialog( QWidget *parent, const QString &currentPage, in
if ( optionsDialog->exec() )
{
QgsProject::instance()->layerTreeRegistryBridge()->setNewLayersVisible( mySettings.value( QStringLiteral( "qgis/new_layers_visible" ), true ).toBool() );
QgsProject::instance()->layerTreeRegistryBridge()->setLayerInsertionMethod( mySettings.enumValue( QStringLiteral( "qgis/layerTreeInsertionMethod" ), Qgis::LayerTreeInsertionMethod::AboveInsertionPoint ) );
setupLayerTreeViewFromSettings();

View File

@ -16,7 +16,7 @@
#include "qgslayertreeregistrybridge.h"
#include "qgslayertree.h"
#include "qgslayertreeutils.h"
#include "qgsproject.h"
#include "qgslogger.h"
@ -55,7 +55,16 @@ void QgsLayerTreeRegistryBridge::layersAdded( const QList<QgsMapLayer *> &layers
QList<QgsLayerTreeNode *> nodes;
for ( QgsMapLayer *layer : layers )
{
QgsLayerTreeLayer *nodeLayer = new QgsLayerTreeLayer( layer );
QgsLayerTreeLayer *nodeLayer;
if ( mInsertionMethod == Qgis::LayerTreeInsertionMethod::OptimalInInsertionGroup )
{
nodeLayer = QgsLayerTreeUtils::insertLayerAtOptimalPlacement( mInsertionPoint.group, layer );
}
else
{
nodeLayer = new QgsLayerTreeLayer( layer );
}
nodeLayer->setItemVisibilityChecked( mNewLayersVisible );
nodes << nodeLayer;
@ -69,8 +78,18 @@ void QgsLayerTreeRegistryBridge::layersAdded( const QList<QgsMapLayer *> &layers
}
}
// add new layers to the right place
mInsertionPoint.group->insertChildNodes( mInsertionPoint.position, nodes );
switch ( mInsertionMethod )
{
case Qgis::LayerTreeInsertionMethod::AboveInsertionPoint:
mInsertionPoint.group->insertChildNodes( mInsertionPoint.position, nodes );
break;
case Qgis::LayerTreeInsertionMethod::TopOfTree:
mRoot->insertChildNodes( 0, nodes );
break;
case Qgis::LayerTreeInsertionMethod::OptimalInInsertionGroup:
default:
break;
}
// tell other components that layers have been added - this signal is used in QGIS to auto-select the first layer
emit addedLayersToLayerTree( layers );

View File

@ -21,6 +21,7 @@
#include "qgis_core.h"
#include "qgis_sip.h"
#include "qgis.h"
class QgsLayerTreeGroup;
class QgsLayerTreeNode;
@ -84,6 +85,18 @@ class CORE_EXPORT QgsLayerTreeRegistryBridge : public QObject
*/
void setLayerInsertionPoint( const InsertionPoint &insertionPoint );
/**
* Sets the insertion \a method used to add layers to the tree
* \since QGIS 3.30
*/
void setLayerInsertionMethod( Qgis::LayerTreeInsertionMethod method ) { mInsertionMethod = method; }
/**
* Returns the insertion method used to add layers to the tree
* \since QGIS 3.30
*/
Qgis::LayerTreeInsertionMethod layerInsertionMethod() const { return mInsertionMethod; }
signals:
/**
@ -110,6 +123,7 @@ class CORE_EXPORT QgsLayerTreeRegistryBridge : public QObject
bool mNewLayersVisible;
InsertionPoint mInsertionPoint;
Qgis::LayerTreeInsertionMethod mInsertionMethod = Qgis::LayerTreeInsertionMethod::AboveInsertionPoint;
};
#endif // QGSLAYERTREEREGISTRYBRIDGE_H

View File

@ -623,26 +623,14 @@ QgsLayerTreeLayer *QgsLayerTreeUtils::insertLayerAtOptimalPlacement( QgsLayerTre
if ( vlayer->geometryType() == QgsWkbTypes::PointGeometry )
{
index = 0;
vectorLineIndex++;
vectorPolygonIndex++;
pointCloudIndex++;
meshIndex++;
rasterIndex++;
}
else if ( vlayer->geometryType() == QgsWkbTypes::LineGeometry )
{
index = vectorLineIndex;
vectorPolygonIndex++;
pointCloudIndex++;
meshIndex++;
rasterIndex++;
}
else if ( vlayer->geometryType() == QgsWkbTypes::PolygonGeometry )
{
index = vectorPolygonIndex;
pointCloudIndex++;
meshIndex++;
rasterIndex++;
}
break;
}
@ -650,15 +638,12 @@ QgsLayerTreeLayer *QgsLayerTreeUtils::insertLayerAtOptimalPlacement( QgsLayerTre
case QgsMapLayerType::PointCloudLayer:
{
index = pointCloudIndex;
meshIndex++;
rasterIndex++;
break;
}
case QgsMapLayerType::MeshLayer:
{
index = meshIndex;
rasterIndex++;
break;
}

View File

@ -2304,6 +2304,19 @@ class CORE_EXPORT Qgis
};
Q_ENUM( ScriptLanguage )
/**
* Layer tree insertion methods
*
* \since QGIS 3.30
*/
enum class LayerTreeInsertionMethod : int
{
AboveInsertionPoint, //!< Layers are added in the tree above the insertion point
TopOfTree, //!< Layers are added at the top of the layer tree
OptimalInInsertionGroup, //!< Layers are added at optimal locations across the insertion point's group
};
Q_ENUM( LayerTreeInsertionMethod )
/**
* Identify search radius in mm
* \since QGIS 2.3

View File

@ -2552,225 +2552,159 @@
<property name="title">
<string>Layer Legend</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_21">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item>
<widget class="QLabel" name="label_15">
<property name="text">
<string>Double-click action in legend</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QComboBox" name="cmbLegendDoubleClickAction">
<item>
<property name="text">
<string>Open layer properties</string>
</property>
</item>
<item>
<property name="text">
<string>Open attribute table</string>
</property>
</item>
<item>
<property name="text">
<string>Open layer styling dock</string>
</property>
</item>
</widget>
</item>
</layout>
<layout class="QGridLayout" name="gridLayout_35">
<item row="0" column="0">
<widget class="QLabel" name="label_15">
<property name="text">
<string>Double-click action in legend</string>
</property>
</widget>
</item>
<item>
<item row="0" column="1">
<widget class="QComboBox" name="cmbLegendDoubleClickAction">
<item>
<property name="text">
<string>Open layer properties</string>
</property>
</item>
<item>
<property name="text">
<string>Open attribute table</string>
</property>
</item>
<item>
<property name="text">
<string>Open layer styling dock</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="mLayerTreeInsertionMethodLabel">
<property name="text">
<string>Behavior used when adding new layers</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="mLayerTreeInsertionMethod">
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QCheckBox" name="mShowFeatureCountByDefaultCheckBox">
<property name="text">
<string>Show feature count for newly added layers</string>
</property>
</widget>
</item>
<item>
<item row="3" column="0" colspan="2">
<widget class="QCheckBox" name="cbxLegendClassifiers">
<property name="text">
<string>Display classification attribute in layer titles</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_34">
<item>
<widget class="QLabel" name="label_58">
<property name="text">
<string>WMS getLegendGraphic resolution</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_48">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>30</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QgsSpinBox" name="mLegendGraphicResolutionSpinBox">
<property name="toolTip">
<item row="4" column="0">
<widget class="QLabel" name="label_58">
<property name="text">
<string>WMS getLegendGraphic resolution</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QgsSpinBox" name="mLegendGraphicResolutionSpinBox">
<property name="toolTip">
<string extracomment="MAP_RESOLUTION or DPI value overloading getMap default value (set 0 to use default)"/>
</property>
<property name="whatsThis">
</property>
<property name="whatsThis">
<string extracomment="MAP_RESOLUTION or DPI value overloading getMap default value (set 0 to use default)"/>
</property>
<property name="suffix">
</property>
<property name="suffix">
<string> dpi</string>
</property>
<property name="minimum">
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
</property>
<property name="maximum">
<number>1000000</number>
</property>
</widget>
</item>
</layout>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_41">
<item>
<widget class="QLabel" name="labelLegendSymbolMinimumSize">
<property name="text">
<string>Minimum legend symbol size</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_49">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>30</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QgsDoubleSpinBox" name="mLegendSymbolMinimumSizeSpinBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string extracomment="(set value to 0 to skip minimum size)"/>
</property>
<property name="suffix">
<string> mm</string>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="maximum">
<double>999.000000000000000</double>
</property>
<property name="singleStep">
<double>0.200000000000000</double>
</property>
<property name="value">
<double>0.100000000000000</double>
</property>
<property name="showClearButton" stdset="0">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
<item row="5" column="0">
<widget class="QLabel" name="labelLegendSymbolMinimumSize">
<property name="text">
<string>Minimum legend symbol size</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_43">
<item>
<widget class="QLabel" name="labelLegendSymbolMaximumSize">
<property name="text">
<string>Maximum legend symbol size</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_50">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>30</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QgsDoubleSpinBox" name="mLegendSymbolMaximumSizeSpinBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string extracomment="(set value to 0 to skip maximum size)"/>
</property>
<property name="suffix">
<string> mm</string>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="maximum">
<double>999.000000000000000</double>
</property>
<property name="singleStep">
<double>0.200000000000000</double>
</property>
<property name="value">
<double>20.000000000000000</double>
</property>
<property name="showClearButton" stdset="0">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
<item row="5" column="1">
<widget class="QgsDoubleSpinBox" name="mLegendSymbolMinimumSizeSpinBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string extracomment="(set value to 0 to skip minimum size)"/>
</property>
<property name="suffix">
<string> mm</string>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="maximum">
<double>999.000000000000000</double>
</property>
<property name="singleStep">
<double>0.200000000000000</double>
</property>
<property name="value">
<double>0.100000000000000</double>
</property>
<property name="showClearButton" stdset="0">
<bool>true</bool>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="labelLegendSymbolMaximumSize">
<property name="text">
<string>Maximum legend symbol size</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QgsDoubleSpinBox" name="mLegendSymbolMaximumSizeSpinBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string extracomment="(set value to 0 to skip maximum size)"/>
</property>
<property name="suffix">
<string> mm</string>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="maximum">
<double>999.000000000000000</double>
</property>
<property name="singleStep">
<double>0.200000000000000</double>
</property>
<property name="value">
<double>20.000000000000000</double>
</property>
<property name="showClearButton" stdset="0">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
@ -2780,37 +2714,15 @@
<property name="title">
<string>Map Tips</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_42">
<item>
<layout class="QGridLayout" name="gridLayout_40">
<item row="0" column="0">
<widget class="QLabel" name="textLabel1_16">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Delay (in milliseconds)</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_39">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>30</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<item row="0" column="1">
<widget class="QgsSpinBox" name="mMapTipsDelaySpinBox">
<property name="toolTip">
<string extracomment="MAP_RESOLUTION or DPI value overloading getMap default value (set 0 to use default)"/>