qgsspatialquerydialog.cpp

Fix bug for "Remove from selection" - Luiz Motta, 2011-02-21 10:37 AM

Download (32.5 KB)

 
1
/***************************************************************************
2
                          qgsspatialquerydialog.cpp
3
                             -------------------
4
    begin                : Dec 29, 2009
5
    copyright            : (C) 2009 by Diego Moreira And Luiz Motta
6
    email                : moreira.geo at gmail.com And motta.luiz at gmail.com
7

8
 ***************************************************************************/
9

    
10
/***************************************************************************
11
 *                                                                         *
12
 *   This program is free software; you can redistribute it and/or modify  *
13
 *   it under the terms of the GNU General Public License as published by  *
14
 *   the Free Software Foundation; either version 2 of the License, or     *
15
 *   (at your option) any later version.                                   *
16
 *                                                                         *
17
 ***************************************************************************/
18
/*  $Id: qgsspatialquerydialog.cpp 15141 2011-02-08 13:34:43Z jef $ */
19

    
20
#include <QMessageBox>
21
#include <QDateTime>
22
#include <QPushButton>
23

    
24
#include "qgis.h"
25
#include "qgsapplication.h"
26
#include "qgsmaplayer.h"
27
#include "qgsmaplayerregistry.h"
28
#include "qgsproject.h"
29
#include "qgsvectordataprovider.h"
30

    
31
#include "qgsspatialquerydialog.h"
32
#include "qgsspatialquery.h"
33
#include "qgsrubberselectid.h"
34
#include "qgsmngprogressbar.h"
35

    
36
QgsSpatialQueryDialog::QgsSpatialQueryDialog( QWidget* parent, QgisInterface* iface ): QDialog( parent )
37
{
38
  setupUi( this );
39

    
40
  mLayerReference = mLayerTarget = NULL;
41
  mIface = iface;
42
  mRubberSelectId = new QgsRubberSelectId( iface->mapCanvas() );
43

    
44
  initGui();
45
  connectAll();
46

    
47
  mMsgLayersLessTwo = tr( "The spatial query requires at least two layers" );
48

    
49
} // QgsSpatialQueryDialog::QgsSpatialQueryDialog( QWidget* parent, QgisInterface* iface )
50

    
51
QgsSpatialQueryDialog::~QgsSpatialQueryDialog()
52
{
53
  disconnectAll();
54
  delete mRubberSelectId;
55
  mMapIdVectorLayers.clear();
56
  mFeatureResult.clear();
57
  mFeatureInvalidTarget.clear();
58
  mFeatureInvalidReference.clear();
59

    
60
} // QgsSpatialQueryDialog::~QgsSpatialQueryDialog()
61

    
62
void QgsSpatialQueryDialog::show()
63
{
64
  QDialog::show();
65
  adjustSize();
66
} // void QgsSpatialQueryDialog::show()
67

    
68
void QgsSpatialQueryDialog::messageLayersLessTwo()
69
{
70
  QString msgLayersLessTwo = tr( "The spatial query requires at least two layers" );
71
  QMessageBox::warning( 0, tr( "Insufficient number of layers" ), msgLayersLessTwo, QMessageBox::Ok );
72
} // void QgsSpatialQueryDialog::messageLayersLessTwo()
73

    
74
void QgsSpatialQueryDialog::initGui()
75
{
76
  mRubberSelectId->setStyle(250, 0, 0, 2); // Same identify
77

    
78
  visibleResult( false );
79
  teStatus->setVisible( false );
80
  populateTypeItems();
81
  populateCbTargetLayer();
82
  if ( cbTargetLayer->count() > 1 )
83
  {
84
    setLayer( true, 0 );
85
    setSelectedGui();
86
    evaluateCheckBoxLayer( true );
87
    populateCbReferenceLayer();
88
    setLayer( false, 0 );
89
    evaluateCheckBoxLayer( false );
90
    populateCbOperation();
91
  }
92
  else
93
  {
94
    bbMain->button( QDialogButtonBox::Apply )->hide();
95
  }
96
  populateCbResulFor(); // Depend if Target is selected
97
} // QgsSpatialQueryDialog::initGui()
98

    
99
void QgsSpatialQueryDialog::setLayer( bool isTarget, int index )
100
{
101
  if ( isTarget )
102
  {
103
    if ( mLayerTarget )
104
    {
105
      disconnect( mLayerTarget, SIGNAL( selectionChanged() ),
106
                  this, SLOT( signal_layerTarget_selectionFeaturesChanged() ) );
107
    }
108
    mLayerTarget = getLayerFromCombobox( isTarget, index );
109
    connect( mLayerTarget, SIGNAL( selectionChanged() ),
110
             this, SLOT( signal_layerTarget_selectionFeaturesChanged() ) );
111
  }
112
  else
113
  {
114
    if ( mLayerReference )
115
    {
116
      disconnect( mLayerReference, SIGNAL( selectionChanged() ),
117
                  this, SLOT( signal_layerReference_selectionFeaturesChanged() ) );
118
    }
119
    mLayerReference = getLayerFromCombobox( isTarget, index );
120
    connect( mLayerReference, SIGNAL( selectionChanged() ),
121
             this, SLOT( signal_layerReference_selectionFeaturesChanged() ) );
122
  }
123

    
124
} // void QgsSpatialQueryDialog::setLayer(bool isTarget, int index)
125

    
126
void QgsSpatialQueryDialog::evaluateCheckBoxLayer( bool isTarget )
127
{
128
  QgsVectorLayer* lyr = NULL;
129
  QCheckBox* checkbox = NULL;
130
  if ( isTarget )
131
  {
132
    lyr = mLayerTarget;
133
    checkbox = ckbUsingSelectedTarget;
134
  }
135
  else
136
  {
137
    lyr = mLayerReference;
138
    checkbox = ckbUsingSelectedReference;
139
  }
140
  int selectedCount = lyr->selectedFeatureCount();
141
  bool isCheckBoxValid = ( lyr != NULL &&  selectedCount > 0 );
142
  checkbox->setChecked( isCheckBoxValid );
143
  checkbox->setEnabled( isCheckBoxValid );
144
  QString textCheckBox  = isCheckBoxValid
145
                          ? tr( "%n selected geometries", "selected geometries", selectedCount )
146
                          : tr( "Selected geometries" );
147
  checkbox->setText( textCheckBox );
148

    
149
} // void QgsSpatialQueryDialog::evaluateCheckBoxLayer(bool isTarget)
150

    
151
void QgsSpatialQueryDialog::runQuery()
152
{
153
  bbMain->setEnabled( false );
154
  MngProgressBar* pb = new MngProgressBar( pgbStatus );
155
  QgsSpatialQuery* spatialQuery = new QgsSpatialQuery( pb );
156
  if ( ckbUsingSelectedTarget->isChecked() )
157
  {
158
    spatialQuery->setSelectedFeaturesTarget( true );
159
  }
160
  if ( ckbUsingSelectedReference->isChecked() )
161
  {
162
    spatialQuery->setSelectedFeaturesReference( true );
163
  }
164
  pgbStatus->setTextVisible( true );
165
  mFeatureResult.clear();
166
  mFeatureInvalidTarget.clear();
167
  mFeatureInvalidReference.clear();
168

    
169
  int currentItem = cbOperantion->currentIndex();
170
  int operation = cbOperantion->itemData( currentItem ).toInt();
171
  spatialQuery->runQuery( mFeatureResult, mFeatureInvalidTarget, mFeatureInvalidReference, operation, mLayerTarget, mLayerReference );
172
  delete spatialQuery;
173
  delete pb;
174

    
175
  bbMain->setEnabled( true );
176
} // void QgsSpatialQueryDialog::runQuery()
177

    
178
void QgsSpatialQueryDialog::showResultQuery( QDateTime *datetimeStart, QDateTime *datetimeEnd )
179
{
180
  static int countQuery = 0;
181
  // Report processing
182
  countQuery++;
183
  QString msg = tr( "%1)Query" ).arg( countQuery );
184
  teStatus->append( msg );
185
  msg = tr( "Begin at %L1" ).arg( datetimeStart->toString() );
186
  teStatus->append( msg );
187
  teStatus->append( "" );
188
  msg = QString( "%1" ).arg( getDescriptionLayerShow( true ) );
189
  teStatus->append( msg );
190
  msg = tr( "< %1 >" ).arg( cbOperantion->currentText() );
191
  teStatus->append( msg );
192
  msg = QString( "%1" ).arg( getDescriptionLayerShow( false ) );
193
  teStatus->append( msg );
194
  msg = tr( "Total of features =  %1" ).arg( mFeatureResult.size() );
195
  teStatus->append( msg );
196
  teStatus->append( "" );
197
  teStatus->append( tr("Total of invalid features:") );
198
  teStatus->append( getDescriptionInvalidFeaturesShow( true ) );
199
  teStatus->append( getDescriptionInvalidFeaturesShow( false ) );
200
  teStatus->append( "" );
201
  double timeProcess = ( double )datetimeStart->secsTo( *datetimeEnd ) / 60.0;
202
  msg = tr( "Finish at %L1 (processing time %L2 minutes)" ).arg( datetimeEnd->toString() ).arg( timeProcess, 0, 'f', 2 );
203
  teStatus->append( msg );
204
  teStatus->append( "" );
205

    
206
  ckbLogProcessing->setChecked( false );
207
  QVariant item = QVariant::fromValue( (int)itemsResult );
208
  int index = cbTypeItems->findData(item);
209
  cbTypeItems->setCurrentIndex( index );
210
  on_cbTypeItems_currentIndexChanged( index );
211

    
212
  // Result target
213
  if ( mFeatureResult.size() > 0 )
214
  {
215
    // Select features
216
    TypeResultFor typeResultFor = (TypeResultFor) cbResultFor->itemData( cbResultFor->currentItem() ).toInt();
217
    switch( typeResultFor )
218
    {
219
      case selectedNew:
220
        mLayerTarget->setSelectedFeatures( mFeatureResult );
221
        break;
222
      case selectedAdd:
223
        mLayerTarget->setSelectedFeatures( mLayerTarget->selectedFeaturesIds() + mFeatureResult );
224
        break;
225
      case selectedRemove:
226
        mLayerTarget->setSelectedFeatures( mLayerTarget->selectedFeaturesIds() - mFeatureResult);
227
        break;
228
      default:
229
        return;
230
    }
231
  }
232
} // void QgsSpatialQueryDialog::showResultQuery(QDateTime *datetimeStart, QDateTime *datetimeEnd)
233

    
234
QString QgsSpatialQueryDialog::getSubsetFIDs( const QSet< int > *fids, QString fieldFID )
235
{
236
  if( fids->size() == 0 )
237
  {
238
    return QString("");
239
  }
240
  QSetIterator <int>item( *fids );
241
  QStringList lstFID;
242
  while ( item.hasNext() )
243
  {
244
    lstFID.append( QString::number( item.next() ) );
245
  }
246
  QString qFormat("%1 in (%2)");
247
  QString qReturn  = qFormat.arg( fieldFID ).arg( lstFID.join(",") );
248
  lstFID.clear();
249
  return qReturn;
250
} // QString QgsSpatialQueryDialog::getSubsetFIDs( const QSet< int > *fids, QString fieldFID )
251

    
252
QgsSpatialQueryDialog::TypeVerifyCreateSubset QgsSpatialQueryDialog::verifyCreateSubset(QString &msg, QString &fieldFID)
253
{
254
  QString providerType = mLayerTarget->providerType().toUpper();
255
  // OGR
256
  if( providerType  == "OGR")
257
  {
258
    fieldFID = QString("FID");
259
    return verifyOk;
260
  }
261
  // Database Postgis and Spatialite
262
  if( providerType  == "POSTGRES" || providerType  == "SPATIALITE" )
263
  {
264
    fieldFID = mLayerTarget->dataProvider()->fields().value( 0 ).name();
265
    msg = tr("Using the field \"%1\" for subset").arg( fieldFID );
266
    return verifyTry;
267
  }
268
  msg = tr("Sorry! Only this providers are enable: OGR, POSTGRES and SPATIALITE.");
269
  return verifyImpossible;
270
} // TypeVerifyCreateSubset QgsSpatialQueryDialog::verifyCreateSubset(QString &msg, QString &fieldFID)
271

    
272
bool QgsSpatialQueryDialog::addLayerSubset( QString name, QString subset )
273
{
274
  QgsVectorLayer *addLyr = new QgsVectorLayer( mLayerTarget->source(), name, mLayerTarget->providerType() );
275
  if( ! addLyr->setSubsetString( subset ) )
276
  {
277
    delete addLyr;
278
    return false;
279
  }
280
  QgsMapLayerRegistry::instance()->addMapLayer( addLyr );
281
  return true;
282
} // bool QgsSpatialQueryDialog::addLayerSubset( QString name, QString subset )
283

    
284
QString QgsSpatialQueryDialog::getDescriptionLayerShow( bool isTarget )
285
{
286
  QgsVectorLayer* lyr = NULL;
287
  QCheckBox * checkBox = NULL;
288
  if ( isTarget )
289
  {
290
    lyr = mLayerTarget;
291
    checkBox = ckbUsingSelectedTarget;
292
  }
293
  else
294
  {
295
    lyr = mLayerReference;
296
    checkBox = ckbUsingSelectedReference;
297
  }
298

    
299
  QString sDescFeatures = checkBox->isChecked()
300
                          ? tr( "%1 of %2" ).arg( lyr->selectedFeatureCount() ).arg( lyr->featureCount() )
301
                          : tr( "all = %1" ).arg( lyr->featureCount() );
302

    
303
  return QString( "%1 (%2)" ).arg( lyr->name() ).arg( sDescFeatures );
304

    
305
} // QString QgsSpatialQueryDialog::getDescriptionLayerShow(bool isTarget)
306

    
307
QString QgsSpatialQueryDialog::getDescriptionInvalidFeaturesShow( bool isTarget )
308
{
309

    
310
  QgsVectorLayer* lyr = NULL;
311
  QCheckBox* checkBox = NULL;
312
  int totalInvalid = 0;
313
  if ( isTarget )
314
  {
315
    lyr = mLayerTarget;
316
    checkBox = ckbUsingSelectedTarget;
317
    totalInvalid = mFeatureInvalidTarget.size();
318
  }
319
  else
320
  {
321
    lyr = mLayerReference;
322
    checkBox = ckbUsingSelectedReference;
323
    totalInvalid = mFeatureInvalidReference.size();
324
  }
325

    
326

    
327
  QString sDescFeatures = checkBox->isChecked()
328
                          ? tr( "%1 of %2(selected features)" ).arg( totalInvalid ).arg( lyr->selectedFeatureCount() )
329
                          : tr( "%1 of %2" ).arg( totalInvalid ).arg( lyr->featureCount() );
330

    
331
  return QString( "%1: %2" ).arg( lyr->name() ).arg( sDescFeatures );
332

    
333
} // QString QgsSpatialQueryDialog::getDescriptionInvalidFeatures(bool isTarget)
334

    
335
void QgsSpatialQueryDialog::connectAll()
336
{
337
  connect( QgsMapLayerRegistry::instance(), SIGNAL( layerWasAdded( QgsMapLayer* ) ),
338
           this, SLOT( signal_qgis_layerWasAdded( QgsMapLayer* ) ) ) ;
339
  connect( QgsMapLayerRegistry::instance(), SIGNAL( layerWillBeRemoved( QString ) ),
340
           this, SLOT( signal_qgis_layerWillBeRemoved( QString ) ) );
341
  connect( ckbLogProcessing, SIGNAL( clicked( bool ) ),
342
           this, SLOT( on_ckbLogProcessing_clicked( bool ) ) );
343

    
344
} // QgsSpatialQueryDialog::connectAll()
345

    
346
void QgsSpatialQueryDialog::disconnectAll()
347
{
348
  disconnect( QgsMapLayerRegistry::instance(), SIGNAL( layerWasAdded( QgsMapLayer* ) ),
349
              this, SLOT( signal_qgis_layerWasAdded( QgsMapLayer* ) ) ) ;
350
  disconnect( QgsMapLayerRegistry::instance(), SIGNAL( layerWillBeRemoved( QString ) ),
351
              this, SLOT( signal_qgis_layerWillBeRemoved( QString ) ) );
352

    
353
  if ( mLayerTarget )
354
  {
355
    disconnect( mLayerTarget, SIGNAL( selectionChanged() ),
356
                this, SLOT( signal_layerTarget_selectionFeaturesChanged() ) );
357

    
358
  }
359
  if ( mLayerReference )
360
  {
361
    disconnect( mLayerReference, SIGNAL( selectionChanged() ),
362
                this, SLOT( signal_layerReference_selectionFeaturesChanged() ) );
363
  }
364

    
365
} // QgsSpatialQueryDialog::disconnectAll()
366

    
367
void QgsSpatialQueryDialog::reject()
368
{
369
  disconnectAll();
370

    
371
  mRubberSelectId->reset();
372
  mLayerTarget = mLayerReference = NULL;
373
  mFeatureResult.clear();
374
  mFeatureInvalidTarget.clear();
375
  mFeatureInvalidReference.clear();
376
  mMapIdVectorLayers.clear();
377

    
378
  QDialog::reject();
379

    
380
} // QgsSpatialQueryDialog::reject()
381

    
382
QgsVectorLayer * QgsSpatialQueryDialog::getLayerFromCombobox( bool isTarget, int index )
383
{
384
  QVariant data = isTarget
385
                  ? cbTargetLayer->itemData( index )
386
                  : cbReferenceLayer->itemData( index );
387
  QgsVectorLayer* lyr = static_cast<QgsVectorLayer*>( data.value<void *>() );
388
  return lyr;
389

    
390
} // QgsVectorLayer * QgsSpatialQueryDialog::getLayerFromCombobox(bool isTarget, int index)
391

    
392
QIcon QgsSpatialQueryDialog::getIconTypeGeometry( QGis::GeometryType geomType )
393
{
394
  QString theName;
395
  if ( geomType == QGis::Point )
396
  {
397
    theName = "/mIconPointLayer.png";
398
  }
399
  else if ( geomType == QGis::Line )
400
  {
401
    theName = "/mIconLineLayer.png";
402
  }
403
  else // Polygon
404
  {
405
    theName = "/mIconPolygonLayer.png";
406
  }
407
  // Copy from qgisapp.cpp
408
  QString myPreferredPath = QgsApplication::activeThemePath() + QDir::separator() + theName;
409
  QString myDefaultPath = QgsApplication::defaultThemePath() + QDir::separator() + theName;
410
  if ( QFile::exists( myPreferredPath ) )
411
  {
412
    return QIcon( myPreferredPath );
413
  }
414
  else if ( QFile::exists( myDefaultPath ) )
415
  {
416
    //could still return an empty icon if it
417
    //doesnt exist in the default theme either!
418
    return QIcon( myDefaultPath );
419
  }
420
  else
421
  {
422
    return QIcon();
423
  }
424

    
425
} // QIcon QgsSpatialQueryDialog::getIconTypeGeometry(int typeGeometry)
426

    
427
void QgsSpatialQueryDialog::addCbLayer( bool isTarget, QgsVectorLayer* lyr )
428
{
429
  QVariant item = QVariant::fromValue(( void * )lyr );
430
  QComboBox * cmb = isTarget ? cbTargetLayer : cbReferenceLayer;
431
  int idNew = cmb->count();
432
  QIcon icon = getIconTypeGeometry( lyr->geometryType() );
433
  cmb->addItem( icon, lyr->name(), item );
434
  cmb->setItemData( idNew, QVariant( lyr->source() ), Qt::ToolTipRole );
435

    
436
} // void QgsSpatialQueryDialog::removeLayerCombobox(bool isTarget, QgsVectorLayer* lyr)
437

    
438
int QgsSpatialQueryDialog::getCbIndexLayer( bool isTarget, QgsVectorLayer* lyr )
439
{
440
  QVariant item = QVariant::fromValue(( void * )lyr );
441
  QComboBox * cmb = isTarget ? cbTargetLayer : cbReferenceLayer;
442
  return cmb->findData( item );
443

    
444
} //
445

    
446
void QgsSpatialQueryDialog::removeLayer( bool isTarget, QgsVectorLayer* lyr )
447
{
448
  QComboBox * cmb = isTarget ? cbTargetLayer : cbReferenceLayer;
449
  cmb->blockSignals( true );
450
  // Remove Combobox
451
  int index = getCbIndexLayer( isTarget, lyr );
452
  if ( index > -1 )
453
  {
454
    cmb->removeItem( index );
455
  }
456
  else
457
  {
458
    return;
459
  }
460
  // Set Layers (Target or Reference)
461
  QgsVectorLayer* lyrThis = mLayerTarget;
462
  if ( !isTarget )
463
  {
464
    lyrThis = mLayerReference;
465
  }
466
  if ( lyr == lyrThis )
467
  {
468
    lyrThis = NULL;
469
    if ( cmb->count() > 0 )
470
    {
471
      cmb->setCurrentIndex( 0 );
472
      setLayer( isTarget, 0 );
473
      evaluateCheckBoxLayer( isTarget );
474
      if (isTarget)
475
      {
476
        if( gbResultQuery->isShown() )
477
        {
478
          visibleResult( false );
479
        }
480
      }
481
    }
482
  }
483
  cmb->blockSignals( false );
484

    
485
} // void QgsSpatialQueryDialog::removeLayer(bool isTarget, QgsVectorLayer* lyr)
486

    
487
void QgsSpatialQueryDialog::populateCbResulFor()
488
{
489
  cbResultFor->blockSignals( true );
490
  cbResultFor->clear();
491
  QVariant item;
492
  item = QVariant::fromValue( (int)selectedNew );
493
  cbResultFor->addItem( tr("Create new selection"), item );
494
  if( ! ckbUsingSelectedTarget->isChecked() )
495
  {
496
    item = QVariant::fromValue( (int)selectedAdd );
497
    cbResultFor->addItem( tr("Add to current selection"), item );
498
  }
499
  item = QVariant::fromValue( (int)selectedRemove );
500
  cbResultFor->addItem( tr("Remove from current selection"), item );
501
  cbResultFor->blockSignals( false );
502
} // void QgsSpatialQueryDialog::populateCbResulFor()
503

    
504
void QgsSpatialQueryDialog::populateTypeItems()
505
{
506
  QVariant item;
507
  cbTypeItems->blockSignals( true );
508
  item = QVariant::fromValue( (int)itemsResult );
509
  cbTypeItems->addItem( tr("Result query"), item );
510
  item = QVariant::fromValue( (int)itemsInvalidTarget );
511
  cbTypeItems->addItem( tr("Invalid source"), item );
512
  item = QVariant::fromValue( (int)itemsInvalidReference );
513
  cbTypeItems->addItem( tr("Invalid reference"), item );
514
  cbTypeItems->blockSignals( false );
515
}
516

    
517
void QgsSpatialQueryDialog::populateCbTargetLayer()
518
{
519
  cbTargetLayer->blockSignals( true );
520

    
521
  QMap <QString, QgsMapLayer*> map = QgsMapLayerRegistry::instance()->mapLayers();
522
  QMapIterator <QString, QgsMapLayer*> item( map );
523
  QgsMapLayer * mapLayer = NULL;
524
  QgsVectorLayer * lyr = NULL;
525
  QString layerId;
526
  while ( item.hasNext() )
527
  {
528
    item.next();
529
    mapLayer = item.value();
530
    if ( mapLayer->type() != QgsMapLayer::VectorLayer )
531
    {
532
      continue;
533
    }
534
    lyr = qobject_cast<QgsVectorLayer *>( mapLayer );
535
    if ( !lyr )
536
    {
537
      continue;
538
    }
539

    
540
    addCbLayer( true, lyr );
541
    mMapIdVectorLayers.insert( lyr->getLayerID(), lyr );
542
  }
543
  cbTargetLayer->setCurrentIndex( 0 );
544
  cbTargetLayer->blockSignals( false );
545

    
546
} // void QgsSpatialQueryDialog::populateCbTargetLayer()
547

    
548
void QgsSpatialQueryDialog::populateCbReferenceLayer()
549
{
550
  cbReferenceLayer->blockSignals( true );
551
  cbReferenceLayer->clear();
552

    
553
  // Populate new values and Set current item keeping the previous value
554
  QString itemText;
555
  QVariant itemData;
556
  QIcon itemIcon;
557
  QgsVectorLayer * lyr = NULL;
558
  int idNew = 0;
559
  for ( int id = 0; id < cbTargetLayer->count(); id++ )
560
  {
561
    itemText = cbTargetLayer->itemText( id );
562
    itemData = cbTargetLayer->itemData( id );
563
    itemIcon = cbTargetLayer->itemIcon( id );
564
    lyr = static_cast<QgsVectorLayer *>( itemData.value<void *>() );
565
    if ( lyr == mLayerTarget )
566
    {
567
      continue;
568
    }
569
    cbReferenceLayer->addItem( itemIcon, itemText, itemData );
570
    cbReferenceLayer->setItemData( idNew, QVariant( lyr->source() ), Qt::ToolTipRole );
571
    idNew++;
572
  }
573
  int idCurrent = getCbIndexLayer( false, mLayerReference );
574
  if ( idCurrent == -1 )
575
  {
576
    idCurrent = 0;
577
  }
578
  cbReferenceLayer->setCurrentIndex( idCurrent );
579
  cbReferenceLayer->blockSignals( false );
580

    
581
} // QgsSpatialQueryDialog::populateCbReferenceLayer()
582

    
583
void QgsSpatialQueryDialog::populateCbOperation()
584
{
585
  cbOperantion->blockSignals( true );
586

    
587
  if ( mLayerTarget == NULL || mLayerReference == NULL )
588
  {
589
    cbOperantion->clear();
590
    cbOperantion->blockSignals( true );
591
  }
592

    
593
  QVariant currentValueItem;
594
  bool isStartEmpty = false;
595
  if ( cbOperantion->count() == 0 )
596
  {
597
    isStartEmpty = true;
598
  }
599
  else
600
  {
601
    currentValueItem = cbOperantion->itemData( cbOperantion->currentIndex() );
602
  }
603

    
604
  // Populate new values
605
  QMap<QString, int> * map = QgsSpatialQuery::getTypesOperations( mLayerTarget, mLayerReference );
606
  QMapIterator <QString, int> item( *map );
607
  cbOperantion->clear();
608
  while ( item.hasNext() )
609
  {
610
    item.next();
611
    cbOperantion->addItem( item.key(), QVariant( item.value() ) );
612
  }
613
  delete map;
614

    
615
  // Set current item keeping the previous value
616
  int idCurrent = 0;
617
  if ( !isStartEmpty )
618
  {
619
    idCurrent = cbOperantion->findData( currentValueItem );
620
    if ( idCurrent == -1 )
621
    {
622
      idCurrent = 0;
623
    }
624
  }
625
  cbOperantion->setCurrentIndex( idCurrent );
626
  cbOperantion->blockSignals( false );
627

    
628
} // QgsSpatialQueryDialog::populatecbOperantion()
629

    
630
void QgsSpatialQueryDialog::setSelectedGui()
631
{
632
  int selectedFeat = mLayerTarget->selectedFeatureCount();
633
  int totalFeat = mLayerTarget->featureCount();
634
  QString formatLabel( tr("%1 of %2 selected"));
635
  lbStatusSelected->setText( formatLabel.arg( selectedFeat ).arg( totalFeat ) );
636
  pbCreateLayerSelected->setEnabled( selectedFeat > 0 );
637
} // void QgsSpatialQueryDialog::setSelectedGui()
638

    
639
void QgsSpatialQueryDialog::changeLwFeature( QgsVectorLayer* lyr, int fid )
640
{
641
  lwFeatures->setEnabled( false ); // The showRubberFeature can be slow
642
  showRubberFeature( lyr, fid );
643
  // Zoom
644
  if( ckbZoomItem->isChecked() )
645
  {
646
    zoomFeature(lyr, fid);
647
  }
648
  lwFeatures->setEnabled( true );
649
  lwFeatures->setFocus();
650
} // void QgsSpatialQueryDialog::changeLwFeature( QListWidget *listWidget, QgsVectorLayer* lyr, int fid )
651

    
652
void QgsSpatialQueryDialog::zoomFeature(QgsVectorLayer* lyr, int fid)
653
{
654
  static QgsVectorLayer* lyrCheck = NULL;
655
  static bool hasMsg = false;
656
  if( ! lyrCheck || lyrCheck != lyr )
657
  {
658
    lyrCheck = lyr;
659
    hasMsg = true;
660
  }
661
  else
662
  {
663
    hasMsg = false;
664
  }
665

    
666
  QgsFeature feat;
667
  if ( !lyr->featureAtId( fid, feat, true, false ) )
668
  {
669
    return;
670
  }
671
  if ( !feat.geometry() )
672
  {
673
    return;
674
  }
675
  // Set system reference
676
 QgsCoordinateReferenceSystem srsSource = lyr->dataProvider()->crs();
677
  QgsCoordinateReferenceSystem srcMapcanvas = mIface->mapCanvas()->mapRenderer()->destinationSrs();
678
  if( ! srsSource.isValid() )
679
  {
680
    if( hasMsg )
681
    {
682
      long epsgMapcanvas = srcMapcanvas.epsg();
683
      bool isFly = mIface->mapCanvas()->mapRenderer()->hasCrsTransformEnabled();
684
      QString msgFly = tr("Map \"%1\" \"on the fly\" transformation.").arg( isFly ? tr( "enable" ) : tr( "disable") );
685
      QString msg = tr("Coordinate reference system(CRS) of\n\"%1\" is invalid(see CRS of provider).").arg( lyr->name() );
686
      msg.append( tr("\n\nEPSG of map is %1.\n%2.").arg( epsgMapcanvas ).arg( msgFly ) );
687
      msg.append("\n\nUsing CRS of map for all features!");
688

    
689
      QMessageBox::warning(this, tr( "Zoom to feature" ), msg, QMessageBox::Ok );
690
    }
691
    mIface->mapCanvas()->setExtent( feat.geometry()->boundingBox() );
692
  }
693
  else if ( srsSource == srcMapcanvas)
694
  {
695
     mIface->mapCanvas()->setExtent( feat.geometry()->boundingBox() );
696
  }
697
  else
698
  {
699
    QgsCoordinateTransform * coordTransform =  new QgsCoordinateTransform( srsSource, srcMapcanvas );
700
    QgsRectangle rectExtent = coordTransform->transform( feat.geometry()->boundingBox() );
701
    delete coordTransform;
702
    mIface->mapCanvas()->setExtent( rectExtent );
703
  }
704
  mIface->mapCanvas()->refresh();
705
} // void QgsSpatialQueryDialog::zoomFeatureTarget(QgsVectorLayer* lyr, int fid)
706

    
707
void QgsSpatialQueryDialog::showRubberFeature( QgsVectorLayer* lyr, int id )
708
{
709
  mRubberSelectId->reset();
710

    
711
  Qt::CursorShape shapeCurrent = cursor().shape();
712

    
713
  QCursor c;
714
  c.setShape( Qt::WaitCursor );
715
  setCursor( c );
716

    
717
  mRubberSelectId->addFeature( lyr, id );
718
  mRubberSelectId->show();
719

    
720
  c.setShape( shapeCurrent );
721
  setCursor( c );
722
} // void QgsSpatialQueryDialog::showRubberFeature( QgsVectorLayer* lyr, int id )
723

    
724
void QgsSpatialQueryDialog::apply()
725
{
726
  if ( ! mLayerReference )
727
  {
728
    QMessageBox::warning( 0, tr( "Missing reference layer" ), tr( "Select reference layer!" ), QMessageBox::Ok );
729
    return;
730
  }
731
  if ( ! mLayerTarget )
732
  {
733
    QMessageBox::warning( 0, tr( "Missing target layer" ), tr( "Select target layer!" ), QMessageBox::Ok );
734
    return;
735
  }
736

    
737
  QDateTime datetimeStart = QDateTime::currentDateTime();
738
  runQuery();
739
  QDateTime datetimeEnd = QDateTime::currentDateTime();
740
  showResultQuery( &datetimeStart, &datetimeEnd );
741
  visibleResult( true );
742
} // void QgsSpatialQueryDialog::apply()
743

    
744
void QgsSpatialQueryDialog::visibleResult( bool show )
745
{
746
  if( show == false)
747
  {
748
    mRubberSelectId->reset();
749
  }
750
  lineSeparator->setVisible( show );
751
  gbResultQuery->setVisible( show );
752
  lbStatusSelected->setVisible( show );
753
  pbCreateLayerSelected->setVisible( show );
754
  ckbLogProcessing->setVisible(  show );
755
  pgbStatus->setVisible( !show );
756
  adjustSize();
757
} // void QgsSpatialQueryDialog::visibleResult( bool show )
758

    
759
//! Slots for signs of Dialog
760
void QgsSpatialQueryDialog::on_bbMain_clicked( QAbstractButton * button)
761
{
762
  switch( bbMain->buttonRole( button ) )
763
  {
764
    case QDialogButtonBox::ApplyRole:
765
      apply();
766
      break;
767
    case QDialogButtonBox::DestructiveRole:
768
    case QDialogButtonBox::RejectRole:
769
      reject();
770
      break;
771
    default:
772
      return;
773
  }
774
} // QgsSpatialQueryDialog::on_bbMain_accepted()
775

    
776
void QgsSpatialQueryDialog::on_pbCreateLayerItems_clicked()
777
{
778
  TypeItems typeItem = (TypeItems) cbTypeItems->itemData( cbTypeItems->currentItem() ).toInt();
779
  QSet<int> * fids = 0;
780
  switch( typeItem )
781
  {
782
    case itemsResult:
783
      fids = &mFeatureResult;
784
      break;
785
    case itemsInvalidTarget:
786
      fids = &mFeatureInvalidTarget;
787
      break;
788
    case itemsInvalidReference:
789
      fids = &mFeatureInvalidReference;
790
      break;
791
    default:
792
      return;
793
  }
794
  QString title = tr( "Create new layer from items" );
795
  QString msg;
796
  QString fieldFID;
797
  TypeVerifyCreateSubset verify = verifyCreateSubset( msg, fieldFID );
798
  if( verify == verifyImpossible )
799
  {
800
    QMessageBox::critical(this, title, msg, QMessageBox::Ok );
801
    return;
802
  }
803
  if( verify == verifyTry )
804
  {
805
    QMessageBox::warning(this, title, msg, QMessageBox::Ok );
806
  }
807

    
808
  QString subset = getSubsetFIDs(  fids, fieldFID );
809
  QString name = QString("%1 < %2 > %3").arg( mLayerTarget->name() ).arg( cbOperantion->currentText() ).arg( mLayerReference->name() );
810
  if( ! addLayerSubset( name, subset ) )
811
  {
812
    msg = tr("The query from \"%1\" using \"%2\" in field not possible.").arg( mLayerTarget->name() ).arg( fieldFID );
813
    QMessageBox::critical(this, title, msg, QMessageBox::Ok );
814
  }
815
} // void QgsSpatialQueryDialog::on_pbCreateLayerItems_clicked()
816

    
817
void QgsSpatialQueryDialog::on_pbCreateLayerSelected_clicked()
818
{
819
  const QSet < int > *fids = & ( mLayerTarget->selectedFeaturesIds() );
820
  QString title = tr( "Create new layer from selected" );
821
  QString msg;
822
  QString fieldFID;
823
  TypeVerifyCreateSubset verify = verifyCreateSubset( msg, fieldFID );
824
  if( verify == verifyImpossible )
825
  {
826
    QMessageBox::critical(this, title, msg, QMessageBox::Ok );
827
    return;
828
  }
829
  if( verify == verifyTry )
830
  {
831
    QMessageBox::warning(this, title, msg, QMessageBox::Ok );
832
  }
833

    
834
  QString subset = getSubsetFIDs(  fids, fieldFID );
835
  QString name = QString("%1 selected").arg( mLayerTarget->name() );
836
  if( ! addLayerSubset( name, subset ) )
837
  {
838
    msg = tr("The query from \"%1\" using \"%2\" in field not possible.").arg( mLayerTarget->name() ).arg( fieldFID );
839
    QMessageBox::critical(this, title, msg, QMessageBox::Ok );
840
  }
841
} // void QgsSpatialQueryDialog::on_pbCreateLayerSelected_clicked()
842

    
843
void QgsSpatialQueryDialog::on_cbTargetLayer_currentIndexChanged( int index )
844
{
845
  // Add old target layer in reference combobox
846
  addCbLayer( false, mLayerTarget );
847

    
848
  // Set target layer
849
  setLayer( true, index );
850
  evaluateCheckBoxLayer( true );
851
  setSelectedGui();
852

    
853
  // Remove new target layer in reference combobox
854
  removeLayer( false, mLayerTarget );
855

    
856
  populateCbOperation();
857

    
858
  if( gbResultQuery->isShown() )
859
  {
860
    visibleResult( false );
861
  }
862
} // QgsSpatialQueryDialog::on_cbTargetLayer_currentIndexChanged(int index)
863

    
864
void QgsSpatialQueryDialog::on_cbReferenceLayer_currentIndexChanged( int index )
865
{
866
  setLayer( false, index );
867
  evaluateCheckBoxLayer( false );
868

    
869
  populateCbOperation();
870

    
871
  if( gbResultQuery->isShown() )
872
  {
873
    visibleResult( false );
874
  }
875
} // QgsSpatialQueryDialog::on_cbReferenceLayer_currentIndexChanged(int index);
876

    
877
void QgsSpatialQueryDialog::on_cbTypeItems_currentIndexChanged( int index )
878
{
879
  // Get Value type Item
880
  QVariant qtypItem = cbTypeItems->itemData( index );
881
  TypeItems typeItem = (TypeItems) qtypItem.toInt();
882

    
883
  QSet<int> * setItems = 0;
884
  switch( typeItem )
885
  {
886
    case itemsResult:
887
      setItems = &mFeatureResult;
888
      break;
889
    case itemsInvalidTarget:
890
      setItems = &mFeatureInvalidTarget;
891
      break;
892
    case itemsInvalidReference:
893
      setItems = &mFeatureInvalidReference;
894
      break;
895
    default:
896
      return;
897
  }
898

    
899
  lwFeatures->blockSignals( true );
900
  lwFeatures->clear();
901
  int totalItens = setItems->size();
902
  if ( totalItens > 0 )
903
  {
904
    // Populate lwFeatures
905
    QSetIterator <int>item( *setItems );
906
    QListWidgetItem *lwItem = NULL;
907
    while ( item.hasNext() )
908
    {
909
      lwItem = new QListWidgetItem(lwFeatures);
910
      QVariant fid  = QVariant( item.next() );
911
      lwItem->setData( Qt::UserRole, fid ); // Data
912
      lwItem->setData( Qt::DisplayRole, fid ); // Label
913
      lwFeatures->addItem( lwItem );
914
    }
915
    lwFeatures->sortItems();
916
    lwFeatures->blockSignals( false );
917
    lwFeatures->setCurrentRow(0);
918
  }
919
  else
920
  {
921
    mRubberSelectId->reset();
922
    lwFeatures->blockSignals( false );
923
  }
924
  // Set lbStatusItems and pbCreateLayer
925
  QString formatLabel( tr("Total %1"));
926
  lbStatusItems->setText( formatLabel.arg( totalItens ) );
927
  pbCreateLayerItems->setEnabled( totalItens > 0 );
928
  ckbZoomItem->setEnabled( totalItens > 0 );
929
}
930

    
931
void QgsSpatialQueryDialog::on_cbResultFor_currentIndexChanged()
932
{
933
  if( gbResultQuery->isShown() )
934
  {
935
    visibleResult( false );
936
  }
937
} // void QgsSpatialQueryDialog::on_cbResultFor_currentIndexChanged()
938

    
939
void QgsSpatialQueryDialog::on_lwFeatures_currentItemChanged( QListWidgetItem * item )
940
{
941
  TypeItems typeItem = (TypeItems)( cbTypeItems->itemData( cbTypeItems->currentItem() ).toInt() );
942
  QgsVectorLayer *lyr = typeItem == itemsInvalidReference
943
                        ? mLayerReference : mLayerTarget;
944
  int fid = item->data(Qt::UserRole).toInt();
945
  changeLwFeature( lyr, fid );
946
} // void QgsSpatialQueryDialog::on_lwFeatures_currentItemChanged( QListWidgetItem * item )
947

    
948
void QgsSpatialQueryDialog::on_ckbUsingSelectedTarget_toggled()
949
{
950
  populateCbResulFor();
951
} // void QgsSpatialQueryDialog::on_ckbUsingSelectedTarget_clicked( bool checked )
952

    
953
void QgsSpatialQueryDialog::on_ckbLogProcessing_clicked( bool checked )
954
{
955
  teStatus->setVisible( checked );
956
  adjustSize();
957

    
958
} // void QgsSpatialQueryDialog::on_ckbLogProcessing_clicked(bool checked)
959

    
960
void QgsSpatialQueryDialog::on_ckbZoomItem_clicked( bool checked )
961
{
962
  if( checked )
963
  {
964
    if( lwFeatures->count() > 0 )
965
    {
966
      int fid = lwFeatures->currentItem()->data(Qt::UserRole).toInt();
967
      TypeItems typeItem = (TypeItems)( cbTypeItems->itemData( cbTypeItems->currentItem() ).toInt() );
968
      QgsVectorLayer *lyr = typeItem == itemsInvalidReference
969
                            ? mLayerReference : mLayerTarget;
970
      zoomFeature(lyr, fid);
971
    }
972
  }
973
} // QgsSpatialQueryDialog::on_ckbZoomItem_clicked( bool checked )
974

    
975
//! Slots for signs of QGIS
976
void QgsSpatialQueryDialog::signal_qgis_layerWasAdded( QgsMapLayer* mapLayer )
977
{
978
  if ( mapLayer->type() != QgsMapLayer::VectorLayer )
979
  {
980
    return;
981
  }
982
  QgsVectorLayer * lyr = qobject_cast<QgsVectorLayer *>( mapLayer );
983
  if ( !lyr )
984
  {
985
    return;
986
  }
987
  addCbLayer( true, lyr );
988
  if ( cbTargetLayer->count() > 1 && bbMain->button( QDialogButtonBox::Apply )->isHidden() )
989
  {
990
    bbMain->button( QDialogButtonBox::Apply )->show();
991
    cbOperantion->setEnabled( true );
992
    cbResultFor->setEnabled( true );
993
  }
994
  addCbLayer( false, lyr );
995
  mMapIdVectorLayers.insert( lyr->getLayerID(), lyr );
996

    
997
} // QgsSpatialQueryDialog::signal_qgis_layerWasAdded(QgsMapLayer* mapLayer)
998

    
999
void QgsSpatialQueryDialog::signal_qgis_layerWillBeRemoved( QString idLayer )
1000
{
1001
  // If Frozen: the QGis can be: Exit, Add Project, New Project
1002
  if ( mIface->mapCanvas()->isFrozen() )
1003
  {
1004
    reject();
1005
  }
1006
  // idLayer = QgsMapLayer::getLayerID()
1007
  // Get Pointer layer removed
1008
  QMap<QString, QgsVectorLayer *>::const_iterator i = mMapIdVectorLayers.find( idLayer );
1009
  if ( i == mMapIdVectorLayers.end() )
1010
  {
1011
    return;
1012
  }
1013
  mMapIdVectorLayers.remove( idLayer );
1014
  QgsVectorLayer *lyr = i.value();
1015
  removeLayer( true, lyr ); // set new target if need
1016
  removeLayer( false, lyr ); // set new reference if need
1017
  if ( mLayerTarget && getCbIndexLayer( cbReferenceLayer, mLayerTarget ) > -1 )
1018
  {
1019
    removeLayer( false, mLayerTarget );
1020
  }
1021

    
1022
  if( cbTargetLayer->count() < 2 )
1023
  {
1024
    bbMain->button( QDialogButtonBox::Apply )->hide();
1025
    cbOperantion->setEnabled( false );
1026
    cbResultFor->setEnabled( false );
1027
    if( gbResultQuery->isShown() )
1028
    {
1029
      visibleResult( false );
1030
    }
1031

    
1032
    mLayerReference = NULL;
1033
    if( cbTargetLayer->count() < 1 )
1034
    {
1035
      mLayerTarget = NULL;
1036
    }
1037
  }
1038
  else
1039
  {
1040
    populateCbOperation();
1041
  }
1042

    
1043
} // QgsSpatialQueryDialog::signal_qgis_layerWillBeRemoved(QString idLayer)
1044

    
1045
//! Slots for signals of Layers (Target or Reference)
1046
void QgsSpatialQueryDialog::signal_layerTarget_selectionFeaturesChanged()
1047
{
1048
  evaluateCheckBoxLayer( true );
1049
  setSelectedGui();
1050
} // void QgsSpatialQueryDialog::signal_layerTarget_selectionFeaturesChanged()
1051

    
1052
void QgsSpatialQueryDialog::signal_layerReference_selectionFeaturesChanged()
1053
{
1054
  evaluateCheckBoxLayer( false );
1055

    
1056
} // void QgsSpatialQueryDialog::signal_layerReference_selectionFeaturesChanged()
1057

    
1058
void QgsSpatialQueryDialog::MsgDEBUG( QString sMSg )
1059
{
1060
  QMessageBox::warning( 0, tr( "DEBUG" ), sMSg, QMessageBox::Ok );
1061
}