Skip to content

Commit bc7036f

Browse files
author
Hugo Mercier
committed
Fix virtual layer creation UI
Expose embedded layers inclusion to the creation UI
1 parent baaeedf commit bc7036f

7 files changed

+430
-23
lines changed

src/providers/virtual/CMakeLists.txt

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ QT4_WRAP_CPP(vlayer_provider_MOC_SRCS
88
qgsvirtuallayerprovider.h
99
qgsslottofunction.h
1010
qgsvirtuallayersourceselect.h
11+
qgsembeddedlayerselectdialog.h
1112
)
1213

13-
QT4_WRAP_UI(vlayer_provider_UI_H qgsvirtuallayersourceselectbase.ui)
14+
QT4_WRAP_UI(vlayer_provider_UI_H qgsvirtuallayersourceselectbase.ui qgsembeddedlayerselect.ui)
1415

1516
SET(QGIS_VLAYER_PROVIDER_SRCS
1617
${vlayer_provider_MOC_SRCS}
@@ -23,6 +24,7 @@ SET(QGIS_VLAYER_PROVIDER_SRCS
2324
qgsvirtuallayersqlitehelper.cpp
2425
qgsvirtuallayerqueryparser.cpp
2526
qgsvirtuallayersourceselect.cpp
27+
qgsembeddedlayerselectdialog.cpp
2628
)
2729

2830
INCLUDE_DIRECTORIES(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<ui version="4.0">
3+
<class>QgsEmbeddedLayerSelectDialog</class>
4+
<widget class="QDialog" name="QgsEmbeddedLayerSelectDialog">
5+
<property name="geometry">
6+
<rect>
7+
<x>0</x>
8+
<y>0</y>
9+
<width>422</width>
10+
<height>366</height>
11+
</rect>
12+
</property>
13+
<property name="windowTitle">
14+
<string>Select layers to embed</string>
15+
</property>
16+
<layout class="QVBoxLayout" name="verticalLayout">
17+
<item>
18+
<widget class="QListWidget" name="mLayers">
19+
<property name="selectionMode">
20+
<enum>QAbstractItemView::ExtendedSelection</enum>
21+
</property>
22+
<property name="selectionBehavior">
23+
<enum>QAbstractItemView::SelectRows</enum>
24+
</property>
25+
</widget>
26+
</item>
27+
<item>
28+
<widget class="QDialogButtonBox" name="buttonBox">
29+
<property name="orientation">
30+
<enum>Qt::Horizontal</enum>
31+
</property>
32+
<property name="standardButtons">
33+
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
34+
</property>
35+
</widget>
36+
</item>
37+
</layout>
38+
</widget>
39+
<resources/>
40+
<connections>
41+
<connection>
42+
<sender>buttonBox</sender>
43+
<signal>rejected()</signal>
44+
<receiver>QgsEmbeddedLayerSelectDialog</receiver>
45+
<slot>reject()</slot>
46+
<hints>
47+
<hint type="sourcelabel">
48+
<x>316</x>
49+
<y>260</y>
50+
</hint>
51+
<hint type="destinationlabel">
52+
<x>286</x>
53+
<y>274</y>
54+
</hint>
55+
</hints>
56+
</connection>
57+
<connection>
58+
<sender>buttonBox</sender>
59+
<signal>accepted()</signal>
60+
<receiver>QgsEmbeddedLayerSelectDialog</receiver>
61+
<slot>accept()</slot>
62+
<hints>
63+
<hint type="sourcelabel">
64+
<x>248</x>
65+
<y>254</y>
66+
</hint>
67+
<hint type="destinationlabel">
68+
<x>157</x>
69+
<y>274</y>
70+
</hint>
71+
</hints>
72+
</connection>
73+
<connection>
74+
<sender>mLayers</sender>
75+
<signal>itemDoubleClicked(QListWidgetItem*)</signal>
76+
<receiver>QgsEmbeddedLayerSelectDialog</receiver>
77+
<slot>accept()</slot>
78+
<hints>
79+
<hint type="sourcelabel">
80+
<x>210</x>
81+
<y>166</y>
82+
</hint>
83+
<hint type="destinationlabel">
84+
<x>210</x>
85+
<y>182</y>
86+
</hint>
87+
</hints>
88+
</connection>
89+
</connections>
90+
</ui>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/***************************************************************************
2+
Virtual layer embedded layer selection widget
3+
4+
begin : Feb 2016
5+
copyright : (C) 2016 Hugo Mercier, Oslandia
6+
email : hugo dot mercier at oslandia dot com
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
11+
* This program is free software; you can redistribute it and/or modify *
12+
* it under the terms of the GNU General Public License as published by *
13+
* the Free Software Foundation; either version 2 of the License, or *
14+
* (at your option) any later version. *
15+
* *
16+
***************************************************************************/
17+
18+
#include "qgsembeddedlayerselectdialog.h"
19+
20+
#include <QMainWindow>
21+
#include <QSettings>
22+
23+
#include <qgsvectorlayer.h>
24+
#include <layertree/qgslayertreeview.h>
25+
#include <layertree/qgslayertreemodel.h>
26+
#include <layertree/qgslayertreegroup.h>
27+
#include <layertree/qgslayertreelayer.h>
28+
#include <qgsproviderregistry.h>
29+
#include <qgsvectordataprovider.h>
30+
31+
QgsEmbeddedLayerSelectDialog::QgsEmbeddedLayerSelectDialog( QWidget* parent, QgsLayerTreeView* tv )
32+
: QDialog( parent )
33+
{
34+
setupUi( this );
35+
36+
// populate list
37+
QList<QgsLayerTreeLayer*> layers = tv->layerTreeModel()->rootGroup()->findLayers();
38+
Q_FOREACH ( const QgsLayerTreeLayer* l, layers )
39+
{
40+
if ( l->layer() && l->layer()->type() == QgsMapLayer::VectorLayer )
41+
{
42+
// display layer name and store its pointer
43+
QListWidgetItem *item = new QListWidgetItem();
44+
item->setText( l->layer()->name() );
45+
item->setData( Qt::UserRole, QVariant::fromValue( static_cast<void*>( l->layer() ) ) );
46+
mLayers->insertItem( mLayers->count(), item );
47+
}
48+
}
49+
}
50+
51+
QStringList QgsEmbeddedLayerSelectDialog::layers() const
52+
{
53+
QStringList ids;
54+
QModelIndexList selected = mLayers->selectionModel()->selectedRows();
55+
for ( int i = 0; i < selected.size(); i++ )
56+
{
57+
QgsVectorLayer* l = static_cast<QgsVectorLayer*>( mLayers->item( selected[i].row() )->data( Qt::UserRole ).value<void*>() );
58+
ids << l->id();
59+
}
60+
return ids;
61+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/***************************************************************************
2+
Virtual layer embedded layer selection widget
3+
4+
begin : Feb 2016
5+
copyright : (C) 2016 Hugo Mercier, Oslandia
6+
email : hugo dot mercier at oslandia dot com
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
11+
* This program is free software; you can redistribute it and/or modify *
12+
* it under the terms of the GNU General Public License as published by *
13+
* the Free Software Foundation; either version 2 of the License, or *
14+
* (at your option) any later version. *
15+
* *
16+
***************************************************************************/
17+
18+
#ifndef QGSVIRTUAL_EMBEDDED_LAYER_SELECT_DIALOG_H
19+
#define QGSVIRTUAL_EMBEDDED_LAYER_SELECT_DIALOG_H
20+
21+
#include "ui_qgsembeddedlayerselect.h"
22+
23+
#include <QDialog>
24+
25+
class QgsVectorLayer;
26+
class QMainWindow;
27+
class QgsLayerTreeView;
28+
29+
class QgsEmbeddedLayerSelectDialog : public QDialog, private Ui::QgsEmbeddedLayerSelectDialog
30+
{
31+
Q_OBJECT
32+
33+
public:
34+
QgsEmbeddedLayerSelectDialog( QWidget * parent, QgsLayerTreeView* tv );
35+
36+
/** Returns the list of layer ids selected */
37+
QStringList layers() const;
38+
};
39+
40+
#endif

src/providers/virtual/qgsvirtuallayersourceselect.cpp

+102-3
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ email : hugo dot mercier at oslandia dot com
2626
#include <layertree/qgslayertreemodel.h>
2727
#include <layertree/qgslayertreegroup.h>
2828
#include <layertree/qgslayertreelayer.h>
29+
#include <qgsproviderregistry.h>
30+
31+
#include "qgsembeddedlayerselectdialog.h"
2932

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

4144
QObject::connect( mTestButton, SIGNAL( clicked() ), this, SLOT( onTestQuery() ) );
4245
QObject::connect( mBrowseCRSBtn, SIGNAL( clicked() ), this, SLOT( onBrowseCRS() ) );
46+
QObject::connect( mAddLayerBtn, SIGNAL( clicked() ), this, SLOT( onAddLayer() ) );
47+
QObject::connect( mRemoveLayerBtn, SIGNAL( clicked() ), this, SLOT( onRemoveLayer() ) );
48+
QObject::connect( mImportLayerBtn, SIGNAL( clicked() ), this, SLOT( onImportLayer() ) );
49+
QObject::connect( mLayersTable->selectionModel(), SIGNAL( currentRowChanged( const QModelIndex&, const QModelIndex& ) ), this, SLOT( onTableRowChanged( const QModelIndex&, const QModelIndex& ) ) );
50+
51+
// prepare provider list
52+
Q_FOREACH ( QString pk, QgsProviderRegistry::instance()->providerList() )
53+
{
54+
// we cannot know before trying to actually load a dataset
55+
// if the provider is raster or vector
56+
// so we manually exclude well-known raster providers
57+
if ( pk != "gdal" && pk != "ows" && pk != "wcs" && pk != "wms" )
58+
{
59+
mProviderList << pk;
60+
}
61+
}
4362

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

106125
mQueryEdit->setWrapMode( QsciScintilla::WrapWord );
107-
}
108126

109-
QgsVirtualLayerSourceSelect::~QgsVirtualLayerSourceSelect()
110-
{
127+
// prepare embedded layer selection dialog
128+
mEmbeddedSelectionDialog = new QgsEmbeddedLayerSelectDialog( this, treeView );
111129
}
112130

113131
void QgsVirtualLayerSourceSelect::onLayerComboChanged( int idx )
@@ -145,6 +163,15 @@ void QgsVirtualLayerSourceSelect::onLayerComboChanged( int idx )
145163
mGeometryType->setCurrentIndex( static_cast<long>( def.geometryWkbType() ) - 1 );
146164
mGeometryField->setText( def.geometryField() );
147165
}
166+
167+
// add embedded layers
168+
Q_FOREACH ( const QgsVirtualLayerDefinition::SourceLayer& l, def.sourceLayers() )
169+
{
170+
if ( ! l.isReferenced() )
171+
{
172+
addEmbeddedLayer( l.name(), l.provider(), l.encoding(), l.source() );
173+
}
174+
}
148175
}
149176

