Skip to content

Commit

Permalink
Fix virtual layer creation UI
Browse files Browse the repository at this point in the history
Expose embedded layers inclusion to the creation UI
  • Loading branch information
Hugo Mercier committed Feb 17, 2016
1 parent baaeedf commit bc7036f
Show file tree
Hide file tree
Showing 7 changed files with 430 additions and 23 deletions.
4 changes: 3 additions & 1 deletion src/providers/virtual/CMakeLists.txt
Expand Up @@ -8,9 +8,10 @@ QT4_WRAP_CPP(vlayer_provider_MOC_SRCS
qgsvirtuallayerprovider.h
qgsslottofunction.h
qgsvirtuallayersourceselect.h
qgsembeddedlayerselectdialog.h
)

QT4_WRAP_UI(vlayer_provider_UI_H qgsvirtuallayersourceselectbase.ui)
QT4_WRAP_UI(vlayer_provider_UI_H qgsvirtuallayersourceselectbase.ui qgsembeddedlayerselect.ui)

SET(QGIS_VLAYER_PROVIDER_SRCS
${vlayer_provider_MOC_SRCS}
Expand All @@ -23,6 +24,7 @@ SET(QGIS_VLAYER_PROVIDER_SRCS
qgsvirtuallayersqlitehelper.cpp
qgsvirtuallayerqueryparser.cpp
qgsvirtuallayersourceselect.cpp
qgsembeddedlayerselectdialog.cpp
)

INCLUDE_DIRECTORIES(
Expand Down
90 changes: 90 additions & 0 deletions src/providers/virtual/qgsembeddedlayerselect.ui
@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QgsEmbeddedLayerSelectDialog</class>
<widget class="QDialog" name="QgsEmbeddedLayerSelectDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>422</width>
<height>366</height>
</rect>
</property>
<property name="windowTitle">
<string>Select layers to embed</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QListWidget" name="mLayers">
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>QgsEmbeddedLayerSelectDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>QgsEmbeddedLayerSelectDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>mLayers</sender>
<signal>itemDoubleClicked(QListWidgetItem*)</signal>
<receiver>QgsEmbeddedLayerSelectDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>210</x>
<y>166</y>
</hint>
<hint type="destinationlabel">
<x>210</x>
<y>182</y>
</hint>
</hints>
</connection>
</connections>
</ui>
61 changes: 61 additions & 0 deletions src/providers/virtual/qgsembeddedlayerselectdialog.cpp
@@ -0,0 +1,61 @@
/***************************************************************************
Virtual layer embedded layer selection widget
begin : Feb 2016
copyright : (C) 2016 Hugo Mercier, Oslandia
email : hugo dot mercier at oslandia dot com
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsembeddedlayerselectdialog.h"

#include <QMainWindow>
#include <QSettings>

#include <qgsvectorlayer.h>
#include <layertree/qgslayertreeview.h>
#include <layertree/qgslayertreemodel.h>
#include <layertree/qgslayertreegroup.h>
#include <layertree/qgslayertreelayer.h>
#include <qgsproviderregistry.h>
#include <qgsvectordataprovider.h>

QgsEmbeddedLayerSelectDialog::QgsEmbeddedLayerSelectDialog( QWidget* parent, QgsLayerTreeView* tv )
: QDialog( parent )
{
setupUi( this );

// populate list
QList<QgsLayerTreeLayer*> layers = tv->layerTreeModel()->rootGroup()->findLayers();
Q_FOREACH ( const QgsLayerTreeLayer* l, layers )
{
if ( l->layer() && l->layer()->type() == QgsMapLayer::VectorLayer )
{
// display layer name and store its pointer
QListWidgetItem *item = new QListWidgetItem();
item->setText( l->layer()->name() );
item->setData( Qt::UserRole, QVariant::fromValue( static_cast<void*>( l->layer() ) ) );
mLayers->insertItem( mLayers->count(), item );
}
}
}

QStringList QgsEmbeddedLayerSelectDialog::layers() const
{
QStringList ids;
QModelIndexList selected = mLayers->selectionModel()->selectedRows();
for ( int i = 0; i < selected.size(); i++ )
{
QgsVectorLayer* l = static_cast<QgsVectorLayer*>( mLayers->item( selected[i].row() )->data( Qt::UserRole ).value<void*>() );
ids << l->id();
}
return ids;
}
40 changes: 40 additions & 0 deletions src/providers/virtual/qgsembeddedlayerselectdialog.h
@@ -0,0 +1,40 @@
/***************************************************************************
Virtual layer embedded layer selection widget
begin : Feb 2016
copyright : (C) 2016 Hugo Mercier, Oslandia
email : hugo dot mercier at oslandia dot com
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSVIRTUAL_EMBEDDED_LAYER_SELECT_DIALOG_H
#define QGSVIRTUAL_EMBEDDED_LAYER_SELECT_DIALOG_H

#include "ui_qgsembeddedlayerselect.h"

#include <QDialog>

class QgsVectorLayer;
class QMainWindow;
class QgsLayerTreeView;

class QgsEmbeddedLayerSelectDialog : public QDialog, private Ui::QgsEmbeddedLayerSelectDialog
{
Q_OBJECT

public:
QgsEmbeddedLayerSelectDialog( QWidget * parent, QgsLayerTreeView* tv );

/** Returns the list of layer ids selected */
QStringList layers() const;
};

#endif
105 changes: 102 additions & 3 deletions src/providers/virtual/qgsvirtuallayersourceselect.cpp
Expand Up @@ -26,6 +26,9 @@ email : hugo dot mercier at oslandia dot com
#include <layertree/qgslayertreemodel.h>
#include <layertree/qgslayertreegroup.h>
#include <layertree/qgslayertreelayer.h>
#include <qgsproviderregistry.h>

#include "qgsembeddedlayerselectdialog.h"

#include <QUrl>
#include <Qsci/qscilexer.h>
Expand All @@ -40,6 +43,22 @@ QgsVirtualLayerSourceSelect::QgsVirtualLayerSourceSelect( QWidget* parent, Qt::W

QObject::connect( mTestButton, SIGNAL( clicked() ), this, SLOT( onTestQuery() ) );
QObject::connect( mBrowseCRSBtn, SIGNAL( clicked() ), this, SLOT( onBrowseCRS() ) );
QObject::connect( mAddLayerBtn, SIGNAL( clicked() ), this, SLOT( onAddLayer() ) );
QObject::connect( mRemoveLayerBtn, SIGNAL( clicked() ), this, SLOT( onRemoveLayer() ) );
QObject::connect( mImportLayerBtn, SIGNAL( clicked() ), this, SLOT( onImportLayer() ) );
QObject::connect( mLayersTable->selectionModel(), SIGNAL( currentRowChanged( const QModelIndex&, const QModelIndex& ) ), this, SLOT( onTableRowChanged( const QModelIndex&, const QModelIndex& ) ) );

// prepare provider list
Q_FOREACH ( QString pk, QgsProviderRegistry::instance()->providerList() )
{
// we cannot know before trying to actually load a dataset
// if the provider is raster or vector
// so we manually exclude well-known raster providers
if ( pk != "gdal" && pk != "ows" && pk != "wcs" && pk != "wms" )
{
mProviderList << pk;
}
}

QgsLayerTreeView* treeView = parent->findChild<QgsLayerTreeView*>( "theLayerTreeView" );
if ( treeView )
Expand Down Expand Up @@ -104,10 +123,9 @@ QgsVirtualLayerSourceSelect::QgsVirtualLayerSourceSelect( QWidget* parent, Qt::W
mQueryEdit->lexer()->setAPIs( apis );

mQueryEdit->setWrapMode( QsciScintilla::WrapWord );
}

QgsVirtualLayerSourceSelect::~QgsVirtualLayerSourceSelect()
{
// prepare embedded layer selection dialog
mEmbeddedSelectionDialog = new QgsEmbeddedLayerSelectDialog( this, treeView );
}

void QgsVirtualLayerSourceSelect::onLayerComboChanged( int idx )
Expand Down Expand Up @@ -145,6 +163,15 @@ void QgsVirtualLayerSourceSelect::onLayerComboChanged( int idx )
mGeometryType->setCurrentIndex( static_cast<long>( def.geometryWkbType() ) - 1 );
mGeometryField->setText( def.geometryField() );
}

// add embedded layers
Q_FOREACH ( const QgsVirtualLayerDefinition::SourceLayer& l, def.sourceLayers() )
{
if ( ! l.isReferenced() )
{
addEmbeddedLayer( l.name(), l.provider(), l.encoding(), l.source() );
}
}
}

