Skip to content

Commit

Permalink
[layertree] Add Python bindings - part two (gui)
Browse files Browse the repository at this point in the history
  • Loading branch information
wonder-sk committed Jun 3, 2014
1 parent 73358c3 commit cf4393e
Show file tree
Hide file tree
Showing 6 changed files with 296 additions and 2 deletions.
6 changes: 6 additions & 0 deletions python/gui/gui.sip
Expand Up @@ -108,6 +108,12 @@
%Include attributetable/qgsfeatureselectionmodel.sip
%Include attributetable/qgsifeatureselectionmanager.sip

%Include layertree/qgscustomlayerorderwidget.sip
%Include layertree/qgslayertreemapcanvasbridge.sip
%Include layertree/qgslayertreemodel.sip
%Include layertree/qgslayertreeview.sip
%Include layertree/qgslayertreeviewdefaultactions.sip

%Include raster/qgsmultibandcolorrendererwidget.sip
%Include raster/qgspalettedrendererwidget.sip
%Include raster/qgsrasterhistogramwidget.sip
Expand Down
20 changes: 20 additions & 0 deletions python/gui/layertree/qgscustomlayerorderwidget.sip
@@ -0,0 +1,20 @@
/**
* The QgsCustomLayerOrderWidget class provides a list box where the user can define
* custom order for drawing of layers. It also features a checkbox for enabling
* or disabling the custom order. Any changes made by the user are automatically
* propagated to the assigned QgsLayerTreeMapCanvasBridge. Also, any updates
* to the layer tree cause refresh of the list.
*
* @see QgsLayerTreeMapCanvasBridge
* @note added in 2.4
*/
class QgsCustomLayerOrderWidget : QWidget
{
%TypeHeaderCode
#include <qgscustomlayerorderwidget.h>
%End

public:
explicit QgsCustomLayerOrderWidget( QgsLayerTreeMapCanvasBridge* bridge, QWidget *parent /TransferThis/ = 0 );

};
60 changes: 60 additions & 0 deletions python/gui/layertree/qgslayertreemapcanvasbridge.sip
@@ -0,0 +1,60 @@
/**
* The QgsLayerTreeMapCanvasBridge class takes care of updates of layer set
* for QgsMapCanvas from a layer tree. The class listens to the updates in the layer tree
* and updates the list of layers for rendering whenever some layers are added, removed,
* or their visibility changes.
*
* The update of layers is not done immediately - it is postponed, so a series of updates
* to the layer tree will trigger just one update of canvas layers.
*
* Also allows the client to override the default order of layers. This is useful
* in advanced cases where the grouping in layer tree should be independent from the actual
* order in the canvas.
*
* @added in 2.4
*/
class QgsLayerTreeMapCanvasBridge : QObject
{
%TypeHeaderCode
#include <qgslayertreemapcanvasbridge.h>
%End

public:
//! Constructor: does not take ownership of the layer tree nor canvas
QgsLayerTreeMapCanvasBridge( QgsLayerTreeGroup* root, QgsMapCanvas* canvas, QObject* parent /TransferThis/ = 0 );

void clear();

QgsLayerTreeGroup* rootGroup() const;
QgsMapCanvas* mapCanvas() const;

bool hasCustomLayerOrder() const;
QStringList customLayerOrder() const;

QStringList defaultLayerOrder() const;

//! if enabled, will automatically set full canvas extent and destination CRS + map units
//! when first layer(s) are added
void setAutoSetupOnFirstLayer( bool enabled );
bool autoSetupOnFirstLayer() const;

//! if enabled, will automatically turn on on-the-fly reprojection of layers if a layer
//! with different source CRS is added
void setAutoEnableCrsTransform( bool enabled );
bool autoEnableCrsTransform() const;

public slots:
void setHasCustomLayerOrder( bool override );
void setCustomLayerOrder( const QStringList& order );

//! force update of canvas layers from the layer tree. Normally this should not be needed to be called.
void setCanvasLayers();

void readProject( const QDomDocument& doc );
void writeProject( QDomDocument& doc );

signals:
void hasCustomLayerOrderChanged( bool );
void customLayerOrderChanged( const QStringList& order );

};
93 changes: 93 additions & 0 deletions python/gui/layertree/qgslayertreemodel.sip
@@ -0,0 +1,93 @@
/**
* The QgsLayerTreeModel class is model implementation for Qt item views framework.
* The model can be used in any QTreeView, it is however recommended to use it
* with QgsLayerTreeView which brings additional functionality specific to layer tree handling.
*
* The model listens to the changes in the layer tree and signals the changes as appropriate,
* so that any view that uses the model is updated accordingly.
*
* Behavior of the model can be customized with flags. For example, whether to show symbology or
* whether to allow changes to the layer tree.
*
* @see QgsLayerTreeView
* @note added in 2.4
*/
class QgsLayerTreeModel : QAbstractItemModel
{
%TypeHeaderCode
#include <qgslayertreemodel.h>
%End

public:
//! Construct a new tree model with given layer tree (root node must not be null pointer).
//! The root node is not transferred by the model.
explicit QgsLayerTreeModel( QgsLayerTreeGroup* rootNode, QObject *parent /TransferThis/ = 0 );
~QgsLayerTreeModel();

// Implementation of virtual functions from QAbstractItemModel

int rowCount( const QModelIndex &parent = QModelIndex() ) const;
int columnCount( const QModelIndex &parent = QModelIndex() ) const;
QModelIndex index( int row, int column, const QModelIndex &parent = QModelIndex() ) const;
QModelIndex parent( const QModelIndex &child ) const;
QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const;
Qt::ItemFlags flags( const QModelIndex &index ) const;
bool setData( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole );
Qt::DropActions supportedDropActions() const;
QStringList mimeTypes() const;
QMimeData* mimeData( const QModelIndexList& indexes ) const;
bool dropMimeData( const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent );
bool removeRows( int row, int count, const QModelIndex& parent = QModelIndex() );

// New stuff

enum Flag
{
// display flags
ShowSymbology, //!< Add symbology items for layer nodes

// behavioral flags
AllowNodeReorder, //!< Allow reordering with drag'n'drop
AllowNodeRename, //!< Allow renaming of groups and layers
AllowNodeChangeVisibility, //!< Allow user to set node visibility with a check box
};
typedef QFlags<QgsLayerTreeModel::Flag> Flags;

//! Set OR-ed combination of model flags
void setFlags( Flags f );
//! Enable or disable a model flag
void setFlag( Flag f, bool on = true );
//! Return OR-ed combination of model flags
Flags flags() const;
//! Check whether a flag is enabled
bool testFlag( Flag f ) const;

//! Return layer tree node for given index. Returns root node for invalid index.
//! Returns null pointer if index does not refer to a layer tree node (e.g. it is a symbology item)
QgsLayerTreeNode* index2node( const QModelIndex& index ) const;
//! Return index for a given node. If the node does not belong to the layer tree, the result is undefined
QModelIndex node2index( QgsLayerTreeNode* node ) const;
//! Convert a list of indexes to a list of layer tree nodes.
//! Indices that do not represent layer tree nodes are skipped.
//! @arg skipInternal If true, a node is included in the output list only if no parent node is in the list
QList<QgsLayerTreeNode*> indexes2nodes( const QModelIndexList& list, bool skipInternal = false ) const;
//! Return true if index represents a symbology node (instead of layer node)
bool isIndexSymbologyNode( const QModelIndex& index ) const;
//! Return layer node to which a symbology node belongs to. Returns null pointer if index is not a symbology node.
QgsLayerTreeLayer* layerNodeForSymbologyNode( const QModelIndex& index ) const;

//! Return pointer to the root node of the layer tree. Always a non-null pointer.
QgsLayerTreeGroup* rootGroup();

//! Force a refresh of symbology of layer node.
//! Not necessary to call when layer's renderer is changed as the model listens to these events.
void refreshLayerSymbology( QgsLayerTreeLayer* nodeLayer );

//! Get index of the item marked as current. Item marked as current is underlined.
QModelIndex currentIndex() const;
//! Set index of the current item. May be used by view. Item marked as current is underlined.
void setCurrentIndex( const QModelIndex& currentIndex );

signals:

};
83 changes: 81 additions & 2 deletions python/gui/layertree/qgslayertreeview.sip
@@ -1,9 +1,88 @@

