mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-09 00:08:52 -04:00
[gui] Move Diagrams properties to a panel widget, showing tabs instead of a list when docked; harmonize stacked diagram configuration with rule-based labeling; allow QgsDiagramProperties to sync to renderers and diagram layer settings, in addition to syncing to layers; when editing a subdiagram of a stacked diagram, only show widgets for diagram layer settings if the subdiagram is the first one, for the rest, hide those widgets and show a note informing users; make sure stacked diagrams handle enabled and disabled subdiagrams (i.e., don't take into account disabled subdiagrams) and add a test for it; switching from single to stacked diagram: take the single diagram definition as the first stacked diagram; fix #58782 (calling twice the apply method for label rendering)
This commit is contained in:
parent
e855941a34
commit
f81df2876c
@ -1017,30 +1017,24 @@ Writes stacked renderers state to a DOM element.
|
|||||||
virtual QList< QgsLayerTreeModelLegendNode * > legendItems( QgsLayerTreeLayer *nodeLayer ) const /Factory/;
|
virtual QList< QgsLayerTreeModelLegendNode * > legendItems( QgsLayerTreeLayer *nodeLayer ) const /Factory/;
|
||||||
|
|
||||||
|
|
||||||
QList< QgsDiagramRenderer * > renderers() const;
|
QList< QgsDiagramRenderer * > renderers( bool sortByDiagramMode = false ) const;
|
||||||
%Docstring
|
%Docstring
|
||||||
Returns an ordered list with the renderers of the stacked renderer object.
|
Returns an ordered list with the renderers of the stacked renderer object.
|
||||||
If the stacked diagram orientation is vertical, the list is returned backwards.
|
@param sortByDiagramMode If true, the list is returned backwards for vertical orientation.
|
||||||
%End
|
%End
|
||||||
|
|
||||||
void addRenderer( QgsDiagramRenderer *renderer );
|
void addRenderer( QgsDiagramRenderer *renderer );
|
||||||
%Docstring
|
%Docstring
|
||||||
Adds a renderer to the stacked renderer object.
|
Adds a renderer to the stacked renderer object.
|
||||||
|
@param renderer diagram renderer to be added to the stacked renderer
|
||||||
:param renderer: diagram renderer to be added to the stacked renderer
|
Renderers added first will render their diagrams first, i.e., more to
|
||||||
Renderers added first will render their diagrams first, i.e., more to
|
the left (horizontal mode) or more to the top (vertical mode).
|
||||||
the left (horizontal mode) or more to the top (vertical mode).
|
|
||||||
%End
|
%End
|
||||||
|
|
||||||
const QgsDiagramRenderer *renderer( const int index ) const;
|
const QgsDiagramRenderer *renderer( const int index ) const;
|
||||||
%Docstring
|
%Docstring
|
||||||
Returns the renderer at the given ``index``.
|
Returns the renderer at the given ``index``.
|
||||||
@param index index of the disired renderer in the stacked renderer
|
@param index index of the disired renderer in the stacked renderer
|
||||||
%End
|
|
||||||
|
|
||||||
int rendererCount() const;
|
|
||||||
%Docstring
|
|
||||||
Returns the number of renderers that this stacked renderer is composed of.
|
|
||||||
%End
|
%End
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -1017,30 +1017,24 @@ Writes stacked renderers state to a DOM element.
|
|||||||
virtual QList< QgsLayerTreeModelLegendNode * > legendItems( QgsLayerTreeLayer *nodeLayer ) const /Factory/;
|
virtual QList< QgsLayerTreeModelLegendNode * > legendItems( QgsLayerTreeLayer *nodeLayer ) const /Factory/;
|
||||||
|
|
||||||
|
|
||||||
QList< QgsDiagramRenderer * > renderers() const;
|
QList< QgsDiagramRenderer * > renderers( bool sortByDiagramMode = false ) const;
|
||||||
%Docstring
|
%Docstring
|
||||||
Returns an ordered list with the renderers of the stacked renderer object.
|
Returns an ordered list with the renderers of the stacked renderer object.
|
||||||
If the stacked diagram orientation is vertical, the list is returned backwards.
|
@param sortByDiagramMode If true, the list is returned backwards for vertical orientation.
|
||||||
%End
|
%End
|
||||||
|
|
||||||
void addRenderer( QgsDiagramRenderer *renderer );
|
void addRenderer( QgsDiagramRenderer *renderer );
|
||||||
%Docstring
|
%Docstring
|
||||||
Adds a renderer to the stacked renderer object.
|
Adds a renderer to the stacked renderer object.
|
||||||
|
@param renderer diagram renderer to be added to the stacked renderer
|
||||||
:param renderer: diagram renderer to be added to the stacked renderer
|
Renderers added first will render their diagrams first, i.e., more to
|
||||||
Renderers added first will render their diagrams first, i.e., more to
|
the left (horizontal mode) or more to the top (vertical mode).
|
||||||
the left (horizontal mode) or more to the top (vertical mode).
|
|
||||||
%End
|
%End
|
||||||
|
|
||||||
const QgsDiagramRenderer *renderer( const int index ) const;
|
const QgsDiagramRenderer *renderer( const int index ) const;
|
||||||
%Docstring
|
%Docstring
|
||||||
Returns the renderer at the given ``index``.
|
Returns the renderer at the given ``index``.
|
||||||
@param index index of the disired renderer in the stacked renderer
|
@param index index of the disired renderer in the stacked renderer
|
||||||
%End
|
|
||||||
|
|
||||||
int rendererCount() const;
|
|
||||||
%Docstring
|
|
||||||
Returns the number of renderers that this stacked renderer is composed of.
|
|
||||||
%End
|
%End
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -8049,35 +8049,8 @@ void QgisApp::diagramProperties()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDialog dlg;
|
mapStyleDock( true );
|
||||||
dlg.setWindowTitle( tr( "Layer Diagram Properties" ) );
|
mMapStyleWidget->setCurrentPage( QgsLayerStylingWidget::VectorDiagram );
|
||||||
QgsStackedDiagramProperties *gui = new QgsStackedDiagramProperties( vlayer, &dlg, mMapCanvas );
|
|
||||||
gui->layout()->setContentsMargins( 0, 0, 0, 0 );
|
|
||||||
QVBoxLayout *layout = new QVBoxLayout( &dlg );
|
|
||||||
layout->addWidget( gui );
|
|
||||||
|
|
||||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(
|
|
||||||
QDialogButtonBox::Help | QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Apply,
|
|
||||||
Qt::Horizontal, &dlg );
|
|
||||||
layout->addWidget( buttonBox );
|
|
||||||
|
|
||||||
dlg.setLayout( layout );
|
|
||||||
|
|
||||||
connect( buttonBox->button( QDialogButtonBox::Ok ), &QAbstractButton::clicked,
|
|
||||||
&dlg, &QDialog::accept );
|
|
||||||
connect( buttonBox->button( QDialogButtonBox::Cancel ), &QAbstractButton::clicked,
|
|
||||||
&dlg, &QDialog::reject );
|
|
||||||
connect( buttonBox->button( QDialogButtonBox::Apply ), &QAbstractButton::clicked,
|
|
||||||
gui, &QgsStackedDiagramProperties::apply );
|
|
||||||
connect( buttonBox->button( QDialogButtonBox::Help ), &QAbstractButton::clicked, gui, [ = ]
|
|
||||||
{
|
|
||||||
QgsHelp::openHelp( QStringLiteral( "working_with_vector/vector_properties.html#diagrams-properties" ) );
|
|
||||||
} );
|
|
||||||
|
|
||||||
if ( dlg.exec() )
|
|
||||||
gui->apply();
|
|
||||||
|
|
||||||
activateDeactivateLayerRelatedActions( vlayer );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgisApp::createAnnotationLayer()
|
void QgisApp::createAnnotationLayer()
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "qgsapplication.h"
|
#include "qgsapplication.h"
|
||||||
#include "qgslabelingwidget.h"
|
#include "qgslabelingwidget.h"
|
||||||
#include "qgsmaskingwidget.h"
|
#include "qgsmaskingwidget.h"
|
||||||
|
#include "qgsdiagramwidget.h"
|
||||||
#include "qgslayerstylingwidget.h"
|
#include "qgslayerstylingwidget.h"
|
||||||
#include "qgsrastertransparencywidget.h"
|
#include "qgsrastertransparencywidget.h"
|
||||||
#include "qgsrendererpropertiesdialog.h"
|
#include "qgsrendererpropertiesdialog.h"
|
||||||
@ -217,6 +218,11 @@ void QgsLayerStylingWidget::setLayer( QgsMapLayer *layer )
|
|||||||
symbol3DItem->setToolTip( tr( "3D View" ) );
|
symbol3DItem->setToolTip( tr( "3D View" ) );
|
||||||
mOptionsListWidget->addItem( symbol3DItem );
|
mOptionsListWidget->addItem( symbol3DItem );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
QListWidgetItem *diagramItem = new QListWidgetItem( QgsApplication::getThemeIcon( QStringLiteral( "/propertyicons/diagram.svg" ) ), QString() );
|
||||||
|
diagramItem->setData( Qt::UserRole, VectorDiagram );
|
||||||
|
diagramItem->setToolTip( tr( "Diagrams" ) );
|
||||||
|
mOptionsListWidget->addItem( diagramItem );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Qgis::LayerType::Raster:
|
case Qgis::LayerType::Raster:
|
||||||
@ -334,12 +340,6 @@ void QgsLayerStylingWidget::apply()
|
|||||||
|
|
||||||
bool styleWasChanged = false;
|
bool styleWasChanged = false;
|
||||||
bool triggerRepaint = false; // whether the change needs the layer to be repainted
|
bool triggerRepaint = false; // whether the change needs the layer to be repainted
|
||||||
if ( QgsLabelingWidget *widget = qobject_cast<QgsLabelingWidget *>( current ) )
|
|
||||||
{
|
|
||||||
widget->apply();
|
|
||||||
styleWasChanged = true;
|
|
||||||
undoName = QStringLiteral( "Label Change" );
|
|
||||||
}
|
|
||||||
if ( QgsMaskingWidget *widget = qobject_cast<QgsMaskingWidget *>( current ) )
|
if ( QgsMaskingWidget *widget = qobject_cast<QgsMaskingWidget *>( current ) )
|
||||||
{
|
{
|
||||||
widget->apply();
|
widget->apply();
|
||||||
@ -373,8 +373,23 @@ void QgsLayerStylingWidget::apply()
|
|||||||
styleWasChanged = true;
|
styleWasChanged = true;
|
||||||
triggerRepaint = true;
|
triggerRepaint = true;
|
||||||
}
|
}
|
||||||
|
else if ( QgsLabelingWidget *widget = qobject_cast<QgsLabelingWidget *>( current ) )
|
||||||
|
{
|
||||||
|
widget->apply();
|
||||||
|
styleWasChanged = true;
|
||||||
|
undoName = QStringLiteral( "Label Change" );
|
||||||
|
}
|
||||||
|
else if ( QgsDiagramWidget *widget = qobject_cast<QgsDiagramWidget *>( current ) )
|
||||||
|
{
|
||||||
|
widget->apply();
|
||||||
|
styleWasChanged = true;
|
||||||
|
undoName = QStringLiteral( "Diagram Change" );
|
||||||
|
}
|
||||||
else if ( QgsMapLayerConfigWidget *widget = qobject_cast<QgsMapLayerConfigWidget *>( current ) )
|
else if ( QgsMapLayerConfigWidget *widget = qobject_cast<QgsMapLayerConfigWidget *>( current ) )
|
||||||
{
|
{
|
||||||
|
// Warning: All classes inheriting from QgsMapLayerConfigWidget
|
||||||
|
// should come in the current if block, before this else-if
|
||||||
|
// clause, to avoid duplicate calls to apply()!
|
||||||
widget->apply();
|
widget->apply();
|
||||||
styleWasChanged = true;
|
styleWasChanged = true;
|
||||||
triggerRepaint = widget->shouldTriggerLayerRepaint();
|
triggerRepaint = widget->shouldTriggerLayerRepaint();
|
||||||
@ -463,6 +478,10 @@ void QgsLayerStylingWidget::updateCurrentWidgetLayer()
|
|||||||
mMesh3DWidget = widget;
|
mMesh3DWidget = widget;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
else if ( QgsDiagramWidget *widget = qobject_cast<QgsDiagramWidget *>( current ) )
|
||||||
|
{
|
||||||
|
mDiagramWidget = widget;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mWidgetStack->clear();
|
mWidgetStack->clear();
|
||||||
@ -495,6 +514,11 @@ void QgsLayerStylingWidget::updateCurrentWidgetLayer()
|
|||||||
{
|
{
|
||||||
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCurrentLayer );
|
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCurrentLayer );
|
||||||
|
|
||||||
|
#ifdef HAVE_3D
|
||||||
|
const int tabShift = 1; // To move subsequent tabs
|
||||||
|
#else
|
||||||
|
const int tabShift = 0;
|
||||||
|
#endif
|
||||||
switch ( row )
|
switch ( row )
|
||||||
{
|
{
|
||||||
case 0: // Style
|
case 0: // Style
|
||||||
@ -550,6 +574,15 @@ void QgsLayerStylingWidget::updateCurrentWidgetLayer()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
case 3 + tabShift: // Diagrams
|
||||||
|
{
|
||||||
|
mDiagramWidget = new QgsDiagramWidget( vlayer, mMapCanvas, mWidgetStack );
|
||||||
|
mDiagramWidget->setDockMode( true );
|
||||||
|
connect( mDiagramWidget, &QgsDiagramWidget::widgetChanged, this, &QgsLayerStylingWidget::autoApply );
|
||||||
|
mDiagramWidget->syncToOwnLayer();
|
||||||
|
mWidgetStack->setMainPanel( mDiagramWidget );
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
class QgsLabelingWidget;
|
class QgsLabelingWidget;
|
||||||
class QgsMaskingWidget;
|
class QgsMaskingWidget;
|
||||||
|
class QgsDiagramWidget;
|
||||||
class QgsMapLayer;
|
class QgsMapLayer;
|
||||||
class QgsMapCanvas;
|
class QgsMapCanvas;
|
||||||
class QgsRendererPropertiesDialog;
|
class QgsRendererPropertiesDialog;
|
||||||
@ -101,6 +102,7 @@ class APP_EXPORT QgsLayerStylingWidget : public QWidget, private Ui::QgsLayerSty
|
|||||||
History,
|
History,
|
||||||
Symbology3D,
|
Symbology3D,
|
||||||
RasterAttributeTables, //!< Raster attribute tables, since QGIS 3.30
|
RasterAttributeTables, //!< Raster attribute tables, since QGIS 3.30
|
||||||
|
VectorDiagram, //!< Vector diagram, since QGIS 3.40
|
||||||
};
|
};
|
||||||
|
|
||||||
QgsLayerStylingWidget( QgsMapCanvas *canvas, QgsMessageBar *messageBar, const QList<const QgsMapLayerConfigWidgetFactory *> &pages, QWidget *parent = nullptr );
|
QgsLayerStylingWidget( QgsMapCanvas *canvas, QgsMessageBar *messageBar, const QList<const QgsMapLayerConfigWidgetFactory *> &pages, QWidget *parent = nullptr );
|
||||||
@ -175,6 +177,7 @@ class APP_EXPORT QgsLayerStylingWidget : public QWidget, private Ui::QgsLayerSty
|
|||||||
QgsVectorLayer3DRendererWidget *mVector3DWidget = nullptr;
|
QgsVectorLayer3DRendererWidget *mVector3DWidget = nullptr;
|
||||||
QgsMeshLayer3DRendererWidget *mMesh3DWidget = nullptr;
|
QgsMeshLayer3DRendererWidget *mMesh3DWidget = nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
QgsDiagramWidget *mDiagramWidget = nullptr;
|
||||||
QgsRendererRasterPropertiesWidget *mRasterStyleWidget = nullptr;
|
QgsRendererRasterPropertiesWidget *mRasterStyleWidget = nullptr;
|
||||||
QgsRasterAttributeTableWidget *mRasterAttributeTableWidget = nullptr;
|
QgsRasterAttributeTableWidget *mRasterAttributeTableWidget = nullptr;
|
||||||
QgsPanelWidget *mRasterAttributeTableDisabledWidget = nullptr;
|
QgsPanelWidget *mRasterAttributeTableDisabledWidget = nullptr;
|
||||||
|
@ -528,7 +528,7 @@ void QgsDiagramRenderer::renderDiagram( const QgsFeature &feature, QgsRenderCont
|
|||||||
QSizeF QgsDiagramRenderer::sizeMapUnits( const QgsFeature &feature, const QgsRenderContext &c ) const
|
QSizeF QgsDiagramRenderer::sizeMapUnits( const QgsFeature &feature, const QgsRenderContext &c ) const
|
||||||
{
|
{
|
||||||
QgsDiagramSettings s;
|
QgsDiagramSettings s;
|
||||||
if ( !diagramSettings( feature, c, s ) )
|
if ( !diagramSettings( feature, c, s ) || !s.enabled )
|
||||||
{
|
{
|
||||||
return QSizeF();
|
return QSizeF();
|
||||||
}
|
}
|
||||||
@ -845,16 +845,18 @@ QgsStackedDiagramRenderer *QgsStackedDiagramRenderer::clone() const
|
|||||||
QSizeF QgsStackedDiagramRenderer::sizeMapUnits( const QgsFeature &feature, const QgsRenderContext &c ) const
|
QSizeF QgsStackedDiagramRenderer::sizeMapUnits( const QgsFeature &feature, const QgsRenderContext &c ) const
|
||||||
{
|
{
|
||||||
QSizeF stackedSize( 0, 0 );
|
QSizeF stackedSize( 0, 0 );
|
||||||
|
int enabledDiagramCount = 0; // We'll add spacing only for enabled subDiagrams
|
||||||
|
|
||||||
// Iterate renderers. For each renderer, get the diagram
|
// Iterate renderers. For each renderer, get the diagram
|
||||||
// size for the feature and add it to the total size
|
// size for the feature and add it to the total size
|
||||||
// accounting for stacked diagram defined spacing
|
// accounting for stacked diagram defined spacing
|
||||||
for ( int i = 0; i < mDiagramRenderers.count(); i++ )
|
for ( const auto &subRenderer : std::as_const( mDiagramRenderers ) )
|
||||||
{
|
{
|
||||||
QSizeF size = mDiagramRenderers.at( i )->sizeMapUnits( feature, c );
|
QSizeF size = subRenderer->sizeMapUnits( feature, c );
|
||||||
|
|
||||||
if ( size.isValid() )
|
if ( size.isValid() )
|
||||||
{
|
{
|
||||||
|
enabledDiagramCount++;
|
||||||
switch ( mSettings.stackedDiagramMode )
|
switch ( mSettings.stackedDiagramMode )
|
||||||
{
|
{
|
||||||
case QgsDiagramSettings::Horizontal:
|
case QgsDiagramSettings::Horizontal:
|
||||||
@ -875,11 +877,11 @@ QSizeF QgsStackedDiagramRenderer::sizeMapUnits( const QgsFeature &feature, const
|
|||||||
switch ( mSettings.stackedDiagramMode )
|
switch ( mSettings.stackedDiagramMode )
|
||||||
{
|
{
|
||||||
case QgsDiagramSettings::Horizontal:
|
case QgsDiagramSettings::Horizontal:
|
||||||
stackedSize.scale( stackedSize.width() + spacing * ( mDiagramRenderers.count() - 1 ), stackedSize.height(), Qt::IgnoreAspectRatio );
|
stackedSize.scale( stackedSize.width() + spacing * ( enabledDiagramCount - 1 ), stackedSize.height(), Qt::IgnoreAspectRatio );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QgsDiagramSettings::Vertical:
|
case QgsDiagramSettings::Vertical:
|
||||||
stackedSize.scale( stackedSize.width(), stackedSize.height() + spacing * ( mDiagramRenderers.count() - 1 ), Qt::IgnoreAspectRatio );
|
stackedSize.scale( stackedSize.width(), stackedSize.height() + spacing * ( enabledDiagramCount - 1 ), Qt::IgnoreAspectRatio );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return stackedSize;
|
return stackedSize;
|
||||||
@ -893,11 +895,15 @@ void QgsStackedDiagramRenderer::renderDiagram( const QgsFeature &feature, QgsRen
|
|||||||
}
|
}
|
||||||
|
|
||||||
QPointF newPos = pos; // Each subdiagram will have its own newPos
|
QPointF newPos = pos; // Each subdiagram will have its own newPos
|
||||||
QList< QgsDiagramRenderer * > stackedRenderers = renderers();
|
|
||||||
for ( const auto &stackedRenderer : std::as_const( stackedRenderers ) )
|
// Get subrenderers sorted by mode (vertical diagrams are returned backwards)
|
||||||
|
const QList< QgsDiagramRenderer * > stackedRenderers = renderers( true );
|
||||||
|
|
||||||
|
for ( const auto &stackedRenderer : stackedRenderers )
|
||||||
{
|
{
|
||||||
if ( stackedRenderer->rendererName() == QStringLiteral( "Stacked" ) )
|
if ( stackedRenderer->rendererName() == QStringLiteral( "Stacked" ) )
|
||||||
{
|
{
|
||||||
|
// Nested stacked diagrams will use this recursion
|
||||||
stackedRenderer->renderDiagram( feature, c, newPos, properties );
|
stackedRenderer->renderDiagram( feature, c, newPos, properties );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -905,7 +911,12 @@ void QgsStackedDiagramRenderer::renderDiagram( const QgsFeature &feature, QgsRen
|
|||||||
QgsDiagramSettings s;
|
QgsDiagramSettings s;
|
||||||
if ( !stackedRenderer->diagramSettings( feature, c, s ) )
|
if ( !stackedRenderer->diagramSettings( feature, c, s ) )
|
||||||
{
|
{
|
||||||
return;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !s.enabled )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( properties.hasActiveProperties() )
|
if ( properties.hasActiveProperties() )
|
||||||
@ -963,26 +974,19 @@ QList<QString> QgsStackedDiagramRenderer::diagramAttributes() const
|
|||||||
QList< QgsLayerTreeModelLegendNode * > QgsStackedDiagramRenderer::legendItems( QgsLayerTreeLayer *nodeLayer ) const
|
QList< QgsLayerTreeModelLegendNode * > QgsStackedDiagramRenderer::legendItems( QgsLayerTreeLayer *nodeLayer ) const
|
||||||
{
|
{
|
||||||
QList< QgsLayerTreeModelLegendNode * > nodes;
|
QList< QgsLayerTreeModelLegendNode * > nodes;
|
||||||
for ( int i = 0; i < rendererCount(); i++ )
|
for ( const auto &renderer : std::as_const( mDiagramRenderers ) )
|
||||||
{
|
{
|
||||||
nodes << mDiagramRenderers.at( i )->legendItems( nodeLayer );
|
nodes << renderer->legendItems( nodeLayer );
|
||||||
}
|
}
|
||||||
|
|
||||||
return nodes;
|
return nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList< QgsDiagramRenderer * > QgsStackedDiagramRenderer::renderers() const
|
QList< QgsDiagramRenderer * > QgsStackedDiagramRenderer::renderers( bool sortByDiagramMode ) const
|
||||||
{
|
{
|
||||||
QList< QgsDiagramRenderer * > renderers;
|
QList< QgsDiagramRenderer * > renderers;
|
||||||
|
|
||||||
if ( mSettings.stackedDiagramMode == QgsDiagramSettings::Horizontal )
|
if ( sortByDiagramMode && mSettings.stackedDiagramMode == QgsDiagramSettings::Vertical )
|
||||||
{
|
|
||||||
for ( const auto &item : std::as_const( mDiagramRenderers ) )
|
|
||||||
{
|
|
||||||
renderers.append( item );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// We draw vertical diagrams backwards, so
|
// We draw vertical diagrams backwards, so
|
||||||
// we return the subrenderers in reverse order
|
// we return the subrenderers in reverse order
|
||||||
@ -992,6 +996,10 @@ QList< QgsDiagramRenderer * > QgsStackedDiagramRenderer::renderers() const
|
|||||||
renderers.append( *iter );
|
renderers.append( *iter );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
renderers = mDiagramRenderers;
|
||||||
|
}
|
||||||
return renderers;
|
return renderers;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1013,11 +1021,6 @@ const QgsDiagramRenderer *QgsStackedDiagramRenderer::renderer( const int index )
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int QgsStackedDiagramRenderer::rendererCount() const
|
|
||||||
{
|
|
||||||
return mDiagramRenderers.count();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QgsStackedDiagramRenderer::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
|
void QgsStackedDiagramRenderer::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
|
||||||
{
|
{
|
||||||
const QDomElement categoryElem = elem.firstChildElement( QStringLiteral( "DiagramCategory" ) );
|
const QDomElement categoryElem = elem.firstChildElement( QStringLiteral( "DiagramCategory" ) );
|
||||||
@ -1234,7 +1237,7 @@ QList< QgsLayerTreeModelLegendNode * > QgsDiagramRenderer::legendItems( QgsLayer
|
|||||||
QList< QgsLayerTreeModelLegendNode * > QgsSingleCategoryDiagramRenderer::legendItems( QgsLayerTreeLayer *nodeLayer ) const
|
QList< QgsLayerTreeModelLegendNode * > QgsSingleCategoryDiagramRenderer::legendItems( QgsLayerTreeLayer *nodeLayer ) const
|
||||||
{
|
{
|
||||||
QList< QgsLayerTreeModelLegendNode * > nodes;
|
QList< QgsLayerTreeModelLegendNode * > nodes;
|
||||||
if ( mShowAttributeLegend )
|
if ( mShowAttributeLegend && mSettings.enabled )
|
||||||
nodes = mSettings.legendItems( nodeLayer );
|
nodes = mSettings.legendItems( nodeLayer );
|
||||||
|
|
||||||
return nodes;
|
return nodes;
|
||||||
@ -1243,6 +1246,11 @@ QList< QgsLayerTreeModelLegendNode * > QgsSingleCategoryDiagramRenderer::legendI
|
|||||||
QList< QgsLayerTreeModelLegendNode * > QgsLinearlyInterpolatedDiagramRenderer::legendItems( QgsLayerTreeLayer *nodeLayer ) const
|
QList< QgsLayerTreeModelLegendNode * > QgsLinearlyInterpolatedDiagramRenderer::legendItems( QgsLayerTreeLayer *nodeLayer ) const
|
||||||
{
|
{
|
||||||
QList< QgsLayerTreeModelLegendNode * > nodes;
|
QList< QgsLayerTreeModelLegendNode * > nodes;
|
||||||
|
if ( !mSettings.enabled )
|
||||||
|
{
|
||||||
|
return nodes;
|
||||||
|
}
|
||||||
|
|
||||||
if ( mShowAttributeLegend )
|
if ( mShowAttributeLegend )
|
||||||
nodes = mSettings.legendItems( nodeLayer );
|
nodes = mSettings.legendItems( nodeLayer );
|
||||||
|
|
||||||
|
@ -1039,13 +1039,13 @@ class CORE_EXPORT QgsStackedDiagramRenderer : public QgsDiagramRenderer
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an ordered list with the renderers of the stacked renderer object.
|
* Returns an ordered list with the renderers of the stacked renderer object.
|
||||||
* If the stacked diagram orientation is vertical, the list is returned backwards.
|
* @param sortByDiagramMode If true, the list is returned backwards for vertical orientation.
|
||||||
*/
|
*/
|
||||||
QList< QgsDiagramRenderer * > renderers() const;
|
QList< QgsDiagramRenderer * > renderers( bool sortByDiagramMode = false ) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a renderer to the stacked renderer object.
|
* Adds a renderer to the stacked renderer object.
|
||||||
* \param renderer diagram renderer to be added to the stacked renderer
|
* @param renderer diagram renderer to be added to the stacked renderer
|
||||||
* Renderers added first will render their diagrams first, i.e., more to
|
* Renderers added first will render their diagrams first, i.e., more to
|
||||||
* the left (horizontal mode) or more to the top (vertical mode).
|
* the left (horizontal mode) or more to the top (vertical mode).
|
||||||
*/
|
*/
|
||||||
@ -1057,11 +1057,6 @@ class CORE_EXPORT QgsStackedDiagramRenderer : public QgsDiagramRenderer
|
|||||||
*/
|
*/
|
||||||
const QgsDiagramRenderer *renderer( const int index ) const;
|
const QgsDiagramRenderer *renderer( const int index ) const;
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the number of renderers that this stacked renderer is composed of.
|
|
||||||
*/
|
|
||||||
int rendererCount() const;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool diagramSettings( const QgsFeature &feature, const QgsRenderContext &c, QgsDiagramSettings &s ) const override;
|
bool diagramSettings( const QgsFeature &feature, const QgsRenderContext &c, QgsDiagramSettings &s ) const override;
|
||||||
QSizeF diagramSize( const QgsFeature &, const QgsRenderContext &c ) const override;
|
QSizeF diagramSize( const QgsFeature &, const QgsRenderContext &c ) const override;
|
||||||
|
@ -35,6 +35,7 @@ set(QGIS_GUI_SRCS
|
|||||||
vector/qgsattributesforminitcode.cpp
|
vector/qgsattributesforminitcode.cpp
|
||||||
vector/qgsattributesformproperties.cpp
|
vector/qgsattributesformproperties.cpp
|
||||||
vector/qgsdiagramproperties.cpp
|
vector/qgsdiagramproperties.cpp
|
||||||
|
vector/qgsdiagramwidget.cpp
|
||||||
vector/qgsfieldcalculator.cpp
|
vector/qgsfieldcalculator.cpp
|
||||||
vector/qgsjoindialog.cpp
|
vector/qgsjoindialog.cpp
|
||||||
vector/qgssourcefieldsproperties.cpp
|
vector/qgssourcefieldsproperties.cpp
|
||||||
@ -1497,6 +1498,7 @@ set(QGIS_GUI_HDRS
|
|||||||
vector/qgsattributesforminitcode.h
|
vector/qgsattributesforminitcode.h
|
||||||
vector/qgsattributesformproperties.h
|
vector/qgsattributesformproperties.h
|
||||||
vector/qgsdiagramproperties.h
|
vector/qgsdiagramproperties.h
|
||||||
|
vector/qgsdiagramwidget.h
|
||||||
vector/qgsfieldcalculator.h
|
vector/qgsfieldcalculator.h
|
||||||
vector/qgsjoindialog.h
|
vector/qgsjoindialog.h
|
||||||
vector/qgssourcefieldsproperties.h
|
vector/qgssourcefieldsproperties.h
|
||||||
|
@ -59,10 +59,10 @@ QgsExpressionContext QgsDiagramProperties::createExpressionContext() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
QgsDiagramProperties::QgsDiagramProperties( QgsVectorLayer *layer, QWidget *parent, QgsMapCanvas *canvas )
|
QgsDiagramProperties::QgsDiagramProperties( QgsVectorLayer *layer, QWidget *parent, QgsMapCanvas *canvas )
|
||||||
: QWidget( parent )
|
: QgsPanelWidget( parent )
|
||||||
|
, mLayer( layer )
|
||||||
, mMapCanvas( canvas )
|
, mMapCanvas( canvas )
|
||||||
{
|
{
|
||||||
mLayer = layer;
|
|
||||||
if ( !layer )
|
if ( !layer )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -80,6 +80,10 @@ QgsDiagramProperties::QgsDiagramProperties( QgsVectorLayer *layer, QWidget *pare
|
|||||||
// get rid of annoying outer focus rect on Mac
|
// get rid of annoying outer focus rect on Mac
|
||||||
mDiagramOptionsListWidget->setAttribute( Qt::WA_MacShowFocusRect, false );
|
mDiagramOptionsListWidget->setAttribute( Qt::WA_MacShowFocusRect, false );
|
||||||
|
|
||||||
|
const int iconSize = QgsGuiUtils::scaleIconSize( 20 );
|
||||||
|
mOptionsTab->setIconSize( QSize( iconSize, iconSize ) );
|
||||||
|
mDiagramOptionsListWidget->setIconSize( QSize( iconSize, iconSize ) ) ;
|
||||||
|
|
||||||
mBarSpacingSpinBox->setClearValue( 0 );
|
mBarSpacingSpinBox->setClearValue( 0 );
|
||||||
mBarSpacingUnitComboBox->setUnits( { Qgis::RenderUnit::Millimeters,
|
mBarSpacingUnitComboBox->setUnits( { Qgis::RenderUnit::Millimeters,
|
||||||
Qgis::RenderUnit::MetersInMapUnits,
|
Qgis::RenderUnit::MetersInMapUnits,
|
||||||
@ -144,6 +148,7 @@ QgsDiagramProperties::QgsDiagramProperties( QgsVectorLayer *layer, QWidget *pare
|
|||||||
if ( layerType == Qgis::GeometryType::Unknown || layerType == Qgis::GeometryType::Null )
|
if ( layerType == Qgis::GeometryType::Unknown || layerType == Qgis::GeometryType::Null )
|
||||||
{
|
{
|
||||||
mDiagramTypeComboBox->setEnabled( false );
|
mDiagramTypeComboBox->setEnabled( false );
|
||||||
|
mOptionsTab->setEnabled( false );
|
||||||
mDiagramFrame->setEnabled( false );
|
mDiagramFrame->setEnabled( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,6 +229,10 @@ QgsDiagramProperties::QgsDiagramProperties( QgsVectorLayer *layer, QWidget *pare
|
|||||||
mDiagramOptionsSplitter->restoreState( settings.value( QStringLiteral( "Windows/Diagrams/OptionsSplitState" ) ).toByteArray() );
|
mDiagramOptionsSplitter->restoreState( settings.value( QStringLiteral( "Windows/Diagrams/OptionsSplitState" ) ).toByteArray() );
|
||||||
mDiagramOptionsListWidget->setCurrentRow( settings.value( QStringLiteral( "Windows/Diagrams/Tab" ), 0 ).toInt() );
|
mDiagramOptionsListWidget->setCurrentRow( settings.value( QStringLiteral( "Windows/Diagrams/Tab" ), 0 ).toInt() );
|
||||||
|
|
||||||
|
// set correct initial tab to match displayed setting page
|
||||||
|
whileBlocking( mOptionsTab )->setCurrentIndex( mDiagramStackedWidget->currentIndex() );
|
||||||
|
mOptionsTab->tabBar()->setUsesScrollButtons( true );
|
||||||
|
|
||||||
// field combo and expression button
|
// field combo and expression button
|
||||||
mSizeFieldExpressionWidget->setLayer( mLayer );
|
mSizeFieldExpressionWidget->setLayer( mLayer );
|
||||||
QgsDistanceArea myDa;
|
QgsDistanceArea myDa;
|
||||||
@ -250,6 +259,11 @@ QgsDiagramProperties::QgsDiagramProperties( QgsVectorLayer *layer, QWidget *pare
|
|||||||
mOrientationUpButton->setProperty( "direction", QgsDiagramSettings::Up );
|
mOrientationUpButton->setProperty( "direction", QgsDiagramSettings::Up );
|
||||||
mOrientationDownButton->setProperty( "direction", QgsDiagramSettings::Down );
|
mOrientationDownButton->setProperty( "direction", QgsDiagramSettings::Down );
|
||||||
|
|
||||||
|
// Labels to let users know some widgets are not present
|
||||||
|
// when editing sub diagrams in a stacked diagram.
|
||||||
|
mDlsLabel_1->hide();
|
||||||
|
mDlsLabel_2->hide();
|
||||||
|
|
||||||
//force a refresh of widget status to match diagram type
|
//force a refresh of widget status to match diagram type
|
||||||
mDiagramTypeComboBox_currentIndexChanged( mDiagramTypeComboBox->currentIndex() );
|
mDiagramTypeComboBox_currentIndexChanged( mDiagramTypeComboBox->currentIndex() );
|
||||||
|
|
||||||
@ -268,15 +282,99 @@ QgsDiagramProperties::QgsDiagramProperties( QgsVectorLayer *layer, QWidget *pare
|
|||||||
registerDataDefinedButton( mStartAngleDDBtn, QgsDiagramLayerSettings::Property::StartAngle );
|
registerDataDefinedButton( mStartAngleDDBtn, QgsDiagramLayerSettings::Property::StartAngle );
|
||||||
|
|
||||||
connect( mButtonSizeLegendSettings, &QPushButton::clicked, this, &QgsDiagramProperties::showSizeLegendDialog );
|
connect( mButtonSizeLegendSettings, &QPushButton::clicked, this, &QgsDiagramProperties::showSizeLegendDialog );
|
||||||
|
|
||||||
|
QList<QWidget *> widgets;
|
||||||
|
widgets << chkLineAbove;
|
||||||
|
widgets << chkLineBelow;
|
||||||
|
widgets << chkLineOn;
|
||||||
|
widgets << chkLineOrientationDependent;
|
||||||
|
widgets << mAngleDirectionComboBox;
|
||||||
|
widgets << mAngleOffsetComboBox;
|
||||||
|
widgets << mAttributeBasedScalingRadio;
|
||||||
|
widgets << mAxisLineStyleButton;
|
||||||
|
widgets << mBackgroundColorButton;
|
||||||
|
widgets << mBarSpacingSpinBox;
|
||||||
|
widgets << mBarSpacingUnitComboBox;
|
||||||
|
widgets << mBarWidthSpinBox;
|
||||||
|
widgets << mCheckBoxAttributeLegend;
|
||||||
|
widgets << mDiagramAttributesTreeWidget;
|
||||||
|
widgets << mDiagramDistanceSpinBox;
|
||||||
|
//widgets << mDiagramFontButton;
|
||||||
|
widgets << mDiagramPenColorButton;
|
||||||
|
widgets << mDiagramSizeSpinBox;
|
||||||
|
widgets << mDiagramLineUnitComboBox;
|
||||||
|
widgets << mDiagramTypeComboBox;
|
||||||
|
widgets << mDiagramUnitComboBox;
|
||||||
|
widgets << mFixedSizeRadio;
|
||||||
|
widgets << mIncreaseMinimumSizeSpinBox;
|
||||||
|
widgets << mIncreaseSmallDiagramsCheck;
|
||||||
|
widgets << mLabelPlacementComboBox;
|
||||||
|
widgets << mMaxValueSpinBox;
|
||||||
|
widgets << mPenWidthSpinBox;
|
||||||
|
widgets << mPrioritySlider;
|
||||||
|
widgets << mOpacityWidget;
|
||||||
|
widgets << mOrientationDownButton;
|
||||||
|
widgets << mOrientationLeftButton;
|
||||||
|
widgets << mOrientationRightButton;
|
||||||
|
widgets << mOrientationUpButton;
|
||||||
|
widgets << mScaleDependencyComboBox;
|
||||||
|
widgets << mScaleRangeWidget;
|
||||||
|
widgets << mScaleVisibilityGroupBox;
|
||||||
|
widgets << mShowAllCheckBox;
|
||||||
|
widgets << mShowAxisGroupBox;
|
||||||
|
widgets << mSizeFieldExpressionWidget;
|
||||||
|
widgets << mSizeSpinBox;
|
||||||
|
widgets << mZIndexSpinBox;
|
||||||
|
widgets << radAroundCentroid;
|
||||||
|
widgets << radAroundLine;
|
||||||
|
widgets << radAroundPoint;
|
||||||
|
widgets << radInsidePolygon;
|
||||||
|
widgets << radOverCentroid;
|
||||||
|
widgets << radOverLine;
|
||||||
|
widgets << radOverPoint;
|
||||||
|
widgets << radPolygonPerimeter;
|
||||||
|
|
||||||
|
connectValueChanged( widgets, SIGNAL( widgetChanged() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsDiagramProperties::syncToLayer( const QgsDiagramRenderer *dr )
|
void QgsDiagramProperties::setDockMode( bool dockMode )
|
||||||
|
{
|
||||||
|
QgsPanelWidget::setDockMode( dockMode );
|
||||||
|
mOptionsTab->setVisible( dockMode );
|
||||||
|
mOptionsTab->setTabToolTip( 0, tr( "Attributes" ) );
|
||||||
|
mOptionsTab->setTabToolTip( 1, tr( "Rendering" ) );
|
||||||
|
mOptionsTab->setTabToolTip( 2, tr( "Size" ) );
|
||||||
|
mOptionsTab->setTabToolTip( 3, tr( "Placement" ) );
|
||||||
|
mOptionsTab->setTabToolTip( 4, tr( "Options" ) );
|
||||||
|
mOptionsTab->setTabToolTip( 5, tr( "Legend" ) );
|
||||||
|
mDiagramOptionsListFrame->setVisible( !dockMode );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsDiagramProperties::setDiagramType( const QString diagramType )
|
||||||
|
{
|
||||||
|
mDiagramType = diagramType;
|
||||||
|
|
||||||
|
mDiagramTypeComboBox->setVisible( false );
|
||||||
|
mDiagramTypeComboBox->blockSignals( true );
|
||||||
|
mDiagramTypeComboBox->setCurrentIndex( mDiagramTypeComboBox->findData( mDiagramType ) );
|
||||||
|
mDiagramTypeComboBox->blockSignals( false );
|
||||||
|
|
||||||
|
//force a refresh of widget status to match diagram type
|
||||||
|
mDiagramTypeComboBox_currentIndexChanged( mDiagramTypeComboBox->currentIndex() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsDiagramProperties::syncToLayer()
|
||||||
|
{
|
||||||
|
const QgsDiagramRenderer *renderer = mLayer->diagramRenderer();
|
||||||
|
syncToRenderer( renderer );
|
||||||
|
|
||||||
|
const QgsDiagramLayerSettings *layerDls = mLayer->diagramLayerSettings();
|
||||||
|
syncToSettings( layerDls );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsDiagramProperties::syncToRenderer( const QgsDiagramRenderer *dr )
|
||||||
{
|
{
|
||||||
mDiagramAttributesTreeWidget->clear();
|
mDiagramAttributesTreeWidget->clear();
|
||||||
if ( !dr )
|
|
||||||
{
|
|
||||||
dr = mLayer->diagramRenderer();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !dr ) //no diagram renderer yet, insert reasonable default
|
if ( !dr ) //no diagram renderer yet, insert reasonable default
|
||||||
{
|
{
|
||||||
@ -344,6 +442,7 @@ void QgsDiagramProperties::syncToLayer( const QgsDiagramRenderer *dr )
|
|||||||
const QList<QgsDiagramSettings> settingList = dr->diagramSettings();
|
const QList<QgsDiagramSettings> settingList = dr->diagramSettings();
|
||||||
if ( !settingList.isEmpty() )
|
if ( !settingList.isEmpty() )
|
||||||
{
|
{
|
||||||
|
mOptionsTab->setEnabled( settingList.at( 0 ).enabled );
|
||||||
mDiagramFrame->setEnabled( settingList.at( 0 ).enabled );
|
mDiagramFrame->setEnabled( settingList.at( 0 ).enabled );
|
||||||
mDiagramFontButton->setCurrentFont( settingList.at( 0 ).font );
|
mDiagramFontButton->setCurrentFont( settingList.at( 0 ).font );
|
||||||
const QSizeF size = settingList.at( 0 ).size;
|
const QSizeF size = settingList.at( 0 ).size;
|
||||||
@ -458,51 +557,6 @@ void QgsDiagramProperties::syncToLayer( const QgsDiagramRenderer *dr )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const QgsDiagramLayerSettings *dls = mLayer->diagramLayerSettings();
|
|
||||||
if ( dls )
|
|
||||||
{
|
|
||||||
mDiagramDistanceSpinBox->setValue( dls->distance() );
|
|
||||||
mPrioritySlider->setValue( dls->priority() );
|
|
||||||
mZIndexSpinBox->setValue( dls->zIndex() );
|
|
||||||
|
|
||||||
switch ( dls->placement() )
|
|
||||||
{
|
|
||||||
case QgsDiagramLayerSettings::AroundPoint:
|
|
||||||
radAroundPoint->setChecked( true );
|
|
||||||
radAroundCentroid->setChecked( true );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case QgsDiagramLayerSettings::OverPoint:
|
|
||||||
radOverPoint->setChecked( true );
|
|
||||||
radOverCentroid->setChecked( true );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case QgsDiagramLayerSettings::Line:
|
|
||||||
radAroundLine->setChecked( true );
|
|
||||||
radPolygonPerimeter->setChecked( true );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case QgsDiagramLayerSettings::Horizontal:
|
|
||||||
radOverLine->setChecked( true );
|
|
||||||
radInsidePolygon->setChecked( true );
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
chkLineAbove->setChecked( dls->linePlacementFlags() & QgsDiagramLayerSettings::AboveLine );
|
|
||||||
chkLineBelow->setChecked( dls->linePlacementFlags() & QgsDiagramLayerSettings::BelowLine );
|
|
||||||
chkLineOn->setChecked( dls->linePlacementFlags() & QgsDiagramLayerSettings::OnLine );
|
|
||||||
if ( !( dls->linePlacementFlags() & QgsDiagramLayerSettings::MapOrientation ) )
|
|
||||||
chkLineOrientationDependent->setChecked( true );
|
|
||||||
updatePlacementWidgets();
|
|
||||||
|
|
||||||
mShowAllCheckBox->setChecked( dls->showAllDiagrams() );
|
|
||||||
|
|
||||||
mDataDefinedProperties = dls->dataDefinedProperties();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( dr->diagram() )
|
if ( dr->diagram() )
|
||||||
{
|
{
|
||||||
mDiagramType = dr->diagram()->diagramName();
|
mDiagramType = dr->diagram()->diagramName();
|
||||||
@ -523,6 +577,53 @@ void QgsDiagramProperties::syncToLayer( const QgsDiagramRenderer *dr )
|
|||||||
mPaintEffectWidget->setPaintEffect( mPaintEffect.get() );
|
mPaintEffectWidget->setPaintEffect( mPaintEffect.get() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QgsDiagramProperties::syncToSettings( const QgsDiagramLayerSettings *dls )
|
||||||
|
{
|
||||||
|
if ( dls )
|
||||||
|
{
|
||||||
|
mDiagramDistanceSpinBox->setValue( dls->distance() );
|
||||||
|
mPrioritySlider->setValue( dls->priority() );
|
||||||
|
mZIndexSpinBox->setValue( dls->zIndex() );
|
||||||
|
|
||||||
|
switch ( dls->placement() )
|
||||||
|
{
|
||||||
|
case QgsDiagramLayerSettings::AroundPoint:
|
||||||
|
radAroundPoint->setChecked( true );
|
||||||
|
radAroundCentroid->setChecked( true );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QgsDiagramLayerSettings::OverPoint:
|
||||||
|
radOverPoint->setChecked( true );
|
||||||
|
radOverCentroid->setChecked( true );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QgsDiagramLayerSettings::Line:
|
||||||
|
radAroundLine->setChecked( true );
|
||||||
|
radPolygonPerimeter->setChecked( true );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QgsDiagramLayerSettings::Horizontal:
|
||||||
|
radOverLine->setChecked( true );
|
||||||
|
radInsidePolygon->setChecked( true );
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
chkLineAbove->setChecked( dls->linePlacementFlags() & QgsDiagramLayerSettings::AboveLine );
|
||||||
|
chkLineBelow->setChecked( dls->linePlacementFlags() & QgsDiagramLayerSettings::BelowLine );
|
||||||
|
chkLineOn->setChecked( dls->linePlacementFlags() & QgsDiagramLayerSettings::OnLine );
|
||||||
|
if ( !( dls->linePlacementFlags() & QgsDiagramLayerSettings::MapOrientation ) )
|
||||||
|
chkLineOrientationDependent->setChecked( true );
|
||||||
|
updatePlacementWidgets();
|
||||||
|
|
||||||
|
mShowAllCheckBox->setChecked( dls->showAllDiagrams() );
|
||||||
|
|
||||||
|
mDataDefinedProperties = dls->dataDefinedProperties();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QgsDiagramProperties::~QgsDiagramProperties()
|
QgsDiagramProperties::~QgsDiagramProperties()
|
||||||
{
|
{
|
||||||
QgsSettings settings;
|
QgsSettings settings;
|
||||||
@ -543,6 +644,7 @@ void QgsDiagramProperties::updateProperty()
|
|||||||
QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
|
QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
|
||||||
const QgsDiagramLayerSettings::Property key = static_cast< QgsDiagramLayerSettings::Property >( button->propertyKey() );
|
const QgsDiagramLayerSettings::Property key = static_cast< QgsDiagramLayerSettings::Property >( button->propertyKey() );
|
||||||
mDataDefinedProperties.setProperty( key, button->toProperty() );
|
mDataDefinedProperties.setProperty( key, button->toProperty() );
|
||||||
|
emit widgetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsDiagramProperties::mDiagramTypeComboBox_currentIndexChanged( int index )
|
void QgsDiagramProperties::mDiagramTypeComboBox_currentIndexChanged( int index )
|
||||||
@ -750,6 +852,29 @@ void QgsDiagramProperties::mDiagramAttributesTreeWidget_itemDoubleClicked( QTree
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr< QgsDiagram > QgsDiagramProperties::createDiagramObject()
|
||||||
|
{
|
||||||
|
std::unique_ptr< QgsDiagram > diagram;
|
||||||
|
|
||||||
|
if ( mDiagramType == DIAGRAM_NAME_TEXT )
|
||||||
|
{
|
||||||
|
diagram = std::make_unique< QgsTextDiagram >();
|
||||||
|
}
|
||||||
|
else if ( mDiagramType == DIAGRAM_NAME_PIE )
|
||||||
|
{
|
||||||
|
diagram = std::make_unique< QgsPieDiagram >();
|
||||||
|
}
|
||||||
|
else if ( mDiagramType == DIAGRAM_NAME_STACKED_BAR )
|
||||||
|
{
|
||||||
|
diagram = std::make_unique< QgsStackedBarDiagram >();
|
||||||
|
}
|
||||||
|
else // if ( diagramType == DIAGRAM_NAME_HISTOGRAM )
|
||||||
|
{
|
||||||
|
diagram = std::make_unique< QgsHistogramDiagram >();
|
||||||
|
}
|
||||||
|
return diagram;
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<QgsDiagramSettings> QgsDiagramProperties::createDiagramSettings()
|
std::unique_ptr<QgsDiagramSettings> QgsDiagramProperties::createDiagramSettings()
|
||||||
{
|
{
|
||||||
std::unique_ptr< QgsDiagramSettings > ds = std::make_unique< QgsDiagramSettings>();
|
std::unique_ptr< QgsDiagramSettings > ds = std::make_unique< QgsDiagramSettings>();
|
||||||
@ -821,13 +946,15 @@ std::unique_ptr<QgsDiagramSettings> QgsDiagramProperties::createDiagramSettings(
|
|||||||
return ds;
|
return ds;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<QgsDiagramRenderer> QgsDiagramProperties::createRendererBaseInfo( const QgsDiagramSettings &ds )
|
std::unique_ptr<QgsDiagramRenderer> QgsDiagramProperties::createRenderer()
|
||||||
{
|
{
|
||||||
|
std::unique_ptr< QgsDiagramSettings > ds = createDiagramSettings();
|
||||||
|
|
||||||
std::unique_ptr< QgsDiagramRenderer > renderer;
|
std::unique_ptr< QgsDiagramRenderer > renderer;
|
||||||
if ( mFixedSizeRadio->isChecked() )
|
if ( mFixedSizeRadio->isChecked() )
|
||||||
{
|
{
|
||||||
std::unique_ptr< QgsSingleCategoryDiagramRenderer > dr = std::make_unique< QgsSingleCategoryDiagramRenderer >();
|
std::unique_ptr< QgsSingleCategoryDiagramRenderer > dr = std::make_unique< QgsSingleCategoryDiagramRenderer >();
|
||||||
dr->setDiagramSettings( ds );
|
dr->setDiagramSettings( *ds );
|
||||||
renderer = std::move( dr );
|
renderer = std::move( dr );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -849,7 +976,7 @@ std::unique_ptr<QgsDiagramRenderer> QgsDiagramProperties::createRendererBaseInfo
|
|||||||
{
|
{
|
||||||
dr->setClassificationField( sizeFieldNameOrExp );
|
dr->setClassificationField( sizeFieldNameOrExp );
|
||||||
}
|
}
|
||||||
dr->setDiagramSettings( ds );
|
dr->setDiagramSettings( *ds );
|
||||||
|
|
||||||
dr->setDataDefinedSizeLegend( mSizeLegend ? new QgsDataDefinedSizeLegend( *mSizeLegend ) : nullptr );
|
dr->setDataDefinedSizeLegend( mSizeLegend ? new QgsDataDefinedSizeLegend( *mSizeLegend ) : nullptr );
|
||||||
|
|
||||||
@ -857,6 +984,10 @@ std::unique_ptr<QgsDiagramRenderer> QgsDiagramProperties::createRendererBaseInfo
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderer->setAttributeLegend( mCheckBoxAttributeLegend->isChecked() );
|
renderer->setAttributeLegend( mCheckBoxAttributeLegend->isChecked() );
|
||||||
|
|
||||||
|
std::unique_ptr< QgsDiagram > diagram = createDiagramObject();
|
||||||
|
renderer->setDiagram( diagram.release() );
|
||||||
|
|
||||||
return renderer;
|
return renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -914,34 +1045,18 @@ void QgsDiagramProperties::apply()
|
|||||||
const int index = mDiagramTypeComboBox->currentIndex();
|
const int index = mDiagramTypeComboBox->currentIndex();
|
||||||
const bool diagramsEnabled = ( index != -1 );
|
const bool diagramsEnabled = ( index != -1 );
|
||||||
|
|
||||||
std::unique_ptr< QgsDiagram > diagram;
|
// Avoid this messageBox when in both dock and liveUpdate mode
|
||||||
|
QgsSettings settings;
|
||||||
if ( diagramsEnabled && 0 == mDiagramAttributesTreeWidget->topLevelItemCount() )
|
if ( !dockMode() || !settings.value( QStringLiteral( "UI/autoApplyStyling" ), true ).toBool() )
|
||||||
{
|
{
|
||||||
QMessageBox::warning( this, tr( "Diagrams: No attributes added." ),
|
if ( diagramsEnabled && 0 == mDiagramAttributesTreeWidget->topLevelItemCount() )
|
||||||
tr( "You did not add any attributes to this diagram layer. Please specify the attributes to visualize on the diagrams or disable diagrams." ) );
|
{
|
||||||
|
QMessageBox::warning( this, tr( "Diagrams: No attributes added." ),
|
||||||
|
tr( "You did not add any attributes to this diagram layer. Please specify the attributes to visualize on the diagrams or disable diagrams." ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( mDiagramType == DIAGRAM_NAME_TEXT )
|
std::unique_ptr< QgsDiagramRenderer > renderer = createRenderer();
|
||||||
{
|
|
||||||
diagram = std::make_unique< QgsTextDiagram >();
|
|
||||||
}
|
|
||||||
else if ( mDiagramType == DIAGRAM_NAME_PIE )
|
|
||||||
{
|
|
||||||
diagram = std::make_unique< QgsPieDiagram >();
|
|
||||||
}
|
|
||||||
else if ( mDiagramType == DIAGRAM_NAME_STACKED_BAR )
|
|
||||||
{
|
|
||||||
diagram = std::make_unique< QgsStackedBarDiagram >();
|
|
||||||
}
|
|
||||||
else // if ( diagramType == DIAGRAM_NAME_HISTOGRAM )
|
|
||||||
{
|
|
||||||
diagram = std::make_unique< QgsHistogramDiagram >();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr< QgsDiagramSettings > ds = createDiagramSettings();
|
|
||||||
std::unique_ptr< QgsDiagramRenderer > renderer = createRendererBaseInfo( *ds );
|
|
||||||
renderer->setDiagram( diagram.release() );
|
|
||||||
mLayer->setDiagramRenderer( renderer.release() );
|
mLayer->setDiagramRenderer( renderer.release() );
|
||||||
|
|
||||||
QgsDiagramLayerSettings dls = createDiagramLayerSettings();
|
QgsDiagramLayerSettings dls = createDiagramLayerSettings();
|
||||||
@ -1051,6 +1166,30 @@ void QgsDiagramProperties::scalingTypeChanged()
|
|||||||
mButtonSizeLegendSettings->setEnabled( mAttributeBasedScalingRadio->isChecked() );
|
mButtonSizeLegendSettings->setEnabled( mAttributeBasedScalingRadio->isChecked() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QgsDiagramProperties::setAllowedToEditDiagramLayerSettings( bool allowed )
|
||||||
|
{
|
||||||
|
mAllowedToEditDls = allowed;
|
||||||
|
|
||||||
|
label_16->setVisible( allowed );
|
||||||
|
mZIndexSpinBox->setVisible( allowed );
|
||||||
|
mZOrderDDBtn->setVisible( allowed );
|
||||||
|
mShowAllCheckBox->setVisible( allowed );
|
||||||
|
mDlsLabel_1->setVisible( !allowed );
|
||||||
|
|
||||||
|
mCoordinatesGrpBox->setVisible( allowed );
|
||||||
|
mLinePlacementFrame->setVisible( allowed );
|
||||||
|
mObstaclesGrpBox->setVisible( allowed );
|
||||||
|
mPlacementFrame->setVisible( allowed );
|
||||||
|
mPriorityGrpBox->setVisible( allowed );
|
||||||
|
stackedPlacement->setVisible( allowed );
|
||||||
|
mDlsLabel_2->setVisible( !allowed );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QgsDiagramProperties::isAllowedToEditDiagramLayerSettings() const
|
||||||
|
{
|
||||||
|
return mAllowedToEditDls;
|
||||||
|
}
|
||||||
|
|
||||||
void QgsDiagramProperties::showSizeLegendDialog()
|
void QgsDiagramProperties::showSizeLegendDialog()
|
||||||
{
|
{
|
||||||
// prepare size transformer
|
// prepare size transformer
|
||||||
@ -1112,3 +1251,71 @@ void QgsDiagramProperties::createAuxiliaryField()
|
|||||||
|
|
||||||
emit auxiliaryFieldCreated();
|
emit auxiliaryFieldCreated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QgsDiagramProperties::connectValueChanged( const QList<QWidget *> &widgets, const char *signal )
|
||||||
|
{
|
||||||
|
const auto constWidgets = widgets;
|
||||||
|
for ( QWidget *widget : constWidgets )
|
||||||
|
{
|
||||||
|
if ( QgsSymbolButton *w = qobject_cast<QgsSymbolButton *>( widget ) )
|
||||||
|
{
|
||||||
|
connect( w, SIGNAL( changed() ), this, signal );
|
||||||
|
}
|
||||||
|
else if ( QgsFieldExpressionWidget *w = qobject_cast< QgsFieldExpressionWidget *>( widget ) )
|
||||||
|
{
|
||||||
|
connect( w, SIGNAL( fieldChanged( QString ) ), this, signal );
|
||||||
|
}
|
||||||
|
else if ( QgsOpacityWidget *w = qobject_cast< QgsOpacityWidget *>( widget ) )
|
||||||
|
{
|
||||||
|
connect( w, SIGNAL( opacityChanged( double ) ), this, signal );
|
||||||
|
}
|
||||||
|
else if ( QgsUnitSelectionWidget *w = qobject_cast<QgsUnitSelectionWidget *>( widget ) )
|
||||||
|
{
|
||||||
|
connect( w, SIGNAL( changed() ), this, signal );
|
||||||
|
}
|
||||||
|
else if ( QComboBox *w = qobject_cast<QComboBox *>( widget ) )
|
||||||
|
{
|
||||||
|
connect( w, SIGNAL( currentIndexChanged( int ) ), this, signal );
|
||||||
|
}
|
||||||
|
else if ( QSpinBox *w = qobject_cast<QSpinBox *>( widget ) )
|
||||||
|
{
|
||||||
|
connect( w, SIGNAL( valueChanged( int ) ), this, signal );
|
||||||
|
}
|
||||||
|
else if ( QDoubleSpinBox *w = qobject_cast<QDoubleSpinBox *>( widget ) )
|
||||||
|
{
|
||||||
|
connect( w, SIGNAL( valueChanged( double ) ), this, signal );
|
||||||
|
}
|
||||||
|
else if ( QgsColorButton *w = qobject_cast<QgsColorButton *>( widget ) )
|
||||||
|
{
|
||||||
|
connect( w, SIGNAL( colorChanged( QColor ) ), this, signal );
|
||||||
|
}
|
||||||
|
else if ( QCheckBox *w = qobject_cast<QCheckBox *>( widget ) )
|
||||||
|
{
|
||||||
|
connect( w, SIGNAL( toggled( bool ) ), this, signal );
|
||||||
|
}
|
||||||
|
else if ( QRadioButton *w = qobject_cast<QRadioButton *>( widget ) )
|
||||||
|
{
|
||||||
|
connect( w, SIGNAL( toggled( bool ) ), this, signal );
|
||||||
|
}
|
||||||
|
else if ( QSlider *w = qobject_cast<QSlider *>( widget ) )
|
||||||
|
{
|
||||||
|
connect( w, SIGNAL( valueChanged( int ) ), this, signal );
|
||||||
|
}
|
||||||
|
else if ( QGroupBox *w = qobject_cast<QGroupBox *>( widget ) )
|
||||||
|
{
|
||||||
|
connect( w, SIGNAL( toggled( bool ) ), this, signal );
|
||||||
|
}
|
||||||
|
else if ( QTreeWidget *w = qobject_cast<QTreeWidget *>( widget ) )
|
||||||
|
{
|
||||||
|
connect( w, SIGNAL( itemChanged( QTreeWidgetItem *, int ) ), this, signal );
|
||||||
|
}
|
||||||
|
else if ( QgsScaleRangeWidget *w = qobject_cast<QgsScaleRangeWidget *>( widget ) )
|
||||||
|
{
|
||||||
|
connect( w, SIGNAL( rangeChanged( double, double ) ), this, signal );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QgsLogger::warning( QStringLiteral( "Could not create connection for widget %1" ).arg( widget->objectName() ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -36,26 +36,68 @@ class QgsMapCanvas;
|
|||||||
/**
|
/**
|
||||||
* \ingroup gui
|
* \ingroup gui
|
||||||
* \class QgsDiagramProperties
|
* \class QgsDiagramProperties
|
||||||
|
*
|
||||||
|
* \note This class is not a part of public API
|
||||||
*/
|
*/
|
||||||
class GUI_EXPORT QgsDiagramProperties : public QWidget, private Ui::QgsDiagramPropertiesBase, private QgsExpressionContextGenerator
|
class GUI_EXPORT QgsDiagramProperties : public QgsPanelWidget, private Ui::QgsDiagramPropertiesBase, private QgsExpressionContextGenerator
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QgsDiagramProperties( QgsVectorLayer *layer, QWidget *parent, QgsMapCanvas *canvas );
|
QgsDiagramProperties( QgsVectorLayer *layer, QWidget *parent, QgsMapCanvas *canvas );
|
||||||
|
~QgsDiagramProperties() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the widget to reflect the layer's current diagram settings.
|
* Updates the widget to reflect the layer's current diagram settings.
|
||||||
*
|
*
|
||||||
* \since QGIS 3.16
|
* \since QGIS 3.16
|
||||||
*/
|
*/
|
||||||
void syncToLayer( const QgsDiagramRenderer *dr = nullptr );
|
void syncToLayer();
|
||||||
|
|
||||||
~QgsDiagramProperties() override;
|
/**
|
||||||
|
* Updates the widget to reflect the diagram renderer.
|
||||||
|
* \param dr Diagram renderer where settings are taken from.
|
||||||
|
*
|
||||||
|
* \since QGIS 3.40
|
||||||
|
*/
|
||||||
|
void syncToRenderer( const QgsDiagramRenderer *dr );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the widget to reflect the diagram layer settings.
|
||||||
|
* \param dls Diagram Layer Settings to update the widget.
|
||||||
|
*
|
||||||
|
* \since QGIS 3.40
|
||||||
|
*/
|
||||||
|
void syncToSettings( const QgsDiagramLayerSettings *dls );
|
||||||
|
|
||||||
//! Adds an attribute from the list of available attributes to the assigned attributes with a random color.
|
//! Adds an attribute from the list of available attributes to the assigned attributes with a random color.
|
||||||
void addAttribute( QTreeWidgetItem *item );
|
void addAttribute( QTreeWidgetItem *item );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the widget in dock mode.
|
||||||
|
* \param dockMode TRUE for dock mode.
|
||||||
|
*/
|
||||||
|
void setDockMode( bool dockMode ) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the widget's diagram type and lets it know it should hide the type comboBox.
|
||||||
|
* @param diagramType Type of diagram to be set
|
||||||
|
*/
|
||||||
|
void setDiagramType( const QString diagramType );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether the widget should show diagram layer settings.
|
||||||
|
* Used by stacked diagrams, which disable editing of DLS for sub diagrams
|
||||||
|
* other than the first one.
|
||||||
|
* @param allowed Whether this widget should be allowed to edit diagram layer settings.
|
||||||
|
*/
|
||||||
|
void setAllowedToEditDiagramLayerSettings( bool allowed );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether this widget is allowed to edit diagram layer settings.
|
||||||
|
*/
|
||||||
|
bool isAllowedToEditDiagramLayerSettings() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void auxiliaryFieldCreated();
|
void auxiliaryFieldCreated();
|
||||||
@ -118,8 +160,24 @@ class GUI_EXPORT QgsDiagramProperties : public QWidget, private Ui::QgsDiagramPr
|
|||||||
|
|
||||||
QgsExpressionContext createExpressionContext() const override;
|
QgsExpressionContext createExpressionContext() const override;
|
||||||
|
|
||||||
|
bool mAllowedToEditDls = true;
|
||||||
|
|
||||||
void registerDataDefinedButton( QgsPropertyOverrideButton *button, QgsDiagramLayerSettings::Property key );
|
void registerDataDefinedButton( QgsPropertyOverrideButton *button, QgsDiagramLayerSettings::Property key );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience function to chain widgets' change value signal to another signal.
|
||||||
|
* @param widgets List of widgets.
|
||||||
|
* @param signal Signal to be triggered by each widget's change value signal.
|
||||||
|
*/
|
||||||
|
void connectValueChanged( const QList<QWidget *> &widgets, const char *signal );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a QgsDiagram object from the GUI settings.
|
||||||
|
*
|
||||||
|
* \since QGIS 3.40
|
||||||
|
*/
|
||||||
|
std::unique_ptr< QgsDiagram > createDiagramObject();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a QgsDiagramSettings object from the GUI settings.
|
* Creates a QgsDiagramSettings object from the GUI settings.
|
||||||
*
|
*
|
||||||
@ -132,7 +190,7 @@ class GUI_EXPORT QgsDiagramProperties : public QWidget, private Ui::QgsDiagramPr
|
|||||||
*
|
*
|
||||||
* \since QGIS 3.40
|
* \since QGIS 3.40
|
||||||
*/
|
*/
|
||||||
std::unique_ptr<QgsDiagramRenderer> createRendererBaseInfo( const QgsDiagramSettings &ds );
|
std::unique_ptr<QgsDiagramRenderer> createRenderer();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a QgsDiagramLayerSettings object from the GUI settings.
|
* Creates a QgsDiagramLayerSettings object from the GUI settings.
|
||||||
@ -142,6 +200,7 @@ class GUI_EXPORT QgsDiagramProperties : public QWidget, private Ui::QgsDiagramPr
|
|||||||
QgsDiagramLayerSettings createDiagramLayerSettings();
|
QgsDiagramLayerSettings createDiagramLayerSettings();
|
||||||
|
|
||||||
friend class QgsStackedDiagramProperties;
|
friend class QgsStackedDiagramProperties;
|
||||||
|
friend class QgsStackedDiagramPropertiesDialog;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
220
src/gui/vector/qgsdiagramwidget.cpp
Normal file
220
src/gui/vector/qgsdiagramwidget.cpp
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
qgsdiagramwidget.h
|
||||||
|
Container widget for diagram layers
|
||||||
|
-------------------
|
||||||
|
begin : September 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 "diagram/qgshistogramdiagram.h"
|
||||||
|
#include "diagram/qgspiediagram.h"
|
||||||
|
#include "diagram/qgstextdiagram.h"
|
||||||
|
#include "diagram/qgsstackedbardiagram.h"
|
||||||
|
|
||||||
|
#include "qgsdiagramwidget.h"
|
||||||
|
#include "qgsvectorlayer.h"
|
||||||
|
#include "qgsapplication.h"
|
||||||
|
#include "qgsguiutils.h"
|
||||||
|
#include "qgslabelengineconfigdialog.h"
|
||||||
|
#include "qgsdiagramproperties.h"
|
||||||
|
#include "qgsstackeddiagramproperties.h"
|
||||||
|
|
||||||
|
|
||||||
|
QgsDiagramWidget::QgsDiagramWidget( QgsVectorLayer *layer, QgsMapCanvas *canvas, QWidget *parent )
|
||||||
|
: QgsMapLayerConfigWidget( layer, canvas, parent )
|
||||||
|
, mLayer( layer )
|
||||||
|
, mCanvas( canvas )
|
||||||
|
{
|
||||||
|
if ( !layer )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setupUi( this );
|
||||||
|
|
||||||
|
// Initialize stacked diagram controls
|
||||||
|
mDiagramTypeComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "diagramNone.svg" ) ), tr( "No Diagrams" ), ModeNone );
|
||||||
|
mDiagramTypeComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "pie-chart.svg" ) ), tr( "Pie Chart" ), ModePie );
|
||||||
|
mDiagramTypeComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "text.svg" ) ), tr( "Text Diagram" ), ModeText );
|
||||||
|
mDiagramTypeComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "histogram.svg" ) ), tr( "Histogram" ), ModeHistogram );
|
||||||
|
mDiagramTypeComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "stacked-bar.svg" ) ), tr( "Stacked Bars" ), ModeStackedBar );
|
||||||
|
mDiagramTypeComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "diagramNone.svg" ) ), tr( "Stacked Diagram" ), ModeStacked );
|
||||||
|
|
||||||
|
connect( mEngineSettingsButton, &QAbstractButton::clicked, this, &QgsDiagramWidget::showEngineConfigDialog );
|
||||||
|
|
||||||
|
connect( mDiagramTypeComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsDiagramWidget::mDiagramTypeComboBox_currentIndexChanged );
|
||||||
|
|
||||||
|
const int iconSize16 = QgsGuiUtils::scaleIconSize( 16 );
|
||||||
|
mEngineSettingsButton->setIconSize( QSize( iconSize16, iconSize16 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsDiagramWidget::apply()
|
||||||
|
{
|
||||||
|
const Mode mode = static_cast< Mode >( mDiagramTypeComboBox->currentData().toInt() );
|
||||||
|
|
||||||
|
switch ( mode )
|
||||||
|
{
|
||||||
|
case ModeStacked:
|
||||||
|
{
|
||||||
|
// Delegate to stacked diagram's apply
|
||||||
|
static_cast<QgsStackedDiagramProperties *>( mWidget )->apply();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ModePie:
|
||||||
|
case ModeText:
|
||||||
|
case ModeHistogram:
|
||||||
|
case ModeStackedBar:
|
||||||
|
{
|
||||||
|
// Delegate to single diagram's apply
|
||||||
|
static_cast<QgsDiagramProperties *>( mWidget )->apply();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ModeNone:
|
||||||
|
{
|
||||||
|
mLayer->setDiagramRenderer( nullptr );
|
||||||
|
|
||||||
|
QgsDiagramLayerSettings dls;
|
||||||
|
mLayer->setDiagramLayerSettings( dls );
|
||||||
|
|
||||||
|
// refresh
|
||||||
|
QgsProject::instance()->setDirty( true );
|
||||||
|
mLayer->triggerRepaint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsDiagramWidget::syncToOwnLayer()
|
||||||
|
{
|
||||||
|
if ( !mLayer )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
whileBlocking( mDiagramTypeComboBox )->setCurrentIndex( -1 );
|
||||||
|
|
||||||
|
const QgsDiagramRenderer *dr = mLayer->diagramRenderer();
|
||||||
|
|
||||||
|
// pick the right mode from the layer
|
||||||
|
if ( dr && dr->diagram() )
|
||||||
|
{
|
||||||
|
if ( dr->rendererName() == QStringLiteral( "Stacked" ) )
|
||||||
|
{
|
||||||
|
mDiagramTypeComboBox->setCurrentIndex( ModeStacked );
|
||||||
|
}
|
||||||
|
else // Single diagram
|
||||||
|
{
|
||||||
|
const QString diagramName = dr->diagram()->diagramName();
|
||||||
|
if ( diagramName == DIAGRAM_NAME_PIE )
|
||||||
|
{
|
||||||
|
mDiagramTypeComboBox->setCurrentIndex( ModePie ) ;
|
||||||
|
}
|
||||||
|
else if ( diagramName == DIAGRAM_NAME_TEXT )
|
||||||
|
{
|
||||||
|
mDiagramTypeComboBox->setCurrentIndex( ModeText ) ;
|
||||||
|
}
|
||||||
|
else if ( diagramName == DIAGRAM_NAME_STACKED_BAR )
|
||||||
|
{
|
||||||
|
mDiagramTypeComboBox->setCurrentIndex( ModeStackedBar ) ;
|
||||||
|
}
|
||||||
|
else // diagramName == DIAGRAM_NAME_HISTOGRAM
|
||||||
|
{
|
||||||
|
// Play safe and set to histogram by default if the diagram name is unknown
|
||||||
|
mDiagramTypeComboBox->setCurrentIndex( ModeHistogram );
|
||||||
|
}
|
||||||
|
// TODO: if we get a stacked diagram, take the first subdiagram,
|
||||||
|
// Set its diagram type and sync to its settings
|
||||||
|
|
||||||
|
// Delegate to single diagram's syncToLayer
|
||||||
|
static_cast<QgsDiagramProperties *>( mWidget )->syncToLayer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // No Diagram
|
||||||
|
{
|
||||||
|
mDiagramTypeComboBox->setCurrentIndex( ModeNone );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsDiagramWidget::mDiagramTypeComboBox_currentIndexChanged( int index )
|
||||||
|
{
|
||||||
|
if ( mWidget )
|
||||||
|
mStackedWidget->removeWidget( mWidget );
|
||||||
|
|
||||||
|
delete mWidget;
|
||||||
|
mWidget = nullptr;
|
||||||
|
|
||||||
|
if ( index < 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
const Mode mode = static_cast< Mode >( mDiagramTypeComboBox->currentData().toInt() );
|
||||||
|
|
||||||
|
switch ( mode )
|
||||||
|
{
|
||||||
|
case ModePie:
|
||||||
|
case ModeText:
|
||||||
|
case ModeHistogram:
|
||||||
|
case ModeStackedBar:
|
||||||
|
{
|
||||||
|
QgsDiagramProperties *singleWidget = new QgsDiagramProperties( mLayer, this, mMapCanvas );
|
||||||
|
singleWidget->layout()->setContentsMargins( 0, 0, 0, 0 );
|
||||||
|
singleWidget->setDockMode( dockMode() );
|
||||||
|
|
||||||
|
if ( mode == ModePie )
|
||||||
|
singleWidget->setDiagramType( DIAGRAM_NAME_PIE );
|
||||||
|
else if ( mode == ModeText )
|
||||||
|
singleWidget->setDiagramType( DIAGRAM_NAME_TEXT );
|
||||||
|
else if ( mode == ModeHistogram )
|
||||||
|
singleWidget->setDiagramType( DIAGRAM_NAME_HISTOGRAM );
|
||||||
|
else if ( mode == ModeStackedBar )
|
||||||
|
singleWidget->setDiagramType( DIAGRAM_NAME_STACKED_BAR );
|
||||||
|
|
||||||
|
connect( singleWidget, &QgsDiagramProperties::widgetChanged, this, &QgsDiagramWidget::widgetChanged );
|
||||||
|
connect( singleWidget, &QgsDiagramProperties::auxiliaryFieldCreated, this, &QgsDiagramWidget::auxiliaryFieldCreated );
|
||||||
|
|
||||||
|
mWidget = singleWidget;
|
||||||
|
mStackedWidget->addWidget( mWidget );
|
||||||
|
mStackedWidget->setCurrentWidget( mWidget );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ModeStacked:
|
||||||
|
{
|
||||||
|
QgsStackedDiagramProperties *stackedWidget = new QgsStackedDiagramProperties( mLayer, this, mCanvas );
|
||||||
|
stackedWidget->setDockMode( dockMode() );
|
||||||
|
connect( stackedWidget, &QgsPanelWidget::showPanel, this, &QgsPanelWidget::openPanel );
|
||||||
|
connect( stackedWidget, &QgsStackedDiagramProperties::widgetChanged, this, &QgsDiagramWidget::widgetChanged );
|
||||||
|
mWidget = stackedWidget;
|
||||||
|
mStackedWidget->addWidget( mWidget );
|
||||||
|
mStackedWidget->setCurrentWidget( mWidget );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ModeNone:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
emit widgetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsDiagramWidget::showEngineConfigDialog()
|
||||||
|
{
|
||||||
|
QgsPanelWidget *panel = QgsPanelWidget::findParentPanel( this );
|
||||||
|
if ( panel && panel->dockMode() )
|
||||||
|
{
|
||||||
|
QgsLabelEngineConfigWidget *widget = new QgsLabelEngineConfigWidget( mCanvas );
|
||||||
|
connect( widget, &QgsLabelEngineConfigWidget::widgetChanged, widget, &QgsLabelEngineConfigWidget::apply );
|
||||||
|
panel->openPanel( widget );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QgsLabelEngineConfigDialog dialog( mCanvas, this );
|
||||||
|
dialog.exec();
|
||||||
|
// reactivate button's window
|
||||||
|
activateWindow();
|
||||||
|
}
|
||||||
|
}
|
78
src/gui/vector/qgsdiagramwidget.h
Normal file
78
src/gui/vector/qgsdiagramwidget.h
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
qgsdiagramwidget.h
|
||||||
|
Container widget for diagram layers
|
||||||
|
-------------------
|
||||||
|
begin : September 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 QGSDIAGRAMWIDGET_H
|
||||||
|
#define QGSDIAGRAMWIDGET_H
|
||||||
|
|
||||||
|
// We don't want to expose this in the public API
|
||||||
|
#define SIP_NO_FILE
|
||||||
|
|
||||||
|
#include <qgsmaplayerconfigwidget.h>
|
||||||
|
#include "ui_qgsdiagramwidget.h"
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \ingroup gui
|
||||||
|
* \class QgsDiagramWidget
|
||||||
|
*
|
||||||
|
* \since QGIS 3.40
|
||||||
|
*/
|
||||||
|
class GUI_EXPORT QgsDiagramWidget : public QgsMapLayerConfigWidget, private Ui::QgsDiagramWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
//! constructor
|
||||||
|
QgsDiagramWidget( QgsVectorLayer *layer, QgsMapCanvas *canvas, QWidget *parent = nullptr );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the widget to reflect the layer's current diagram settings.
|
||||||
|
*/
|
||||||
|
void syncToOwnLayer();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
//! Saves the labeling configuration and immediately updates the map canvas to reflect the changes
|
||||||
|
void apply() override;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
//! Emitted when an auxiliary field is created
|
||||||
|
void auxiliaryFieldCreated();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void mDiagramTypeComboBox_currentIndexChanged( int index );
|
||||||
|
void showEngineConfigDialog();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
enum Mode
|
||||||
|
{
|
||||||
|
ModeNone,
|
||||||
|
ModePie,
|
||||||
|
ModeText,
|
||||||
|
ModeHistogram,
|
||||||
|
ModeStackedBar,
|
||||||
|
ModeStacked
|
||||||
|
};
|
||||||
|
|
||||||
|
QgsVectorLayer *mLayer = nullptr;
|
||||||
|
QgsMapCanvas *mCanvas = nullptr;
|
||||||
|
|
||||||
|
QWidget *mWidget = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QGSDIAGRAMWIDGET_H
|
@ -19,40 +19,37 @@
|
|||||||
#include "diagram/qgspiediagram.h"
|
#include "diagram/qgspiediagram.h"
|
||||||
#include "diagram/qgstextdiagram.h"
|
#include "diagram/qgstextdiagram.h"
|
||||||
#include "diagram/qgsstackedbardiagram.h"
|
#include "diagram/qgsstackedbardiagram.h"
|
||||||
|
#include "diagram/qgsstackeddiagram.h"
|
||||||
|
|
||||||
#include "qgsapplication.h"
|
#include "qgsgui.h"
|
||||||
#include "qgsdiagramproperties.h"
|
#include "qgsdiagramproperties.h"
|
||||||
#include "qgslabelengineconfigdialog.h"
|
#include "qgslabelengineconfigdialog.h"
|
||||||
#include "qgsproject.h"
|
#include "qgsproject.h"
|
||||||
#include "qgsstackeddiagram.h"
|
|
||||||
#include "qgsstackeddiagramproperties.h"
|
#include "qgsstackeddiagramproperties.h"
|
||||||
#include "qgsvectorlayer.h"
|
#include "qgsvectorlayer.h"
|
||||||
|
#include "qgshelp.h"
|
||||||
|
|
||||||
QgsStackedDiagramProperties::QgsStackedDiagramProperties( QgsVectorLayer *layer, QWidget *parent, QgsMapCanvas *canvas )
|
QgsStackedDiagramProperties::QgsStackedDiagramProperties( QgsVectorLayer *layer, QWidget *parent, QgsMapCanvas *canvas )
|
||||||
: QWidget{parent}
|
: QgsPanelWidget( parent )
|
||||||
|
, mLayer( layer )
|
||||||
, mMapCanvas( canvas )
|
, mMapCanvas( canvas )
|
||||||
{
|
{
|
||||||
mLayer = layer;
|
|
||||||
if ( !layer )
|
if ( !layer )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setupUi( this );
|
setupUi( this );
|
||||||
connect( mDiagramTypeComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsStackedDiagramProperties::mDiagramTypeComboBox_currentIndexChanged );
|
|
||||||
connect( mEngineSettingsButton, &QPushButton::clicked, this, &QgsStackedDiagramProperties::mEngineSettingsButton_clicked );
|
connect( mSubDiagramsView, &QAbstractItemView::doubleClicked, this, static_cast<void ( QgsStackedDiagramProperties::* )( const QModelIndex & )>( &QgsStackedDiagramProperties::editSubDiagram ) );
|
||||||
|
|
||||||
connect( mAddSubDiagramButton, &QPushButton::clicked, this, &QgsStackedDiagramProperties::addSubDiagram );
|
connect( mAddSubDiagramButton, &QPushButton::clicked, this, &QgsStackedDiagramProperties::addSubDiagram );
|
||||||
|
connect( mEditSubDiagramButton, &QAbstractButton::clicked, this, static_cast<void ( QgsStackedDiagramProperties::* )()>( &QgsStackedDiagramProperties::editSubDiagram ) );
|
||||||
connect( mRemoveSubDiagramButton, &QPushButton::clicked, this, &QgsStackedDiagramProperties::removeSubDiagram );
|
connect( mRemoveSubDiagramButton, &QPushButton::clicked, this, &QgsStackedDiagramProperties::removeSubDiagram );
|
||||||
connect( mSubDiagramsTabWidget->tabBar(), &QTabBar::tabMoved, this, &QgsStackedDiagramProperties::mSubDiagramsTabWidget_tabMoved );
|
|
||||||
|
|
||||||
// Initialize stacked diagram controls
|
// Initialize stacked diagram controls
|
||||||
QIcon icon = QgsApplication::getThemeIcon( QStringLiteral( "diagramNone.svg" ) );
|
|
||||||
mDiagramTypeComboBox->addItem( icon, tr( "No Diagrams" ), "None" );
|
|
||||||
mDiagramTypeComboBox->addItem( tr( "Single diagram" ), QgsDiagramLayerSettings::Single );
|
|
||||||
mDiagramTypeComboBox->addItem( tr( "Stacked diagrams" ), QgsDiagramLayerSettings::Stacked );
|
|
||||||
mStackedDiagramModeComboBox->addItem( tr( "Horizontal" ), QgsDiagramSettings::Horizontal );
|
mStackedDiagramModeComboBox->addItem( tr( "Horizontal" ), QgsDiagramSettings::Horizontal );
|
||||||
mStackedDiagramModeComboBox->addItem( tr( "Vertical" ), QgsDiagramSettings::Vertical );
|
mStackedDiagramModeComboBox->addItem( tr( "Vertical" ), QgsDiagramSettings::Vertical );
|
||||||
mRemoveSubDiagramButton->setEnabled( false );
|
|
||||||
|
|
||||||
mStackedDiagramSpacingSpinBox->setClearValue( 0 );
|
mStackedDiagramSpacingSpinBox->setClearValue( 0 );
|
||||||
mStackedDiagramSpacingUnitComboBox->setUnits( { Qgis::RenderUnit::Millimeters,
|
mStackedDiagramSpacingUnitComboBox->setUnits( { Qgis::RenderUnit::Millimeters,
|
||||||
@ -62,37 +59,117 @@ QgsStackedDiagramProperties::QgsStackedDiagramProperties( QgsVectorLayer *layer,
|
|||||||
Qgis::RenderUnit::Points,
|
Qgis::RenderUnit::Points,
|
||||||
Qgis::RenderUnit::Inches } );
|
Qgis::RenderUnit::Inches } );
|
||||||
|
|
||||||
// Add default subdiagram tab
|
connect( mStackedDiagramModeComboBox, qOverload< int >( &QComboBox::currentIndexChanged ), this, &QgsStackedDiagramProperties::widgetChanged );
|
||||||
addSubDiagram();
|
connect( mStackedDiagramSpacingSpinBox, qOverload< double >( &QgsDoubleSpinBox::valueChanged ), this, &QgsStackedDiagramProperties::widgetChanged );
|
||||||
|
connect( mStackedDiagramSpacingUnitComboBox, &QgsUnitSelectionWidget::changed, this, &QgsStackedDiagramProperties::widgetChanged );
|
||||||
|
|
||||||
|
mModel = new QgsStackedDiagramPropertiesModel();
|
||||||
|
mSubDiagramsView->setModel( mModel );
|
||||||
|
|
||||||
|
connect( mModel, &QAbstractItemModel::dataChanged, this, &QgsStackedDiagramProperties::widgetChanged );
|
||||||
|
connect( mModel, &QAbstractItemModel::rowsInserted, this, &QgsStackedDiagramProperties::widgetChanged );
|
||||||
|
connect( mModel, &QAbstractItemModel::rowsRemoved, this, &QgsStackedDiagramProperties::widgetChanged );
|
||||||
|
|
||||||
syncToLayer();
|
syncToLayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsStackedDiagramProperties::addSubDiagram()
|
void QgsStackedDiagramProperties::addSubDiagram()
|
||||||
{
|
{
|
||||||
QgsDiagramProperties *gui = new QgsDiagramProperties( mLayer, this, mMapCanvas );
|
// Create a single category renderer by default
|
||||||
gui->layout()->setContentsMargins( 6, 6, 6, 6 );
|
std::unique_ptr< QgsDiagramRenderer > renderer;
|
||||||
connect( gui, &QgsDiagramProperties::auxiliaryFieldCreated, this, &QgsStackedDiagramProperties::auxiliaryFieldCreated );
|
std::unique_ptr< QgsSingleCategoryDiagramRenderer > dr = std::make_unique< QgsSingleCategoryDiagramRenderer >();
|
||||||
|
renderer = std::move( dr );
|
||||||
|
|
||||||
mSubDiagramsTabWidget->addTab( gui, tr( "Diagram %1" ).arg( mSubDiagramsTabWidget->count() + 1 ) );
|
QItemSelectionModel *sel = mSubDiagramsView->selectionModel();
|
||||||
|
const QModelIndex index = sel->currentIndex();
|
||||||
|
|
||||||
mRemoveSubDiagramButton->setEnabled( mSubDiagramsTabWidget->count() > 2 );
|
if ( index.isValid() )
|
||||||
|
{
|
||||||
|
// add after this subDiagram
|
||||||
|
const QModelIndex currentIndex = mSubDiagramsView->selectionModel()->currentIndex();
|
||||||
|
mModel->insertSubDiagram( currentIndex.row() + 1, renderer.release() );
|
||||||
|
const QModelIndex newIndex = mModel->index( currentIndex.row() + 1, 0 );
|
||||||
|
mSubDiagramsView->selectionModel()->setCurrentIndex( newIndex, QItemSelectionModel::ClearAndSelect );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// append to root
|
||||||
|
appendSubDiagram( renderer.release() );
|
||||||
|
}
|
||||||
|
editSubDiagram();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsStackedDiagramProperties::appendSubDiagram( QgsDiagramRenderer *dr )
|
||||||
|
{
|
||||||
|
const int rows = mModel->rowCount();
|
||||||
|
mModel->insertSubDiagram( rows, dr );
|
||||||
|
const QModelIndex newIndex = mModel->index( rows, 0 );
|
||||||
|
mSubDiagramsView->selectionModel()->setCurrentIndex( newIndex, QItemSelectionModel::ClearAndSelect );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsStackedDiagramProperties::editSubDiagram()
|
||||||
|
{
|
||||||
|
editSubDiagram( mSubDiagramsView->selectionModel()->currentIndex() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsStackedDiagramProperties::editSubDiagram( const QModelIndex &index )
|
||||||
|
{
|
||||||
|
if ( !index.isValid() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
QgsDiagramRenderer *renderer = mModel->subDiagramForIndex( index );
|
||||||
|
QgsDiagramLayerSettings dls = mModel->diagramLayerSettings();
|
||||||
|
QgsPanelWidget *panel = QgsPanelWidget::findParentPanel( this );
|
||||||
|
|
||||||
|
if ( panel && panel->dockMode() )
|
||||||
|
{
|
||||||
|
QgsDiagramProperties *widget = new QgsDiagramProperties( mLayer, this, mMapCanvas );
|
||||||
|
widget->setPanelTitle( tr( "Edit Sub Diagram" ) );
|
||||||
|
widget->layout()->setContentsMargins( 0, 0, 0, 0 );
|
||||||
|
widget->syncToRenderer( renderer );
|
||||||
|
widget->syncToSettings( &dls );
|
||||||
|
if ( !couldBeFirstSubDiagram( index ) )
|
||||||
|
{
|
||||||
|
widget->setAllowedToEditDiagramLayerSettings( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
connect( widget, &QgsDiagramProperties::auxiliaryFieldCreated, this, &QgsStackedDiagramProperties::auxiliaryFieldCreated );
|
||||||
|
connect( widget, &QgsPanelWidget::panelAccepted, this, &QgsStackedDiagramProperties::subDiagramWidgetPanelAccepted );
|
||||||
|
connect( widget, &QgsDiagramProperties::widgetChanged, this, &QgsStackedDiagramProperties::liveUpdateSubDiagramFromPanel );
|
||||||
|
openPanel( widget );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsStackedDiagramPropertiesDialog dlg( mLayer, this, mMapCanvas );
|
||||||
|
dlg.syncToRenderer( renderer );
|
||||||
|
dlg.syncToSettings( &dls );
|
||||||
|
if ( !couldBeFirstSubDiagram( index ) )
|
||||||
|
{
|
||||||
|
dlg.setAllowedToEditDiagramLayerSettings( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( dlg.exec() )
|
||||||
|
{
|
||||||
|
const QModelIndex index = mSubDiagramsView->selectionModel()->currentIndex();
|
||||||
|
if ( dlg.isAllowedToEditDiagramLayerSettings() )
|
||||||
|
mModel->updateDiagramLayerSettings( dlg.diagramLayerSettings() );
|
||||||
|
|
||||||
|
// This call will emit dataChanged, which in turns triggers widgetChanged()
|
||||||
|
mModel->updateSubDiagram( index, dlg.renderer() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsStackedDiagramProperties::removeSubDiagram()
|
void QgsStackedDiagramProperties::removeSubDiagram()
|
||||||
{
|
{
|
||||||
if ( mSubDiagramsTabWidget->count() > 2 )
|
const QItemSelection sel = mSubDiagramsView->selectionModel()->selection();
|
||||||
|
const auto constSel = sel;
|
||||||
|
for ( const QItemSelectionRange &range : constSel )
|
||||||
{
|
{
|
||||||
const int index = mSubDiagramsTabWidget->currentIndex();
|
if ( range.isValid() )
|
||||||
delete mSubDiagramsTabWidget->widget( index );
|
mModel->removeRows( range.top(), range.bottom() - range.top() + 1, range.parent() );
|
||||||
|
|
||||||
mRemoveSubDiagramButton->setEnabled( mSubDiagramsTabWidget->count() > 2 );
|
|
||||||
|
|
||||||
for ( int i = index; i < mSubDiagramsTabWidget->count(); i++ )
|
|
||||||
{
|
|
||||||
mSubDiagramsTabWidget->setTabText( i, tr( "Diagram %1" ).arg( i + 1 ) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// make sure that the selection is gone
|
||||||
|
mSubDiagramsView->selectionModel()->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsStackedDiagramProperties::syncToLayer()
|
void QgsStackedDiagramProperties::syncToLayer()
|
||||||
@ -101,222 +178,372 @@ void QgsStackedDiagramProperties::syncToLayer()
|
|||||||
|
|
||||||
if ( dr && dr->diagram() )
|
if ( dr && dr->diagram() )
|
||||||
{
|
{
|
||||||
if ( dr->rendererName() == QStringLiteral( "Stacked" ) )
|
const QList<QgsDiagramSettings> settingList = dr->diagramSettings();
|
||||||
|
mStackedDiagramModeComboBox->setCurrentIndex( settingList.at( 0 ).stackedDiagramMode );
|
||||||
|
mStackedDiagramSpacingSpinBox->setValue( settingList.at( 0 ).stackedDiagramSpacing() );
|
||||||
|
mStackedDiagramSpacingUnitComboBox->setUnit( settingList.at( 0 ).stackedDiagramSpacingUnit() );
|
||||||
|
|
||||||
|
if ( dr->rendererName() == QLatin1String( "Stacked" ) )
|
||||||
{
|
{
|
||||||
mDiagramTypeComboBox->blockSignals( true );
|
|
||||||
mDiagramTypeComboBox->setCurrentIndex( mDiagramTypeComboBox->findData( QgsDiagramLayerSettings::Stacked ) );
|
|
||||||
mDiagramTypeComboBox->blockSignals( false );
|
|
||||||
//force a refresh of widget status to match diagram type
|
|
||||||
mDiagramTypeComboBox_currentIndexChanged( mDiagramTypeComboBox->currentIndex() );
|
|
||||||
|
|
||||||
const QList<QgsDiagramSettings> settingList = dr->diagramSettings();
|
|
||||||
mStackedDiagramModeComboBox->setCurrentIndex( settingList.at( 0 ).stackedDiagramMode );
|
|
||||||
mStackedDiagramSpacingSpinBox->setValue( settingList.at( 0 ).stackedDiagramSpacing() );
|
|
||||||
mStackedDiagramSpacingUnitComboBox->setUnit( settingList.at( 0 ).stackedDiagramSpacingUnit() );
|
|
||||||
|
|
||||||
// Create/remove as many tabs as necessary
|
|
||||||
const QgsStackedDiagramRenderer *stackedDiagramRenderer = static_cast< const QgsStackedDiagramRenderer * >( dr );
|
const QgsStackedDiagramRenderer *stackedDiagramRenderer = static_cast< const QgsStackedDiagramRenderer * >( dr );
|
||||||
const int rendererCount = stackedDiagramRenderer->rendererCount();
|
const auto renderers = stackedDiagramRenderer->renderers();
|
||||||
while ( mSubDiagramsTabWidget->count() < rendererCount )
|
for ( const auto &renderer : renderers )
|
||||||
{
|
{
|
||||||
addSubDiagram();
|
appendSubDiagram( renderer );
|
||||||
}
|
|
||||||
while ( mSubDiagramsTabWidget->count() > rendererCount )
|
|
||||||
{
|
|
||||||
mSubDiagramsTabWidget->setCurrentIndex( mSubDiagramsTabWidget->count() - 1 );
|
|
||||||
removeSubDiagram();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call subdiagrams' syncToLayer with the corresponding rendering object
|
|
||||||
for ( int i = 0; i < mSubDiagramsTabWidget->count(); i++ )
|
|
||||||
{
|
|
||||||
QgsDiagramProperties *diagramProperties = static_cast<QgsDiagramProperties *>( mSubDiagramsTabWidget->widget( i ) );
|
|
||||||
diagramProperties->syncToLayer( stackedDiagramRenderer->renderer( i ) );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // Single diagram
|
else
|
||||||
{
|
{
|
||||||
mDiagramTypeComboBox->blockSignals( true );
|
// Take this single renderer as the first stacked renderer
|
||||||
mDiagramTypeComboBox->setCurrentIndex( mDiagramTypeComboBox->findData( QgsDiagramLayerSettings::Single ) );
|
appendSubDiagram( dr->clone() );
|
||||||
mDiagramTypeComboBox->blockSignals( false );
|
|
||||||
//force a refresh of widget status to match diagram type
|
|
||||||
mDiagramTypeComboBox_currentIndexChanged( mDiagramTypeComboBox->currentIndex() );
|
|
||||||
|
|
||||||
// Delegate to single diagram's syncToLayer
|
|
||||||
// If the diagram name is unknown, the single diagram will choose a default one (pie)
|
|
||||||
static_cast<QgsDiagramProperties *>( mSubDiagramsTabWidget->widget( 0 ) )->syncToLayer();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else // No Diagram
|
|
||||||
{
|
|
||||||
mDiagramTypeComboBox->blockSignals( true );
|
|
||||||
mDiagramTypeComboBox->setCurrentIndex( 0 );
|
|
||||||
mDiagramTypeComboBox->blockSignals( false );
|
|
||||||
//force a refresh of widget status to match diagram type
|
|
||||||
mDiagramTypeComboBox_currentIndexChanged( mDiagramTypeComboBox->currentIndex() );
|
|
||||||
|
|
||||||
// Delegate to first diagram's syncToLayer
|
const QgsDiagramLayerSettings *dls = mLayer->diagramLayerSettings();
|
||||||
// It will add required reasonable defaults
|
mModel->updateDiagramLayerSettings( *dls );
|
||||||
static_cast<QgsDiagramProperties *>( mSubDiagramsTabWidget->widget( 0 ) )->syncToLayer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void QgsStackedDiagramProperties::mSubDiagramsTabWidget_tabMoved( int from, int to )
|
|
||||||
{
|
|
||||||
Q_UNUSED( from )
|
|
||||||
Q_UNUSED( to )
|
|
||||||
for ( int i = 0; i < mSubDiagramsTabWidget->count(); i++ )
|
|
||||||
{
|
|
||||||
mSubDiagramsTabWidget->setTabText( i, tr( "Diagram %1" ).arg( i + 1 ) );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsStackedDiagramProperties::apply()
|
void QgsStackedDiagramProperties::apply()
|
||||||
{
|
{
|
||||||
if ( mDiagramTypeComboBox->currentData( Qt::UserRole ) == "None" )
|
std::unique_ptr< QgsDiagramSettings> ds = std::make_unique< QgsDiagramSettings >();
|
||||||
|
ds->stackedDiagramMode = static_cast<QgsDiagramSettings::StackedDiagramMode>( mStackedDiagramModeComboBox->currentData().toInt() );
|
||||||
|
ds->setStackedDiagramSpacingUnit( mStackedDiagramSpacingUnitComboBox->unit() );
|
||||||
|
ds->setStackedDiagramSpacing( mStackedDiagramSpacingSpinBox->value() );
|
||||||
|
|
||||||
|
// Create diagram renderer for the StackedDiagram
|
||||||
|
QgsStackedDiagramRenderer *dr = new QgsStackedDiagramRenderer();
|
||||||
|
dr->setDiagram( new QgsStackedDiagram() );
|
||||||
|
|
||||||
|
// Get DiagramSettings from each subdiagram
|
||||||
|
const QList< QgsDiagramRenderer *> renderers = mModel->subRenderers();
|
||||||
|
for ( const auto &renderer : renderers )
|
||||||
{
|
{
|
||||||
std::unique_ptr< QgsDiagramRenderer > renderer;
|
const QList< QgsDiagramSettings > ds1 = renderer->diagramSettings();
|
||||||
mLayer->setDiagramRenderer( renderer.release() );
|
if ( !ds1.isEmpty() )
|
||||||
|
|
||||||
QgsDiagramLayerSettings dls;
|
|
||||||
mLayer->setDiagramLayerSettings( dls );
|
|
||||||
|
|
||||||
// refresh
|
|
||||||
QgsProject::instance()->setDirty( true );
|
|
||||||
mLayer->triggerRepaint();
|
|
||||||
}
|
|
||||||
else if ( mDiagramTypeComboBox->currentData( Qt::UserRole ) == QgsDiagramLayerSettings::Single )
|
|
||||||
{
|
|
||||||
static_cast<QgsDiagramProperties *>( mSubDiagramsTabWidget->widget( 0 ) )->apply();
|
|
||||||
}
|
|
||||||
else // Stacked diagram
|
|
||||||
{
|
|
||||||
// Create diagram settings for the StackedDiagram
|
|
||||||
std::unique_ptr< QgsDiagramSettings> ds = std::make_unique< QgsDiagramSettings >();
|
|
||||||
ds->stackedDiagramMode = static_cast<QgsDiagramSettings::StackedDiagramMode>( mStackedDiagramModeComboBox->currentData().toInt() );
|
|
||||||
ds->setStackedDiagramSpacingUnit( mStackedDiagramSpacingUnitComboBox->unit() );
|
|
||||||
ds->setStackedDiagramSpacing( mStackedDiagramSpacingSpinBox->value() );
|
|
||||||
|
|
||||||
// Create diagram renderer for the StackedDiagram
|
|
||||||
QgsStackedDiagramRenderer *dr = new QgsStackedDiagramRenderer();
|
|
||||||
dr->setDiagram( new QgsStackedDiagram() );
|
|
||||||
|
|
||||||
// Get DiagramSettings from each subdiagram
|
|
||||||
for ( int i = 0; i < mSubDiagramsTabWidget->count(); i++ )
|
|
||||||
{
|
{
|
||||||
QgsDiagramProperties *diagramProperties = static_cast<QgsDiagramProperties *>( mSubDiagramsTabWidget->widget( i ) );
|
ds->categoryAttributes += ds1.at( 0 ).categoryAttributes;
|
||||||
std::unique_ptr< QgsDiagramSettings > ds1 = diagramProperties->createDiagramSettings();
|
ds->categoryLabels += ds1.at( 0 ).categoryLabels;
|
||||||
ds->categoryAttributes += ds1->categoryAttributes;
|
ds->categoryColors += ds1.at( 0 ).categoryColors;
|
||||||
ds->categoryLabels += ds1->categoryLabels;
|
|
||||||
ds->categoryColors += ds1->categoryColors;
|
|
||||||
|
|
||||||
std::unique_ptr< QgsDiagramRenderer > dr1 = diagramProperties->createRendererBaseInfo( *ds1 );
|
|
||||||
|
|
||||||
std::unique_ptr< QgsDiagram > diagram;
|
|
||||||
|
|
||||||
if ( diagramProperties->mDiagramType == DIAGRAM_NAME_TEXT )
|
|
||||||
{
|
|
||||||
diagram = std::make_unique< QgsTextDiagram >();
|
|
||||||
}
|
|
||||||
else if ( diagramProperties->mDiagramType == DIAGRAM_NAME_PIE )
|
|
||||||
{
|
|
||||||
diagram = std::make_unique< QgsPieDiagram >();
|
|
||||||
}
|
|
||||||
else if ( diagramProperties->mDiagramType == DIAGRAM_NAME_STACKED_BAR )
|
|
||||||
{
|
|
||||||
diagram = std::make_unique< QgsStackedBarDiagram >();
|
|
||||||
}
|
|
||||||
else // DIAGRAM_NAME_HISTOGRAM
|
|
||||||
{
|
|
||||||
diagram = std::make_unique< QgsHistogramDiagram >();
|
|
||||||
}
|
|
||||||
|
|
||||||
dr1->setDiagram( diagram.release() );
|
|
||||||
dr->addRenderer( dr1.release() );
|
|
||||||
}
|
}
|
||||||
|
dr->addRenderer( renderer );
|
||||||
dr->setDiagramSettings( *ds );
|
|
||||||
mLayer->setDiagramRenderer( dr );
|
|
||||||
|
|
||||||
// Create DiagramLayerSettings from first diagram
|
|
||||||
QgsDiagramProperties *firstDiagramProperties = static_cast< QgsDiagramProperties * >( mSubDiagramsTabWidget->widget( 0 ) );
|
|
||||||
QgsDiagramLayerSettings dls = firstDiagramProperties->createDiagramLayerSettings();
|
|
||||||
mLayer->setDiagramLayerSettings( dls );
|
|
||||||
|
|
||||||
// refresh
|
|
||||||
QgsProject::instance()->setDirty( true );
|
|
||||||
mLayer->triggerRepaint();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dr->setDiagramSettings( *ds );
|
||||||
|
mLayer->setDiagramRenderer( dr );
|
||||||
|
|
||||||
|
// Get DiagramLayerSettings from the model
|
||||||
|
QgsDiagramLayerSettings dls = mModel->diagramLayerSettings();
|
||||||
|
mLayer->setDiagramLayerSettings( dls );
|
||||||
|
|
||||||
|
// refresh
|
||||||
|
QgsProject::instance()->setDirty( true );
|
||||||
|
mLayer->triggerRepaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsStackedDiagramProperties::mDiagramTypeComboBox_currentIndexChanged( int index )
|
bool QgsStackedDiagramProperties::couldBeFirstSubDiagram( const QModelIndex &index ) const
|
||||||
{
|
{
|
||||||
if ( index == 0 ) // No diagram
|
if ( !index.isValid() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ( mModel->rowCount() == 1 )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Is there any enabled subdiagram before our index.row()?
|
||||||
|
// If so, ours cannot be the first diagram.
|
||||||
|
const QList< QgsDiagramRenderer * > renderers = mModel->subRenderers();
|
||||||
|
|
||||||
|
for ( int i = 0; i < index.row(); i++ )
|
||||||
{
|
{
|
||||||
mDiagramsFrame->setEnabled( false );
|
const auto &renderer = renderers.at( i );
|
||||||
mStackedDiagramSettingsFrame->hide();
|
const QList< QgsDiagramSettings > ds = renderer->diagramSettings();
|
||||||
|
if ( !ds.isEmpty() && ds.at( 0 ).enabled )
|
||||||
// Hide tabs other than the first one
|
|
||||||
for ( int i = 0; i < mSubDiagramsTabWidget->count(); i++ )
|
|
||||||
{
|
{
|
||||||
if ( i < 1 )
|
// First enabled subdiagram found, and we know our row is after.
|
||||||
continue;
|
// Therefore, return false to disallow showing DLS settings for it.
|
||||||
|
return false;
|
||||||
mSubDiagramsTabWidget->setTabVisible( i, false );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ( index == 1 ) // Single
|
|
||||||
{
|
|
||||||
mDiagramsFrame->setEnabled( true );
|
|
||||||
mStackedDiagramSettingsFrame->hide();
|
|
||||||
|
|
||||||
// Hide tabs other than the first one
|
|
||||||
for ( int i = 0; i < mSubDiagramsTabWidget->count(); i++ )
|
|
||||||
{
|
|
||||||
if ( i < 1 )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
mSubDiagramsTabWidget->setTabVisible( i, false );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // Stacked
|
|
||||||
{
|
|
||||||
mDiagramsFrame->setEnabled( true );
|
|
||||||
mStackedDiagramSettingsFrame->show();
|
|
||||||
|
|
||||||
// Create the second tab or show all hidden tabs
|
|
||||||
if ( mSubDiagramsTabWidget->count() == 1 )
|
|
||||||
{
|
|
||||||
// Add second subdiagram tab
|
|
||||||
addSubDiagram();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for ( int i = 0; i < mSubDiagramsTabWidget->count(); i++ )
|
|
||||||
{
|
|
||||||
if ( i < 1 )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
mSubDiagramsTabWidget->setTabVisible( i, true );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Either our row is the first subdiagram enabled or it's disabled,
|
||||||
|
// but there are no enabled ones before. So, ours could be the first
|
||||||
|
// enabled one after being edited.
|
||||||
|
// Therefore, we should allow DLS settings on its corresponding widget.
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsStackedDiagramProperties::mEngineSettingsButton_clicked()
|
void QgsStackedDiagramProperties::subDiagramWidgetPanelAccepted( QgsPanelWidget *panel )
|
||||||
{
|
{
|
||||||
QgsPanelWidget *panel = QgsPanelWidget::findParentPanel( this );
|
QgsDiagramProperties *widget = qobject_cast<QgsDiagramProperties *>( panel );
|
||||||
if ( panel && panel->dockMode() )
|
|
||||||
|
std::unique_ptr< QgsDiagramRenderer > renderer = widget->createRenderer();
|
||||||
|
|
||||||
|
const QModelIndex index = mSubDiagramsView->selectionModel()->currentIndex();
|
||||||
|
if ( widget->isAllowedToEditDiagramLayerSettings() )
|
||||||
|
mModel->updateDiagramLayerSettings( widget->createDiagramLayerSettings() );
|
||||||
|
|
||||||
|
mModel->updateSubDiagram( index, renderer.release() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsStackedDiagramProperties::liveUpdateSubDiagramFromPanel()
|
||||||
|
{
|
||||||
|
subDiagramWidgetPanelAccepted( qobject_cast<QgsPanelWidget *>( sender() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
////
|
||||||
|
|
||||||
|
#include "qgsvscrollarea.h"
|
||||||
|
|
||||||
|
QgsStackedDiagramPropertiesDialog::QgsStackedDiagramPropertiesDialog( QgsVectorLayer *layer, QWidget *parent, QgsMapCanvas *mapCanvas )
|
||||||
|
: QDialog( parent )
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef Q_OS_MAC
|
||||||
|
setWindowModality( Qt::WindowModal );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QVBoxLayout *layout = new QVBoxLayout( this );
|
||||||
|
QgsVScrollArea *scrollArea = new QgsVScrollArea( this );
|
||||||
|
scrollArea->setFrameShape( QFrame::NoFrame );
|
||||||
|
layout->addWidget( scrollArea );
|
||||||
|
|
||||||
|
buttonBox = new QDialogButtonBox( QDialogButtonBox::Cancel | QDialogButtonBox::Help | QDialogButtonBox::Ok );
|
||||||
|
mPropsWidget = new QgsDiagramProperties( layer, this, mapCanvas );
|
||||||
|
mPropsWidget->setDockMode( false );
|
||||||
|
|
||||||
|
scrollArea->setWidget( mPropsWidget );
|
||||||
|
layout->addWidget( buttonBox );
|
||||||
|
this->setWindowTitle( "Edit Sub Diagram" );
|
||||||
|
QgsGui::enableAutoGeometryRestore( this );
|
||||||
|
|
||||||
|
connect( buttonBox, &QDialogButtonBox::accepted, this, &QgsStackedDiagramPropertiesDialog::accept );
|
||||||
|
connect( buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject );
|
||||||
|
connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsStackedDiagramPropertiesDialog::showHelp );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsStackedDiagramPropertiesDialog::syncToRenderer( const QgsDiagramRenderer *dr ) const
|
||||||
|
{
|
||||||
|
mPropsWidget->syncToRenderer( dr );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsStackedDiagramPropertiesDialog::syncToSettings( const QgsDiagramLayerSettings *dls ) const
|
||||||
|
{
|
||||||
|
mPropsWidget->syncToSettings( dls );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsStackedDiagramPropertiesDialog::accept()
|
||||||
|
{
|
||||||
|
// Get renderer and diagram layer settings from widget
|
||||||
|
mRenderer = mPropsWidget->createRenderer();
|
||||||
|
mDiagramLayerSettings = mPropsWidget->createDiagramLayerSettings();
|
||||||
|
QDialog::accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsDiagramRenderer *QgsStackedDiagramPropertiesDialog::renderer()
|
||||||
|
{
|
||||||
|
return mRenderer.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsDiagramLayerSettings QgsStackedDiagramPropertiesDialog::diagramLayerSettings() const
|
||||||
|
{
|
||||||
|
return mDiagramLayerSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsStackedDiagramPropertiesDialog::setAllowedToEditDiagramLayerSettings( bool allowed ) const
|
||||||
|
{
|
||||||
|
mPropsWidget->setAllowedToEditDiagramLayerSettings( allowed );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QgsStackedDiagramPropertiesDialog::isAllowedToEditDiagramLayerSettings() const
|
||||||
|
{
|
||||||
|
return mPropsWidget->isAllowedToEditDiagramLayerSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsStackedDiagramPropertiesDialog::showHelp()
|
||||||
|
{
|
||||||
|
QgsHelp::openHelp( QStringLiteral( "working_with_vector/vector_properties.html#diagrams-properties" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
////
|
||||||
|
|
||||||
|
QgsStackedDiagramPropertiesModel::QgsStackedDiagramPropertiesModel( QObject *parent )
|
||||||
|
: QAbstractTableModel( parent )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::ItemFlags QgsStackedDiagramPropertiesModel::flags( const QModelIndex &index ) const
|
||||||
|
{
|
||||||
|
const Qt::ItemFlag checkable = ( index.column() == 0 ? Qt::ItemIsUserCheckable : Qt::NoItemFlags );
|
||||||
|
|
||||||
|
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | checkable;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant QgsStackedDiagramPropertiesModel::data( const QModelIndex &index, int role ) const
|
||||||
|
{
|
||||||
|
if ( !index.isValid() )
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
QgsDiagramRenderer *dr = subDiagramForIndex( index );
|
||||||
|
|
||||||
|
if ( role == Qt::DisplayRole || role == Qt::ToolTipRole )
|
||||||
{
|
{
|
||||||
QgsLabelEngineConfigWidget *widget = new QgsLabelEngineConfigWidget( mMapCanvas );
|
switch ( index.column() )
|
||||||
connect( widget, &QgsLabelEngineConfigWidget::widgetChanged, widget, &QgsLabelEngineConfigWidget::apply );
|
{
|
||||||
panel->openPanel( widget );
|
case 1:
|
||||||
|
return ( !dr || !dr->diagram() ) ? tr( "(no diagram)" ) : dr->diagram()->diagramName();
|
||||||
|
case 2:
|
||||||
|
if ( !dr )
|
||||||
|
{
|
||||||
|
return tr( "(no renderer)" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( dr->rendererName() == QLatin1String( "SingleCategory" ) )
|
||||||
|
return tr( "Fixed" );
|
||||||
|
else if ( dr->rendererName() == QLatin1String( "LinearlyInterpolated" ) )
|
||||||
|
return tr( "Scaled" );
|
||||||
|
else
|
||||||
|
return tr( "Unknown" );
|
||||||
|
}
|
||||||
|
case 3:
|
||||||
|
if ( dr && dr->diagram() && !dr->diagramSettings().isEmpty() )
|
||||||
|
{
|
||||||
|
if ( DIAGRAM_NAME_HISTOGRAM == dr->diagram()->diagramName() || DIAGRAM_NAME_STACKED_BAR == dr->diagram()->diagramName() )
|
||||||
|
{
|
||||||
|
switch ( dr->diagramSettings().at( 0 ).diagramOrientation )
|
||||||
|
{
|
||||||
|
case QgsDiagramSettings::Left:
|
||||||
|
return tr( "Left" );
|
||||||
|
case QgsDiagramSettings::Right:
|
||||||
|
return tr( "Right" );
|
||||||
|
case QgsDiagramSettings::Up:
|
||||||
|
return tr( "Up" );
|
||||||
|
case QgsDiagramSettings::Down:
|
||||||
|
return tr( "Down" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
case 0:
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( role == Qt::TextAlignmentRole )
|
||||||
|
{
|
||||||
|
return index.column() == 0 ? static_cast<Qt::Alignment::Int>( Qt::AlignCenter ) : static_cast<Qt::Alignment::Int>( Qt::AlignLeft );
|
||||||
|
}
|
||||||
|
else if ( role == Qt::CheckStateRole )
|
||||||
|
{
|
||||||
|
if ( index.column() != 0 )
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
return ( dr && !dr->diagramSettings().isEmpty() && dr->diagramSettings().at( 0 ).enabled ) ? Qt::Checked : Qt::Unchecked;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
QgsLabelEngineConfigDialog dialog( mMapCanvas, this );
|
return QVariant();
|
||||||
dialog.exec();
|
|
||||||
// reactivate button's window
|
|
||||||
activateWindow();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVariant QgsStackedDiagramPropertiesModel::headerData( int section, Qt::Orientation orientation, int role ) const
|
||||||
|
{
|
||||||
|
if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section < 4 )
|
||||||
|
{
|
||||||
|
QStringList lst;
|
||||||
|
lst << tr( "Enabled" ) << tr( "Diagram type" ) << tr( "Size" ) << tr( "Orientation" );
|
||||||
|
return lst[section];
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
int QgsStackedDiagramPropertiesModel::rowCount( const QModelIndex & ) const
|
||||||
|
{
|
||||||
|
return mRenderers.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
int QgsStackedDiagramPropertiesModel::columnCount( const QModelIndex & ) const
|
||||||
|
{
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QgsStackedDiagramPropertiesModel::setData( const QModelIndex &index, const QVariant &value, int role )
|
||||||
|
{
|
||||||
|
if ( !index.isValid() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
QgsDiagramRenderer *dr = subDiagramForIndex( index );
|
||||||
|
|
||||||
|
if ( role == Qt::CheckStateRole )
|
||||||
|
{
|
||||||
|
if ( dr && !dr->diagramSettings().isEmpty() )
|
||||||
|
{
|
||||||
|
QgsDiagramSettings ds = dr->diagramSettings().at( 0 );
|
||||||
|
ds.enabled = ( value.toInt() == Qt::Checked );
|
||||||
|
|
||||||
|
if ( dr->rendererName() == QLatin1String( "SingleCategory" ) )
|
||||||
|
{
|
||||||
|
QgsSingleCategoryDiagramRenderer *dsr = static_cast< QgsSingleCategoryDiagramRenderer * >( dr );
|
||||||
|
dsr->setDiagramSettings( ds );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QgsLinearlyInterpolatedDiagramRenderer *dlir = static_cast< QgsLinearlyInterpolatedDiagramRenderer * >( dr );
|
||||||
|
dlir->setDiagramSettings( ds );
|
||||||
|
}
|
||||||
|
|
||||||
|
emit dataChanged( index, index );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QgsStackedDiagramPropertiesModel::removeRows( int row, int count, const QModelIndex &parent )
|
||||||
|
{
|
||||||
|
if ( row < 0 || row >= mRenderers.size() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
beginRemoveRows( parent, row, row + count - 1 );
|
||||||
|
while ( count-- )
|
||||||
|
mRenderers.removeAt( row );
|
||||||
|
endRemoveRows();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsDiagramRenderer *QgsStackedDiagramPropertiesModel::subDiagramForIndex( const QModelIndex &index ) const
|
||||||
|
{
|
||||||
|
if ( index.isValid() )
|
||||||
|
return mRenderers.at( index.row() );
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsStackedDiagramPropertiesModel::insertSubDiagram( const int index, QgsDiagramRenderer *newSubDiagram )
|
||||||
|
{
|
||||||
|
beginInsertRows( QModelIndex(), index, index );
|
||||||
|
mRenderers.insert( index, newSubDiagram );
|
||||||
|
endInsertRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsStackedDiagramPropertiesModel::updateSubDiagram( const QModelIndex &index, QgsDiagramRenderer *dr )
|
||||||
|
{
|
||||||
|
mRenderers.replace( index.row(), dr );
|
||||||
|
emit dataChanged( index, index );
|
||||||
|
}
|
||||||
|
|
||||||
|
QList< QgsDiagramRenderer *> QgsStackedDiagramPropertiesModel::subRenderers() const
|
||||||
|
{
|
||||||
|
QList<QgsDiagramRenderer *> subRenderers;
|
||||||
|
subRenderers = mRenderers;
|
||||||
|
return subRenderers;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsStackedDiagramPropertiesModel::updateDiagramLayerSettings( QgsDiagramLayerSettings dls )
|
||||||
|
{
|
||||||
|
mDiagramLayerSettings = dls;
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsDiagramLayerSettings QgsStackedDiagramPropertiesModel::diagramLayerSettings() const
|
||||||
|
{
|
||||||
|
return mDiagramLayerSettings;
|
||||||
|
}
|
||||||
|
@ -22,14 +22,71 @@
|
|||||||
#define SIP_NO_FILE
|
#define SIP_NO_FILE
|
||||||
|
|
||||||
#include "qgis_gui.h"
|
#include "qgis_gui.h"
|
||||||
|
#include "qgsdiagramrenderer.h"
|
||||||
#include "ui_qgsstackeddiagrampropertiesbase.h"
|
#include "ui_qgsstackeddiagrampropertiesbase.h"
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
#include <QDialogButtonBox>
|
||||||
|
|
||||||
class QgsVectorLayer;
|
class QgsVectorLayer;
|
||||||
class QgsMapCanvas;
|
class QgsMapCanvas;
|
||||||
class QgsDiagramProperties;
|
class QgsDiagramProperties;
|
||||||
|
class QgsDiagramRenderer;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \ingroup gui
|
||||||
|
* \brief Model for sub diagrams in a stacked diagram view.
|
||||||
|
*
|
||||||
|
* \note This class is not a part of public API
|
||||||
|
* \since QGIS 3.40
|
||||||
|
*/
|
||||||
|
class GUI_EXPORT QgsStackedDiagramPropertiesModel : public QAbstractTableModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
//! constructor
|
||||||
|
QgsStackedDiagramPropertiesModel( QObject *parent = nullptr );
|
||||||
|
|
||||||
|
Qt::ItemFlags flags( const QModelIndex &index ) const override;
|
||||||
|
QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const override;
|
||||||
|
QVariant headerData( int section, Qt::Orientation orientation,
|
||||||
|
int role = Qt::DisplayRole ) const override;
|
||||||
|
int rowCount( const QModelIndex & = QModelIndex() ) const override;
|
||||||
|
int columnCount( const QModelIndex & = QModelIndex() ) const override;
|
||||||
|
|
||||||
|
// editing support
|
||||||
|
bool setData( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole ) override;
|
||||||
|
bool removeRows( int row, int count, const QModelIndex &parent = QModelIndex() ) override;
|
||||||
|
|
||||||
|
// new methods
|
||||||
|
|
||||||
|
//! Returns the diagram renderer at the specified index
|
||||||
|
QgsDiagramRenderer *subDiagramForIndex( const QModelIndex &index ) const;
|
||||||
|
|
||||||
|
//! Inserts a new diagram at the specified position
|
||||||
|
void insertSubDiagram( const int index, QgsDiagramRenderer *newSubDiagram );
|
||||||
|
//! Replaces the diagram located at \a index by \a dr
|
||||||
|
void updateSubDiagram( const QModelIndex &index, QgsDiagramRenderer *dr );
|
||||||
|
|
||||||
|
//! Returns the list of diagram renderers from the model
|
||||||
|
QList< QgsDiagramRenderer *> subRenderers() const;
|
||||||
|
|
||||||
|
//! Returns the diagram layer settings from the model
|
||||||
|
QgsDiagramLayerSettings diagramLayerSettings() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the diagram layer settings for the model.
|
||||||
|
* @param dls DiagramLayerSettings to be set.
|
||||||
|
*/
|
||||||
|
void updateDiagramLayerSettings( QgsDiagramLayerSettings dls );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QList< QgsDiagramRenderer *> mRenderers;
|
||||||
|
QgsDiagramLayerSettings mDiagramLayerSettings;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -38,7 +95,7 @@ class QgsDiagramProperties;
|
|||||||
*
|
*
|
||||||
* \since QGIS 3.40
|
* \since QGIS 3.40
|
||||||
*/
|
*/
|
||||||
class GUI_EXPORT QgsStackedDiagramProperties : public QWidget, private Ui::QgsStackedDiagramPropertiesBase
|
class GUI_EXPORT QgsStackedDiagramProperties : public QgsPanelWidget, private Ui::QgsStackedDiagramPropertiesBase
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@ -55,27 +112,127 @@ class GUI_EXPORT QgsStackedDiagramProperties : public QWidget, private Ui::QgsSt
|
|||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void apply();
|
void apply();
|
||||||
void mDiagramTypeComboBox_currentIndexChanged( int index );
|
|
||||||
void mSubDiagramsTabWidget_tabMoved( int from, int to );
|
|
||||||
void mEngineSettingsButton_clicked();
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a diagram tab to the current QgsStackedDiagramProperties.
|
* Adds a diagram to the current QgsStackedDiagramProperties.
|
||||||
*/
|
*/
|
||||||
void addSubDiagram();
|
void addSubDiagram();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a diagram tab from the current QgsStackedDiagramProperties.
|
* Appends a diagram to the current QgsStackedDiagramProperties.
|
||||||
* Diagram tabs are removed only if the tab count is greater than 2.
|
* @param dr Diagram renderer to be appended.
|
||||||
* Tab texts are adjusted after tab removal, to keep sequential order.
|
*/
|
||||||
|
void appendSubDiagram( QgsDiagramRenderer *dr );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Edits the properties of the current diagram.
|
||||||
|
*/
|
||||||
|
void editSubDiagram();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Edits the properties of a diagram located at a given \a index.
|
||||||
|
* @param index Model index where the diagram is located.
|
||||||
|
*/
|
||||||
|
void editSubDiagram( const QModelIndex &index );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a diagram from the current QgsStackedDiagramProperties.
|
||||||
*/
|
*/
|
||||||
void removeSubDiagram();
|
void removeSubDiagram();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QgsVectorLayer *mLayer = nullptr;
|
QgsVectorLayer *mLayer = nullptr;
|
||||||
QgsMapCanvas *mMapCanvas = nullptr;
|
QgsMapCanvas *mMapCanvas = nullptr;
|
||||||
|
|
||||||
|
QgsStackedDiagramPropertiesModel *mModel = nullptr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines whether the subdiagram in the given \a index may be
|
||||||
|
* the first sub diagram in the stacked diagram. This includes the
|
||||||
|
* first enabled sub diagram, as well as disabled sub diagrams that,
|
||||||
|
* after being edited, can become the first enabled one.
|
||||||
|
* @param index Model index where the sub diagram is located.
|
||||||
|
*/
|
||||||
|
bool couldBeFirstSubDiagram( const QModelIndex &index ) const;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void subDiagramWidgetPanelAccepted( QgsPanelWidget *panel );
|
||||||
|
void liveUpdateSubDiagramFromPanel();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \ingroup gui
|
||||||
|
* \class QgsStackedDiagramPropertiesDialog
|
||||||
|
* \brief Dialog for editing sub diagrams
|
||||||
|
*
|
||||||
|
* \note This class is not a part of public API
|
||||||
|
* \since QGIS 3.40
|
||||||
|
*/
|
||||||
|
class GUI_EXPORT QgsStackedDiagramPropertiesDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for QgsStackedDiagramPropertiesDialog
|
||||||
|
* \param layer source vector layer
|
||||||
|
* \param parent parent widget
|
||||||
|
* \param mapCanvas map canvas
|
||||||
|
*/
|
||||||
|
QgsStackedDiagramPropertiesDialog( QgsVectorLayer *layer, QWidget *parent = nullptr, QgsMapCanvas *mapCanvas = nullptr );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delegates to the diagram properties widget to sync with the given renderer.
|
||||||
|
* @param dr Diagram Renderer to be used for the sync.
|
||||||
|
*/
|
||||||
|
void syncToRenderer( const QgsDiagramRenderer *dr ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delegates to the diagram properties widget to sync with the given diagram layer settings.
|
||||||
|
* @param dls Diagram Layer Settings to be used for the sync.
|
||||||
|
*/
|
||||||
|
void syncToSettings( const QgsDiagramLayerSettings *dls ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a renderer object built from the diagram properties widget.
|
||||||
|
*/
|
||||||
|
QgsDiagramRenderer *renderer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets diagram layer settings built from the diagram properties widget.
|
||||||
|
*/
|
||||||
|
QgsDiagramLayerSettings diagramLayerSettings() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delegates to the main widget to set whether the widget should show
|
||||||
|
* diagram layer settings to be edited.
|
||||||
|
* @param allowed Whether the main widget should be allowed to edit diagram layer settings.
|
||||||
|
*/
|
||||||
|
void setAllowedToEditDiagramLayerSettings( bool allowed ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the main widget is allowed to edit diagram layer settings.
|
||||||
|
*/
|
||||||
|
bool isAllowedToEditDiagramLayerSettings() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies changes from the widget to the internal renderer and diagram layer settings.
|
||||||
|
*/
|
||||||
|
void accept() override;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void showHelp();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QgsDiagramProperties *mPropsWidget = nullptr;
|
||||||
|
std::unique_ptr< QgsDiagramRenderer > mRenderer;
|
||||||
|
QgsDiagramLayerSettings mDiagramLayerSettings;
|
||||||
|
QDialogButtonBox *buttonBox = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // QGSSTACKEDDIAGRAMPROPERTIES_H
|
#endif // QGSSTACKEDDIAGRAMPROPERTIES_H
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
#include "qgsapplication.h"
|
#include "qgsapplication.h"
|
||||||
#include "qgsattributeactiondialog.h"
|
#include "qgsattributeactiondialog.h"
|
||||||
#include "qgsdatumtransformdialog.h"
|
#include "qgsdatumtransformdialog.h"
|
||||||
#include "qgsstackeddiagramproperties.h"
|
#include "qgsdiagramwidget.h"
|
||||||
#include "qgssourcefieldsproperties.h"
|
#include "qgssourcefieldsproperties.h"
|
||||||
#include "qgsattributesformproperties.h"
|
#include "qgsattributesformproperties.h"
|
||||||
#include "qgslabelingwidget.h"
|
#include "qgslabelingwidget.h"
|
||||||
@ -280,6 +280,15 @@ QgsVectorLayerProperties::QgsVectorLayerProperties(
|
|||||||
mSelectionSymbolButton->setEnabled( false );
|
mSelectionSymbolButton->setEnabled( false );
|
||||||
mRadioDefaultSelectionColor->setChecked( true );
|
mRadioDefaultSelectionColor->setChecked( true );
|
||||||
|
|
||||||
|
// Diagram tab, before the syncToLayer
|
||||||
|
QVBoxLayout *diagLayout = new QVBoxLayout( mDiagramFrame );
|
||||||
|
diagLayout->setContentsMargins( 0, 0, 0, 0 );
|
||||||
|
diagramPropertiesDialog = new QgsDiagramWidget( mLayer, mCanvas, mDiagramFrame );
|
||||||
|
diagramPropertiesDialog->layout()->setContentsMargins( 0, 0, 0, 0 );
|
||||||
|
connect( diagramPropertiesDialog, &QgsDiagramWidget::auxiliaryFieldCreated, this, [ = ] { updateAuxiliaryStoragePage(); } );
|
||||||
|
diagLayout->addWidget( diagramPropertiesDialog );
|
||||||
|
mDiagramFrame->setLayout( diagLayout );
|
||||||
|
|
||||||
syncToLayer();
|
syncToLayer();
|
||||||
|
|
||||||
if ( mLayer->dataProvider() )
|
if ( mLayer->dataProvider() )
|
||||||
@ -333,14 +342,6 @@ QgsVectorLayerProperties::QgsVectorLayerProperties(
|
|||||||
|
|
||||||
mOldJoins = mLayer->vectorJoins();
|
mOldJoins = mLayer->vectorJoins();
|
||||||
|
|
||||||
QVBoxLayout *diagLayout = new QVBoxLayout( mDiagramFrame );
|
|
||||||
diagLayout->setContentsMargins( 0, 0, 0, 0 );
|
|
||||||
diagramPropertiesDialog = new QgsStackedDiagramProperties( mLayer, mDiagramFrame, mCanvas );
|
|
||||||
diagramPropertiesDialog->layout()->setContentsMargins( 0, 0, 0, 0 );
|
|
||||||
connect( diagramPropertiesDialog, &QgsStackedDiagramProperties::auxiliaryFieldCreated, this, [ = ] { updateAuxiliaryStoragePage(); } );
|
|
||||||
diagLayout->addWidget( diagramPropertiesDialog );
|
|
||||||
mDiagramFrame->setLayout( diagLayout );
|
|
||||||
|
|
||||||
// Legend tab
|
// Legend tab
|
||||||
mLegendWidget->setMapCanvas( mCanvas );
|
mLegendWidget->setMapCanvas( mCanvas );
|
||||||
mLegendWidget->setLayer( mLayer );
|
mLegendWidget->setLayer( mLayer );
|
||||||
@ -728,7 +729,7 @@ void QgsVectorLayerProperties::syncToLayer()
|
|||||||
updateVariableEditor();
|
updateVariableEditor();
|
||||||
|
|
||||||
if ( diagramPropertiesDialog )
|
if ( diagramPropertiesDialog )
|
||||||
diagramPropertiesDialog->syncToLayer();
|
diagramPropertiesDialog->syncToOwnLayer();
|
||||||
|
|
||||||
// sync all plugin dialogs
|
// sync all plugin dialogs
|
||||||
for ( QgsMapLayerConfigWidget *page : std::as_const( mConfigWidgets ) )
|
for ( QgsMapLayerConfigWidget *page : std::as_const( mConfigWidgets ) )
|
||||||
|
@ -33,7 +33,7 @@ class QgsMapLayer;
|
|||||||
class QgsAttributeActionDialog;
|
class QgsAttributeActionDialog;
|
||||||
class QgsVectorLayer;
|
class QgsVectorLayer;
|
||||||
class QgsLabelingWidget;
|
class QgsLabelingWidget;
|
||||||
class QgsStackedDiagramProperties;
|
class QgsDiagramWidget;
|
||||||
class QgsSourceFieldsProperties;
|
class QgsSourceFieldsProperties;
|
||||||
class QgsAttributesFormProperties;
|
class QgsAttributesFormProperties;
|
||||||
class QgsRendererPropertiesDialog;
|
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
|
//! Actions dialog. If apply is pressed, the actions are stored for later use
|
||||||
QgsAttributeActionDialog *mActionDialog = nullptr;
|
QgsAttributeActionDialog *mActionDialog = nullptr;
|
||||||
//! Diagram dialog. If apply is pressed, options are applied to vector's diagrams
|
//! Diagram dialog. If apply is pressed, options are applied to vector's diagrams
|
||||||
QgsStackedDiagramProperties *diagramPropertiesDialog = nullptr;
|
QgsDiagramWidget *diagramPropertiesDialog = nullptr;
|
||||||
//! SourceFields dialog. If apply is pressed, options are applied to vector's diagrams
|
//! SourceFields dialog. If apply is pressed, options are applied to vector's diagrams
|
||||||
QgsSourceFieldsProperties *mSourceFieldsPropertiesDialog = nullptr;
|
QgsSourceFieldsProperties *mSourceFieldsPropertiesDialog = nullptr;
|
||||||
//! AttributesForm dialog. If apply is pressed, options are applied to vector's diagrams
|
//! AttributesForm dialog. If apply is pressed, options are applied to vector's diagrams
|
||||||
|
File diff suppressed because it is too large
Load Diff
59
src/ui/qgsdiagramwidget.ui
Normal file
59
src/ui/qgsdiagramwidget.ui
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>QgsDiagramWidget</class>
|
||||||
|
<widget class="QWidget" name="QgsDiagramWidget">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>842</width>
|
||||||
|
<height>472</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<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 row="0" column="0">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="mDiagramTypeComboBox"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="mEngineSettingsButton">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Automated placement settings (applies to all layers)</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../images/images.qrc">
|
||||||
|
<normaloff>:/images/themes/default/mIconAutoPlacementSettings.svg</normaloff>:/images/themes/default/mIconAutoPlacementSettings.svg</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QStackedWidget" name="mStackedWidget">
|
||||||
|
<widget class="QWidget" name="page"/>
|
||||||
|
<widget class="QWidget" name="page_2"/>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources>
|
||||||
|
<include location="../../images/images.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
@ -11,25 +11,106 @@
|
|||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<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>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
<widget class="QTreeView" name="mSubDiagramsView">
|
||||||
|
<property name="selectionMode">
|
||||||
|
<enum>QAbstractItemView::SelectionMode::SingleSelection</enum>
|
||||||
|
</property>
|
||||||
|
<property name="itemsExpandable">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="expandsOnDoubleClick">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<attribute name="headerMinimumSectionSize">
|
||||||
|
<number>57</number>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QComboBox" name="mDiagramTypeComboBox"/>
|
<widget class="QPushButton" name="mAddSubDiagramButton">
|
||||||
</item>
|
<property name="sizePolicy">
|
||||||
<item>
|
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||||
<widget class="QToolButton" name="mEngineSettingsButton">
|
<horstretch>0</horstretch>
|
||||||
<property name="enabled">
|
<verstretch>0</verstretch>
|
||||||
<bool>true</bool>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Automated placement settings (apply to all layers)</string>
|
<string>Add subdiagram to the stacked diagram</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../../images/images.qrc">
|
<iconset resource="../../images/images.qrc">
|
||||||
<normaloff>:/images/themes/default/mIconAutoPlacementSettings.svg</normaloff>:/images/themes/default/mIconAutoPlacementSettings.svg</iconset>
|
<normaloff>:/images/themes/default/symbologyAdd.svg</normaloff>:/images/themes/default/symbologyAdd.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="mEditSubDiagramButton">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Edit subdiagram from the stacked diagram</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../images/images.qrc">
|
||||||
|
<normaloff>:/images/themes/default/symbologyEdit.svg</normaloff>:/images/themes/default/symbologyEdit.svg</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="mRemoveSubDiagramButton">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" 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>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
@ -41,93 +122,6 @@
|
|||||||
<enum>QFrame::Shadow::Raised</enum>
|
<enum>QFrame::Shadow::Raised</enum>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<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>Add subdiagram</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>Remove subdiagram</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">
|
<item row="1" column="0">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
<item>
|
<item>
|
||||||
@ -175,42 +169,32 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</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">
|
<item row="0" column="0">
|
||||||
<widget class="QTabWidget" name="mSubDiagramsTabWidget">
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
<property name="currentIndex">
|
<item>
|
||||||
<number>-1</number>
|
<widget class="QLabel" name="stackedDiagramModeLabel">
|
||||||
</property>
|
<property name="text">
|
||||||
<property name="movable">
|
<string>Stacked diagram mode</string>
|
||||||
<bool>true</bool>
|
</property>
|
||||||
</property>
|
</widget>
|
||||||
</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>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -286,7 +286,8 @@ ACCEPTABLE_MISSING_DOCS = {
|
|||||||
"QgsEffectStack": ["QgsEffectStack(const QgsEffectStack &other)"],
|
"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)"],
|
"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()"],
|
"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()", "mEngineSettingsButton_clicked()", "mSubDiagramsTabWidget_tabMoved(int from, int to)", "auxiliaryFieldCreated()", "QgsStackedDiagramProperties(QgsVectorLayer *layer, QWidget *parent, QgsMapCanvas *canvas)"],
|
"QgsStackedDiagramProperties": ["apply()", "auxiliaryFieldCreated()", "QgsStackedDiagramProperties(QgsVectorLayer *layer, QWidget *parent, QgsMapCanvas *canvas)"],
|
||||||
|
"QgsDiagramWidget": ["mDiagramTypeComboBox_currentIndexChanged(int index)", "showEngineConfigDialog()"],
|
||||||
"QgsFeatureListView": ["repaintRequested()", "repaintRequested(const QModelIndexList &indexes)"],
|
"QgsFeatureListView": ["repaintRequested()", "repaintRequested(const QModelIndexList &indexes)"],
|
||||||
"QgsGradientFillSymbolLayerWidget": ["setGradientSpread(int index)", "setColor(const QColor &color)", "setCoordinateMode(int index)", "setColor2(const QColor &color)", "setGradientType(int index)"],
|
"QgsGradientFillSymbolLayerWidget": ["setGradientSpread(int index)", "setColor(const QColor &color)", "setCoordinateMode(int index)", "setColor2(const QColor &color)", "setGradientType(int index)"],
|
||||||
"QgsFillSymbol": ["setAngle(double angle) const"],
|
"QgsFillSymbol": ["setAngle(double angle) const"],
|
||||||
|
@ -191,6 +191,96 @@ class TestQgsStackedDiagram : public QgsTest
|
|||||||
QGSVERIFYRENDERMAPSETTINGSCHECK( "stackedhistograms", "stackedhistograms", *mMapSettings, 200, 15 );
|
QGSVERIFYRENDERMAPSETTINGSCHECK( "stackedhistograms", "stackedhistograms", *mMapSettings, 200, 15 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void testDisabledSubDiagram()
|
||||||
|
{
|
||||||
|
// Histogram 1 (disabled)
|
||||||
|
QgsDiagramSettings ds1;
|
||||||
|
QColor col1 = Qt::blue;
|
||||||
|
QColor col2 = Qt::red;
|
||||||
|
QColor col3 = Qt::yellow;
|
||||||
|
QColor col4 = Qt::green;
|
||||||
|
col1.setAlphaF( 0.5 );
|
||||||
|
col2.setAlphaF( 0.5 );
|
||||||
|
col3.setAlphaF( 0.5 );
|
||||||
|
col4.setAlphaF( 0.5 );
|
||||||
|
ds1.categoryColors = QList<QColor>() << col1 << col2 << col3 << col4;
|
||||||
|
ds1.categoryAttributes = QList<QString>() << QStringLiteral( "\"maennlich_ab_65\"" ) << QStringLiteral( "\"maennlich_18_64\"" ) << QStringLiteral( "\"maennlich_6_17\"" ) << QStringLiteral( "\"maennlich_unter_6\"" ); //#spellok
|
||||||
|
ds1.minimumScale = -1;
|
||||||
|
ds1.maximumScale = -1;
|
||||||
|
ds1.minimumSize = 0;
|
||||||
|
ds1.penColor = Qt::black;
|
||||||
|
ds1.penWidth = .5;
|
||||||
|
ds1.scaleByArea = true;
|
||||||
|
ds1.sizeType = Qgis::RenderUnit::Millimeters;
|
||||||
|
ds1.rotationOffset = 0;
|
||||||
|
ds1.diagramOrientation = QgsDiagramSettings::Left;
|
||||||
|
ds1.enabled = false;
|
||||||
|
|
||||||
|
QgsLinearlyInterpolatedDiagramRenderer *dr1 = new QgsLinearlyInterpolatedDiagramRenderer();
|
||||||
|
dr1->setDiagram( new QgsHistogramDiagram() );
|
||||||
|
dr1->setDiagramSettings( ds1 );
|
||||||
|
dr1->setLowerValue( 0.0 );
|
||||||
|
dr1->setLowerSize( QSizeF( 0.0, 0.0 ) );
|
||||||
|
dr1->setUpperValue( 15000 );
|
||||||
|
dr1->setUpperSize( QSizeF( 20, 20 ) );
|
||||||
|
//dr1->setClassificationField( QStringLiteral( "max(\"maennlich_18_64\", \"maennlich_ab_65\", \"maennlich_6_17\", \"maennlich_unter_6\")" ) ); //#spellok
|
||||||
|
|
||||||
|
// Histogram 2
|
||||||
|
QgsDiagramSettings ds2;
|
||||||
|
col1 = Qt::blue;
|
||||||
|
col2 = Qt::red;
|
||||||
|
col3 = Qt::yellow;
|
||||||
|
col4 = Qt::green;
|
||||||
|
col1.setAlphaF( 0.5 );
|
||||||
|
col2.setAlphaF( 0.5 );
|
||||||
|
col3.setAlphaF( 0.5 );
|
||||||
|
col4.setAlphaF( 0.5 );
|
||||||
|
ds2.categoryColors = QList<QColor>() << col1 << col2 << col3 << col4;
|
||||||
|
ds2.categoryAttributes = QList<QString>() << QStringLiteral( "\"weiblich_ab_65\"" ) << QStringLiteral( "\"weiblich_18_64\"" ) << QStringLiteral( "\"weiblich_6_17\"" ) << QStringLiteral( "\"weiblich_unter_6\"" ); //#spellok
|
||||||
|
ds2.minimumScale = -1;
|
||||||
|
ds2.maximumScale = -1;
|
||||||
|
ds2.minimumSize = 0;
|
||||||
|
ds2.penColor = Qt::black;
|
||||||
|
ds2.penWidth = .5;
|
||||||
|
ds2.scaleByArea = true;
|
||||||
|
ds2.sizeType = Qgis::RenderUnit::Millimeters;
|
||||||
|
ds2.rotationOffset = 0;
|
||||||
|
ds2.diagramOrientation = QgsDiagramSettings::Right;
|
||||||
|
|
||||||
|
QgsLinearlyInterpolatedDiagramRenderer *dr2 = new QgsLinearlyInterpolatedDiagramRenderer();
|
||||||
|
dr2->setDiagram( new QgsHistogramDiagram() );
|
||||||
|
dr2->setDiagramSettings( ds2 );
|
||||||
|
dr2->setLowerValue( 0.0 );
|
||||||
|
dr2->setLowerSize( QSizeF( 0.0, 0.0 ) );
|
||||||
|
dr2->setUpperValue( 15000 );
|
||||||
|
dr2->setUpperSize( QSizeF( 20, 20 ) );
|
||||||
|
//dr2->setClassificationField( QStringLiteral( "max(\"weiblich_unter_6\", \"weiblich_6_17\", \"weiblich_18_64\", \"weiblich_ab_65\")" ) ); //#spellok
|
||||||
|
|
||||||
|
QgsDiagramSettings ds;
|
||||||
|
ds.stackedDiagramMode = QgsDiagramSettings::Horizontal;
|
||||||
|
ds.categoryAttributes = ds1.categoryAttributes + ds2.categoryAttributes;
|
||||||
|
ds.setStackedDiagramSpacingUnit( Qgis::RenderUnit::Pixels );
|
||||||
|
ds.setStackedDiagramSpacing( 0 );
|
||||||
|
|
||||||
|
QgsStackedDiagramRenderer *dr = new QgsStackedDiagramRenderer();
|
||||||
|
dr->setDiagram( new QgsStackedDiagram() );
|
||||||
|
dr->setDiagramSettings( ds );
|
||||||
|
dr->addRenderer( dr1 );
|
||||||
|
dr->addRenderer( dr2 );
|
||||||
|
mPointsLayer->setDiagramRenderer( dr );
|
||||||
|
|
||||||
|
QgsDiagramLayerSettings dls = QgsDiagramLayerSettings();
|
||||||
|
dls.setPlacement( QgsDiagramLayerSettings::OverPoint );
|
||||||
|
dls.setShowAllDiagrams( true );
|
||||||
|
mPointsLayer->setDiagramLayerSettings( dls );
|
||||||
|
|
||||||
|
const QgsRectangle extent( 9.7, 53.5, 9.95, 53.6 );
|
||||||
|
mMapSettings->setExtent( extent );
|
||||||
|
mMapSettings->setFlag( Qgis::MapSettingsFlag::ForceVectorOutput );
|
||||||
|
mMapSettings->setOutputDpi( 96 );
|
||||||
|
QGSVERIFYRENDERMAPSETTINGSCHECK( "disabledsubdiagram", "disabledsubdiagram", *mMapSettings, 200, 15 );
|
||||||
|
}
|
||||||
|
|
||||||
void testVerticallyStackedHistograms()
|
void testVerticallyStackedHistograms()
|
||||||
{
|
{
|
||||||
// Histogram 1
|
// Histogram 1
|
||||||
|
Binary file not shown.
After Width: | Height: | Size: 998 KiB |
Loading…
x
Reference in New Issue
Block a user