void QgsVirtualLayerSourceSelect::onBrowseCRS()
Expand Down Expand Up @@ -184,6 +211,17 @@ QgsVirtualLayerDefinition QgsVirtualLayerSourceSelect::getVirtualLayerDef()
def.setGeometryField( mGeometryField->text() );
def.setGeometrySrid( mSrid );
}

// add embedded layers
for ( int i = 0; i < mLayersTable->rowCount(); i++ )
{
QString name = mLayersTable->item( i, 0 )->text();
QString provider = static_cast<QComboBox*>( mLayersTable->cellWidget( i, 1 ) )->currentText();
QString encoding = static_cast<QComboBox*>( mLayersTable->cellWidget( i, 2 ) )->currentText();
QString source = mLayersTable->item( i, 3 )->text();
def.addSource( name, source, provider, encoding );
}

return def;
}

Expand All @@ -202,6 +240,67 @@ void QgsVirtualLayerSourceSelect::onTestQuery()
}
}

void QgsVirtualLayerSourceSelect::onAddLayer()
{
mLayersTable->insertRow( mLayersTable->rowCount() );

mLayersTable->setItem( mLayersTable->rowCount() - 1, 0, new QTableWidgetItem() );
mLayersTable->setItem( mLayersTable->rowCount() - 1, 3, new QTableWidgetItem() );

QComboBox* providerCombo = new QComboBox();
providerCombo->addItems( mProviderList );
mLayersTable->setCellWidget( mLayersTable->rowCount() - 1, 1, providerCombo );

QComboBox* encodingCombo = new QComboBox();
encodingCombo->addItems( QgsVectorDataProvider::availableEncodings() );
QString defaultEnc = QSettings().value( "/UI/encoding", "System" ).toString();
encodingCombo->setCurrentIndex( encodingCombo->findText( defaultEnc ) );
mLayersTable->setCellWidget( mLayersTable->rowCount() - 1, 2, encodingCombo );
}

