class FinderDock(QDockWidget , Ui_quickFinder ): startSearch = pyqtSignal(QgsVectorLayer,int,str,int,int) def __init__(self,iface): self.iface = iface QDockWidget.__init__(self) self.setupUi(self) self.iface.addDockWidget(Qt.LeftDockWidgetArea,self) self.layerComboManager = LayerCombo(iface, self.layerCombo) self.fieldComboManager = FieldCombo(self.fieldCombo, self.layerComboManager) QObject.connect(self.layerCombo, SIGNAL("currentIndexChanged(int)"), self.layerChanged) QObject.connect(self.modeButtonGroup, SIGNAL("buttonClicked(int)"), self.layerChanged) QObject.connect(self.fieldCombo, SIGNAL("currentIndexChanged(int)"), self.layerChanged) self.layer = None self.operatorBox.hide() self.processWidgetGroup.hide() self.layerChanged(0) self.setVisible(False) def layerChanged(self,i): self.modeWidgetGroup.setEnabled(False) self.searchWidgetGroup.setEnabled(False) self.idLine.clear() self.layer = self.layerComboManager.getLayer() if self.layer is None: return self.modeWidgetGroup.setEnabled(True) if self.fieldButton.isChecked() and self.fieldCombo.currentIndex()==0: return self.searchWidgetGroup.setEnabled(True) self.on_selectBox_clicked() @pyqtSignature("on_selectBox_clicked()") def on_selectBox_clicked(self): if self.layer is None or not self.selectBox.isChecked(): self.panBox.setEnabled(False) self.scaleBox.setEnabled(False) else: self.panBox.setEnabled( self.layer.hasGeometryType() ) self.scaleBox.setEnabled( self.layer.hasGeometryType() ) @pyqtSignature("on_cancelButton_pressed()") def on_cancelButton_pressed(self): self.continueSearch = False @pyqtSignature("on_goButton_pressed()") def on_goButton_pressed(self): i = self.layerCombo.currentIndex() if i < 1 or self.layer is None: return toFind = self.idLine.text() f = QgsFeature() if self.idButton.isChecked(): id,ok = toFind.toInt() if ok is False: QMessageBox.warning( self.iface.mainWindow() , "Quick Finder","ID must be strictly composed of digits." ) return try: if self.layer.getFeatures( QgsFeatureRequest().setFilterFid( id ) ).nextFeature( f ) is False: return except: # qgis <1.9 if self.layer.dataProvider().featureAtId(id,f,True,self.layer.dataProvider().attributeIndexes()) is False: return self.processResults( [f.id()] ) else: results = [] fieldName = self.fieldComboManager.getFieldName() fieldIndex = self.fieldComboManager.getFieldIndex() if fieldName=="": return operator = self.operatorBox.currentIndex() # show progress bar self.progressBar.setMinimum(0) self.progressBar.setMaximum(self.layer.featureCount()) self.progressBar.setValue(0) self.processWidgetGroup.show() # disable rest of UI self.layerWidgetGroup.setEnabled(False) self.modeWidgetGroup.setEnabled(False) self.searchWidgetGroup.setEnabled(False) # create feature request try: featReq = QgsFeatureRequest() featReq.setSubsetOfAttributes( [fieldIndex] ) iter = self.layer.getFeatures(featReq) except: iter = self.layer.dataProvider() iter.select( [fieldIndex] ) # process k=0 self.continueSearch = True while( iter.nextFeature( f ) and self.continueSearch): k+=1 try: value = f.attribute( fieldName ) except: value = f.attributeMap()[fieldIndex] if self.evaluate(value, toFind, operator): results.append( f.id() ) self.progressBar.setValue(k) QCoreApplication.processEvents() # reset UI self.processWidgetGroup.hide() self.layerWidgetGroup.setEnabled(True) self.modeWidgetGroup.setEnabled(True) self.searchWidgetGroup.setEnabled(True) # process results if self.continueSearch: self.processResults( results ) def evaluate(self, v1, v2, operator): if operator == 0: return v1.toString() == v2 elif operator == 1: return v1.toDouble()[0] == v2.toDouble()[0] elif operator == 2: return v1.toDouble()[0] <= v2.toDouble()[0] elif operator == 3: return v1.toDouble()[0] >= v2.toDouble()[0] elif operator == 4: return v1.toDouble()[0] < v2.toDouble()[0] elif operator == 5: return v1.toDouble()[0] > v2.toDouble()[0] elif operator == 6: return v1.toString().contains(v2, Qt.CaseInsensitive) def processResults(self, results): if self.layer is None: return if self.selectBox.isChecked(): self.layer.setSelectedFeatures(results) if len(results)==0: return if self.panBox.isEnabled() and self.panBox.isChecked(): canvas = self.iface.mapCanvas() rect = canvas.mapRenderer().layerExtentToOutputExtent( self.layer, self.layer.boundingBoxOfSelected() ) if self.scaleBox.isChecked(): canvas.setExtent( rect ) else: canvas.setExtent( QgsRectangle( rect.center(), rect.center() ) ) canvas.refresh() if self.formBox.isChecked(): nResults = len(results) if nResults > 25: return if nResults > 3: reply = QMessageBox.question( self.iface.mainWindow() , "Quick Finder", "%s results were found. Are you sure to open the %s feature forms ?" % (nResults,nResults), QMessageBox.Yes, QMessageBox.No ) if reply == QMessageBox.No: return f = QgsFeature() try: for id in results: if self.layer.getFeatures( QgsFeatureRequest().setFilterFid( id ) ).nextFeature( f ): self.iface.openFeatureForm(self.layer, f ) except: for id in results: if self.layer.featureAtId(id, f): self.iface.openFeatureForm(self.layer, f )