150177
void QgsVirtualLayerSourceSelect::onBrowseCRS()
@@ -184,6 +211,17 @@ QgsVirtualLayerDefinition QgsVirtualLayerSourceSelect::getVirtualLayerDef()
184211
def.setGeometryField( mGeometryField->text() );
185212
def.setGeometrySrid( mSrid );
186213
}
214+
215+
// add embedded layers
216+
for ( int i = 0; i < mLayersTable->rowCount(); i++ )
217+
{
218+
QString name = mLayersTable->item( i, 0 )->text();
219+
QString provider = static_cast<QComboBox*>( mLayersTable->cellWidget( i, 1 ) )->currentText();
220+
QString encoding = static_cast<QComboBox*>( mLayersTable->cellWidget( i, 2 ) )->currentText();
221+
QString source = mLayersTable->item( i, 3 )->text();
222+
def.addSource( name, source, provider, encoding );
223+
}
224+
187225
return def;
188226
}
189227

@@ -202,6 +240,67 @@ void QgsVirtualLayerSourceSelect::onTestQuery()
202240
}
203241
}
204242

243+
void QgsVirtualLayerSourceSelect::onAddLayer()
244+
{
245+
mLayersTable->insertRow( mLayersTable->rowCount() );
246+
247+
mLayersTable->setItem( mLayersTable->rowCount() - 1, 0, new QTableWidgetItem() );
248+
mLayersTable->setItem( mLayersTable->rowCount() - 1, 3, new QTableWidgetItem() );
249+
250+
QComboBox* providerCombo = new QComboBox();
251+
providerCombo->addItems( mProviderList );
252+
mLayersTable->setCellWidget( mLayersTable->rowCount() - 1, 1, providerCombo );
253+
254+
QComboBox* encodingCombo = new QComboBox();
255+
encodingCombo->addItems( QgsVectorDataProvider::availableEncodings() );
256+
QString defaultEnc = QSettings().value( "/UI/encoding", "System" ).toString();
257+
encodingCombo->setCurrentIndex( encodingCombo->findText( defaultEnc ) );
258+
mLayersTable->setCellWidget( mLayersTable->rowCount() - 1, 2, encodingCombo );
259+
}
260+
261+
void QgsVirtualLayerSourceSelect::onRemoveLayer()
262+
{
263+
int currentRow = mLayersTable->selectionModel()->currentIndex().row();
264+
if ( currentRow != -1 )
265+
mLayersTable->removeRow( currentRow );
266+
}
267+
268+
void QgsVirtualLayerSourceSelect::onTableRowChanged( const QModelIndex& current, const QModelIndex& previous )
269+
{
270+
Q_UNUSED( previous );
271+
mRemoveLayerBtn->setEnabled( current.row() != -1 );
272+
}
273+
274+
void QgsVirtualLayerSourceSelect::addEmbeddedLayer( QString name, QString provider, QString encoding, QString source )
275+
{
276+
// insert a new row
277+
onAddLayer();
278+
const int n = mLayersTable->rowCount() - 1;
279+
// local name
280+
mLayersTable->item( n, 0 )->setText( name );
281+
// source
282+
mLayersTable->item( n, 3 )->setText( source );
283+
// provider
284+
QComboBox* providerCombo = static_cast<QComboBox*>( mLayersTable->cellWidget( n, 1 ) );
285+
providerCombo->setCurrentIndex( providerCombo->findText( provider ) );
286+
// encoding
287+
QComboBox* encodingCombo = static_cast<QComboBox*>( mLayersTable->cellWidget( n, 2 ) );
288+
encodingCombo->setCurrentIndex( encodingCombo->findText( encoding ) );
289+
}
290+
291+
void QgsVirtualLayerSourceSelect::onImportLayer()
292+
{
293+
if ( mEmbeddedSelectionDialog->exec() == QDialog::Accepted )
294+
{
295+
QStringList ids = mEmbeddedSelectionDialog->layers();
296+
Q_FOREACH ( QString id, ids )
297+
{
298+
QgsVectorLayer *vl = static_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( id ) );
299+
addEmbeddedLayer( vl->name(), vl->providerType(), vl->dataProvider()->encoding(), vl->source() );
300+
}
301+
}
302+
}
303+
205304
void QgsVirtualLayerSourceSelect::on_buttonBox_accepted()
206305
{
207306
QString layerName = "virtual_layer";

src/providers/virtual/qgsvirtuallayersourceselect.h

+8-1
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,24 @@ email : hugo dot mercier at oslandia dot com
2626

2727
class QgsVectorLayer;
2828
class QMainWindow;
29+
class QgsEmbeddedLayerSelectDialog;
2930

3031
class QgsVirtualLayerSourceSelect : public QDialog, private Ui::QgsVirtualLayerSourceSelectBase
3132
{
3233
Q_OBJECT
3334

3435
public:
3536
QgsVirtualLayerSourceSelect( QWidget * parent, Qt::WindowFlags fl = QgisGui::ModalDialogFlags );
36-
~QgsVirtualLayerSourceSelect();
3737

3838
private slots:
3939
void on_buttonBox_accepted();
4040
void onTestQuery();
4141
void onBrowseCRS();
4242
void onLayerComboChanged( int );
43+
void onAddLayer();
44+
void onRemoveLayer();
45+
void onImportLayer();
46+
void onTableRowChanged( const QModelIndex& current, const QModelIndex& previous );
4347

4448
signals:
4549
/** Source, name, provider */
@@ -50,6 +54,9 @@ class QgsVirtualLayerSourceSelect : public QDialog, private Ui::QgsVirtualLayerS
5054
private:
5155
QgsVirtualLayerDefinition getVirtualLayerDef();
5256
long mSrid;
57+
QStringList mProviderList;
58+
QgsEmbeddedLayerSelectDialog* mEmbeddedSelectionDialog;
59+
void addEmbeddedLayer( QString name, QString provider, QString encoding, QString source );
5360
};
5461

5562
#endif

0 commit comments

Comments
 (0)