void QgsVirtualLayerSourceSelect::onRemoveLayer()
{
int currentRow = mLayersTable->selectionModel()->currentIndex().row();
if ( currentRow != -1 )
mLayersTable->removeRow( currentRow );
}

void QgsVirtualLayerSourceSelect::onTableRowChanged( const QModelIndex& current, const QModelIndex& previous )
{
Q_UNUSED( previous );
mRemoveLayerBtn->setEnabled( current.row() != -1 );
}

void QgsVirtualLayerSourceSelect::addEmbeddedLayer( QString name, QString provider, QString encoding, QString source )
{
// insert a new row
onAddLayer();
const int n = mLayersTable->rowCount() - 1;
// local name
mLayersTable->item( n, 0 )->setText( name );
// source
mLayersTable->item( n, 3 )->setText( source );
// provider
QComboBox* providerCombo = static_cast<QComboBox*>( mLayersTable->cellWidget( n, 1 ) );
providerCombo->setCurrentIndex( providerCombo->findText( provider ) );
// encoding
QComboBox* encodingCombo = static_cast<QComboBox*>( mLayersTable->cellWidget( n, 2 ) );
encodingCombo->setCurrentIndex( encodingCombo->findText( encoding ) );
}

void QgsVirtualLayerSourceSelect::onImportLayer()
{
if ( mEmbeddedSelectionDialog->exec() == QDialog::Accepted )
{
QStringList ids = mEmbeddedSelectionDialog->layers();
Q_FOREACH ( QString id, ids )
{
QgsVectorLayer *vl = static_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( id ) );
addEmbeddedLayer( vl->name(), vl->providerType(), vl->dataProvider()->encoding(), vl->source() );
}
}
}

void QgsVirtualLayerSourceSelect::on_buttonBox_accepted()
{
QString layerName = "virtual_layer";
Expand Down
9 changes: 8 additions & 1 deletion src/providers/virtual/qgsvirtuallayersourceselect.h
Expand Up @@ -26,20 +26,24 @@ email : hugo dot mercier at oslandia dot com

class QgsVectorLayer;
class QMainWindow;
class QgsEmbeddedLayerSelectDialog;

class QgsVirtualLayerSourceSelect : public QDialog, private Ui::QgsVirtualLayerSourceSelectBase
{
Q_OBJECT

public:
QgsVirtualLayerSourceSelect( QWidget * parent, Qt::WindowFlags fl = QgisGui::ModalDialogFlags );
~QgsVirtualLayerSourceSelect();

private slots:
void on_buttonBox_accepted();
void onTestQuery();
void onBrowseCRS();
void onLayerComboChanged( int );
void onAddLayer();
void onRemoveLayer();
void onImportLayer();
void onTableRowChanged( const QModelIndex& current, const QModelIndex& previous );

signals:
/** Source, name, provider */
Expand All @@ -50,6 +54,9 @@ class QgsVirtualLayerSourceSelect : public QDialog, private Ui::QgsVirtualLayerS
private:
QgsVirtualLayerDefinition getVirtualLayerDef();
long mSrid;
QStringList mProviderList;
QgsEmbeddedLayerSelectDialog* mEmbeddedSelectionDialog;
void addEmbeddedLayer( QString name, QString provider, QString encoding, QString source );
};

#endif

0 comments on commit bc7036f

Please sign in to comment.