1414 ***************************************************************************/
1515/* $Id$ */
1616
17+ #include < QDomDocument>
18+ #include < QDomElement>
19+ #include < QFileDialog>
20+ #include < QFileInfo>
21+ #include < QInputDialog>
1722#include < QListView>
1823#include < QMessageBox>
24+ #include < QSettings>
1925#include < QStandardItem>
26+ #include < QTextStream>
2027#include " qgsfeature.h"
2128#include " qgsfield.h"
2229#include " qgssearchquerybuilder.h"
@@ -43,6 +50,16 @@ QgsSearchQueryBuilder::QgsSearchQueryBuilder( QgsVectorLayer* layer,
4350 buttonBox->addButton ( pbn, QDialogButtonBox::ActionRole );
4451 connect ( pbn, SIGNAL ( clicked () ), this , SLOT ( on_btnClear_clicked () ) );
4552
53+ pbn = new QPushButton ( tr ( " &Save..." ) );
54+ buttonBox->addButton ( pbn, QDialogButtonBox::ActionRole );
55+ pbn->setToolTip ( tr ( " Save query to an xml file" ) );
56+ connect ( pbn, SIGNAL ( clicked () ), this , SLOT ( saveQuery () ) );
57+
58+ pbn = new QPushButton ( tr ( " &Load..." ) );
59+ buttonBox->addButton ( pbn, QDialogButtonBox::ActionRole );
60+ pbn->setToolTip ( tr ( " Load query from xml file" ) );
61+ connect ( pbn, SIGNAL ( clicked () ), this , SLOT ( loadQuery () ) );
62+
4663 // disable unsupported operators
4764 btnIn->setHidden ( true );
4865 btnNotIn->setHidden ( true );
@@ -327,3 +344,132 @@ void QgsSearchQueryBuilder::on_btnILike_clicked()
327344 txtSQL->insertPlainText ( " ~ " );
328345}
329346
347+ void QgsSearchQueryBuilder::saveQuery ()
348+ {
349+ QSettings s;
350+ QString lastQueryFileDir = s.value ( " /UI/lastQueryFileDir" , " " ).toString ();
351+ // save as qqt (QGIS query file)
352+ QString saveFileName = QFileDialog::getSaveFileName ( 0 , tr ( " Save query to file" ), lastQueryFileDir, " *.qqf" );
353+ if ( saveFileName.isNull () )
354+ {
355+ return ;
356+ }
357+
358+ QFile saveFile ( saveFileName );
359+ if ( !saveFile.open ( QIODevice::WriteOnly ) )
360+ {
361+ QMessageBox::critical ( 0 , tr ( " Error" ), tr ( " Could not open file for writing" ) );
362+ return ;
363+ }
364+
365+ QDomDocument xmlDoc;
366+ QDomElement queryElem = xmlDoc.createElement ( " Query" );
367+ QDomText queryTextNode = xmlDoc.createTextNode ( txtSQL->toPlainText () );
368+ queryElem.appendChild ( queryTextNode );
369+ xmlDoc.appendChild ( queryElem );
370+
371+ QTextStream fileStream ( &saveFile );
372+ xmlDoc.save ( fileStream, 2 );
373+
374+ QFileInfo fi ( saveFile );
375+ s.setValue ( " /UI/lastQueryFileDir" , fi.absolutePath () );
376+ }
377+
378+ void QgsSearchQueryBuilder::loadQuery ()
379+ {
380+ QSettings s;
381+ QString lastQueryFileDir = s.value ( " /UI/lastQueryFileDir" , " " ).toString ();
382+
383+ QString queryFileName = QFileDialog::getOpenFileName ( 0 , tr ( " Load query from file" ), lastQueryFileDir, tr ( " Query files" ) + " (*.qqf);;" + tr ( " All files" ) + " (*)" );
384+ if ( queryFileName.isNull () )
385+ {
386+ return ;
387+ }
388+
389+ QFile queryFile ( queryFileName );
390+ if ( !queryFile.open ( QIODevice::ReadOnly ) )
391+ {
392+ QMessageBox::critical ( 0 , tr ( " Error" ), tr ( " Could not open file for reading" ) );
393+ return ;
394+ }
395+ QDomDocument queryDoc;
396+ if ( !queryDoc.setContent ( &queryFile ) )
397+ {
398+ QMessageBox::critical ( 0 , tr ( " Error" ), tr ( " File is not a valid xml document" ) );
399+ return ;
400+ }
401+
402+ QDomElement queryElem = queryDoc.firstChildElement ( " Query" );
403+ if ( queryElem.isNull () )
404+ {
405+ QMessageBox::critical ( 0 , tr ( " Error" ), tr ( " File is not a valid query document" ) );
406+ return ;
407+ }
408+
409+ QString query = queryElem.text ();
410+
411+ // todo: test if all the attributes are valid
412+ QgsSearchString search;
413+ if ( !search.setString ( query ) )
414+ {
415+ QMessageBox::critical ( this , tr ( " Search string parsing error" ), search.parserErrorMsg () );
416+ return ;
417+ }
418+
419+ QgsSearchTreeNode* searchTree = search.tree ();
420+ if ( !searchTree )
421+ {
422+ QMessageBox::critical ( this , tr ( " Error creating search tree" ), search.parserErrorMsg () );
423+ return ;
424+ }
425+
426+ QStringList attributes = searchTree->referencedColumns ();
427+ QMap< QString, QString> attributesToReplace;
428+ QStringList existingAttributes;
429+
430+ // get all existing fields
431+ QMap<QString, int >::const_iterator fieldIt = mFieldMap .constBegin ();
432+ for ( ; fieldIt != mFieldMap .constEnd (); ++fieldIt )
433+ {
434+ existingAttributes.push_back ( fieldIt.key () );
435+ }
436+
437+ // if a field does not exist, ask what field should be used instead
438+ QStringList::const_iterator attIt = attributes.constBegin ();
439+ for ( ; attIt != attributes.constEnd (); ++attIt )
440+ {
441+ // test if attribute is there
442+ if ( !mFieldMap .contains ( *attIt ) )
443+ {
444+ bool ok;
445+ 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 ),
446+ existingAttributes, 0 , false , &ok );
447+ if ( !ok || replaceAttribute.isEmpty () )
448+ {
449+ return ;
450+ }
451+ attributesToReplace.insert ( *attIt, replaceAttribute );
452+ }
453+ }
454+
455+ // Now replace all the string in the query
456+ QList<QgsSearchTreeNode*> columnRefList = searchTree->columnRefNodes ();
457+ QList<QgsSearchTreeNode*>::iterator columnIt = columnRefList.begin ();
458+ for ( ; columnIt != columnRefList.end (); ++columnIt )
459+ {
460+ QMap< QString, QString>::const_iterator replaceIt = attributesToReplace.find (( *columnIt )->columnRef () );
461+ if ( replaceIt != attributesToReplace.constEnd () )
462+ {
463+ ( *columnIt )->setColumnRef ( replaceIt.value () );
464+ }
465+ }
466+
467+ txtSQL->clear ();
468+ QString newQueryText = query;
469+ if ( attributesToReplace.size () > 0 )
470+ {
471+ newQueryText = searchTree->makeSearchString ();
472+ }
473+ txtSQL->insertPlainText ( newQueryText );
474+ }
475+
0 commit comments