[QGIS Commit] r13571 - in trunk/qgis: python/core src/app src/core
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Tue May 25 09:57:05 EDT 2010
Author: mhugent
Date: 2010-05-25 09:57:05 -0400 (Tue, 25 May 2010)
New Revision: 13571
Modified:
trunk/qgis/python/core/qgssearchtreenode.sip
trunk/qgis/src/app/qgssearchquerybuilder.cpp
trunk/qgis/src/app/qgssearchquerybuilder.h
trunk/qgis/src/core/qgssearchtreenode.cpp
trunk/qgis/src/core/qgssearchtreenode.h
Log:
[FEATURE]: Load/save queries created in the query builder. Added method columnRefNodes() in qgssearchtreenode and added some consts
Modified: trunk/qgis/python/core/qgssearchtreenode.sip
===================================================================
--- trunk/qgis/python/core/qgssearchtreenode.sip 2010-05-25 11:29:12 UTC (rev 13570)
+++ trunk/qgis/python/core/qgssearchtreenode.sip 2010-05-25 13:57:05 UTC (rev 13571)
@@ -65,19 +65,19 @@
~QgsSearchTreeNode();
//! returns type of current node
- Type type();
+ Type type() const;
//! node value getters
- Operator op();
- double number();
- QString columnRef();
- QString string();
+ Operator op() const;
+ double number() const;
+ QString columnRef() const;
+ QString string() const;
//! node value setters (type is set also)
void setOp( Operator o );
void setNumber( double number );
- void setColumnRef( QString& str );
- void setString( QString& str );
+ void setColumnRef( const QString& str );
+ void setString( const QString& str );
//! children
QgsSearchTreeNode* Left();
@@ -107,6 +107,10 @@
//! @note added in 1.5
QStringList referencedColumns();
+ //! return a list of all attribute nodes
+ //! @note added in 1.5
+ QList<QgsSearchTreeNode*> columnRefNodes();
+
//! check whether there are any operators that need geometry (for area, length)
//! @note added in 1.5
bool needsGeometry();
Modified: trunk/qgis/src/app/qgssearchquerybuilder.cpp
===================================================================
--- trunk/qgis/src/app/qgssearchquerybuilder.cpp 2010-05-25 11:29:12 UTC (rev 13570)
+++ trunk/qgis/src/app/qgssearchquerybuilder.cpp 2010-05-25 13:57:05 UTC (rev 13571)
@@ -14,9 +14,16 @@
***************************************************************************/
/* $Id$ */
+#include <QDomDocument>
+#include <QDomElement>
+#include <QFileDialog>
+#include <QFileInfo>
+#include <QInputDialog>
#include <QListView>
#include <QMessageBox>
+#include <QSettings>
#include <QStandardItem>
+#include <QTextStream>
#include "qgsfeature.h"
#include "qgsfield.h"
#include "qgssearchquerybuilder.h"
@@ -43,6 +50,16 @@
buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
connect( pbn, SIGNAL( clicked() ), this, SLOT( on_btnClear_clicked() ) );
+ pbn = new QPushButton( tr( "&Save..." ) );
+ buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
+ pbn->setToolTip( tr( "Save query to an xml file" ) );
+ connect( pbn, SIGNAL( clicked() ), this, SLOT( saveQuery() ) );
+
+ pbn = new QPushButton( tr( "&Load..." ) );
+ buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
+ pbn->setToolTip( tr( "Load query from xml file" ) );
+ connect( pbn, SIGNAL( clicked() ), this, SLOT( loadQuery() ) );
+
// disable unsupported operators
btnIn->setHidden( true );
btnNotIn->setHidden( true );
@@ -327,3 +344,132 @@
txtSQL->insertPlainText( " ~ " );
}
+void QgsSearchQueryBuilder::saveQuery()
+{
+ QSettings s;
+ QString lastQueryFileDir = s.value( "/UI/lastQueryFileDir", "" ).toString();
+ //save as qqt (QGIS query file)
+ QString saveFileName = QFileDialog::getSaveFileName( 0, tr( "Save query to file" ), lastQueryFileDir, "*.qqf" );
+ if ( saveFileName.isNull() )
+ {
+ return;
+ }
+
+ QFile saveFile( saveFileName );
+ if ( !saveFile.open( QIODevice::WriteOnly ) )
+ {
+ QMessageBox::critical( 0, tr( "Error" ), tr( "Could not open file for writing" ) );
+ return;
+ }
+
+ QDomDocument xmlDoc;
+ QDomElement queryElem = xmlDoc.createElement( "Query" );
+ QDomText queryTextNode = xmlDoc.createTextNode( txtSQL->toPlainText() );
+ queryElem.appendChild( queryTextNode );
+ xmlDoc.appendChild( queryElem );
+
+ QTextStream fileStream( &saveFile );
+ xmlDoc.save( fileStream, 2 );
+
+ QFileInfo fi( saveFile );
+ s.setValue( "/UI/lastQueryFileDir", fi.absolutePath() );
+}
+
+void QgsSearchQueryBuilder::loadQuery()
+{
+ QSettings s;
+ QString lastQueryFileDir = s.value( "/UI/lastQueryFileDir", "" ).toString();
+
+ QString queryFileName = QFileDialog::getOpenFileName( 0, tr( "Load query from file" ), lastQueryFileDir, tr( "Query files" ) + "(*.qqf);;" + tr( "All files" ) + "(*)" );
+ if ( queryFileName.isNull() )
+ {
+ return;
+ }
+
+ QFile queryFile( queryFileName );
+ if ( !queryFile.open( QIODevice::ReadOnly ) )
+ {
+ QMessageBox::critical( 0, tr( "Error" ), tr( "Could not open file for reading" ) );
+ return;
+ }
+ QDomDocument queryDoc;
+ if ( !queryDoc.setContent( &queryFile ) )
+ {
+ QMessageBox::critical( 0, tr( "Error" ), tr( "File is not a valid xml document" ) );
+ return;
+ }
+
+ QDomElement queryElem = queryDoc.firstChildElement( "Query" );
+ if ( queryElem.isNull() )
+ {
+ QMessageBox::critical( 0, tr( "Error" ), tr( "File is not a valid query document" ) );
+ return;
+ }
+
+ QString query = queryElem.text();
+
+ //todo: test if all the attributes are valid
+ QgsSearchString search;
+ if ( !search.setString( query ) )
+ {
+ QMessageBox::critical( this, tr( "Search string parsing error" ), search.parserErrorMsg() );
+ return;
+ }
+
+ QgsSearchTreeNode* searchTree = search.tree();
+ if ( !searchTree )
+ {
+ QMessageBox::critical( this, tr( "Error creating search tree" ), search.parserErrorMsg() );
+ return;
+ }
+
+ QStringList attributes = searchTree->referencedColumns();
+ QMap< QString, QString> attributesToReplace;
+ QStringList existingAttributes;
+
+ //get all existing fields
+ QMap<QString, int>::const_iterator fieldIt = mFieldMap.constBegin();
+ for ( ; fieldIt != mFieldMap.constEnd(); ++fieldIt )
+ {
+ existingAttributes.push_back( fieldIt.key() );
+ }
+
+ //if a field does not exist, ask what field should be used instead
+ QStringList::const_iterator attIt = attributes.constBegin();
+ for ( ; attIt != attributes.constEnd(); ++attIt )
+ {
+ //test if attribute is there
+ if ( !mFieldMap.contains( *attIt ) )
+ {
+ bool ok;
+ 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 ),
+ existingAttributes, 0, false, &ok );
+ if ( !ok || replaceAttribute.isEmpty() )
+ {
+ return;
+ }
+ attributesToReplace.insert( *attIt, replaceAttribute );
+ }
+ }
+
+ //Now replace all the string in the query
+ QList<QgsSearchTreeNode*> columnRefList = searchTree->columnRefNodes();
+ QList<QgsSearchTreeNode*>::iterator columnIt = columnRefList.begin();
+ for ( ; columnIt != columnRefList.end(); ++columnIt )
+ {
+ QMap< QString, QString>::const_iterator replaceIt = attributesToReplace.find(( *columnIt )->columnRef() );
+ if ( replaceIt != attributesToReplace.constEnd() )
+ {
+ ( *columnIt )->setColumnRef( replaceIt.value() );
+ }
+ }
+
+ txtSQL->clear();
+ QString newQueryText = query;
+ if ( attributesToReplace.size() > 0 )
+ {
+ newQueryText = searchTree->makeSearchString();
+ }
+ txtSQL->insertPlainText( newQueryText );
+}
+
Modified: trunk/qgis/src/app/qgssearchquerybuilder.h
===================================================================
--- trunk/qgis/src/app/qgssearchquerybuilder.h 2010-05-25 11:29:12 UTC (rev 13570)
+++ trunk/qgis/src/app/qgssearchquerybuilder.h 2010-05-25 13:57:05 UTC (rev 13571)
@@ -87,6 +87,9 @@
*/
void on_btnSampleValues_clicked();
+ void saveQuery();
+ void loadQuery();
+
private:
/*!
Modified: trunk/qgis/src/core/qgssearchtreenode.cpp
===================================================================
--- trunk/qgis/src/core/qgssearchtreenode.cpp 2010-05-25 11:29:12 UTC (rev 13570)
+++ trunk/qgis/src/core/qgssearchtreenode.cpp 2010-05-25 13:57:05 UTC (rev 13571)
@@ -228,25 +228,36 @@
QStringList QgsSearchTreeNode::referencedColumns()
{
+ QList<QgsSearchTreeNode*> columnNodeList = columnRefNodes();
+ QSet<QString> columnStringSet;
+
+ QList<QgsSearchTreeNode*>::const_iterator nodeIt = columnNodeList.constBegin();
+ for ( ; nodeIt != columnNodeList.constEnd(); ++nodeIt )
+ {
+ columnStringSet.insert(( *nodeIt )->columnRef() );
+ }
+ return columnStringSet.toList();
+}
+
+QList<QgsSearchTreeNode*> QgsSearchTreeNode::columnRefNodes()
+{
+ QList<QgsSearchTreeNode*> nodeList;
if ( mType == tOperator )
{
- QStringList lst;
if ( mLeft )
- lst += mLeft->referencedColumns();
+ {
+ nodeList += mLeft->columnRefNodes();
+ }
if ( mRight )
- lst += mRight->referencedColumns();
- return lst.toSet().toList(); // make union and convert back to list
+ {
+ nodeList += mRight->columnRefNodes();
+ }
}
else if ( mType == tColumnRef )
{
- return QStringList( mText );
+ nodeList.push_back( this );
}
- else
- {
- // string or number - do nothing
- return QStringList();
- }
-
+ return nodeList;
}
bool QgsSearchTreeNode::needsGeometry()
Modified: trunk/qgis/src/core/qgssearchtreenode.h
===================================================================
--- trunk/qgis/src/core/qgssearchtreenode.h 2010-05-25 11:29:12 UTC (rev 13570)
+++ trunk/qgis/src/core/qgssearchtreenode.h 2010-05-25 13:57:05 UTC (rev 13571)
@@ -103,19 +103,19 @@
~QgsSearchTreeNode();
//! returns type of current node
- Type type() { return mType; }
+ Type type() const { return mType; }
//! node value getters
- Operator op() { return mOp; }
- double number() { return mNumber; }
- QString columnRef() { return mText; }
- QString string() { return mText; }
+ Operator op() const { return mOp; }
+ double number() const { return mNumber; }
+ QString columnRef() const { return mText; }
+ QString string() const { return mText; }
//! node value setters (type is set also)
void setOp( Operator op ) { mType = tOperator; mOp = op; }
void setNumber( double number ) { mType = tNumber; mNumber = number; }
- void setColumnRef( QString& str ) { mType = tColumnRef; mText = str; }
- void setString( QString& str ) { mType = tString; mText = str; stripText(); }
+ void setColumnRef( const QString& str ) { mType = tColumnRef; mText = str; }
+ void setString( const QString& str ) { mType = tString; mText = str; stripText(); }
//! children
QgsSearchTreeNode* Left() { return mLeft; }
@@ -145,6 +145,10 @@
//! @note added in 1.5
QStringList referencedColumns();
+ //! return a list of all attribute nodes
+ //! @note added in 1.5
+ QList<QgsSearchTreeNode*> columnRefNodes();
+
//! check whether there are any operators that need geometry (for area, length)
//! @note added in 1.5
bool needsGeometry();
More information about the QGIS-commit
mailing list