Skip to content

Commit

Permalink
Use QgsLayerTreeView in QgsProjectLayerGroupDialog
Browse files Browse the repository at this point in the history
This also replaces routines for parsing of the project file
  • Loading branch information
wonder-sk committed May 21, 2014
1 parent a6158d5 commit 2972768
Show file tree
Hide file tree
Showing 10 changed files with 101 additions and 133 deletions.
1 change: 1 addition & 0 deletions src/app/qgisapp.cpp
Expand Up @@ -2180,6 +2180,7 @@ void QgisApp::initLayerTreeView()
mLayerTreeDock->setAllowedAreas( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea );

QgsLayerTreeModel* model = new QgsLayerTreeModel( QgsProject::instance()->layerTreeRoot(), this );
model->setFlag(QgsLayerTreeModel::AllowVisibilityManagement);

mLayerTreeView = new QgsLayerTreeView( this );
mLayerTreeView->setModel( model );
Expand Down
168 changes: 57 additions & 111 deletions src/app/qgsprojectlayergroupdialog.cpp
Expand Up @@ -17,6 +17,10 @@
#include "qgisapp.h"
#include "qgsapplication.h"

#include "qgslayertreemodel.h"
#include "qgslayertreenode.h"
#include "qgslayertreeutils.h"

#include <QDomDocument>
#include <QFileDialog>
#include <QFileInfo>
Expand All @@ -25,6 +29,7 @@

QgsProjectLayerGroupDialog::QgsProjectLayerGroupDialog( QWidget * parent, const QString& projectFile, Qt::WindowFlags f ): QDialog( parent, f ),
mShowEmbeddedContent( false )
, mRootGroup( new QgsLayerTreeGroup )
{
setupUi( this );

Expand All @@ -48,49 +53,45 @@ QgsProjectLayerGroupDialog::~QgsProjectLayerGroupDialog()
{
QSettings settings;
settings.setValue( "/Windows/EmbedLayer/geometry", saveGeometry() );

delete mRootGroup;
}

QStringList QgsProjectLayerGroupDialog::selectedGroups() const
{
QStringList groups;
QList<QTreeWidgetItem*> items = mTreeWidget->selectedItems();
QList<QTreeWidgetItem*>::iterator itemIt = items.begin();
for ( ; itemIt != items.end(); ++itemIt )
QgsLayerTreeModel* model = mTreeView->layerTreeModel();
foreach( QModelIndex index, mTreeView->selectionModel()->selectedIndexes() )
{
if (( *itemIt )->data( 0, Qt::UserRole ).toString() == "group" )
{
groups.push_back(( *itemIt )->text( 0 ) );
}
QgsLayerTreeNode* node = model->index2node( index );
if ( node->nodeType() == QgsLayerTreeNode::NodeGroup )
groups << static_cast<QgsLayerTreeGroup*>( node )->name();
}
return groups;
}

QStringList QgsProjectLayerGroupDialog::selectedLayerIds() const
{
QStringList layerIds;
QList<QTreeWidgetItem*> items = mTreeWidget->selectedItems();
QList<QTreeWidgetItem*>::iterator itemIt = items.begin();
for ( ; itemIt != items.end(); ++itemIt )
QgsLayerTreeModel* model = mTreeView->layerTreeModel();
foreach( QModelIndex index, mTreeView->selectionModel()->selectedIndexes() )
{
if (( *itemIt )->data( 0, Qt::UserRole ).toString() == "layer" )
{
layerIds.push_back(( *itemIt )->data( 0, Qt::UserRole + 1 ).toString() );
}
QgsLayerTreeNode* node = model->index2node( index );
if ( node->nodeType() == QgsLayerTreeNode::NodeLayer )
layerIds << static_cast<QgsLayerTreeLayer*>( node )->layerId();
}
return layerIds;
}

QStringList QgsProjectLayerGroupDialog::selectedLayerNames() const
{
QStringList layerNames;
QList<QTreeWidgetItem*> items = mTreeWidget->selectedItems();
QList<QTreeWidgetItem*>::iterator itemIt = items.begin();
for ( ; itemIt != items.end(); ++itemIt )
QgsLayerTreeModel* model = mTreeView->layerTreeModel();
foreach( QModelIndex index, mTreeView->selectionModel()->selectedIndexes() )
{
if (( *itemIt )->data( 0, Qt::UserRole ).toString() == "layer" )
{
layerNames.push_back(( *itemIt )->text( 0 ) );
}
QgsLayerTreeNode* node = model->index2node( index );
if ( node->nodeType() == QgsLayerTreeNode::NodeLayer )
layerNames << static_cast<QgsLayerTreeLayer*>( node )->layerName();
}
return layerNames;
}
Expand Down Expand Up @@ -144,8 +145,6 @@ void QgsProjectLayerGroupDialog::changeProjectFile()
return;
}