/**
* The QgsLayerTreeView class extends QTreeView and provides some additional functionality
* when working with a layer tree.
*
* The view updates expanded state of layer tree nodes and also listens to changes
* to expanded states in the layer tree.
*
* The view keeps track of the current layer and emits a signal when the current layer has changed.
*
* Allows the client to specify a context menu provider with custom actions. Also it comes
* with a set of default actions that can be used when building context menu.
*
* @see QgsLayerTreeModel
* @note added in 2.4
*/
class QgsLayerTreeView : QTreeView
{
%TypeHeaderCode
#include <qgslayertreeview.h>
%End

// this is just a stub
public:
explicit QgsLayerTreeView( QWidget *parent /TransferThis/ = 0 );
~QgsLayerTreeView();

//! Overridden setModel() from base class. Only QgsLayerTreeModel is an acceptable model.
virtual void setModel( QAbstractItemModel* model );

//! Get access to the model casted to QgsLayerTreeModel
QgsLayerTreeModel* layerTreeModel() const;

//! Get access to the default actions that may be used with the tree view
QgsLayerTreeViewDefaultActions* defaultActions();

//! Set provider for context menu. Takes ownership of the instance
void setMenuProvider( QgsLayerTreeViewMenuProvider* menuProvider /Transfer/ );
//! Return pointer to the context menu provider. May be null
QgsLayerTreeViewMenuProvider* menuProvider() const;

//! Get currently selected layer. May be null
QgsMapLayer* currentLayer() const;
//! Set currently selected layer. Null pointer will deselect any layer.
void setCurrentLayer( QgsMapLayer* layer );

//! Get current node. May be null
QgsLayerTreeNode* currentNode() const;
//! Get current group node. If a layer is current node, the function will return parent group. May be null.
QgsLayerTreeGroup* currentGroupNode() const;

//! Return list of selected nodes
//! @arg skipInternal If true, will ignore nodes which have an ancestor in the selection
QList<QgsLayerTreeNode*> selectedNodes( bool skipInternal = false ) const;
//! Return list of selected nodes filtered to just layer nodes
QList<QgsLayerTreeLayer*> selectedLayerNodes() const;

//! Get list of selected layers
QList<QgsMapLayer*> selectedLayers() const;

public slots:
//! Force refresh of layer symbology. Normally not needed as the changes of layer's renderer are monitored by the model
void refreshLayerSymbology( const QString& layerId );

signals:
//! Emitted when a current layer is changed
void currentLayerChanged( QgsMapLayer* layer );

};


