[gui] Introduce StackedDiagramProperties and use it as dialog and as vector properties page. For the moment, it works with single diagrams, hiding controls for stacked diagrams

This commit is contained in:
Germán Carrillo 2024-08-23 14:09:51 -05:00
parent 6c60810d44
commit 614ce76156
20 changed files with 445 additions and 17 deletions

View File

@ -64,6 +64,8 @@ QgsDiagramLayerSettings.Property.__doc__ = """Data definable properties.
"""
# --
QgsDiagramLayerSettings.Single = QgsDiagramLayerSettings.DiagramType.Single
QgsDiagramLayerSettings.Stacked = QgsDiagramLayerSettings.DiagramType.Stacked
QgsDiagramSettings.Height = QgsDiagramSettings.LabelPlacementMethod.Height
QgsDiagramSettings.XHeight = QgsDiagramSettings.LabelPlacementMethod.XHeight
QgsDiagramSettings.Up = QgsDiagramSettings.DiagramOrientation.Up

View File

@ -0,0 +1,9 @@
# The following has been generated automatically from src/core/diagram/qgsstackeddiagram.h
try:
QgsStackedDiagram.__group__ = ['diagram']
except NameError:
pass
try:
QgsStackedDiagram.DiagramData.__group__ = ['diagram']
except NameError:
pass

View File

@ -3,7 +3,7 @@
* *
* src/core/diagram/qgsstackeddiagram.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
* Do not edit manually ! Edit header and run scripts/sipify.py again *
************************************************************************/
@ -88,5 +88,5 @@ Calculates the position for the next subdiagram, updating the ``newPos`` object.
* *
* src/core/diagram/qgsstackeddiagram.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
* Do not edit manually ! Edit header and run scripts/sipify.py again *
************************************************************************/

View File

@ -63,6 +63,12 @@ Stores the settings for rendering of all diagrams for a layer.
StartAngle,
};
enum DiagramType /BaseType=IntEnum/
{
Single,
Stacked
};
static const QgsPropertiesDefinition &propertyDefinitions();
%Docstring
Returns the diagram property definitions.

View File

@ -0,0 +1,9 @@
# The following has been generated automatically from src/core/diagram/qgsstackeddiagram.h
try:
QgsStackedDiagram.__group__ = ['diagram']
except NameError:
pass
try:
QgsStackedDiagram.DiagramData.__group__ = ['diagram']
except NameError:
pass

View File

@ -3,7 +3,7 @@
* *
* src/core/diagram/qgsstackeddiagram.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
* Do not edit manually ! Edit header and run scripts/sipify.py again *
************************************************************************/
@ -88,5 +88,5 @@ Calculates the position for the next subdiagram, updating the ``newPos`` object.
* *
* src/core/diagram/qgsstackeddiagram.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
* Do not edit manually ! Edit header and run scripts/sipify.py again *
************************************************************************/

View File

@ -63,6 +63,12 @@ Stores the settings for rendering of all diagrams for a layer.
StartAngle,
};
enum DiagramType
{
Single,
Stacked
};
static const QgsPropertiesDefinition &propertyDefinitions();
%Docstring
Returns the diagram property definitions.

View File