mTreeWidget->clear();

//parse project file and fill tree
if ( !projectFile.open( QIODevice::ReadOnly ) )
{
Expand All @@ -158,115 +157,64 @@ void QgsProjectLayerGroupDialog::changeProjectFile()
return;
}

QDomElement legendElem = projectDom.documentElement().firstChildElement( "legend" );
if ( legendElem.isNull() )
mRootGroup->removeAllChildren();

QDomElement layerTreeElem = projectDom.documentElement().firstChildElement( "layer-tree-group" );
if ( !layerTreeElem.isNull() )
{
return;
mRootGroup->readChildrenFromXML( layerTreeElem );
}

QDomNodeList legendChildren = legendElem.childNodes();
QDomElement currentChildElem;

for ( int i = 0; i < legendChildren.size(); ++i )
else
{
currentChildElem = legendChildren.at( i ).toElement();
if ( currentChildElem.tagName() == "legendlayer" )
{
addLegendLayerToTreeWidget( currentChildElem );
}
else if ( currentChildElem.tagName() == "legendgroup" )
{
addLegendGroupToTreeWidget( currentChildElem );
}
QgsLayerTreeUtils::readOldLegend( mRootGroup, projectDom.documentElement().firstChildElement( "legend" ) );
}

mProjectPath = mProjectFileLineEdit->text();
}
if ( !mShowEmbeddedContent )
removeEmbeddedNodes( mRootGroup );

void QgsProjectLayerGroupDialog::addLegendGroupToTreeWidget( const QDomElement& groupElem, QTreeWidgetItem* parent )
{
QDomNodeList groupChildren = groupElem.childNodes();
QDomElement currentChildElem;

if ( !mShowEmbeddedContent && groupElem.attribute( "embedded" ) == "1" )
{
return;
}
QgsLayerTreeModel* model = new QgsLayerTreeModel( mRootGroup, this );
mTreeView->setModel( model );

QTreeWidgetItem* groupItem = 0;
if ( !parent )
{
groupItem = new QTreeWidgetItem( mTreeWidget );
}
else
{
groupItem = new QTreeWidgetItem( parent );
}
groupItem->setIcon( 0, QgsApplication::getThemeIcon( "mActionFolder.png" ) );
groupItem->setText( 0, groupElem.attribute( "name" ) );
groupItem->setData( 0, Qt::UserRole, "group" );
QObject::connect( mTreeView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(onTreeViewSelectionChanged()));

for ( int i = 0; i < groupChildren.size(); ++i )
{
currentChildElem = groupChildren.at( i ).toElement();
if ( currentChildElem.tagName() == "legendlayer" )
{
addLegendLayerToTreeWidget( currentChildElem, groupItem );
}
else if ( currentChildElem.tagName() == "legendgroup" )
{
addLegendGroupToTreeWidget( currentChildElem, groupItem );
}
}
mProjectPath = mProjectFileLineEdit->text();
}

