29#include "moc_qgsstackeddiagramproperties.cpp"
38 , mMapCanvas( canvas )
46 connect( mSubDiagramsView, &QAbstractItemView::doubleClicked,
this,
static_cast<void (
QgsStackedDiagramProperties::* )(
const QModelIndex & )
>( &QgsStackedDiagramProperties::editSubDiagramRenderer ) );
48 connect( mAddSubDiagramButton, &QPushButton::clicked,
this, &QgsStackedDiagramProperties::addSubDiagramRenderer );
49 connect( mEditSubDiagramButton, &QAbstractButton::clicked,
this,
static_cast<void (
QgsStackedDiagramProperties::* )()
>( &QgsStackedDiagramProperties::editSubDiagramRenderer ) );
50 connect( mRemoveSubDiagramButton, &QPushButton::clicked,
this, &QgsStackedDiagramProperties::removeSubDiagramRenderer );
56 mStackedDiagramSpacingSpinBox->setClearValue( 0 );
64 mSubDiagramsView->setModel( mModel );
73void QgsStackedDiagramProperties::addSubDiagramRenderer()
76 std::unique_ptr<QgsDiagramRenderer> renderer;
77 auto dr = std::make_unique<QgsSingleCategoryDiagramRenderer>();
78 renderer = std::move( dr );
80 QItemSelectionModel *sel = mSubDiagramsView->selectionModel();
81 const QModelIndex index = sel->currentIndex();
83 if ( index.isValid() )
86 const QModelIndex currentIndex = mSubDiagramsView->selectionModel()->currentIndex();
88 const QModelIndex newIndex = mModel->index( currentIndex.row() + 1, 0 );
89 mSubDiagramsView->selectionModel()->setCurrentIndex( newIndex, QItemSelectionModel::ClearAndSelect );
94 appendSubDiagramRenderer( renderer.release() );
96 editSubDiagramRenderer();
101 const int rows = mModel->
rowCount();
103 const QModelIndex newIndex = mModel->index( rows, 0 );
104 mSubDiagramsView->selectionModel()->setCurrentIndex( newIndex, QItemSelectionModel::ClearAndSelect );
107void QgsStackedDiagramProperties::editSubDiagramRenderer()
109 editSubDiagramRenderer( mSubDiagramsView->selectionModel()->currentIndex() );
112void QgsStackedDiagramProperties::editSubDiagramRenderer(
const QModelIndex &index )
114 if ( !index.isValid() )
125 widget->layout()->setContentsMargins( 0, 0, 0, 0 );
128 if ( !couldBeFirstSubDiagram( index ) )
141 dlg.syncToRenderer( renderer );
142 dlg.syncToSettings( &dls );
143 if ( !couldBeFirstSubDiagram( index ) )
145 dlg.setAllowedToEditDiagramLayerSettings(
false );
150 const QModelIndex index = mSubDiagramsView->selectionModel()->currentIndex();
151 if ( dlg.isAllowedToEditDiagramLayerSettings() )
159void QgsStackedDiagramProperties::removeSubDiagramRenderer()
161 const QItemSelection sel = mSubDiagramsView->selectionModel()->selection();
162 const auto constSel = sel;
163 for (
const QItemSelectionRange &range : constSel )
165 if ( range.isValid() )
166 mModel->
removeRows( range.top(), range.bottom() - range.top() + 1, range.parent() );
169 mSubDiagramsView->selectionModel()->clear();
179 mStackedDiagramModeComboBox->setCurrentIndex( settingList.at( 0 ).stackedDiagramMode );
180 mStackedDiagramSpacingSpinBox->setValue( settingList.at( 0 ).stackedDiagramSpacing() );
181 mStackedDiagramSpacingUnitComboBox->setUnit( settingList.at( 0 ).stackedDiagramSpacingUnit() );
186 const QList<QgsDiagramRenderer *> renderers = stackedDiagramRenderer->
renderers();
189 appendSubDiagramRenderer( renderer->
clone() );
195 appendSubDiagramRenderer( dr->
clone() );
205 auto ds = std::make_unique<QgsDiagramSettings>();
207 ds->setStackedDiagramSpacingUnit( mStackedDiagramSpacingUnitComboBox->unit() );
208 ds->setStackedDiagramSpacing( mStackedDiagramSpacingSpinBox->value() );
215 const QList<QgsDiagramRenderer *> renderers = mModel->
subRenderers();
219 if ( !ds1.isEmpty() )
221 ds->categoryAttributes += ds1.at( 0 ).categoryAttributes;
222 ds->categoryLabels += ds1.at( 0 ).categoryLabels;
223 ds->categoryColors += ds1.at( 0 ).categoryColors;
240bool QgsStackedDiagramProperties::couldBeFirstSubDiagram(
const QModelIndex &index )
const
242 if ( !index.isValid() )
250 const QList<QgsDiagramRenderer *> renderers = mModel->
subRenderers();
252 for (
int i = 0; i < index.row(); i++ )
256 if ( !ds.isEmpty() && ds.at( 0 ).enabled )
270void QgsStackedDiagramProperties::subDiagramWidgetPanelAccepted(
QgsPanelWidget *panel )
274 std::unique_ptr<QgsDiagramRenderer> renderer = widget->createRenderer();
276 const QModelIndex index = mSubDiagramsView->selectionModel()->currentIndex();
283void QgsStackedDiagramProperties::liveUpdateSubDiagramFromPanel()
285 subDiagramWidgetPanelAccepted( qobject_cast<QgsPanelWidget *>( sender() ) );
296 setWindowModality( Qt::WindowModal );
299 QVBoxLayout *layout =
new QVBoxLayout(
this );
301 scrollArea->setFrameShape( QFrame::NoFrame );
302 layout->addWidget( scrollArea );
304 buttonBox =
new QDialogButtonBox( QDialogButtonBox::Cancel | QDialogButtonBox::Help | QDialogButtonBox::Ok );
308 scrollArea->setWidget( mPropsWidget );
309 layout->addWidget( buttonBox );
310 this->setWindowTitle(
"Edit Sub Diagram" );
314 connect( buttonBox, &QDialogButtonBox::rejected,
this, &QDialog::reject );
315 connect( buttonBox, &QDialogButtonBox::helpRequested,
this, &QgsStackedDiagramPropertiesDialog::showHelp );
331 mRenderer = mPropsWidget->createRenderer();
332 mDiagramLayerSettings = mPropsWidget->createDiagramLayerSettings();
338 return mRenderer.release();
343 return mDiagramLayerSettings;
356void QgsStackedDiagramPropertiesDialog::showHelp()
358 QgsHelp::openHelp( QStringLiteral(
"working_with_vector/vector_properties.html#diagrams-properties" ) );
364 : QAbstractTableModel( parent )
375 const Qt::ItemFlag checkable = ( index.column() == 0 ? Qt::ItemIsUserCheckable : Qt::NoItemFlags );
378 const Qt::ItemFlag drop = ( index.column() == 0 ? Qt::ItemIsDropEnabled : Qt::NoItemFlags );
380 return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | drop | checkable;
385 return Qt::MoveAction;
391 types << QStringLiteral(
"application/vnd.text.list" );
397 QMimeData *
mimeData =
new QMimeData();
398 QByteArray encodedData;
400 QDataStream stream( &encodedData, QIODevice::WriteOnly );
402 for (
const QModelIndex &index : indexes )
405 if ( !index.isValid() || index.column() != 0 )
412 QDomElement rootElem = doc.createElement( QStringLiteral(
"diagram_mime" ) );
414 doc.appendChild( rootElem );
415 stream << doc.toString( -1 );
419 mimeData->setData( QStringLiteral(
"application/vnd.text.list" ), encodedData );
427 if ( action == Qt::IgnoreAction )
430 if ( !
data->hasFormat( QStringLiteral(
"application/vnd.text.list" ) ) )
433 if ( parent.column() > 0 )
436 QByteArray encodedData =
data->data( QStringLiteral(
"application/vnd.text.list" ) );
437 QDataStream stream( &encodedData, QIODevice::ReadOnly );
446 while ( !stream.atEnd() )
452 if ( !doc.setContent( text ) )
454 const QDomElement rootElem = doc.documentElement();
455 if ( rootElem.tagName() != QLatin1String(
"diagram_mime" ) || !rootElem.hasChildNodes() )
457 const QDomElement childElem = rootElem.firstChild().toElement();
460 if ( childElem.nodeName() == QLatin1String(
"SingleCategoryDiagramRenderer" ) )
465 else if ( childElem.nodeName() == QLatin1String(
"LinearlyInterpolatedDiagramRenderer" ) )
470 else if ( childElem.nodeName() == QLatin1String(
"StackedDiagramRenderer" ) )
488 if ( !index.isValid() )
493 if ( role == Qt::DisplayRole || role == Qt::ToolTipRole )
495 switch ( index.column() )
502 return tr(
"Pie Chart" );
506 return tr(
"Text Diagram" );
510 return tr(
"Histogram" );
514 return tr(
"Stacked Bars" );
518 return tr(
"Stacked Diagram" );
527 return tr(
"(no diagram)" );
532 return tr(
"(no renderer)" );
537 return tr(
"Fixed" );
539 return tr(
"Scaled" );
541 return tr(
"Unknown" );
553 return tr(
"Right" );
566 else if ( role == Qt::CheckStateRole )
568 if ( index.column() != 0 )
581 if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section < 3 )
584 lst << tr(
"Diagram type" ) << tr(
"Size" ) << tr(
"Orientation" );
603 if ( !index.isValid() )
608 if ( role == Qt::CheckStateRole )
613 ds.
enabled = ( value.toInt() == Qt::Checked );
626 emit dataChanged( index, index );
638 beginRemoveRows( parent, row, row + count - 1 );
648 if ( index.isValid() )
655 beginInsertRows( QModelIndex(), index, index );
662 if ( !index.isValid() )
667 emit dataChanged( index, index );
@ Millimeters
Millimeters.
@ Points
Points (e.g., for font sizes)
@ MetersInMapUnits
Meters value as Map units.
Stores the settings for rendering of all diagrams for a layer.
void syncToSettings(const QgsDiagramLayerSettings *dls)
Updates the widget to reflect the diagram layer settings.
void setDockMode(bool dockMode) override
Sets the widget in dock mode.
bool isAllowedToEditDiagramLayerSettings() const
Returns whether this widget is allowed to edit diagram layer settings.
void syncToRenderer(const QgsDiagramRenderer *dr)
Updates the widget to reflect the diagram renderer.
void auxiliaryFieldCreated()
void setAllowedToEditDiagramLayerSettings(bool allowed)
Sets whether the widget should show diagram layer settings.
Evaluates and returns the diagram settings relating to a diagram for a specific feature.
virtual QString rendererName() const =0
QgsDiagram * diagram() const
virtual QList< QgsDiagramSettings > diagramSettings() const =0
Returns list with all diagram settings in the renderer.
virtual void readXml(const QDomElement &elem, const QgsReadWriteContext &context)=0
Reads diagram state from a DOM element.
void setDiagram(QgsDiagram *d)
virtual QgsDiagramRenderer * clone() const =0
Returns new instance that is equivalent to this one.
Stores the settings for rendering a single diagram.
StackedDiagramMode
Orientation of the stacked diagrams.
virtual QString diagramName() const =0
Gets a descriptive name for this diagram type.
static void enableAutoGeometryRestore(QWidget *widget, const QString &key=QString())
Register the widget to allow its position to be automatically saved and restored when open and closed...
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
static const QString DIAGRAM_NAME_HISTOGRAM
Alters the size of rendered diagrams using a linear scaling.
void setDiagramSettings(const QgsDiagramSettings &s)
static const QString DIAGRAM_RENDERER_NAME_LINEARLY_INTERPOLATED
Map canvas is a class for displaying all GIS data types on a canvas.
void triggerRepaint(bool deferredUpdate=false)
Will advise the map canvas (and any other interested party) that this layer requires to be repainted.
static const QString DIAGRAM_NAME_PIE
static QgsProject * instance()
Returns the QgsProject singleton instance.
void setDirty(bool b=true)
Flag the project as dirty (modified).
The class is used as a container of context for various read/write operations on other objects.
Renders the diagrams for all features with the same settings.
void setDiagramSettings(const QgsDiagramSettings &s)
static const QString DIAGRAM_RENDERER_NAME_SINGLE_CATEGORY
static const QString DIAGRAM_NAME_STACKED_BAR
Dialog for editing sub diagrams.
QgsStackedDiagramPropertiesDialog(QgsVectorLayer *layer, QWidget *parent=nullptr, QgsMapCanvas *mapCanvas=nullptr)
Constructor for QgsStackedDiagramPropertiesDialog.
QgsDiagramLayerSettings diagramLayerSettings() const
Gets diagram layer settings built from the diagram properties widget.
void setAllowedToEditDiagramLayerSettings(bool allowed) const
Delegates to the main widget to set whether the widget should show diagram layer settings to be edite...
void syncToRenderer(const QgsDiagramRenderer *dr) const
Delegates to the diagram properties widget to sync with the given renderer.
void syncToSettings(const QgsDiagramLayerSettings *dls) const
Delegates to the diagram properties widget to sync with the given diagram layer settings.
bool isAllowedToEditDiagramLayerSettings() const
Returns whether the main widget is allowed to edit diagram layer settings.
void accept() override
Applies changes from the widget to the internal renderer and diagram layer settings.
QgsDiagramRenderer * renderer()
Gets a renderer object built from the diagram properties widget.
Model for sub diagrams in a stacked diagram view.
Qt::DropActions supportedDropActions() const override
~QgsStackedDiagramPropertiesModel() override
QMimeData * mimeData(const QModelIndexList &indexes) const override
void updateSubDiagram(const QModelIndex &index, QgsDiagramRenderer *dr)
Replaces the diagram located at index by dr. Takes ownership.
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override
bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
void insertSubDiagram(const int index, QgsDiagramRenderer *newSubDiagram)
Inserts a new diagram at the specified position. Takes ownership.
QStringList mimeTypes() const override
QList< QgsDiagramRenderer * > mRenderers
QgsDiagramLayerSettings mDiagramLayerSettings
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
QgsDiagramRenderer * subDiagramForIndex(const QModelIndex &index) const
Returns the diagram renderer at the specified index. Does not transfer ownership.
void updateDiagramLayerSettings(QgsDiagramLayerSettings dls)
Sets the diagram layer settings for the model.
Qt::ItemFlags flags(const QModelIndex &index) const override
QgsDiagramLayerSettings diagramLayerSettings() const
Returns the diagram layer settings from the model.
QList< QgsDiagramRenderer * > subRenderers() const
Returns the list of diagram renderers from the model. Does not transfer ownership.
int columnCount(const QModelIndex &=QModelIndex()) const override
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override
QgsStackedDiagramPropertiesModel(QObject *parent=nullptr)
constructor
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
int rowCount(const QModelIndex &=QModelIndex()) const override
void syncToLayer()
Updates the widget to reflect the layer's current diagram settings.
void auxiliaryFieldCreated()
QgsStackedDiagramProperties(QgsVectorLayer *layer, QWidget *parent, QgsMapCanvas *canvas)
Renders diagrams using mixed diagram render types.
void setDiagramSettings(const QgsDiagramSettings &s)
static const QString DIAGRAM_RENDERER_NAME_STACKED
void addRenderer(QgsDiagramRenderer *renderer)
Adds a renderer to the stacked renderer object.
QList< QgsDiagramRenderer * > renderers(bool sortByDiagramMode=false) const
Returns an ordered list with the renderers of the stacked renderer object.
A diagram composed of several subdiagrams, located side by side.
static const QString DIAGRAM_NAME_STACKED
static const QString DIAGRAM_NAME_TEXT
Represents a vector layer which manages a vector based data sets.
const QgsDiagramLayerSettings * diagramLayerSettings() const
void setDiagramLayerSettings(const QgsDiagramLayerSettings &s)
void setDiagramRenderer(QgsDiagramRenderer *r)
Sets diagram rendering object (takes ownership)
const QgsDiagramRenderer * diagramRenderer() const