35
35
#include < QMessageBox>
36
36
#include < QSettings>
37
37
#include < QFileDialog>
38
+ #include < QPainter>
38
39
39
40
40
41
QgsWFSSourceSelect::QgsWFSSourceSelect ( QWidget* parent, Qt::WFlags fl, bool embeddedMode )
@@ -43,30 +44,57 @@ QgsWFSSourceSelect::QgsWFSSourceSelect( QWidget* parent, Qt::WFlags fl, bool emb
43
44
{
44
45
setupUi ( this );
45
46
46
- btnAdd = buttonBox->button ( QDialogButtonBox::Apply );
47
- btnAdd->setEnabled ( false );
48
-
49
47
if ( embeddedMode )
50
48
{
51
- buttonBox->button ( QDialogButtonBox::Apply )->hide ();
52
49
buttonBox->button ( QDialogButtonBox::Close )->hide ();
53
50
}
54
51
55
- connect ( buttonBox->button ( QDialogButtonBox::Apply ), SIGNAL ( clicked () ), this , SLOT ( addLayer () ) );
52
+ mAddButton = new QPushButton ( tr ( " &Add" ) );
53
+ mAddButton ->setEnabled ( false );
54
+
55
+ mBuildQueryButton = new QPushButton ( tr ( " &Build query" ) );
56
+ mBuildQueryButton ->setToolTip ( tr ( " Build query" ) );
57
+ mBuildQueryButton ->setDisabled ( true );
58
+
59
+
60
+ buttonBox->addButton ( mAddButton , QDialogButtonBox::ActionRole );
61
+ connect ( mAddButton , SIGNAL ( clicked () ), this , SLOT ( addLayer () ) );
62
+
63
+ buttonBox->addButton ( mBuildQueryButton , QDialogButtonBox::ActionRole );
64
+ connect ( mBuildQueryButton , SIGNAL ( clicked () ), this , SLOT ( on_mBuildQueryButton_clicked () ) );
65
+
56
66
connect ( buttonBox, SIGNAL ( rejected () ), this , SLOT ( reject () ) );
57
67
connect ( btnNew, SIGNAL ( clicked () ), this , SLOT ( addEntryToServerList () ) );
58
68
connect ( btnEdit, SIGNAL ( clicked () ), this , SLOT ( modifyEntryOfServerList () ) );
59
69
connect ( btnDelete, SIGNAL ( clicked () ), this , SLOT ( deleteEntryOfServerList () ) );
60
70
connect ( btnConnect, SIGNAL ( clicked () ), this , SLOT ( connectToServer () ) );
61
71
connect ( btnChangeSpatialRefSys, SIGNAL ( clicked () ), this , SLOT ( changeCRS () ) );
62
- connect ( treeWidget , SIGNAL ( currentItemChanged ( QTreeWidgetItem*, QTreeWidgetItem* ) ), this , SLOT ( changeCRSFilter ( ) ) );
72
+ connect ( lineFilter , SIGNAL ( textChanged ( QString ) ), this , SLOT ( filterChanged ( QString ) ) );
63
73
populateConnectionList ();
64
74
mProjectionSelector = new QgsGenericProjectionSelector ( this );
65
75
mProjectionSelector ->setMessage ();
66
76
77
+ mItemDelegate = new QgsWFSItemDelegate ( treeView );
78
+ treeView->setItemDelegate ( mItemDelegate );
79
+
67
80
QSettings settings;
68
81
QgsDebugMsg ( " restoring geometry" );
69
82
restoreGeometry ( settings.value ( " /Windows/WFSSourceSelect/geometry" ).toByteArray () );
83
+
84
+ mModel = new QStandardItemModel ();
85
+ mModel ->setHorizontalHeaderItem ( 0 , new QStandardItem ( " Title" ) );
86
+ mModel ->setHorizontalHeaderItem ( 1 , new QStandardItem ( " Name" ) );
87
+ mModel ->setHorizontalHeaderItem ( 2 , new QStandardItem ( " Abstract" ) );
88
+ mModel ->setHorizontalHeaderItem ( 3 , new QStandardItem ( " Cache Feature" ) );
89
+ mModel ->setHorizontalHeaderItem ( 4 , new QStandardItem ( " Filter" ) );
90
+
91
+ mModelProxy = new QSortFilterProxyModel ( this );
92
+ mModelProxy ->setSourceModel ( mModel );
93
+ mModelProxy ->setSortCaseSensitivity ( Qt::CaseInsensitive );
94
+ treeView->setModel ( mModelProxy );
95
+
96
+ connect ( treeView, SIGNAL ( doubleClicked (const QModelIndex&) ), this , SLOT ( on_treeWidget_itemDoubleClicked (const QModelIndex&) ) );
97
+ connect ( treeView->selectionModel (), SIGNAL ( currentRowChanged ( QModelIndex, QModelIndex) ), this , SLOT ( on_treeWidget_currentRowChanged (const QModelIndex&, const QModelIndex&) ) );
70
98
}
71
99
72
100
QgsWFSSourceSelect::~QgsWFSSourceSelect ()
@@ -75,8 +103,13 @@ QgsWFSSourceSelect::~QgsWFSSourceSelect()
75
103
QgsDebugMsg ( " saving geometry" );
76
104
settings.setValue ( " /Windows/WFSSourceSelect/geometry" , saveGeometry () );
77
105
106
+ delete mItemDelegate ;
78
107
delete mProjectionSelector ;
79
108
delete mCapabilities ;
109
+ delete mModel ;
110
+ delete mModelProxy ;
111
+ delete mAddButton ;
112
+ delete mBuildQueryButton ;
80
113
}
81
114
82
115
void QgsWFSSourceSelect::populateConnectionList ()
@@ -183,13 +216,18 @@ void QgsWFSSourceSelect::capabilitiesReplyFinished()
183
216
foreach ( QgsWFSCapabilities::FeatureType featureType, caps.featureTypes )
184
217
{
185
218
// insert the typenames, titles and abstracts into the tree view
186
- QTreeWidgetItem* newItem = new QTreeWidgetItem ();
187
- newItem->setText ( 0 , featureType.title );
188
- newItem->setText ( 1 , featureType.name );
189
- newItem->setText ( 2 , featureType.abstract );
190
- newItem->setToolTip ( 2 , " <font color=black>" + featureType.abstract + " </font>" );
191
- newItem->setCheckState ( 3 , Qt::Checked );
192
- treeWidget->addTopLevelItem ( newItem );
219
+ QStandardItem* titleItem = new QStandardItem ( featureType.title );
220
+ QStandardItem* nameItem = new QStandardItem ( featureType.name );
221
+ QStandardItem* abstractItem = new QStandardItem ( featureType.abstract );
222
+ abstractItem->setToolTip ( " <font color=black>" + featureType.abstract + " </font>" );
223
+ abstractItem->setTextAlignment ( Qt::AlignLeft | Qt::AlignTop );
224
+ QStandardItem* cachedItem = new QStandardItem ();
225
+ QStandardItem* filterItem = new QStandardItem ();
226
+ cachedItem->setCheckable ( true );
227
+ cachedItem->setCheckState ( Qt::Checked );
228
+
229
+ typedef QList< QStandardItem* > StandardItemList;
230
+ mModel ->appendRow ( StandardItemList () << titleItem << nameItem << abstractItem << cachedItem << filterItem);
193
231
194
232
// insert the available CRS into mAvailableCRS
195
233
std::list<QString> currentCRSList;
@@ -202,14 +240,30 @@ void QgsWFSSourceSelect::capabilitiesReplyFinished()
202
240
203
241
if ( caps.featureTypes .count () > 0 )
204
242
{
205
- btnAdd->setEnabled ( true );
206
- treeWidget->setCurrentItem ( treeWidget->topLevelItem ( 0 ) );
243
+ treeView->resizeColumnToContents ( 0 );
244
+ treeView->resizeColumnToContents ( 1 );
245
+ treeView->resizeColumnToContents ( 2 );
246
+ treeView->resizeColumnToContents ( 3 );
247
+ for ( int i = 0 ; i < 2 ; i++ )
248
+ {
249
+ if ( treeView->columnWidth ( i ) > 300 )
250
+ {
251
+ treeView->setColumnWidth ( i, 300 );
252
+ }
253
+ }
254
+ if ( treeView->columnWidth ( 2 ) > 150 )
255
+ {
256
+ treeView->setColumnWidth ( 2 , 150 );
257
+ }
207
258
btnChangeSpatialRefSys->setEnabled ( true );
259
+ treeView->selectionModel ()->select ( mModel ->index ( 0 , 0 ), QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows );
260
+ treeView->setFocus ();
208
261
}
209
262
else
210
263
{
211
264
QMessageBox::information ( 0 , tr ( " No Layers" ), tr ( " capabilities document contained no layers." ) );
212
- btnAdd->setEnabled ( false );
265
+ mAddButton ->setEnabled ( false );
266
+ mBuildQueryButton ->setEnabled ( false );
213
267
}
214
268
}
215
269
@@ -253,8 +307,10 @@ void QgsWFSSourceSelect::deleteEntryOfServerList()
253
307
void QgsWFSSourceSelect::connectToServer ()
254
308
{
255
309
btnConnect->setEnabled ( false );
256
- treeWidget->clear ();
257
-
310
+ if ( mModel )
311
+ {
312
+ mModel ->removeRows ( 0 , mModel ->rowCount () );
313
+ }
258
314
if ( mCapabilities )
259
315
{
260
316
mCapabilities ->requestCapabilities ();
@@ -264,16 +320,13 @@ void QgsWFSSourceSelect::connectToServer()
264
320
265
321
void QgsWFSSourceSelect::addLayer ()
266
322
{
267
- // get selected entry in lstWidget
268
- QTreeWidgetItem* tItem = treeWidget-> currentItem ();
269
- if ( !tItem )
323
+ // get selected entry in treeview
324
+ QModelIndex currentIndex = treeView-> selectionModel ()-> currentIndex ();
325
+ if ( !currentIndex. isValid () )
270
326
{
271
327
return ;
272
328
}
273
329
274
- QList<QTreeWidgetItem*> selectedItems = treeWidget->selectedItems ();
275
- QList<QTreeWidgetItem*>::const_iterator sIt = selectedItems.constBegin ();
276
-
277
330
QgsOWSConnection connection ( " WFS" , cmbConnections->currentText () );
278
331
QgsWFSCapabilities conn ( connection.uri ().encodedUri () );
279
332
@@ -312,13 +365,22 @@ void QgsWFSSourceSelect::addLayer()
312
365
}
313
366
}
314
367
}
368
+
315
369
// create layers that user selected from this WFS source
316
- for ( ; sIt != selectedItems.constEnd (); ++sIt )
370
+ QModelIndexList list = treeView->selectionModel ()->selectedRows ();
371
+ for ( int i = 0 ; i < list.size (); i++ )
317
372
{ // add a wfs layer to the map
318
- QString typeName = ( *sIt )->text ( 1 ); // WFS repository's name for layer
319
- QString filter = ( *sIt )->text ( 4 ); // optional filter specified by user
373
+ QModelIndex idx = mModelProxy ->mapToSource ( list[i] );
374
+ if ( !idx.isValid () )
375
+ {
376
+ continue ;
377
+ }
378
+ int row = idx.row ();
379
+ QString typeName = mModel ->item ( row, 1 )->text (); // WFS repository's name for layer
380
+ QString filter = mModel ->item ( row, 4 )->text (); // optional filter specified by user
381
+ QgsDebugMsg ( " Layer " + typeName + " Filter is " + filter );
320
382
// is "cache features" checked?
321
- if (( * sIt )->checkState ( 3 ) == Qt::Checked )
383
+ if ( mModel -> item ( row, 3 )->checkState () == Qt::Checked )
322
384
{ // yes: entire WFS layer will be retrieved and cached
323
385
mUri = conn.uriGetFeature ( typeName, pCrsString, filter );
324
386
}
@@ -331,6 +393,48 @@ void QgsWFSSourceSelect::addLayer()
331
393
accept ();
332
394
}
333
395
396
+ void QgsWFSSourceSelect::buildQuery ( const QModelIndex& index )
397
+ {
398
+ if ( !index.isValid () )
399
+ {
400
+ return ;
401
+ }
402
+ QModelIndex filterIndex = index.sibling ( index.row (), 4 );
403
+ QString typeName = index.sibling ( index.row (), 1 ).data ().toString ();
404
+
405
+ // get available fields for wfs layer
406
+ QgsWFSProvider p ( " " ); // bypasses most provider instantiation logic
407
+ QgsOWSConnection connection ( " WFS" , cmbConnections->currentText () );
408
+ QgsWFSCapabilities conn ( connection.uri ().encodedUri () );
409
+ QString uri = conn.uriDescribeFeatureType ( typeName );
410
+
411
+ QgsFields fields;
412
+ QString geometryAttribute;
413
+ QGis::WkbType geomType;
414
+ if ( p.describeFeatureType ( uri, geometryAttribute, fields, geomType ) != 0 )
415
+ {
416
+ return ;
417
+ }
418
+
419
+ // show expression builder
420
+ QgsExpressionBuilderDialog d ( 0 , filterIndex.data ().toString () );
421
+
422
+ // add available attributes to expression builder
423
+ QgsExpressionBuilderWidget* w = d.expressionBuilder ();
424
+ if ( !w )
425
+ {
426
+ return ;
427
+ }
428
+
429
+ w->loadFieldNames ( fields );
430
+
431
+ if ( d.exec () == QDialog::Accepted )
432
+ {
433
+ QgsDebugMsg ( " Expression text = " + w->expressionText () );
434
+ mModelProxy ->setData ( filterIndex, QVariant ( w->expressionText () ) );
435
+ }
436
+ }
437
+
334
438
void QgsWFSSourceSelect::changeCRS ()
335
439
{
336
440
if ( mProjectionSelector ->exec () )
@@ -342,11 +446,12 @@ void QgsWFSSourceSelect::changeCRS()
342
446
343
447
void QgsWFSSourceSelect::changeCRSFilter ()
344
448
{
449
+ QgsDebugMsg (" changeCRSFilter called" );
345
450
// evaluate currently selected typename and set the CRS filter in mProjectionSelector
346
- QTreeWidgetItem* currentTreeItem = treeWidget-> currentItem ();
347
- if ( currentTreeItem )
451
+ QModelIndex currentIndex = treeView-> selectionModel ()-> currentIndex ();
452
+ if ( currentIndex. isValid () )
348
453
{
349
- QString currentTypename = currentTreeItem-> text ( 1 );
454
+ QString currentTypename = currentIndex. sibling ( currentIndex. row (), 1 ). data (). toString ( );
350
455
QgsDebugMsg ( QString ( " the current typename is: %1" ).arg ( currentTypename ) );
351
456
352
457
std::map<QString, std::list<QString> >::const_iterator crsIterator = mAvailableCRS .find ( currentTypename );
@@ -410,39 +515,47 @@ void QgsWFSSourceSelect::on_btnLoad_clicked()
410
515
emit connectionsChanged ();
411
516
}
412
517
413
- void QgsWFSSourceSelect::on_treeWidget_itemDoubleClicked ( QTreeWidgetItem* item, int column )
518
+ void QgsWFSSourceSelect::on_treeWidget_itemDoubleClicked ( const QModelIndex& index )
414
519
{
415
- if ( item && column == 4 )
416
- {
417
- // get available fields for wfs layer
418
- QgsWFSProvider p ( " " ); // bypasses most provider instantiation logic
419
- QgsOWSConnection connection ( " WFS" , cmbConnections->currentText () );
420
- QgsWFSCapabilities conn ( connection.uri ().encodedUri () );
421
- QString uri = conn.uriDescribeFeatureType ( item->text ( 1 ) );
422
-
423
- QgsFields fields;
424
- QString geometryAttribute;
425
- QGis::WkbType geomType;
426
- if ( p.describeFeatureType ( uri, geometryAttribute, fields, geomType ) != 0 )
427
- {
428
- return ;
429
- }
520
+ QgsDebugMsg ( " double click called" );
521
+ buildQuery ( index );
522
+ }
430
523
431
- // show expression builder
432
- QgsExpressionBuilderDialog d ( 0 , item->text ( 3 ) );
524
+ void QgsWFSSourceSelect::on_treeWidget_currentRowChanged ( const QModelIndex & current, const QModelIndex & previous)
525
+ {
526
+ Q_UNUSED ( previous )
527
+ QgsDebugMsg ( " treeWidget_currentRowChanged called" );
528
+ changeCRSFilter ();
529
+ mBuildQueryButton ->setEnabled ( current.isValid () );
530
+ mAddButton ->setEnabled ( current.isValid () );
531
+ }
433
532
434
- // add available attributes to expression builder
435
- QgsExpressionBuilderWidget* w = d.expressionBuilder ();
436
- if ( !w )
437
- {
438
- return ;
439
- }
533
+ void QgsWFSSourceSelect::on_mBuildQueryButton_clicked ()
534
+ {
535
+ QgsDebugMsg ( " mBuildQueryButton click called" );
536
+ buildQuery ( treeView->selectionModel ()->currentIndex () );
537
+ }
440
538
441
- w->loadFieldNames ( fields );
539
+ void QgsWFSSourceSelect::filterChanged (QString text)
540
+ {
541
+ QgsDebugMsg ( " WFS FeatureType filter changed to :" + text );
542
+ QRegExp::PatternSyntax mySyntax = QRegExp::PatternSyntax ( QRegExp::RegExp );
543
+ Qt::CaseSensitivity myCaseSensitivity = Qt::CaseInsensitive;
544
+ QRegExp myRegExp ( text, myCaseSensitivity, mySyntax );
545
+ mModelProxy ->setFilterRegExp ( myRegExp );
546
+ mModelProxy ->sort ( mModelProxy ->sortColumn (), mModelProxy ->sortOrder () );
547
+ }
442
548
443
- if ( d.exec () == QDialog::Accepted )
549
+ QSize QgsWFSItemDelegate::sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const
550
+ {
551
+ QVariant indexData;
552
+ indexData = index.data (Qt::DisplayRole);
553
+ if ( indexData.isNull () )
444
554
{
445
- item-> setText ( 4 , w-> expressionText () );
555
+ return QSize ( );
446
556
}
447
- }
557
+ QString data = indexData.toString ();
558
+ QSize size = option.fontMetrics .boundingRect (data).size ();
559
+ size.setHeight (size.height () + 2 );
560
+ return size;
448
561
}
0 commit comments