void QgsProjectLayerGroupDialog::addLegendLayerToTreeWidget( const QDomElement& layerElem, QTreeWidgetItem* parent )
{
if ( !mShowEmbeddedContent && layerElem.attribute( "embedded" ) == "1" )
{
return;
}

QTreeWidgetItem* item = 0;
if ( parent )
{
item = new QTreeWidgetItem( parent );
}
else
void QgsProjectLayerGroupDialog::removeEmbeddedNodes( QgsLayerTreeGroup* node )
{
QList<QgsLayerTreeNode*> childrenToRemove;
foreach ( QgsLayerTreeNode* child, node->children() )
{
item = new QTreeWidgetItem( mTreeWidget );
if ( child->customProperty("embedded").toBool() )
childrenToRemove << child;
else if ( child->nodeType() == QgsLayerTreeNode::NodeGroup )
removeEmbeddedNodes( static_cast<QgsLayerTreeGroup*>( child ) );
}
item->setText( 0, layerElem.attribute( "name" ) );
item->setData( 0, Qt::UserRole, "layer" );
item->setData( 0, Qt::UserRole + 1, layerElem.firstChildElement( "filegroup" ).firstChildElement( "legendlayerfile" ).attribute( "layerid" ) );
foreach ( QgsLayerTreeNode* childToRemove, childrenToRemove )
node->removeChildNode( childToRemove );
}

void QgsProjectLayerGroupDialog::on_mTreeWidget_itemSelectionChanged()

void QgsProjectLayerGroupDialog::onTreeViewSelectionChanged()
{
mTreeWidget->blockSignals( true );
QList<QTreeWidgetItem*> items = mTreeWidget->selectedItems();
QList<QTreeWidgetItem*>::iterator itemIt = items.begin();
for ( ; itemIt != items.end(); ++itemIt )
foreach( QModelIndex index, mTreeView->selectionModel()->selectedIndexes() )
{
//deselect children recursively
unselectChildren( *itemIt );
unselectChildren( index );
}
mTreeWidget->blockSignals( false );
}

void QgsProjectLayerGroupDialog::unselectChildren( QTreeWidgetItem* item )

void QgsProjectLayerGroupDialog::unselectChildren( const QModelIndex& index )
{
if ( !item )
int childCount = mTreeView->model()->rowCount( index );
for ( int i = 0; i < childCount; ++i )
{
return;
}
QModelIndex childIndex = mTreeView->model()->index( i, 0, index );
if ( mTreeView->selectionModel()->isSelected( childIndex ) )
mTreeView->selectionModel()->select( childIndex, QItemSelectionModel::Deselect );

QTreeWidgetItem* currentChild = 0;
for ( int i = 0; i < item->childCount(); ++i )
{
currentChild = item->child( i );
currentChild->setSelected( false );
unselectChildren( currentChild );
unselectChildren( childIndex );
}
}

Expand All @@ -280,5 +228,3 @@ void QgsProjectLayerGroupDialog::on_mButtonBox_accepted()
}
accept();
}


11 changes: 7 additions & 4 deletions src/app/qgsprojectlayergroupdialog.h
Expand Up @@ -20,6 +20,8 @@

class QDomElement;

class QgsLayerTreeGroup;

/**A dialog to select layers and groups from a qgs project*/
class APP_EXPORT QgsProjectLayerGroupDialog: public QDialog, private Ui::QgsProjectLayerGroupDialogBase
{
Expand All @@ -37,16 +39,17 @@ class APP_EXPORT QgsProjectLayerGroupDialog: public QDialog, private Ui::QgsProj
private slots:
void on_mBrowseFileToolButton_clicked();
void on_mProjectFileLineEdit_editingFinished();
void on_mTreeWidget_itemSelectionChanged();
void onTreeViewSelectionChanged();
void on_mButtonBox_accepted();

private:
void changeProjectFile();
void addLegendGroupToTreeWidget( const QDomElement& groupElem, QTreeWidgetItem* parent = 0 );
void addLegendLayerToTreeWidget( const QDomElement& layerElem, QTreeWidgetItem* parent = 0 );
void unselectChildren( QTreeWidgetItem* item );
void removeEmbeddedNodes( QgsLayerTreeGroup* node );
void unselectChildren( const QModelIndex& index );
QString mProjectPath;
bool mShowEmbeddedContent;

QgsLayerTreeGroup* mRootGroup;
};

#endif //QGSPROJECTLAYERGROUPDIALOG_H
5 changes: 5 additions & 0 deletions src/core/layertree/qgslayertreenode.cpp
Expand Up @@ -189,6 +189,11 @@ void QgsLayerTreeGroup::removeChildren(int from, int count)
updateVisibilityFromChildren();
}

void QgsLayerTreeGroup::removeAllChildren()
{
removeChildren(0, mChildren.count());
}