/**
* Implementation of this interface can be implemented to allow QgsLayerTreeView
* instance to provide custom context menus (opened upon right-click).
*
* @see QgsLayerTreeView
* @note added in 2.4
*/
class QgsLayerTreeViewMenuProvider
{
%TypeHeaderCode
#include <qgslayertreeview.h>
%End

public:
virtual ~QgsLayerTreeViewMenuProvider();

//! Return a newly created menu instance (or null pointer on error)
virtual QMenu* createContextMenu() = 0 /Factory/;
};
36 changes: 36 additions & 0 deletions python/gui/layertree/qgslayertreeviewdefaultactions.sip
@@ -0,0 +1,36 @@
/**
* The QgsLayerTreeViewDefaultActions class serves as a factory of actions
* that can be used together with a layer tree view.
*
* @see QgsLayerTreeView
* @note added in 2.4
*/
class QgsLayerTreeViewDefaultActions : QObject
{
%TypeHeaderCode
#include <qgslayertreeviewdefaultactions.h>
%End

public:
QgsLayerTreeViewDefaultActions( QgsLayerTreeView* view );

QAction* actionAddGroup( QObject* parent = 0 ) /Factory/;
QAction* actionRemoveGroupOrLayer( QObject* parent = 0 ) /Factory/;
QAction* actionShowInOverview( QObject* parent = 0 ) /Factory/;
QAction* actionRenameGroupOrLayer( QObject* parent = 0 ) /Factory/;
QAction* actionShowFeatureCount( QObject* parent = 0 ) /Factory/;

QAction* actionZoomToLayer( QgsMapCanvas* canvas, QObject* parent = 0 ) /Factory/;
QAction* actionZoomToGroup( QgsMapCanvas* canvas, QObject* parent = 0 ) /Factory/;
// TODO: zoom to selected

QAction* actionMakeTopLevel( QObject* parent = 0 ) /Factory/;
QAction* actionGroupSelected( QObject* parent = 0 ) /Factory/;

void zoomToLayer( QgsMapCanvas* canvas );
void zoomToGroup( QgsMapCanvas* canvas );

public slots:
void showInOverview();

};

0 comments on commit cf4393e

Please sign in to comment.