Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Integration of embedded widgets into layer tree + config GUI
  • Loading branch information
wonder-sk committed Jun 1, 2016
1 parent 2b1560c commit ea2395d
Show file tree
Hide file tree
Showing 14 changed files with 547 additions and 1 deletion.
2 changes: 1 addition & 1 deletion python/core/qgsdataitem.sip
Expand Up @@ -75,7 +75,7 @@ class QgsDataItem : QObject

/** Create children. Children are not expected to have parent set.
* This method MUST BE THREAD SAFE. */
virtual QVector<QgsDataItem*> createChildren();
virtual QVector<QgsDataItem*> createChildren() /Factory/;

enum State
{
Expand Down
1 change: 1 addition & 0 deletions src/app/qgisapp.cpp
Expand Up @@ -2815,6 +2815,7 @@ void QgisApp::initLayerTreeView()
model->setFlag( QgsLayerTreeModel::AllowNodeRename );
model->setFlag( QgsLayerTreeModel::AllowNodeChangeVisibility );
model->setFlag( QgsLayerTreeModel::ShowLegendAsTree );
model->setFlag( QgsLayerTreeModel::UseEmbeddedWidgets );
model->setAutoCollapseLegendNodes( 10 );

mLayerTreeView->setModel( model );
Expand Down
26 changes: 26 additions & 0 deletions src/app/qgsapplayertreeviewmenuprovider.cpp
Expand Up @@ -237,6 +237,9 @@ QMenu* QgsAppLayerTreeViewMenuProvider::createContextMenu()
duplicateLayersAction->setEnabled( false );
}

QAction* embeddedAction = menu->addAction( tr( "Embedded widgets..."), this, SLOT( editEmbeddedWidgets() ) );
embeddedAction->setProperty( "layerId", layer->id() );

addCustomLayerActions( menu, layer );

if ( layer && QgsProject::instance()->layerIsEmbedded( layer->id() ).isEmpty() )
Expand Down Expand Up @@ -555,3 +558,26 @@ void QgsAppLayerTreeViewMenuProvider::setSymbolLegendNodeColor( const QColor &co
newSymbol->setColor( color );
node->setSymbol( newSymbol );
}

#include "qgslayertreeembeddedconfigwidget.h"
void QgsAppLayerTreeViewMenuProvider::editEmbeddedWidgets()
{
QAction* action = qobject_cast< QAction*>( sender() );
if ( !action )
return;

QString layerId = action->property( "layerId" ).toString();
QgsLayerTreeLayer* nodeLayer = QgsProject::instance()->layerTreeRoot()->findLayer( layerId );
if ( !nodeLayer )
return;

QDialog d;
QgsLayerTreeEmbeddedConfigWidget* widget = new QgsLayerTreeEmbeddedConfigWidget(nodeLayer, &d);

QLayout* l = new QVBoxLayout(&d);
l->addWidget(widget);
d.setLayout(l);
d.exec();

mView->layerTreeModel()->refreshLayerLegend( nodeLayer );
}
1 change: 1 addition & 0 deletions src/app/qgsapplayertreeviewmenuprovider.h
Expand Up @@ -69,6 +69,7 @@ class QgsAppLayerTreeViewMenuProvider : public QObject, public QgsLayerTreeViewM
void setVectorSymbolColor( const QColor &color );
void editSymbolLegendNodeSymbol();
void setSymbolLegendNodeColor( const QColor &color );
void editEmbeddedWidgets();
};

#endif // QGSAPPLAYERTREEVIEWMENUPROVIDER_H
25 changes: 25 additions & 0 deletions src/core/layertree/qgslayertreemodel.cpp
Expand Up @@ -1149,6 +1149,21 @@ void QgsLayerTreeModel::removeLegendFromLayer( QgsLayerTreeLayer* nodeLayer )
}
}

class EmbeddedWidgetLegendNode : public QgsLayerTreeModelLegendNode
{
public:
EmbeddedWidgetLegendNode( QgsLayerTreeLayer* nodeL )
: QgsLayerTreeModelLegendNode( nodeL )
{
}

virtual QVariant data( int role ) const override
{
Q_UNUSED( role );
return QVariant();
}

};

