-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Commit
This allows definition of widgets embedded into layer tree for individual layers in the layer properties dialog (in new Legend tab). The idea is to have a way to quickly access to some actions that are often used with a layer. The implementation comes with transparency widget, in the future there may be more standard widgets coming, e.g. to setup filtering, selection, style or other stuff. The API allows plugins to register their own widgets, which will be useful for various domain specific plugins to assign custom widgets to layers they manage.
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
|
||
/** \ingroup gui | ||
* \class QgsLayerTreeEmbeddedConfigWidget | ||
* A widget to configure layer tree embedded widgets for a particular map layer. | ||
* @note introduced in QGIS 2.16 | ||
*/ | ||
class QgsLayerTreeEmbeddedConfigWidget : public QWidget | ||
{ | ||
%TypeHeaderCode | ||
#include <qgslayertreeembeddedconfigwidget.h> | ||
%End | ||
|
||
public: | ||
QgsLayerTreeEmbeddedConfigWidget( QWidget* parent /TransferThis/ = nullptr ); | ||
|
||
//! Initialize widget with a map layer | ||
void setLayer( QgsMapLayer* layer ); | ||
|
||
//! Store changes made in the widget to the layer | ||
void applyToLayer(); | ||
|
||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
|
||
/** \ingroup gui | ||
* \class QgsLayerTreeEmbeddedWidgetProvider | ||
* Provider interface to be implemented in order to introduce new kinds of embedded widgets for use in layer tree. | ||
* Embedded widgets are assigned per individual map layers and they are shown before any legend entries. | ||
* @see QgsLayerTreeEmbeddedWidgetRegistry | ||
* @note introduced in QGIS 2.16 | ||
*/ | ||
class QgsLayerTreeEmbeddedWidgetProvider | ||
{ | ||
%TypeHeaderCode | ||
#include <qgslayertreeembeddedwidgetregistry.h> | ||
%End | ||
|
||
public: | ||
virtual ~QgsLayerTreeEmbeddedWidgetProvider(); | ||
|
||
//! Unique name of the provider (among other providers) | ||
virtual QString id() const = 0; | ||
|
||
//! Human readable name - may be translatable with tr() | ||
virtual QString name() const = 0; | ||
|
||
//! Factory to create widgets. The returned widget is owned by the caller. | ||
//! The widgetIndex argument may be used to identify which widget is being | ||
//! created (useful when using multiple widgets from the same provider for one layer). | ||
virtual QWidget* createWidget( QgsMapLayer* layer, int widgetIndex ) = 0 /Factory/; | ||
|
||
//! Whether it makes sense to use this widget for a particular layer | ||
virtual bool supportsLayer( QgsMapLayer* layer ) = 0; | ||
}; | ||
|
||
/** \ingroup gui | ||
* \class QgsLayerTreeEmbeddedWidgetRegistry | ||
* Registry of widgets that may be embedded into layer tree view. | ||
* Embedded widgets are assigned per individual map layers and they are shown before any legend entries. | ||
* Layer tree must have UseEmbeddedWidgets flag enabled in order to show assigned widgets. | ||
* | ||
* @see QgsLayerTreeEmbeddedWidgetRegistry | ||
* @note introduced in QGIS 2.16 | ||
*/ | ||
class QgsLayerTreeEmbeddedWidgetRegistry | ||
{ | ||
%TypeHeaderCode | ||
#include <qgslayertreeembeddedwidgetregistry.h> | ||
%End | ||
|
||
public: | ||
|
||
/** Means of accessing canonical single instance */ | ||
static QgsLayerTreeEmbeddedWidgetRegistry* instance(); | ||
|
||
~QgsLayerTreeEmbeddedWidgetRegistry(); | ||
|
||
/** Return list of all registered providers */ | ||
QStringList providers() const; | ||
|
||
/** Get provider object from the provider's ID */ | ||
QgsLayerTreeEmbeddedWidgetProvider* provider( const QString& providerId ) const; | ||
|
||
/** Register a provider, takes ownership of the object. | ||
* Returns true on success, false if the provider is already registered. */ | ||
bool addProvider( QgsLayerTreeEmbeddedWidgetProvider* provider /Transfer/ ); | ||
|
||
/** Unregister a provider, the provider object is deleted. | ||
* Returns true on success, false if the provider was not registered. */ | ||
bool removeProvider( const QString& providerId ); | ||
|
||
protected: | ||
//! Protected constructor - use instance() to access the registry. | ||
QgsLayerTreeEmbeddedWidgetRegistry(); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,6 +33,27 @@ | |
#include "qgsvectorlayer.h" | ||
|
||
|
||
/** In order to support embedded widgets in layer tree view, the model | ||
* generates one placeholder legend node for each embedded widget. | ||
* The placeholder will be replaced by an embedded widget in QgsLayerTreeView | ||
*/ | ||
class EmbeddedWidgetLegendNode : public QgsLayerTreeModelLegendNode | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
wonder-sk
Author
Member
|
||
{ | ||
public: | ||
EmbeddedWidgetLegendNode( QgsLayerTreeLayer* nodeL ) | ||
: QgsLayerTreeModelLegendNode( nodeL ) | ||
{ | ||
} | ||
|
||
virtual QVariant data( int role ) const override | ||
{ | ||
Q_UNUSED( role ); | ||
return QVariant(); | ||
} | ||
}; | ||
|
||
|
||
|
||
QgsLayerTreeModel::QgsLayerTreeModel( QgsLayerTreeGroup* rootNode, QObject *parent ) | ||
: QAbstractItemModel( parent ) | ||
, mRootNode( rootNode ) | ||
|
@@ -1169,9 +1190,20 @@ void QgsLayerTreeModel::addLegendToLayer( QgsLayerTreeLayer* nodeL ) | |
// apply filtering defined in layer node's custom properties (reordering, filtering, custom labels) | ||
QgsMapLayerLegendUtils::applyLayerNodeProperties( nodeL, lstNew ); | ||
|
||
if ( testFlag( UseEmbeddedWidgets ) ) | ||
{ | ||
// generate placeholder legend nodes that will be replaced by widgets in QgsLayerTreeView | ||
int widgetsCount = ml->customProperty( "embeddedWidgets/count", 0 ).toInt(); | ||
while ( widgetsCount > 0 ) | ||
{ | ||
lstNew.insert( 0, new EmbeddedWidgetLegendNode( nodeL ) ); | ||
--widgetsCount; | ||
} | ||
} | ||
|
||
QList<QgsLayerTreeModelLegendNode*> filteredLstNew = filterLegendNodes( lstNew ); | ||
|
||
bool isEmbedded = filteredLstNew.count() == 1 && filteredLstNew[0]->isEmbeddedInParent(); | ||
bool hasOnlyEmbedded = filteredLstNew.count() == 1 && filteredLstNew[0]->isEmbeddedInParent(); | ||
|
||
Q_FOREACH ( QgsLayerTreeModelLegendNode* n, lstNew ) | ||
{ | ||
|
@@ -1190,11 +1222,11 @@ void QgsLayerTreeModel::addLegendToLayer( QgsLayerTreeLayer* nodeL ) | |
|
||
int count = data.tree ? data.tree->children[nullptr].count() : filteredLstNew.count(); | ||
|
||
if ( ! isEmbedded ) beginInsertRows( node2index( nodeL ), 0, count - 1 ); | ||
if ( ! hasOnlyEmbedded ) beginInsertRows( node2index( nodeL ), 0, count - 1 ); | ||
|
||
mLegend[nodeL] = data; | ||
|
||
if ( ! isEmbedded ) endInsertRows(); | ||
if ( ! hasOnlyEmbedded ) endInsertRows(); | ||
|
||
if ( hasStyleOverride ) | ||
ml->styleManager()->restoreOverrideStyle(); | ||
|
@@ -1291,17 +1323,19 @@ int QgsLayerTreeModel::legendNodeRowCount( QgsLayerTreeModelLegendNode* node ) c | |
|
||
int QgsLayerTreeModel::legendRootRowCount( QgsLayerTreeLayer* nL ) const | ||
{ | ||
if ( legendEmbeddedInParent( nL ) ) | ||
return 0; | ||
|
||
if ( !mLegend.contains( nL ) ) | ||
return 0; | ||
|
||
const LayerLegendData& data = mLegend[nL]; | ||
if ( data.tree ) | ||
return data.tree->children[nullptr].count(); | ||
|
||
return data.activeNodes.count(); | ||
int count = data.activeNodes.count(); | ||
|
||
if ( legendEmbeddedInParent( nL ) ) | ||
count--; // one item less -- it is embedded in parent | ||
|
||
return count; | ||
} | ||
|
||
|
||
|
@@ -1365,14 +1399,29 @@ Qt::ItemFlags QgsLayerTreeModel::legendNodeFlags( QgsLayerTreeModelLegendNode* n | |
|
||
bool QgsLayerTreeModel::legendEmbeddedInParent( QgsLayerTreeLayer* nodeLayer ) const | ||
{ | ||
return legendNodeEmbeddedInParent( nodeLayer ); | ||
} | ||
|
||
QgsLayerTreeModelLegendNode* QgsLayerTreeModel::legendNodeEmbeddedInParent( QgsLayerTreeLayer* nodeLayer ) const | ||
{ | ||
// legend node embedded in parent does not have to be the first one... | ||
// there could be extra legend nodes generated for embedded widgets | ||
const LayerLegendData& data = mLegend[nodeLayer]; | ||
return data.activeNodes.count() == 1 && data.activeNodes[0]->isEmbeddedInParent(); | ||
Q_FOREACH ( QgsLayerTreeModelLegendNode* legendNode, data.activeNodes ) | ||
{ | ||
if ( legendNode->isEmbeddedInParent() ) | ||
return legendNode; | ||
} | ||
return nullptr; | ||
} | ||
|
||
|
||
QIcon QgsLayerTreeModel::legendIconEmbeddedInParent( QgsLayerTreeLayer* nodeLayer ) const | ||
{ | ||
return QIcon( qvariant_cast<QPixmap>( mLegend[nodeLayer].activeNodes[0]->data( Qt::DecorationRole ) ) ); | ||
QgsLayerTreeModelLegendNode* legendNode = legendNodeEmbeddedInParent( nodeLayer ); | ||
if ( !legendNode ) | ||
return QIcon(); | ||
return QIcon( qvariant_cast<QPixmap>( legendNode->data( Qt::DecorationRole ) ) ); | ||
} | ||
|
||
|
||
|
3 comments
on commit 9c7dbb9
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@wonder-sk , nice! is there any way we can get the style dock transparency slider to synchronize with the legend transparency slider?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will have a look...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yay! 👍
Some bindings are missing apparently.
https://travis-ci.org/qgis/QGIS/jobs/135002563#L2022-L2025