QgsLayerTreeLayer *QgsLayerTreeGroup::findLayer(const QString& layerId)
{
foreach (QgsLayerTreeNode* child, mChildren)
Expand Down
2 changes: 2 additions & 0 deletions src/core/layertree/qgslayertreenode.h
Expand Up @@ -147,6 +147,8 @@ class QgsLayerTreeGroup : public QgsLayerTreeNode

void removeChildren(int from, int count);

void removeAllChildren();

QgsLayerTreeLayer* findLayer(const QString& layerId);

static QgsLayerTreeGroup* readXML(QDomElement& element);
Expand Down
2 changes: 1 addition & 1 deletion src/core/qgsproject.cpp
Expand Up @@ -425,7 +425,7 @@ void QgsProject::clear()
mEmbeddedLayers.clear();
mRelationManager->clear();

mRootGroup->removeChildren(0, mRootGroup->children().count());
mRootGroup->removeAllChildren();

// reset some default project properties
// XXX THESE SHOULD BE MOVED TO STATUSBAR RELATED SOURCE
Expand Down
8 changes: 7 additions & 1 deletion src/gui/layertree/qgslayertreemodel.cpp
Expand Up @@ -190,6 +190,9 @@ QVariant QgsLayerTreeModel::data(const QModelIndex &index, int role) const
}
else if ( role == Qt::CheckStateRole )
{
if (!testFlag(AllowVisibilityManagement))
return QVariant();

if (node->nodeType() == QgsLayerTreeNode::NodeLayer)
{
QgsLayerTreeLayer* nodeLayer = static_cast<QgsLayerTreeLayer*>(node);
Expand All @@ -215,7 +218,7 @@ Qt::ItemFlags QgsLayerTreeModel::flags(const QModelIndex& index) const

Qt::ItemFlags f = Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled;
QgsLayerTreeNode* node = index2node(index);
if (node->nodeType() == QgsLayerTreeNode::NodeLayer)
if (testFlag(AllowVisibilityManagement) && node->nodeType() == QgsLayerTreeNode::NodeLayer)
f |= Qt::ItemIsUserCheckable;
else if (node->nodeType() == QgsLayerTreeNode::NodeGroup)
f |= Qt::ItemIsDropEnabled | Qt::ItemIsUserCheckable;
Expand All @@ -230,6 +233,9 @@ bool QgsLayerTreeModel::setData(const QModelIndex& index, const QVariant& value,

if (role == Qt::CheckStateRole)
{
if (!testFlag(AllowVisibilityManagement))
return false;

if (node->nodeType() == QgsLayerTreeNode::NodeLayer)
{
QgsLayerTreeLayer* layer = static_cast<QgsLayerTreeLayer*>(node);
Expand Down
2 changes: 2 additions & 0 deletions src/gui/layertree/qgslayertreemodel.h
Expand Up @@ -55,11 +55,13 @@ class GUI_EXPORT QgsLayerTreeModel : public QAbstractItemModel
{
AllowTreeManagement,
ShowSymbology,
AllowVisibilityManagement,
ShowFeatureCounts, // TODO: this is per-layer
};
Q_DECLARE_FLAGS(Flags, Flag)

void setFlags(Flags f) { mFlags = f; }
void setFlag(Flag f, bool on = true) { if (on) mFlags |= f; else mFlags &= ~f; }
Flags flags() const { return mFlags; }
bool testFlag(Flag f) const { return mFlags.testFlag(f); }

Expand Down
3 changes: 2 additions & 1 deletion src/gui/layertree/qgslayertreeview.cpp
Expand Up @@ -20,7 +20,6 @@ QgsLayerTreeView::QgsLayerTreeView(QWidget *parent)

connect(this, SIGNAL(collapsed(QModelIndex)), this, SLOT(updateExpandedStateToNode(QModelIndex)));
connect(this, SIGNAL(expanded(QModelIndex)), this, SLOT(updateExpandedStateToNode(QModelIndex)));
connect(this, SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(onCurrentChanged(QModelIndex)));
}

void QgsLayerTreeView::setModel(QAbstractItemModel* model)
Expand All @@ -32,6 +31,8 @@ void QgsLayerTreeView::setModel(QAbstractItemModel* model)

QTreeView::setModel(model);

connect(selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(onCurrentChanged(QModelIndex)));

updateExpandedStateFromNode(layerTreeModel()->rootGroup());
}

Expand Down

0 comments on commit 2972768

Please sign in to comment.