void QgsLayerTreeModel::addLegendToLayer( QgsLayerTreeLayer* nodeL )
{
Expand All @@ -1169,6 +1184,16 @@ 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 ) )
{
int widgetsCount = nodeL->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();
Expand Down
1 change: 1 addition & 0 deletions src/core/layertree/qgslayertreemodel.h
Expand Up @@ -80,6 +80,7 @@ class CORE_EXPORT QgsLayerTreeModel : public QAbstractItemModel
ShowRasterPreviewIcon = 0x0002, //!< Will use real preview of raster layer as icon (may be slow)
ShowLegendAsTree = 0x0004, //!< For legends that support it, will show them in a tree instead of a list (needs also ShowLegend). Added in 2.8
DeferredLegendInvalidation = 0x0008, //!< defer legend model invalidation
UseEmbeddedWidgets = 0x0010, //!< Layer nodes may optionally include extra embedded widgets (if used in QgsLayerTreeView). Added in 2.16

// behavioral flags
AllowNodeReorder = 0x1000, //!< Allow reordering with drag'n'drop
Expand Down
1 change: 1 addition & 0 deletions src/core/layertree/qgslayertreenode.h
Expand Up @@ -58,6 +58,7 @@ class QDomElement;
* - "embedded_project" - path to the external project (embedded root node only)
* - "legend/..." - properties for legend appearance customization
* - "expandedLegendNodes" - list of layer's legend nodes' rules in expanded state
* - "embeddedWidgets/..." - properties for embedded widgets (layer node only)
*
* @see also QgsLayerTree, QgsLayerTreeLayer, QgsLayerTreeGroup
* @note added in 2.4
Expand Down
7 changes: 7 additions & 0 deletions src/gui/CMakeLists.txt
Expand Up @@ -153,6 +153,8 @@ SET(QGIS_GUI_SRCS
editorwidgets/qgsvaluerelationwidgetfactory.cpp

layertree/qgscustomlayerorderwidget.cpp
layertree/qgslayertreeembeddedconfigwidget.cpp
layertree/qgslayertreeembeddedwidgetregistry.cpp
layertree/qgslayertreemapcanvasbridge.cpp
layertree/qgslayertreeview.cpp
layertree/qgslayertreeviewdefaultactions.cpp
Expand Down Expand Up @@ -574,6 +576,8 @@ SET(QGIS_GUI_MOC_HDRS
editorwidgets/qgsvaluerelationwidgetwrapper.h

layertree/qgscustomlayerorderwidget.h
layertree/qgslayertreeembeddedconfigwidget.h
layertree/qgslayertreeembeddedwidgetregistry.h
layertree/qgslayertreemapcanvasbridge.h
layertree/qgslayertreeview.h
layertree/qgslayertreeviewdefaultactions.h
Expand Down Expand Up @@ -669,6 +673,9 @@ SET(QGIS_GUI_HDRS
editorwidgets/qgsvaluemapwidgetfactory.h
editorwidgets/qgsvaluerelationwidgetfactory.h

layertree/qgslayertreeembeddedconfigwidget.h
layertree/qgslayertreeembeddedwidgetregistry.h

raster/qgsrasterrendererwidget.h
)

Expand Down
87 changes: 87 additions & 0 deletions src/gui/layertree/qgslayertreeembeddedconfigwidget.cpp
@@ -0,0 +1,87 @@
#include "qgslayertreeembeddedconfigwidget.h"

#include "qgslayertree.h"
#include "qgslayertreeembeddedwidgetregistry.h"

#include <QStringListModel>

QgsLayerTreeEmbeddedConfigWidget::QgsLayerTreeEmbeddedConfigWidget( QgsLayerTreeLayer* nodeLayer, QWidget* parent )
: QWidget( parent )
, mNodeLayer( nodeLayer )
{
setupUi( this );

connect( mBtnAdd, SIGNAL(clicked(bool)), this, SLOT(onAddClicked()));
connect( mBtnRemove, SIGNAL(clicked(bool)), this, SLOT(onRemoveClicked()));

// populate available
QStringList lst;
Q_FOREACH ( const QString& providerId, QgsLayerTreeEmbeddedWidgetRegistry::instance()->providers() )
{
QgsLayerTreeEmbeddedWidgetProvider* provider = QgsLayerTreeEmbeddedWidgetRegistry::instance()->provider( providerId );
lst << provider->id();
}
mListAvailable->setModel( new QStringListModel( lst, this ) );

// populate used
QStringList lstUsed;
int widgetsCount = nodeLayer->customProperty( "embeddedWidgets/count", 0 ).toInt();
for ( int i = 0; i < widgetsCount; ++i )
{
QString providerId = nodeLayer->customProperty( QString( "embeddedWidgets/%1/id" ).arg( i ) ).toString();
if ( /*QgsLayerTreeEmbeddedWidgetProvider* provider =*/ QgsLayerTreeEmbeddedWidgetRegistry::instance()->provider( providerId ) )
{
lstUsed << providerId;
}
}
mListUsed->setModel( new QStringListModel( lstUsed, this ) );
}

void QgsLayerTreeEmbeddedConfigWidget::onAddClicked()
{
if (!mListAvailable->currentIndex().isValid())
return;

QString providerId = mListAvailable->model()->data( mListAvailable->currentIndex() ).toString();
if (QStringListModel* model = qobject_cast<QStringListModel*>(mListUsed->model()))
{
int row = model->rowCount();
model->insertRow( row );
model->setData( model->index(row, 0), providerId );
//QStringList lst = model->stringList();
//lst << providerId;
//model->setStringList( lst );
}

updateCustomProperties();
}

void QgsLayerTreeEmbeddedConfigWidget::onRemoveClicked()
{
if (!mListUsed->currentIndex().isValid())
return;

int row = mListUsed->currentIndex().row();
mListUsed->model()->removeRow( row );

updateCustomProperties();
}

void QgsLayerTreeEmbeddedConfigWidget::updateCustomProperties()
{
// clear old properties
int widgetsCount = mNodeLayer->customProperty( "embeddedWidgets/count", 0 ).toInt();
for ( int i = 0; i < widgetsCount; ++i )
{
mNodeLayer->removeCustomProperty( QString( "embeddedWidgets/%1/id" ).arg( i ) );
}

// setup new properties
int newCount = mListUsed->model()->rowCount();
mNodeLayer->setCustomProperty( "embeddedWidgets/count", newCount );
for ( int i = 0; i < newCount; ++i )
{
QString providerId = mListUsed->model()->data( mListUsed->model()->index(i, 0) ).toString();
mNodeLayer->setCustomProperty( QString( "embeddedWidgets/%1/id" ).arg( i ), providerId );
}
}
25 changes: 25 additions & 0 deletions src/gui/layertree/qgslayertreeembeddedconfigwidget.h
@@ -0,0 +1,25 @@
#ifndef QGSLAYERTREEEMBEDDEDCONFIGWIDGET_H
#define QGSLAYERTREEEMBEDDEDCONFIGWIDGET_H

#include "ui_qgslayertreeembeddedconfigwidget.h"

class QgsLayerTreeLayer;

class GUI_EXPORT QgsLayerTreeEmbeddedConfigWidget : public QWidget, protected Ui::QgsLayerTreeEmbeddedConfigWidget
{
Q_OBJECT
public:
QgsLayerTreeEmbeddedConfigWidget( QgsLayerTreeLayer* nodeLayer, QWidget* parent = nullptr );

private slots:
void onAddClicked();
void onRemoveClicked();

private:
void updateCustomProperties();

private:
QgsLayerTreeLayer* mNodeLayer;
};

#endif // QGSLAYERTREEEMBEDDEDCONFIGWIDGET_H

0 comments on commit ea2395d

Please sign in to comment.