Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recalculate layout when legend item size changes #38882

Merged
merged 2 commits into from
Sep 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,13 @@ Draws label on the right side of the item
void dataChanged();
%Docstring
Emitted on internal data change so the layer tree model can forward the signal to views
%End

void sizeChanged();
%Docstring
Emitted when the size of this node changes.

.. versionadded:: 3.16
%End

protected:
Expand Down
12 changes: 12 additions & 0 deletions src/core/layertree/qgslayertreemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -868,6 +868,17 @@ void QgsLayerTreeModel::legendNodeDataChanged()
emit dataChanged( index, index );
}

void QgsLayerTreeModel::legendNodeSizeChanged()
{
QgsLayerTreeModelLegendNode *legendNode = qobject_cast<QgsLayerTreeModelLegendNode *>( sender() );
if ( !legendNode )
return;

QModelIndex index = legendNode2index( legendNode );
if ( index.isValid() )
emit dataChanged( index, index, QVector<int> { Qt::SizeHintRole } );
}


void QgsLayerTreeModel::connectToLayer( QgsLayerTreeLayer *nodeLayer )
{
Expand Down Expand Up @@ -1293,6 +1304,7 @@ void QgsLayerTreeModel::addLegendToLayer( QgsLayerTreeLayer *nodeL )
{
n->setParent( this );
connect( n, &QgsLayerTreeModelLegendNode::dataChanged, this, &QgsLayerTreeModel::legendNodeDataChanged );
connect( n, &QgsLayerTreeModelLegendNode::sizeChanged, this, &QgsLayerTreeModel::legendNodeSizeChanged );
}

// See if we have an embedded node - if we do, we will not use it among active nodes.
Expand Down
3 changes: 3 additions & 0 deletions src/core/layertree/qgslayertreemodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,9 @@ class CORE_EXPORT QgsLayerTreeModel : public QAbstractItemModel
double mLegendMapViewScale;
QTimer mDeferLegendInvalidationTimer;

private slots:
void legendNodeSizeChanged();

private:

//! Returns a temporary render context
Expand Down
10 changes: 10 additions & 0 deletions src/core/layertree/qgslayertreemodellegendnode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,15 @@ QSizeF QgsLayerTreeModelLegendNode::userPatchSize() const
return mUserSize;
}

void QgsLayerTreeModelLegendNode::setUserPatchSize( QSizeF size )
{
if ( mUserSize == size )
return;

mUserSize = size;
emit sizeChanged();
}

QgsLayerTreeModelLegendNode::ItemMetrics QgsLayerTreeModelLegendNode::draw( const QgsLegendSettings &settings, ItemContext *ctx )
{
QFont symbolLabelFont = settings.style( QgsLegendStyle::SymbolLabel ).font();
Expand Down Expand Up @@ -1146,6 +1155,7 @@ void QgsWmsLegendNode::getLegendGraphicFinished( const QImage &image )
if ( image != mImage )
{
mImage = image;
setUserPatchSize( mImage.size() );
emit dataChanged();
}
mValid = true; // only if not null I guess
Expand Down
9 changes: 8 additions & 1 deletion src/core/layertree/qgslayertreemodellegendnode.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ class CORE_EXPORT QgsLayerTreeModelLegendNode : public QObject
* \see userPatchSize()
* \since QGIS 3.14
*/
virtual void setUserPatchSize( QSizeF size ) { mUserSize = size; }
virtual void setUserPatchSize( QSizeF size );

/**
* Sets whether a forced column break should occur before the node.
Expand Down Expand Up @@ -255,6 +255,13 @@ class CORE_EXPORT QgsLayerTreeModelLegendNode : public QObject
//! Emitted on internal data change so the layer tree model can forward the signal to views
void dataChanged();

/**
* Emitted when the size of this node changes.
*
* \since QGIS 3.16
*/
void sizeChanged();

protected:
//! Construct the node with pointer to its parent layer node
explicit QgsLayerTreeModelLegendNode( QgsLayerTreeLayer *nodeL, QObject *parent SIP_TRANSFERTHIS = nullptr );
Expand Down
28 changes: 22 additions & 6 deletions src/gui/layertree/qgslayertreeview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,28 +76,31 @@ QgsLayerTreeView::~QgsLayerTreeView()

void QgsLayerTreeView::setModel( QAbstractItemModel *model )
{
if ( !qobject_cast<QgsLayerTreeModel *>( model ) )
QgsLayerTreeModel *layerTreeModel = qobject_cast<QgsLayerTreeModel *>( model );
if ( !layerTreeModel )
return;

connect( model, &QAbstractItemModel::rowsInserted, this, &QgsLayerTreeView::modelRowsInserted );
connect( model, &QAbstractItemModel::rowsRemoved, this, &QgsLayerTreeView::modelRowsRemoved );

if ( mMessageBar )
connect( layerTreeModel(), &QgsLayerTreeModel::messageEmitted,
connect( layerTreeModel, &QgsLayerTreeModel::messageEmitted,
[ = ]( const QString & message, Qgis::MessageLevel level = Qgis::Info, int duration = 5 )
{mMessageBar->pushMessage( message, level, duration );}
);

QTreeView::setModel( model );

connect( layerTreeModel()->rootGroup(), &QgsLayerTreeNode::expandedChanged, this, &QgsLayerTreeView::onExpandedChanged );
connect( layerTreeModel()->rootGroup(), &QgsLayerTreeNode::customPropertyChanged, this, &QgsLayerTreeView::onCustomPropertyChanged );
connect( layerTreeModel->rootGroup(), &QgsLayerTreeNode::expandedChanged, this, &QgsLayerTreeView::onExpandedChanged );
connect( layerTreeModel->rootGroup(), &QgsLayerTreeNode::customPropertyChanged, this, &QgsLayerTreeView::onCustomPropertyChanged );

connect( selectionModel(), &QItemSelectionModel::currentChanged, this, &QgsLayerTreeView::onCurrentChanged );

connect( layerTreeModel(), &QAbstractItemModel::modelReset, this, &QgsLayerTreeView::onModelReset );
connect( layerTreeModel, &QAbstractItemModel::modelReset, this, &QgsLayerTreeView::onModelReset );

updateExpandedStateFromNode( layerTreeModel()->rootGroup() );
connect( layerTreeModel, &QgsLayerTreeModel::dataChanged, this, &QgsLayerTreeView::onDataChanged );

updateExpandedStateFromNode( layerTreeModel->rootGroup() );
}

QgsLayerTreeModel *QgsLayerTreeView::layerTreeModel() const
Expand Down Expand Up @@ -586,3 +589,16 @@ void QgsLayerTreeView::onHorizontalScroll( int value )
Q_UNUSED( value )
viewport()->update();
}

void QgsLayerTreeView::onDataChanged( const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles )
{
Q_UNUSED( topLeft )
Q_UNUSED( bottomRight )

// If an item is resized asynchronously (e.g. wms legend)
// The items below will need to be shifted vertically.
// This doesn't happen automatically, unless the viewport update is triggered.

if ( roles.contains( Qt::SizeHintRole ) )
viewport()->update();
}
2 changes: 2 additions & 0 deletions src/gui/layertree/qgslayertreeview.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,8 @@ class GUI_EXPORT QgsLayerTreeView : public QTreeView
//! Handles updating the viewport to avoid flicker
void onHorizontalScroll( int value );

void onDataChanged( const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles );

protected:
//! helper class with default actions. Lazily initialized.
QgsLayerTreeViewDefaultActions *mDefaultActions = nullptr;
Expand Down