@ -182,6 +182,7 @@ my @ALLOWED_NON_CLASS_ENUMS = (
"QgsDataSourceUri::SslMode",
"QgsDiagramLayerSettings::LinePlacementFlag",
"QgsDiagramLayerSettings::Placement",
"QgsDiagramLayerSettings::DiagramType",
"QgsDiagramSettings::DiagramOrientation",
"QgsDiagramSettings::Direction",
"QgsDiagramSettings::LabelPlacementMethod",

View File

@ -230,9 +230,11 @@ ALLOWED_NON_CLASS_ENUMS = [
"QgsDataSourceUri::SslMode",
"QgsDiagramLayerSettings::LinePlacementFlag",
"QgsDiagramLayerSettings::Placement",
"QgsDiagramLayerSettings::DiagramType",
"QgsDiagramSettings::DiagramOrientation",
"QgsDiagramSettings::Direction",
"QgsDiagramSettings::LabelPlacementMethod",
"QgsDiagramSettings::StackedDiagramMode",
"QgsDoubleSpinBox::ClearValueMode",
"QgsDualView::FeatureListBrowsingAction",
"QgsDualView::ViewMode",

View File

@ -269,7 +269,6 @@
#include "qgsgpstoolbar.h"
#include "qgsgpscanvasbridge.h"
#include "qgsguivectorlayertools.h"
#include "qgsdiagramproperties.h"
#include "qgslayerdefinition.h"
#include "qgslayertree.h"
#include "qgslayertreefiltersettings.h"
@ -384,6 +383,7 @@
#include "qgselevationshadingrenderersettingswidget.h"
#include "qgsshortcutsmanager.h"
#include "qgssnappingwidget.h"
#include "qgsstackeddiagramproperties.h"
#include "qgsstatisticalsummarydockwidget.h"
#include "qgsstatusbar.h"
#include "qgsstatusbarcoordinateswidget.h"
@ -8051,7 +8051,7 @@ void QgisApp::diagramProperties()
QDialog dlg;
dlg.setWindowTitle( tr( "Layer Diagram Properties" ) );
QgsDiagramProperties *gui = new QgsDiagramProperties( vlayer, &dlg, mMapCanvas );
QgsStackedDiagramProperties *gui = new QgsStackedDiagramProperties( vlayer, &dlg, mMapCanvas );
gui->layout()->setContentsMargins( 0, 0, 0, 0 );
QVBoxLayout *layout = new QVBoxLayout( &dlg );
layout->addWidget( gui );
@ -8068,7 +8068,7 @@ void QgisApp::diagramProperties()
connect( buttonBox->button( QDialogButtonBox::Cancel ), &QAbstractButton::clicked,
&dlg, &QDialog::reject );
connect( buttonBox->button( QDialogButtonBox::Apply ), &QAbstractButton::clicked,
gui, &QgsDiagramProperties::apply );
gui, &QgsStackedDiagramProperties::apply );
connect( buttonBox->button( QDialogButtonBox::Help ), &QAbstractButton::clicked, gui, [ = ]
{
QgsHelp::openHelp( QStringLiteral( "working_with_vector/vector_properties.html#diagrams-properties" ) );

View File

@ -138,7 +138,7 @@ class QgsDataItem;
class QgsTileScaleWidget;
class QgsLabelingWidget;
class QgsLayerStylingWidget;
class QgsDiagramProperties;
class QgsStackedDiagramProperties;
class QgsLocatorWidget;
class QgsNominatimGeocoder;
class QgsDataSourceManagerDialog;

View File

@ -18,8 +18,6 @@
#define DIAGRAM_NAME_STACKED "Stacked"
//#include "qgis_core.h"
//#include "qgis.h"
#include "qgsdiagram.h"
#include <QPen>
#include <QBrush>

View File

@ -103,6 +103,16 @@ class CORE_EXPORT QgsDiagramLayerSettings
};
// *INDENT-ON*
/**
* Diagram type
* \since QGIS 3.40
*/
enum DiagramType
{
Single,
Stacked
};
/**
* Returns the diagram property definitions.
*/

View File

@ -38,6 +38,7 @@ set(QGIS_GUI_SRCS
vector/qgsfieldcalculator.cpp
vector/qgsjoindialog.cpp
vector/qgssourcefieldsproperties.cpp
vector/qgsstackeddiagramproperties.cpp
vector/qgsvectorlayerlegendwidget.cpp
vector/qgsvectorlayerproperties.cpp
vector/qgswmsdimensiondialog.cpp
@ -1499,6 +1500,7 @@ set(QGIS_GUI_HDRS
vector/qgsfieldcalculator.h
vector/qgsjoindialog.h
vector/qgssourcefieldsproperties.h
vector/qgsstackeddiagramproperties.h
vector/qgsvectorlayerlegendwidget.h
vector/qgsvectorlayerproperties.h
vector/qgswmsdimensiondialog.h
@ -1656,6 +1658,7 @@ endif()
add_library(qgis_gui ${LIBRARY_TYPE}
${QGIS_GUI_SRCS} ${QGIS_GUI_HDRS} ${QGIS_GUI_PRIVATE_HDRS}
vector/qgsstackeddiagramproperties.h vector/qgsstackeddiagramproperties.cpp
)
# require c++17

View File

@ -0,0 +1,88 @@
/***************************************************************************
qgsstackeddiagramproperties.h
Properties for stacked diagram layers
-------------------
begin : August 2024
copyright : (C) Germán Carrillo
email : german at opengis dot ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgsstackeddiagramproperties.h"
#include "qgsdiagramproperties.h"
QgsStackedDiagramProperties::QgsStackedDiagramProperties( QgsVectorLayer *layer, QWidget *parent, QgsMapCanvas *canvas )
: QWidget{parent}
, mMapCanvas( canvas )
{
mLayer = layer;
if ( !layer )
{
return;
}
setupUi( this );
connect( mDiagramTypeComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsStackedDiagramProperties::mDiagramTypeComboBox_currentIndexChanged );
// Initialize stacked diagram controls
mDiagramTypeComboBox->addItem( tr( "Single diagram" ), QgsDiagramLayerSettings::Single );
mDiagramTypeComboBox->addItem( tr( "Stacked diagrams" ), QgsDiagramLayerSettings::Stacked );
mStackedDiagramModeComboBox->addItem( tr( "Horizontal" ), QgsDiagramSettings::Horizontal );
mStackedDiagramModeComboBox->addItem( tr( "Vertical" ), QgsDiagramSettings::Vertical );
mStackedDiagramSpacingSpinBox->setClearValue( 0 );
mStackedDiagramSpacingUnitComboBox->setUnits( { Qgis::RenderUnit::Millimeters,
Qgis::RenderUnit::MetersInMapUnits,
Qgis::RenderUnit::MapUnits,
Qgis::RenderUnit::Pixels,
Qgis::RenderUnit::Points,
Qgis::RenderUnit::Inches } );
// Add default subdiagram tab
gui = new QgsDiagramProperties( layer, this, mMapCanvas );
gui->layout()->setContentsMargins( 0, 0, 0, 0 );
QVBoxLayout *vLayout = new QVBoxLayout();
vLayout->addWidget( gui );
QWidget *w = new QWidget();
w->setLayout( vLayout );
connect( gui, &QgsDiagramProperties::auxiliaryFieldCreated, this, &QgsStackedDiagramProperties::auxiliaryFieldCreated );
mSubDiagramsTabWidget->addTab( w, tr( "Diagram 1" ) );
}
void QgsStackedDiagramProperties::apply()
{
if ( mDiagramTypeComboBox->currentData( Qt::UserRole ) == QgsDiagramLayerSettings::Single )
{
gui->apply();
}
}
void QgsStackedDiagramProperties::syncToLayer()
{
if ( mDiagramTypeComboBox->currentData( Qt::UserRole ) == QgsDiagramLayerSettings::Single )
{
gui->syncToLayer();
}
}
void QgsStackedDiagramProperties::mDiagramTypeComboBox_currentIndexChanged( int index )
{
if ( index == 0 )
{
mStackedDiagramSettingsFrame->hide();
}
else
{
mStackedDiagramSettingsFrame->show();
}
}

View File

@ -0,0 +1,67 @@
/***************************************************************************
qgsstackeddiagramproperties.h
Properties for stacked diagram layers
-------------------
begin : August 2024
copyright : (C) Germán Carrillo
email : german at opengis dot ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSSTACKEDDIAGRAMPROPERTIES_H
#define QGSSTACKEDDIAGRAMPROPERTIES_H
// We don't want to expose this in the public API
#define SIP_NO_FILE
#include "qgis_gui.h"
#include "ui_qgsstackeddiagrampropertiesbase.h"
#include <QWidget>
#include <QDialog>
class QgsVectorLayer;
class QgsMapCanvas;
class QgsDiagramProperties;
/**
* \ingroup gui
* \class QgsStackedDiagramProperties
*
* \since QGIS 3.40
*/
class GUI_EXPORT QgsStackedDiagramProperties : public QWidget, private Ui::QgsStackedDiagramPropertiesBase
{
Q_OBJECT
public:
explicit QgsStackedDiagramProperties( QgsVectorLayer *layer, QWidget *parent, QgsMapCanvas *canvas );
/**
* Updates the widget to reflect the layer's current diagram settings.
*/
void syncToLayer();
signals:
void auxiliaryFieldCreated();
public slots:
void apply();
void mDiagramTypeComboBox_currentIndexChanged( int index );
private:
QgsVectorLayer *mLayer = nullptr;
QgsMapCanvas *mMapCanvas = nullptr;
QgsDiagramProperties *gui = nullptr;
};
#endif // QGSSTACKEDDIAGRAMPROPERTIES_H

View File

@ -26,7 +26,7 @@
#include "qgsapplication.h"
#include "qgsattributeactiondialog.h"
#include "qgsdatumtransformdialog.h"
#include "qgsdiagramproperties.h"
#include "qgsstackeddiagramproperties.h"
#include "qgssourcefieldsproperties.h"
#include "qgsattributesformproperties.h"
#include "qgslabelingwidget.h"
@ -335,9 +335,9 @@ QgsVectorLayerProperties::QgsVectorLayerProperties(
QVBoxLayout *diagLayout = new QVBoxLayout( mDiagramFrame );
diagLayout->setContentsMargins( 0, 0, 0, 0 );
diagramPropertiesDialog = new QgsDiagramProperties( mLayer, mDiagramFrame, mCanvas );
diagramPropertiesDialog = new QgsStackedDiagramProperties( mLayer, mDiagramFrame, mCanvas );
diagramPropertiesDialog->layout()->setContentsMargins( 0, 0, 0, 0 );
connect( diagramPropertiesDialog, &QgsDiagramProperties::auxiliaryFieldCreated, this, [ = ] { updateAuxiliaryStoragePage(); } );
connect( diagramPropertiesDialog, &QgsStackedDiagramProperties::auxiliaryFieldCreated, this, [ = ] { updateAuxiliaryStoragePage(); } );
diagLayout->addWidget( diagramPropertiesDialog );
mDiagramFrame->setLayout( diagLayout );

View File

@ -33,7 +33,7 @@ class QgsMapLayer;
class QgsAttributeActionDialog;
class QgsVectorLayer;
class QgsLabelingWidget;
class QgsDiagramProperties;
class QgsStackedDiagramProperties;
class QgsSourceFieldsProperties;
class QgsAttributesFormProperties;
class QgsRendererPropertiesDialog;
@ -172,7 +172,7 @@ class GUI_EXPORT QgsVectorLayerProperties : public QgsLayerPropertiesDialog, pri
//! Actions dialog. If apply is pressed, the actions are stored for later use
QgsAttributeActionDialog *mActionDialog = nullptr;
//! Diagram dialog. If apply is pressed, options are applied to vector's diagrams
QgsDiagramProperties *diagramPropertiesDialog = nullptr;
QgsStackedDiagramProperties *diagramPropertiesDialog = nullptr;
//! SourceFields dialog. If apply is pressed, options are applied to vector's diagrams
QgsSourceFieldsProperties *mSourceFieldsPropertiesDialog = nullptr;
//! AttributesForm dialog. If apply is pressed, options are applied to vector's diagrams
@ -181,8 +181,6 @@ class GUI_EXPORT QgsVectorLayerProperties : public QgsLayerPropertiesDialog, pri
//! List of joins of a layer at the time of creation of the dialog. Used to return joins to previous state if dialog is canceled
QList< QgsVectorLayerJoinInfo > mOldJoins;
void initDiagramTab();
//! Adds a new join to mJoinTreeWidget
void addJoinToTreeWidget( const QgsVectorLayerJoinInfo &join, int insertIndex = -1 );

View File

@ -0,0 +1,228 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QgsStackedDiagramPropertiesBase</class>
<widget class="QWidget" name="QgsStackedDiagramPropertiesBase">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>842</width>
<height>472</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_8" stretch="0,0,0">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QComboBox" name="mDiagramTypeComboBox"/>
</item>
<item>
<widget class="QFrame" name="mStackedDiagramSettingsFrame">
<property name="frameShape">
<enum>QFrame::Shape::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Shadow::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="mAddSubDiagramButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Add subdiagram to the stacked diagram</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/symbologyAdd.svg</normaloff>:/images/themes/default/symbologyAdd.svg</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="mRemoveSubDiagramButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Remove subdiagram from the stacked diagram</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/symbologyRemove.svg</normaloff>:/images/themes/default/symbologyRemove.svg</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Policy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="stackedDiagramModeLabel">
<property name="text">
<string>Stacked Diagram Mode</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="mStackedDiagramModeComboBox"/>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="dIagramSpacingLabel">
<property name="text">
<string>Diagram spacing</string>
</property>
</widget>
</item>
<item>
<widget class="QgsDoubleSpinBox" name="mStackedDiagramSpacingSpinBox">
<property name="minimumSize">
<size>
<width>70</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QgsUnitSelectionWidget" name="mStackedDiagramSpacingUnitComboBox" native="true">
<property name="minimumSize">
<size>
<width>120</width>
<height>0</height>
</size>
</property>
<property name="currentText" stdset="0">
<string/>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="mDiagramsFrame">
<property name="frameShape">
<enum>QFrame::Shape::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Shadow::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout_6">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="horizontalSpacing">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QTabWidget" name="mSubDiagramsTabWidget">
<property name="currentIndex">
<number>-1</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QgsDoubleSpinBox</class>
<extends>QDoubleSpinBox</extends>
<header>qgsdoublespinbox.h</header>
</customwidget>
<customwidget>
<class>QgsUnitSelectionWidget</class>
<extends>QWidget</extends>
<header>qgsunitselectionwidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../../images/images.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -285,6 +285,7 @@ ACCEPTABLE_MISSING_DOCS = {
"QgsEffectStack": ["QgsEffectStack(const QgsEffectStack &other)"],
"QgsRelationReferenceWidget": ["setRelation(const QgsRelation &relation, bool allowNullValue)", "CanvasExtent", "setOpenFormButtonVisible(bool openFormButtonVisible)", "QgsRelationReferenceWidget(QWidget *parent)", "setReadOnlySelector(bool readOnly)", "setRelationEditable(bool editable)", "init()", "setAllowMapIdentification(bool allowMapIdentification)", "setEmbedForm(bool display)"],
"QgsDiagramProperties": ["mAttributesTreeWidget_itemDoubleClicked(QTreeWidgetItem *item, int column)", "scalingTypeChanged()", "mAddCategoryPushButton_clicked()", "mEngineSettingsButton_clicked()", "apply()", "mRemoveCategoryPushButton_clicked()", "showSizeLegendDialog()", "QgsDiagramProperties(QgsVectorLayer *layer, QWidget *parent, QgsMapCanvas *canvas)", "mDiagramAttributesTreeWidget_itemDoubleClicked(QTreeWidgetItem *item, int column)", "mDiagramStackedWidget_currentChanged(int index)", "mDiagramTypeComboBox_currentIndexChanged(int index)", "mFindMaximumValueButton_clicked()", "showAddAttributeExpressionDialog()", "auxiliaryFieldCreated()", "updatePlacementWidgets()"],
"QgsStackedDiagramProperties": ["mDiagramTypeComboBox_currentIndexChanged(int index)", "apply()", "auxiliaryFieldCreated()", "QgsStackedDiagramProperties(QgsVectorLayer *layer, QWidget *parent, QgsMapCanvas *canvas)"],
"QgsFeatureListView": ["repaintRequested()", "repaintRequested(const QModelIndexList &indexes)"],
"QgsGradientFillSymbolLayerWidget": ["setGradientSpread(int index)", "setColor(const QColor &color)", "setCoordinateMode(int index)", "setColor2(const QColor &color)", "setGradientType(int index)"],
"QgsFillSymbol": ["setAngle(double angle) const"],