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 );
77void QgsStackedDiagramProperties::addSubDiagramRenderer()
80 std::unique_ptr<QgsDiagramRenderer> renderer;
81 auto dr = std::make_unique<QgsSingleCategoryDiagramRenderer>();
82 renderer = std::move( dr );
84 QItemSelectionModel *sel = mSubDiagramsView->selectionModel();
85 const QModelIndex index = sel->currentIndex();
87 if ( index.isValid() )
90 const QModelIndex currentIndex = mSubDiagramsView->selectionModel()->currentIndex();
92 const QModelIndex newIndex = mModel->index( currentIndex.row() + 1, 0 );
93 mSubDiagramsView->selectionModel()->setCurrentIndex( newIndex, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
98 appendSubDiagramRenderer( renderer.release() );
100 editSubDiagramRenderer();
105 const int rows = mModel->
rowCount();
107 const QModelIndex newIndex = mModel->index( rows, 0 );
108 mSubDiagramsView->selectionModel()->setCurrentIndex( newIndex, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
111void QgsStackedDiagramProperties::editSubDiagramRenderer()
113 editSubDiagramRenderer( mSubDiagramsView->selectionModel()->currentIndex() );
116void QgsStackedDiagramProperties::editSubDiagramRenderer(
const QModelIndex &index )
118 if ( !index.isValid() )
129 widget->layout()->setContentsMargins( 0, 0, 0, 0 );
132 if ( !couldBeFirstSubDiagram( index ) )
145 dlg.syncToRenderer( renderer );
146 dlg.syncToSettings( &dls );
147 if ( !couldBeFirstSubDiagram( index ) )
149 dlg.setAllowedToEditDiagramLayerSettings(
false );
154 const QModelIndex index = mSubDiagramsView->selectionModel()->currentIndex();
155 if ( dlg.isAllowedToEditDiagramLayerSettings() )
163void QgsStackedDiagramProperties::removeSubDiagramRenderer()
165 const QItemSelection sel = mSubDiagramsView->selectionModel()->selection();
166 const auto constSel = sel;
167 for (
const QItemSelectionRange &range : constSel )
169 if ( range.isValid() )
170 mModel->
removeRows( range.top(), range.bottom() - range.top() + 1, range.parent() );
173 mSubDiagramsView->selectionModel()->clear();
178 mSubDiagramsView->selectionModel()->clearCurrentIndex();
188 mStackedDiagramModeComboBox->setCurrentIndex( settingList.at( 0 ).stackedDiagramMode );
189 mStackedDiagramSpacingSpinBox->setValue( settingList.at( 0 ).stackedDiagramSpacing() );
190 mStackedDiagramSpacingUnitComboBox->setUnit( settingList.at( 0 ).stackedDiagramSpacingUnit() );
195 const QList<QgsDiagramRenderer *> renderers = stackedDiagramRenderer->
renderers();
198 appendSubDiagramRenderer( renderer->
clone() );
204 appendSubDiagramRenderer( dr->
clone() );
210 mSubDiagramsView->selectionModel()->clear();
216 auto ds = std::make_unique<QgsDiagramSettings>();
218 ds->setStackedDiagramSpacingUnit( mStackedDiagramSpacingUnitComboBox->unit() );
219 ds->setStackedDiagramSpacing( mStackedDiagramSpacingSpinBox->value() );
226 const QList<QgsDiagramRenderer *> renderers = mModel->
subRenderers();
230 if ( !ds1.isEmpty() )
232 ds->categoryAttributes += ds1.at( 0 ).categoryAttributes;
233 ds->categoryLabels += ds1.at( 0 ).categoryLabels;
234 ds->categoryColors += ds1.at( 0 ).categoryColors;
251bool QgsStackedDiagramProperties::couldBeFirstSubDiagram(
const QModelIndex &index )
const
253 if ( !index.isValid() )
261 const QList<QgsDiagramRenderer *> renderers = mModel->
subRenderers();
263 for (
int i = 0; i < index.row(); i++ )
267 if ( !ds.isEmpty() && ds.at( 0 ).enabled )
281void QgsStackedDiagramProperties::subDiagramWidgetPanelAccepted(
QgsPanelWidget *panel )
285 std::unique_ptr<QgsDiagramRenderer> renderer = widget->createRenderer();
287 const QModelIndex index = mSubDiagramsView->selectionModel()->currentIndex();
294void QgsStackedDiagramProperties::liveUpdateSubDiagramFromPanel()
296 subDiagramWidgetPanelAccepted( qobject_cast<QgsPanelWidget *>( sender() ) );
307 setWindowModality( Qt::WindowModal );
310 QVBoxLayout *layout =
new QVBoxLayout(
this );
312 scrollArea->setFrameShape( QFrame::NoFrame );
313 layout->addWidget( scrollArea );
315 buttonBox =
new QDialogButtonBox( QDialogButtonBox::Cancel | QDialogButtonBox::Help | QDialogButtonBox::Ok );
319 scrollArea->setWidget( mPropsWidget );
320 layout->addWidget( buttonBox );
321 this->setWindowTitle(
"Edit Sub Diagram" );
325 connect( buttonBox, &QDialogButtonBox::rejected,
this, &QDialog::reject );
326 connect( buttonBox, &QDialogButtonBox::helpRequested,
this, &QgsStackedDiagramPropertiesDialog::showHelp );
342 mRenderer = mPropsWidget->createRenderer();
343 mDiagramLayerSettings = mPropsWidget->createDiagramLayerSettings();
349 return mRenderer.release();
354 return mDiagramLayerSettings;
367void QgsStackedDiagramPropertiesDialog::showHelp()
369 QgsHelp::openHelp( QStringLiteral(
"working_with_vector/vector_properties.html#diagrams-properties" ) );
375 : QAbstractTableModel( parent )
387 if ( !index.isValid() )
388 return Qt::ItemIsDropEnabled;
390 Qt::ItemFlags
flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled;
392 if ( index.column() == 0 )
393 flags |= Qt::ItemIsUserCheckable;
400 return Qt::MoveAction;
406 types << QStringLiteral(
"application/vnd.text.list" );
412 QMimeData *
mimeData =
new QMimeData();
413 QByteArray encodedData;
415 QDataStream stream( &encodedData, QIODevice::WriteOnly );
418 QModelIndexList sortedIndexes = indexes;
419 std::sort( sortedIndexes.begin(), sortedIndexes.end() );
421 for (
const QModelIndex &index : std::as_const( sortedIndexes ) )
424 if ( !index.isValid() || index.column() != 0 )
431 QDomElement rootElem = doc.createElement( QStringLiteral(
"diagram_mime" ) );
433 doc.appendChild( rootElem );
434 stream << doc.toString( -1 );
438 mimeData->setData( QStringLiteral(
"application/vnd.text.list" ), encodedData );
447 if ( action == Qt::IgnoreAction )
450 if ( !
data->hasFormat( QStringLiteral(
"application/vnd.text.list" ) ) )
453 QByteArray encodedData =
data->data( QStringLiteral(
"application/vnd.text.list" ) );
454 QDataStream stream( &encodedData, QIODevice::ReadOnly );
463 while ( !stream.atEnd() )
469 if ( !doc.setContent( text ) )
471 const QDomElement rootElem = doc.documentElement();
472 if ( rootElem.tagName() != QLatin1String(
"diagram_mime" ) || !rootElem.hasChildNodes() )
474 const QDomElement childElem = rootElem.firstChild().toElement();
477 if ( childElem.nodeName() == QLatin1String(
"SingleCategoryDiagramRenderer" ) )
482 else if ( childElem.nodeName() == QLatin1String(
"LinearlyInterpolatedDiagramRenderer" ) )
487 else if ( childElem.nodeName() == QLatin1String(
"StackedDiagramRenderer" ) )
506 if ( !index.isValid() )
511 if ( role == Qt::DisplayRole || role == Qt::ToolTipRole )
513 switch ( index.column() )
520 return tr(
"Pie Chart" );
524 return tr(
"Text Diagram" );
528 return tr(
"Histogram" );
532 return tr(
"Stacked Bars" );
536 return tr(
"Stacked Diagram" );
545 return tr(
"(no diagram)" );
550 return tr(
"(no renderer)" );
555 return tr(
"Fixed" );
557 return tr(
"Scaled" );
559 return tr(
"Unknown" );
571 return tr(
"Right" );
584 else if ( role == Qt::CheckStateRole )
586 if ( index.column() != 0 )
599 if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section < 3 )
602 lst << tr(
"Diagram type" ) << tr(
"Size" ) << tr(
"Orientation" );
621 if ( !index.isValid() )
626 if ( role == Qt::CheckStateRole )
631 ds.
enabled = ( value.toInt() == Qt::Checked );
644 emit dataChanged( index, index );
656 beginRemoveRows( parent, row, row + count - 1 );
666 if ( index.isValid() )
673 beginInsertRows( QModelIndex(), index, index );
680 if ( !index.isValid() )
685 emit dataChanged( index, index );
710 if ( element == QStyle::PE_IndicatorItemViewItemDrop && !option->rect.isNull() )
712 QStyleOption opt( *option );
713 opt.rect.setLeft( 0 );
715 opt.rect.setHeight( 0 );
717 opt.rect.setRight( widget->width() );
718 QProxyStyle::drawPrimitive( element, &opt, painter, widget );
721 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.
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).
A QProxyStyle subclass which correctly sets the base style to match the QGIS application style,...
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
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 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 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