Skip to content

Commit

Permalink
Double clicking a legend node when editing a layout legend now opens
Browse files Browse the repository at this point in the history
the rename option in an inline panel widget

This provides us with a place to insert more useful per-node properties
for greater legend customisation power.
  • Loading branch information
nyalldawson committed Apr 17, 2020
1 parent 2be229e commit 9e548a0
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 45 deletions.
116 changes: 72 additions & 44 deletions src/gui/layout/qgslayoutlegendwidget.cpp
Expand Up @@ -1292,54 +1292,16 @@ void QgsLayoutLegendWidget::mItemTreeView_doubleClicked( const QModelIndex &idx
QgsLayerTreeModel *model = mItemTreeView->layerTreeModel();
QgsLayerTreeNode *currentNode = model->index2node( idx );
QgsLayerTreeModelLegendNode *legendNode = model->index2legendNode( idx );
QString currentText;

if ( QgsLayerTree::isGroup( currentNode ) )
int originalIndex = -1;
if ( legendNode )
{
currentText = QgsLayerTree::toGroup( currentNode )->name();
originalIndex = _originalLegendNodeIndex( legendNode );
currentNode = legendNode->layerNode();
}
else if ( QgsLayerTree::isLayer( currentNode ) )
{
currentText = QgsLayerTree::toLayer( currentNode )->name();
QVariant v = currentNode->customProperty( QStringLiteral( "legend/title-label" ) );
if ( !v.isNull() )
currentText = v.toString();
}
else if ( legendNode )
{
currentText = legendNode->data( Qt::EditRole ).toString();
}

bool ok;
QString newText = QInputDialog::getText( this, tr( "Legend Item Properties" ), tr( "Item text" ),
QLineEdit::Normal, currentText, &ok );
if ( !ok || newText == currentText )
return;

mLegend->beginCommand( tr( "Edit Legend Item" ) );

if ( QgsLayerTree::isGroup( currentNode ) )
{
QgsLayerTree::toGroup( currentNode )->setName( newText );
}
else if ( QgsLayerTree::isLayer( currentNode ) )
{
currentNode->setCustomProperty( QStringLiteral( "legend/title-label" ), newText );

// force update of label of the legend node with embedded icon (a bit clumsy i know)
if ( QgsLayerTreeModelLegendNode *embeddedNode = model->legendNodeEmbeddedInParent( QgsLayerTree::toLayer( currentNode ) ) )
embeddedNode->setUserLabel( QString() );
}
else if ( legendNode )
{
int originalIndex = _originalLegendNodeIndex( legendNode );
QgsMapLayerLegendUtils::setLegendNodeUserLabel( legendNode->layerNode(), originalIndex, newText );
model->refreshLayerLegend( legendNode->layerNode() );
}

mLegend->adjustBoxSize();
mLegend->updateFilterByMap();
mLegend->endCommand();
QgsLayoutLegendNodeWidget *widget = new QgsLayoutLegendNodeWidget( mLegend, currentNode, legendNode, originalIndex );
openPanel( widget );
}


Expand Down Expand Up @@ -1382,3 +1344,69 @@ QMenu *QgsLayoutLegendMenuProvider::createContextMenu()

return menu;
}

//
// QgsLayoutLegendNodeWidget
//
QgsLayoutLegendNodeWidget::QgsLayoutLegendNodeWidget( QgsLayoutItemLegend *legend, QgsLayerTreeNode *node, QgsLayerTreeModelLegendNode *legendNode, int originalLegendNodeIndex, QWidget *parent )
: QgsPanelWidget( parent )
, mLegend( legend )
, mNode( node )
, mLayer( qobject_cast< QgsLayerTreeLayer* >( node ) )
, mLegendNode( legendNode )
, mOriginalLegendNodeIndex( originalLegendNodeIndex )
{
setupUi( this );
setPanelTitle( tr( "Legend Item Properties" ) );

// auto close panel if layer removed
connect( node, &QObject::destroyed, this, &QgsPanelWidget::acceptPanel );

QString currentLabel;
if ( mLegendNode )
{
currentLabel = mLegendNode->data( Qt::EditRole ).toString();
}
else if ( mLayer )
{
currentLabel = mLayer->name();
QVariant v = mLayer->customProperty( QStringLiteral( "legend/title-label" ) );
if ( !v.isNull() )
currentLabel = v.toString();
}
else
{
currentLabel = QgsLayerTree::toGroup( mNode )->name();
}

mLabelEdit->setText( currentLabel );
connect( mLabelEdit, &QLineEdit::textChanged, this, &QgsLayoutLegendNodeWidget::labelChanged );

}

