34#include "moc_qgsstackeddiagramproperties.cpp"
39 , mMapCanvas( canvas )
47 connect( mSubDiagramsView, &QAbstractItemView::doubleClicked,
this,
static_cast<void (
QgsStackedDiagramProperties::* )(
const QModelIndex & )
>( &QgsStackedDiagramProperties::editSubDiagramRenderer ) );
49 connect( mAddSubDiagramButton, &QPushButton::clicked,
this, &QgsStackedDiagramProperties::addSubDiagramRenderer );
50 connect( mEditSubDiagramButton, &QAbstractButton::clicked,
this,
static_cast<void (
QgsStackedDiagramProperties::* )()
>( &QgsStackedDiagramProperties::editSubDiagramRenderer ) );
51 connect( mRemoveSubDiagramButton, &QPushButton::clicked,
this, &QgsStackedDiagramProperties::removeSubDiagramRenderer );
57 mStackedDiagramSpacingSpinBox->setClearValue( 0 );
65 mSubDiagramsView->setModel( mModel );
78void QgsStackedDiagramProperties::addSubDiagramRenderer()
81 std::unique_ptr<QgsDiagramRenderer> renderer;
82 auto dr = std::make_unique<QgsSingleCategoryDiagramRenderer>();
83 renderer = std::move( dr );
85 QItemSelectionModel *sel = mSubDiagramsView->selectionModel();
86 const QModelIndex index = sel->currentIndex();
88 if ( index.isValid() )
91 const QModelIndex currentIndex = mSubDiagramsView->selectionModel()->currentIndex();
93 const QModelIndex newIndex = mModel->index( currentIndex.row() + 1, 0 );
94 mSubDiagramsView->selectionModel()->setCurrentIndex( newIndex, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
99 appendSubDiagramRenderer( renderer.release() );
101 editSubDiagramRenderer();
106 const int rows = mModel->rowCount();
107 mModel->insertSubDiagram( rows, dr );
108 const QModelIndex newIndex = mModel->index( rows, 0 );
109 mSubDiagramsView->selectionModel()->setCurrentIndex( newIndex, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
112void QgsStackedDiagramProperties::editSubDiagramRenderer()
114 editSubDiagramRenderer( mSubDiagramsView->selectionModel()->currentIndex() );
117void QgsStackedDiagramProperties::editSubDiagramRenderer(
const QModelIndex &index )
119 if ( !index.isValid() )
122 QgsDiagramRenderer *renderer = mModel->subDiagramForIndex( index );
123 QgsDiagramLayerSettings dls = mModel->diagramLayerSettings();
128 QgsDiagramProperties *widget =
new QgsDiagramProperties( mLayer,
this, mMapCanvas );
130 widget->layout()->setContentsMargins( 0, 0, 0, 0 );
133 if ( !couldBeFirstSubDiagram( index ) )
145 QgsStackedDiagramPropertiesDialog dlg( mLayer,
this, mMapCanvas );
146 dlg.syncToRenderer( renderer );
147 dlg.syncToSettings( &dls );
148 if ( !couldBeFirstSubDiagram( index ) )
150 dlg.setAllowedToEditDiagramLayerSettings(
false );
155 const QModelIndex index = mSubDiagramsView->selectionModel()->currentIndex();
156 if ( dlg.isAllowedToEditDiagramLayerSettings() )
157 mModel->updateDiagramLayerSettings( dlg.diagramLayerSettings() );
160 mModel->updateSubDiagram( index, dlg.renderer() );
164void QgsStackedDiagramProperties::removeSubDiagramRenderer()
166 const QItemSelection sel = mSubDiagramsView->selectionModel()->selection();
167 const auto constSel = sel;
168 for (
const QItemSelectionRange &range : constSel )
170 if ( range.isValid() )
171 mModel->removeRows( range.top(), range.bottom() - range.top() + 1, range.parent() );
174 mSubDiagramsView->selectionModel()->clear();
179 mSubDiagramsView->selectionModel()->clearCurrentIndex();
189 mStackedDiagramModeComboBox->setCurrentIndex( settingList.at( 0 ).stackedDiagramMode );
190 mStackedDiagramSpacingSpinBox->setValue( settingList.at( 0 ).stackedDiagramSpacing() );
191 mStackedDiagramSpacingUnitComboBox->setUnit( settingList.at( 0 ).stackedDiagramSpacingUnit() );
196 const QList<QgsDiagramRenderer *> renderers = stackedDiagramRenderer->
renderers();
199 appendSubDiagramRenderer( renderer->
clone() );
205 appendSubDiagramRenderer( dr->
clone() );
209 mModel->updateDiagramLayerSettings( *dls );
211 mSubDiagramsView->selectionModel()->clear();
217 auto ds = std::make_unique<QgsDiagramSettings>();
219 ds->setStackedDiagramSpacingUnit( mStackedDiagramSpacingUnitComboBox->unit() );
220 ds->setStackedDiagramSpacing( mStackedDiagramSpacingSpinBox->value() );
227 const QList<QgsDiagramRenderer *> renderers = mModel->subRenderers();
231 if ( !ds1.isEmpty() )
233 ds->categoryAttributes += ds1.at( 0 ).categoryAttributes;
234 ds->categoryLabels += ds1.at( 0 ).categoryLabels;
235 ds->categoryColors += ds1.at( 0 ).categoryColors;
241 mLayer->setDiagramRenderer( dr );
245 mLayer->setDiagramLayerSettings( dls );
249 mLayer->triggerRepaint();
252bool QgsStackedDiagramProperties::couldBeFirstSubDiagram(
const QModelIndex &index )
const
254 if ( !index.isValid() )
262 const QList<QgsDiagramRenderer *> renderers = mModel->
subRenderers();
264 for (
int i = 0; i < index.row(); i++ )
268 if ( !ds.isEmpty() && ds.at( 0 ).enabled )
282void QgsStackedDiagramProperties::subDiagramWidgetPanelAccepted(
QgsPanelWidget *panel )
284 QgsDiagramProperties *widget = qobject_cast<QgsDiagramProperties *>( panel );
286 std::unique_ptr<QgsDiagramRenderer> renderer = widget->createRenderer();
288 const QModelIndex index = mSubDiagramsView->selectionModel()->currentIndex();
290 mModel->updateDiagramLayerSettings( widget->createDiagramLayerSettings() );
292 mModel->updateSubDiagram( index, renderer.release() );
295void QgsStackedDiagramProperties::liveUpdateSubDiagramFromPanel()
297 subDiagramWidgetPanelAccepted( qobject_cast<QgsPanelWidget *>( sender() ) );
308 setWindowModality( Qt::WindowModal );
311 QVBoxLayout *layout =
new QVBoxLayout(
this );
313 scrollArea->setFrameShape( QFrame::NoFrame );
314 layout->addWidget( scrollArea );
316 buttonBox =
new QDialogButtonBox( QDialogButtonBox::Cancel | QDialogButtonBox::Help | QDialogButtonBox::Ok );
318 mPropsWidget->setDockMode(
false );
320 scrollArea->setWidget( mPropsWidget );
321 layout->addWidget( buttonBox );
322 this->setWindowTitle(
"Edit Sub Diagram" );
326 connect( buttonBox, &QDialogButtonBox::rejected,
this, &QDialog::reject );
327 connect( buttonBox, &QDialogButtonBox::helpRequested,
this, &QgsStackedDiagramPropertiesDialog::showHelp );
332 mPropsWidget->syncToRenderer( dr );
337 mPropsWidget->syncToSettings( dls );
343 mRenderer = mPropsWidget->createRenderer();
344 mDiagramLayerSettings = mPropsWidget->createDiagramLayerSettings();
350 return mRenderer.release();
355 return mDiagramLayerSettings;
360 mPropsWidget->setAllowedToEditDiagramLayerSettings( allowed );
365 return mPropsWidget->isAllowedToEditDiagramLayerSettings();
368void QgsStackedDiagramPropertiesDialog::showHelp()
370 QgsHelp::openHelp( QStringLiteral(
"working_with_vector/vector_properties.html#diagrams-properties" ) );
376 : QAbstractTableModel( parent )
388 if ( !index.isValid() )
389 return Qt::ItemIsDropEnabled;
391 Qt::ItemFlags
flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled;
393 if ( index.column() == 0 )
394 flags |= Qt::ItemIsUserCheckable;
401 return Qt::MoveAction;
407 types << QStringLiteral(
"application/vnd.text.list" );
413 QMimeData *
mimeData =
new QMimeData();
414 QByteArray encodedData;
416 QDataStream stream( &encodedData, QIODevice::WriteOnly );
419 QModelIndexList sortedIndexes = indexes;
420 std::sort( sortedIndexes.begin(), sortedIndexes.end() );
422 for (
const QModelIndex &index : std::as_const( sortedIndexes ) )
425 if ( !index.isValid() || index.column() != 0 )
432 QDomElement rootElem = doc.createElement( QStringLiteral(
"diagram_mime" ) );
434 doc.appendChild( rootElem );
435 stream << doc.toString( -1 );
439 mimeData->setData( QStringLiteral(
"application/vnd.text.list" ), encodedData );
448 if ( action == Qt::IgnoreAction )
451 if ( !
data->hasFormat( QStringLiteral(
"application/vnd.text.list" ) ) )
454 QByteArray encodedData =
data->data( QStringLiteral(
"application/vnd.text.list" ) );
455 QDataStream stream( &encodedData, QIODevice::ReadOnly );
464 while ( !stream.atEnd() )
470 if ( !doc.setContent( text ) )
472 const QDomElement rootElem = doc.documentElement();
473 if ( rootElem.tagName() != QLatin1String(
"diagram_mime" ) || !rootElem.hasChildNodes() )
475 const QDomElement childElem = rootElem.firstChild().toElement();
478 if ( childElem.nodeName() == QLatin1String(
"SingleCategoryDiagramRenderer" ) )
483 else if ( childElem.nodeName() == QLatin1String(
"LinearlyInterpolatedDiagramRenderer" ) )
488 else if ( childElem.nodeName() == QLatin1String(
"StackedDiagramRenderer" ) )
507 if ( !index.isValid() )
512 if ( role == Qt::DisplayRole || role == Qt::ToolTipRole )
514 switch ( index.column() )
521 return tr(
"Pie Chart" );
525 return tr(
"Text Diagram" );
529 return tr(
"Histogram" );
533 return tr(
"Stacked Bars" );
537 return tr(
"Stacked Diagram" );
546 return tr(
"(no diagram)" );
551 return tr(
"(no renderer)" );
556 return tr(
"Fixed" );
558 return tr(
"Scaled" );
560 return tr(
"Unknown" );
572 return tr(
"Right" );
585 else if ( role == Qt::CheckStateRole )
587 if ( index.column() != 0 )
600 if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section < 3 )
603 lst << tr(
"Diagram type" ) << tr(
"Size" ) << tr(
"Orientation" );
622 if ( !index.isValid() )
627 if ( role == Qt::CheckStateRole )
632 ds.
enabled = ( value.toInt() == Qt::Checked );
645 emit dataChanged( index, index );
657 beginRemoveRows( parent, row, row + count - 1 );
667 if ( index.isValid() )
674 beginInsertRows( QModelIndex(), index, index );
681 if ( !index.isValid() )
686 emit dataChanged( index, index );
711 if ( element == QStyle::PE_IndicatorItemViewItemDrop && !option->rect.isNull() )
713 QStyleOption opt( *option );
714 opt.rect.setLeft( 0 );
716 opt.rect.setHeight( 0 );
718 opt.rect.setRight( widget->width() );
719 QProxyStyle::drawPrimitive( element, &opt, painter, widget );
722 QProxyStyle::drawPrimitive( element, option, painter, widget );
@ 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.
A widget which configures diagrams for a vector layer.
void syncToSettings(const QgsDiagramLayerSettings *dls)
Updates the widget to reflect the diagram layer settings.
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 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.
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).
QgsProxyStyle(QWidget *parent)
Constructor for QgsProxyStyle.
A container for the context for various read/write operations on 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
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
void subDiagramsMoved()
Informs views that subdiagrams were moved in the model.
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 clearCurrentIndex()
Clears current item from the view.
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
View style which shows a drop indicator line between items.
QgsStackedDiagramsViewStyle(QWidget *parent)
Constructor for QgsStackedDiagramsViewStyle.
void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget=nullptr) const override
static const QString DIAGRAM_NAME_TEXT
Represents a vector layer which manages a vector based dataset.