17 #include <QDomDocument>
18 #include <QDomElement>
19 #include <QFileDialog>
21 #include <QInputDialog>
23 #include <QMessageBox>
25 #include <QStandardItem>
26 #include <QTextStream>
36 QWidget *parent, Qt::WFlags fl )
37 : QDialog( parent, fl ), mLayer( layer )
42 setWindowTitle( tr(
"Search query builder" ) );
44 QPushButton *pbn =
new QPushButton( tr(
"&Test" ) );
45 buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
48 pbn =
new QPushButton( tr(
"&Clear" ) );
49 buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
52 pbn =
new QPushButton( tr(
"&Save..." ) );
53 buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
54 pbn->setToolTip( tr(
"Save query to an xml file" ) );
55 connect( pbn, SIGNAL( clicked() ),
this, SLOT(
saveQuery() ) );
57 pbn =
new QPushButton( tr(
"&Load..." ) );
58 buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
59 pbn->setToolTip( tr(
"Load query from xml file" ) );
60 connect( pbn, SIGNAL( clicked() ),
this, SLOT(
loadQuery() ) );
63 lblDataUri->setText( layer->
name() );
78 QRegExp reQuote(
"[A-Za-z_][A-Za-z0-9_]*" );
80 for ( QgsFieldMap::const_iterator it = fields.begin(); it != fields.end(); ++it )
82 QString fieldName = it->name();
84 if ( !reQuote.exactMatch( fieldName ) )
86 QStandardItem *myItem =
new QStandardItem( fieldName );
87 myItem->setEditable(
false );
101 lstFields->setViewMode( QListView::ListMode );
102 lstValues->setViewMode( QListView::ListMode );
103 lstFields->setSelectionBehavior( QAbstractItemView::SelectRows );
104 lstValues->setSelectionBehavior( QAbstractItemView::SelectRows );
106 lstFields->setUniformItemSizes(
true );
107 lstValues->setUniformItemSizes(
true );
120 QString fieldName =
mModelFields->data( lstFields->currentIndex() ).toString();
123 bool numeric = ( field.
type() == QVariant::Int || field.
type() == QVariant::Double );
129 attrs.append( fieldIndex );
133 lstValues->setCursor( Qt::WaitCursor );
136 lstValues->setUpdatesEnabled(
false );
139 QSet<QString> insertedValues;
145 value = attributes[fieldIndex].toString();
150 value =
"'" + value.replace(
"'",
"''" ) +
"'";
154 if ( !insertedValues.contains( value ) )
156 QStandardItem *myItem =
new QStandardItem( value );
157 myItem->setEditable(
false );
159 insertedValues.insert( value );
164 lstValues->setUpdatesEnabled(
true );
167 lstValues->setCursor( Qt::ArrowCursor );
188 QMessageBox::information(
this, tr(
"Search results" ), tr(
"Found %n matching feature(s).",
"test result", count ) );
197 QMessageBox::critical(
this, tr(
"Search string parsing error" ), search.
parserErrorMsg() );
213 QApplication::setOverrideCursor( Qt::WaitCursor );
233 QApplication::restoreOverrideCursor();
237 QMessageBox::critical(
this, tr(
"Error during search" ), searchTree->
errorMsg() );
248 if ( txtSQL->toPlainText().trimmed().length() > 0 )
260 else if ( numRecs == 0 )
262 QMessageBox::warning(
this, tr(
"No Records" ), tr(
"The query you specified results in zero records being returned." ) );
273 txtSQL->insertPlainText(
" = " );
278 txtSQL->insertPlainText(
" < " );
283 txtSQL->insertPlainText(
" > " );
288 txtSQL->insertPlainText(
"%" );
293 txtSQL->insertPlainText(
" IN " );
298 txtSQL->insertPlainText(
" NOT IN " );
303 txtSQL->insertPlainText(
" LIKE " );
308 return txtSQL->toPlainText();
313 txtSQL->setPlainText( searchString );
318 txtSQL->insertPlainText(
mModelFields->data( index ).toString() );
323 txtSQL->insertPlainText(
mModelValues->data( index ).toString() );
328 txtSQL->insertPlainText(
" <= " );
333 txtSQL->insertPlainText(
" >= " );
338 txtSQL->insertPlainText(
" != " );
343 txtSQL->insertPlainText(
" AND " );
348 txtSQL->insertPlainText(
" NOT " );
353 txtSQL->insertPlainText(
" OR " );
363 txtSQL->insertPlainText(
" ILIKE " );
369 QString lastQueryFileDir = s.value(
"/UI/lastQueryFileDir",
"" ).toString();
371 QString saveFileName = QFileDialog::getSaveFileName( 0, tr(
"Save query to file" ), lastQueryFileDir,
"*.qqf" );
372 if ( saveFileName.isNull() )
377 if ( !saveFileName.endsWith(
".qqf", Qt::CaseInsensitive ) )
379 saveFileName +=
".qqf";
382 QFile saveFile( saveFileName );
383 if ( !saveFile.open( QIODevice::WriteOnly ) )
385 QMessageBox::critical( 0, tr(
"Error" ), tr(
"Could not open file for writing" ) );
390 QDomElement queryElem = xmlDoc.createElement(
"Query" );
391 QDomText queryTextNode = xmlDoc.createTextNode( txtSQL->toPlainText() );
392 queryElem.appendChild( queryTextNode );
393 xmlDoc.appendChild( queryElem );
395 QTextStream fileStream( &saveFile );
396 xmlDoc.save( fileStream, 2 );
398 QFileInfo fi( saveFile );
399 s.setValue(
"/UI/lastQueryFileDir", fi.absolutePath() );
405 QString lastQueryFileDir = s.value(
"/UI/lastQueryFileDir",
"" ).toString();
407 QString queryFileName = QFileDialog::getOpenFileName( 0, tr(
"Load query from file" ), lastQueryFileDir, tr(
"Query files" ) +
"(*.qqf);;" + tr(
"All files" ) +
"(*)" );
408 if ( queryFileName.isNull() )
413 QFile queryFile( queryFileName );
414 if ( !queryFile.open( QIODevice::ReadOnly ) )
416 QMessageBox::critical( 0, tr(
"Error" ), tr(
"Could not open file for reading" ) );
419 QDomDocument queryDoc;
420 if ( !queryDoc.setContent( &queryFile ) )
422 QMessageBox::critical( 0, tr(
"Error" ), tr(
"File is not a valid xml document" ) );
426 QDomElement queryElem = queryDoc.firstChildElement(
"Query" );
427 if ( queryElem.isNull() )
429 QMessageBox::critical( 0, tr(
"Error" ), tr(
"File is not a valid query document" ) );
433 QString query = queryElem.text();
439 QMessageBox::critical(
this, tr(
"Search string parsing error" ), search.
parserErrorMsg() );
446 QMessageBox::critical(
this, tr(
"Error creating search tree" ), search.
parserErrorMsg() );
451 QMap< QString, QString> attributesToReplace;
452 QStringList existingAttributes;
455 QMap<QString, int>::const_iterator fieldIt =
mFieldMap.constBegin();
456 for ( ; fieldIt !=
mFieldMap.constEnd(); ++fieldIt )
458 existingAttributes.push_back( fieldIt.key() );
462 QStringList::const_iterator attIt = attributes.constBegin();
463 for ( ; attIt != attributes.constEnd(); ++attIt )
469 QString replaceAttribute = QInputDialog::getItem( 0, tr(
"Select attribute" ), tr(
"There is no attribute '%1' in the current vector layer. Please select an existing attribute" ).arg( *attIt ),
470 existingAttributes, 0,
false, &ok );
471 if ( !ok || replaceAttribute.isEmpty() )
475 attributesToReplace.insert( *attIt, replaceAttribute );
480 QList<QgsSearchTreeNode*> columnRefList = searchTree->
columnRefNodes();
481 QList<QgsSearchTreeNode*>::iterator columnIt = columnRefList.begin();
482 for ( ; columnIt != columnRefList.end(); ++columnIt )
484 QMap< QString, QString>::const_iterator replaceIt = attributesToReplace.find(( *columnIt )->columnRef() );
485 if ( replaceIt != attributesToReplace.constEnd() )
487 ( *columnIt )->setColumnRef( replaceIt.value() );
492 QString newQueryText = query;
493 if ( attributesToReplace.size() > 0 )
497 txtSQL->insertPlainText( newQueryText );