void QgsLayoutLegendNodeWidget::labelChanged( const QString &label )
{
mLegend->beginCommand( tr( "Edit Legend Item" ), QgsLayoutItem::UndoLegendText );

if ( QgsLayerTree::isGroup( mNode ) )
{
QgsLayerTree::toGroup( mNode )->setName( label );
}
else if ( mLegendNode )
{
QgsMapLayerLegendUtils::setLegendNodeUserLabel( mLayer, mOriginalLegendNodeIndex, label );
mLegend->model()->refreshLayerLegend( mLayer );
}
else if ( mLayer )
{
mLayer->setCustomProperty( QStringLiteral( "legend/title-label" ), label );

// force update of label of the legend node with embedded icon (a bit clumsy i know)
if ( QgsLayerTreeModelLegendNode *embeddedNode = mLegend->model()->legendNodeEmbeddedInParent( mLayer ) )
embeddedNode->setUserLabel( QString() );
}

mLegend->adjustBoxSize();
mLegend->updateFilterByMap();
mLegend->endCommand();
}
32 changes: 31 additions & 1 deletion src/gui/layout/qgslayoutlegendwidget.h
Expand Up @@ -85,7 +85,7 @@ class GUI_EXPORT QgsLayoutLegendWidget: public QgsLayoutItemBaseWidget, private
void mBoxSpaceSpinBox_valueChanged( double d );
void mColumnSpaceSpinBox_valueChanged( double d );
void mLineSpacingSpinBox_valueChanged( double d );
void mCheckBoxAutoUpdate_stateChanged( int state );
void mCheckBoxAutoUpdate_stateChanged( int state, bool userTriggered = true );
void composerMapChanged( QgsLayoutItem *item );
void mCheckboxResizeContents_toggled( bool checked );

Expand Down Expand Up @@ -164,6 +164,36 @@ class GUI_EXPORT QgsLayoutLegendMenuProvider : public QgsLayerTreeViewMenuProvid
QgsLayoutLegendWidget *mWidget = nullptr;
};

#include "ui_qgslayoutlegendnodewidgetbase.h"

/**
* \ingroup gui
* A widget for properties relating to a node in a layout legend.
*
* \note This class is not a part of public API
* \since QGIS 3.14
*/
class GUI_EXPORT QgsLayoutLegendNodeWidget: public QgsPanelWidget, private Ui::QgsLayoutLegendNodeWidgetBase
{
Q_OBJECT

public:

QgsLayoutLegendNodeWidget( QgsLayoutItemLegend *legend, QgsLayerTreeNode *node, QgsLayerTreeModelLegendNode *legendNode, int originalLegendNodeIndex, QWidget *parent = nullptr );

private slots:

void labelChanged( const QString &label );

private:

QgsLayoutItemLegend *mLegend = nullptr;
QgsLayerTreeNode *mNode = nullptr;
QgsLayerTreeLayer *mLayer = nullptr;
QgsLayerTreeModelLegendNode *mLegendNode = nullptr;
int mOriginalLegendNodeIndex = -1;

};

#endif //QGSLAYOUTLEGENDWIDGET_H

58 changes: 58 additions & 0 deletions src/ui/layout/qgslayoutlegendnodewidgetbase.ui
@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QgsLayoutLegendNodeWidgetBase</class>
<widget class="QgsPanelWidget" name="QgsLayoutLegendNodeWidgetBase">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</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">
<widget class="QLabel" name="label">
<property name="text">
<string>Label</string>
</property>
</widget>
</item>
<item row="1" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</spacer>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="mLabelEdit"/>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QgsPanelWidget</class>
<extends>QWidget</extends>
<header>qgspanelwidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

0 comments on commit 9e548a0

Please sign in to comment.