[QGIS Commit] r11735 - in trunk/qgis: images/themes/default src/app
src/core src/ui
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Wed Sep 30 03:14:57 EDT 2009
Author: mhugent
Date: 2009-09-30 03:14:54 -0400 (Wed, 30 Sep 2009)
New Revision: 11735
Added:
trunk/qgis/images/themes/default/mActionCalculateField.png
trunk/qgis/src/app/qgsfieldcalculator.cpp
trunk/qgis/src/app/qgsfieldcalculator.h
trunk/qgis/src/ui/qgsfieldcalculatorbase.ui
Modified:
trunk/qgis/src/app/CMakeLists.txt
trunk/qgis/src/app/qgsvectorlayerproperties.cpp
trunk/qgis/src/app/qgsvectorlayerproperties.h
trunk/qgis/src/core/qgssearchstringlexer.ll
trunk/qgis/src/core/qgssearchstringparser.yy
trunk/qgis/src/core/qgssearchtreenode.cpp
trunk/qgis/src/core/qgssearchtreenode.h
trunk/qgis/src/ui/qgsvectorlayerpropertiesbase.ui
Log:
[FEATURE]: A field calculator, accessible with a button in the attribute section of the vector properties
Added: trunk/qgis/images/themes/default/mActionCalculateField.png
===================================================================
(Binary files differ)
Property changes on: trunk/qgis/images/themes/default/mActionCalculateField.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Modified: trunk/qgis/src/app/CMakeLists.txt
===================================================================
--- trunk/qgis/src/app/CMakeLists.txt 2009-09-29 14:52:50 UTC (rev 11734)
+++ trunk/qgis/src/app/CMakeLists.txt 2009-09-30 07:14:54 UTC (rev 11735)
@@ -20,6 +20,7 @@
qgsspatialitefilterproxymodel.cpp
qgsspatialitetablemodel.cpp
qgsdelattrdialog.cpp
+ qgsfieldcalculator.cpp
qgsnewvectorlayerdialog.cpp
qgsgraduatedsymboldialog.cpp
qgshelpviewer.cpp
@@ -122,6 +123,7 @@
qgsconfigureshortcutsdialog.h
qgscustomprojectiondialog.h
qgsdelattrdialog.h
+ qgsfieldcalculator.h
qgsnewvectorlayerdialog.h
qgsgraduatedsymboldialog.h
qgshelpviewer.h
Added: trunk/qgis/src/app/qgsfieldcalculator.cpp
===================================================================
--- trunk/qgis/src/app/qgsfieldcalculator.cpp (rev 0)
+++ trunk/qgis/src/app/qgsfieldcalculator.cpp 2009-09-30 07:14:54 UTC (rev 11735)
@@ -0,0 +1,353 @@
+/***************************************************************************
+ qgsfieldcalculator.cpp
+ ---------------------
+ begin : September 2009
+ copyright : (C) 2009 by Marco Hugentobler
+ email : marco at hugis dot net
+ ***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "qgsfieldcalculator.h"
+#include "qgssearchtreenode.h"
+#include "qgssearchstring.h"
+#include "qgsvectorlayer.h"
+#include <QMessageBox>
+
+QgsFieldCalculator::QgsFieldCalculator( QgsVectorLayer* vl ): QDialog(), mVectorLayer( vl )
+{
+ setupUi( this );
+ mOutputFieldTypeComboBox->addItem( tr( "Double" ) );
+ mOutputFieldTypeComboBox->addItem( tr( "Integer" ) );
+ mOutputFieldTypeComboBox->addItem( tr( "String" ) );
+
+ populateFields();
+
+ //default values for field width and precision
+ mOuputFieldWidthSpinBox->setValue( 10 );
+ mOutputFieldPrecisionSpinBox->setValue( 3 );
+
+ //disable ok button until there is text for output field and expression
+ mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( false );
+}
+
+QgsFieldCalculator::~QgsFieldCalculator()
+{
+
+}
+
+void QgsFieldCalculator::accept()
+{
+ if ( mVectorLayer && mVectorLayer->isEditable() )
+ {
+ QString calcString = mExpressionTextEdit->toPlainText();
+
+ //create QgsSearchString
+ QgsSearchString searchString;
+ if ( !searchString.setString( calcString ) )
+ {
+ //expression not valid
+ QMessageBox::critical( 0, tr( "Syntax error" ), tr( QString( "Invalid expression syntax. The error message of the parser is: '" + searchString.parserErrorMsg() + "'" ).toLocal8Bit().data() ) );
+ return;
+ }
+
+ //get QgsSearchTreeNode
+ QgsSearchTreeNode* searchTree = searchString.tree();
+ if ( !searchTree )
+ {
+ return;
+ }
+
+ mVectorLayer->beginEditCommand( "Field calculator" );
+
+ //create new field
+ QgsField newField( mOutputFieldNameLineEdit->text() );
+ if ( mOutputFieldTypeComboBox->currentText() == tr( "Double" ) )
+ {
+ newField.setType( QVariant::Double );
+ }
+ else if ( mOutputFieldTypeComboBox->currentText() == tr( "Integer" ) )
+ {
+ newField.setType( QVariant::Int );
+ }
+ else if ( mOutputFieldTypeComboBox->currentText() == tr( "String" ) )
+ {
+ newField.setType( QVariant::String );
+ }
+
+ newField.setLength( mOuputFieldWidthSpinBox->value() );
+ newField.setPrecision( mOutputFieldPrecisionSpinBox->value() );
+
+
+ if ( !mVectorLayer->addAttribute( newField ) )
+ {
+ mVectorLayer->destroyEditCommand();
+ return;
+ }
+
+ //get index of the new field
+ const QgsFieldMap fieldList = mVectorLayer->pendingFields();
+ int attributeId = -1;
+ QgsFieldMap::const_iterator it = fieldList.constBegin();
+ for ( ; it != fieldList.constEnd(); ++it )
+ {
+ if ( it.value().name() == mOutputFieldNameLineEdit->text() )
+ {
+ attributeId = it.key();
+ break;
+ }
+ }
+ if ( attributeId == -1 )
+ {
+ mVectorLayer->destroyEditCommand();
+ return;
+ }
+
+ //go through all the features and change the new attribute
+ QgsFeature feature;
+ bool calculationSuccess = true;
+
+ mVectorLayer->select( mVectorLayer->pendingAllAttributesList(), QgsRectangle(), false, false );
+ while ( mVectorLayer->nextFeature( feature ) )
+ {
+ QgsSearchTreeValue value = searchTree->valueAgainst( mVectorLayer->pendingFields(), feature.attributeMap() );
+ if ( value.isError() )
+ {
+ calculationSuccess = false;
+ break;
+ }
+ if ( value.isNumeric() )
+ {
+ mVectorLayer->changeAttributeValue( feature.id(), attributeId, value.number(), false );
+ }
+ else
+ {
+ mVectorLayer->changeAttributeValue( feature.id(), attributeId, value.string(), false );
+ }
+
+ }
+
+ if ( !calculationSuccess )
+ {
+ QMessageBox::critical( 0, tr( "Error" ), tr( "An error occured while evaluating the calculation string." ) );
+
+ //remove new attribute
+ mVectorLayer->deleteAttribute( attributeId );
+ mVectorLayer->destroyEditCommand();
+ return;
+ }
+
+ mVectorLayer->endEditCommand();
+ }
+ QDialog::accept();
+}
+
+void QgsFieldCalculator::populateFields()
+{
+ if ( !mVectorLayer )
+ {
+ return;
+ }
+
+ const QgsFieldMap fieldMap = mVectorLayer->pendingFields();
+ QgsFieldMap::const_iterator fieldIt = fieldMap.constBegin();
+ for ( ; fieldIt != fieldMap.constEnd(); ++fieldIt )
+ {
+ QString fieldName = fieldIt.value().name();
+ mFieldMap.insert( fieldName, fieldIt.key() );
+ mFieldsListWidget->addItem( fieldName );
+ }
+}
+
+void QgsFieldCalculator::on_mFieldsListWidget_itemDoubleClicked( QListWidgetItem * item )
+{
+ if ( !item )
+ {
+ return;
+ }
+ mExpressionTextEdit->insertPlainText( item->text() );
+}
+
+void QgsFieldCalculator::on_mValueListWidget_itemDoubleClicked( QListWidgetItem * item )
+{
+ if ( !item )
+ {
+ return;
+ }
+ mExpressionTextEdit->insertPlainText( " " + item->text() + " " );
+}
+
+void QgsFieldCalculator::on_mPlusPushButton_clicked()
+{
+ mExpressionTextEdit->insertPlainText( " + " );
+}
+
+void QgsFieldCalculator::on_mMinusPushButton_clicked()
+{
+ mExpressionTextEdit->insertPlainText( " - " );
+}
+
+void QgsFieldCalculator::on_mMultiplyPushButton_clicked()
+{
+ mExpressionTextEdit->insertPlainText( " * " );
+}
+
+void QgsFieldCalculator::on_mDividePushButton_clicked()
+{
+ mExpressionTextEdit->insertPlainText( " / " );
+}
+
+void QgsFieldCalculator::on_mSqrtButton_clicked()
+{
+ mExpressionTextEdit->insertPlainText( " sqrt ( " );
+}
+
+void QgsFieldCalculator::on_mExpButton_clicked()
+{
+ mExpressionTextEdit->insertPlainText( " ^ " );
+}
+
+void QgsFieldCalculator::on_mSinButton_clicked()
+{
+ mExpressionTextEdit->insertPlainText( " sin ( " );
+}
+
+void QgsFieldCalculator::on_mCosButton_clicked()
+{
+ mExpressionTextEdit->insertPlainText( " cos ( " );
+}
+
+void QgsFieldCalculator::on_mTanButton_clicked()
+{
+ mExpressionTextEdit->insertPlainText( " tan ( " );
+}
+
+void QgsFieldCalculator::on_mASinButton_clicked()
+{
+ mExpressionTextEdit->insertPlainText( " asin ( " );
+}
+
+void QgsFieldCalculator::on_mACosButton_clicked()
+{
+ mExpressionTextEdit->insertPlainText( " acos ( " );
+}
+
+void QgsFieldCalculator::on_mATanButton_clicked()
+{
+ mExpressionTextEdit->insertPlainText( " atan ( " );
+}
+
+void QgsFieldCalculator::on_mOpenBracketPushButton_clicked()
+{
+ mExpressionTextEdit->insertPlainText( " ( " );
+}
+
+void QgsFieldCalculator::on_mCloseBracketPushButton_clicked()
+{
+ mExpressionTextEdit->insertPlainText( " ) " );
+}
+
+void QgsFieldCalculator::on_mSamplePushButton_clicked()
+{
+ getFieldValues( 25 );
+}
+
+void QgsFieldCalculator::on_mAllPushButton_clicked()
+{
+ getFieldValues( 0 );
+}
+
+void QgsFieldCalculator::on_mOutputFieldNameLineEdit_textChanged( const QString& text )
+{
+ setOkButtonState();
+}
+
+void QgsFieldCalculator::on_mExpressionTextEdit_textChanged()
+{
+ setOkButtonState();
+}
+
+void QgsFieldCalculator::on_mOutputFieldTypeComboBox_currentIndexChanged( const QString& text )
+{
+ if ( text == tr( "Double" ) )
+ {
+ mOutputFieldPrecisionSpinBox->setEnabled( true );
+ }
+ else
+ {
+ mOutputFieldPrecisionSpinBox->setEnabled( false );
+ }
+}
+
+void QgsFieldCalculator::getFieldValues( int limit )
+{
+ mValueListWidget->clear();
+
+ if ( !mVectorLayer )
+ {
+ return;
+ }
+
+ QListWidgetItem* currentItem = mFieldsListWidget->currentItem();
+ if ( !currentItem )
+ {
+ return;
+ }
+
+ QMap<QString, int>::const_iterator attIt = mFieldMap.find( currentItem->text() );
+ if ( attIt == mFieldMap.constEnd() )
+ {
+ return;
+ }
+
+ int attributeIndex = attIt.value();
+ QgsField field = mVectorLayer->pendingFields()[attributeIndex];
+ bool numeric = ( field.type() == QVariant::Int || field.type() == QVariant::Double );
+
+ QgsAttributeList attList;
+ attList << attributeIndex;
+
+ mVectorLayer->select( attList, QgsRectangle(), false );
+ QgsFeature f;
+ int resultCounter = 0;
+
+ mValueListWidget->setUpdatesEnabled( false );
+ mValueListWidget->blockSignals( true );
+ QSet<QString> insertedValues;
+
+ while ( mVectorLayer->nextFeature( f ) && ( limit == 0 || resultCounter != limit ) )
+ {
+ QString value = f.attributeMap()[attributeIndex].toString();
+ if ( !numeric )
+ {
+ value = ( "'" + value + "'" );
+ }
+ //QList<QListWidgetItem *> existingItems = mValueListWidget->findItems(value, Qt::MatchExactly);
+ //if(existingItems.isEmpty())
+ if ( !insertedValues.contains( value ) )
+ {
+ mValueListWidget->addItem( value );
+ insertedValues.insert( value );
+ ++resultCounter;
+ }
+ }
+ mValueListWidget->setUpdatesEnabled( true );
+ mValueListWidget->blockSignals( false );
+}
+
+void QgsFieldCalculator::setOkButtonState()
+{
+ bool okEnabled = true;
+ if ( mOutputFieldNameLineEdit->text().isEmpty() || mExpressionTextEdit->toPlainText().isEmpty() )
+ {
+ okEnabled = false;
+ }
+ mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( okEnabled );
+}
+
+
Added: trunk/qgis/src/app/qgsfieldcalculator.h
===================================================================
--- trunk/qgis/src/app/qgsfieldcalculator.h (rev 0)
+++ trunk/qgis/src/app/qgsfieldcalculator.h 2009-09-30 07:14:54 UTC (rev 11735)
@@ -0,0 +1,71 @@
+/***************************************************************************
+ qgsfieldcalculator.h
+ ---------------------
+ begin : September 2009
+ copyright : (C) 2009 by Marco Hugentobler
+ email : marco at hugis dot net
+ ***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef QGSFIELDCALCULATOR_H
+#define QGSFIELDCALCULATOR_H
+
+#include "ui_qgsfieldcalculatorbase.h"
+
+class QgsVectorLayer;
+
+/**A dialog class that provides calculation of new fields using existing fields, values and a set of operators*/
+class QgsFieldCalculator: public QDialog, private Ui::QgsFieldCalculatorBase
+{
+ Q_OBJECT
+ public:
+ QgsFieldCalculator( QgsVectorLayer* vl );
+ ~QgsFieldCalculator();
+
+ public slots:
+ void accept();
+
+ void on_mFieldsListWidget_itemDoubleClicked( QListWidgetItem * item );
+ void on_mValueListWidget_itemDoubleClicked( QListWidgetItem * item );
+ void on_mPlusPushButton_clicked();
+ void on_mMinusPushButton_clicked();
+ void on_mMultiplyPushButton_clicked();
+ void on_mDividePushButton_clicked();
+ void on_mSqrtButton_clicked();
+ void on_mExpButton_clicked();
+ void on_mSinButton_clicked();
+ void on_mCosButton_clicked();
+ void on_mTanButton_clicked();
+ void on_mASinButton_clicked();
+ void on_mACosButton_clicked();
+ void on_mATanButton_clicked();
+ void on_mOpenBracketPushButton_clicked();
+ void on_mCloseBracketPushButton_clicked();
+ void on_mSamplePushButton_clicked();
+ void on_mAllPushButton_clicked();
+ void on_mOutputFieldNameLineEdit_textChanged( const QString& text );
+ void on_mExpressionTextEdit_textChanged();
+ void on_mOutputFieldTypeComboBox_currentIndexChanged( const QString& text );
+
+ private:
+ //default constructor forbidden
+ QgsFieldCalculator();
+ void populateFields();
+ /**Gets field values and inserts them into mValueListWidget
+ @limit 0: get all feature, != 0 stop after getting limit values*/
+ void getFieldValues( int limit );
+ /**Sets the ok button enabled / disabled*/
+ void setOkButtonState();
+
+ QgsVectorLayer* mVectorLayer;
+ /**Key: field name, Value: field index*/
+ QMap<QString, int> mFieldMap;
+};
+
+#endif // QGSFIELDCALCULATOR_H
Modified: trunk/qgis/src/app/qgsvectorlayerproperties.cpp
===================================================================
--- trunk/qgis/src/app/qgsvectorlayerproperties.cpp 2009-09-29 14:52:50 UTC (rev 11734)
+++ trunk/qgis/src/app/qgsvectorlayerproperties.cpp 2009-09-30 07:14:54 UTC (rev 11735)
@@ -26,6 +26,7 @@
#include "qgscontexthelp.h"
#include "qgscontinuouscolordialog.h"
#include "qgscoordinatetransform.h"
+#include "qgsfieldcalculator.h"
#include "qgsgraduatedsymboldialog.h"
#include "qgslabeldialog.h"
#include "qgslabel.h"
@@ -92,6 +93,7 @@
mAddAttributeButton->setIcon( QgisApp::getThemeIcon( "/mActionNewAttribute.png" ) );
mDeleteAttributeButton->setIcon( QgisApp::getThemeIcon( "/mActionDeleteAttribute.png" ) );
mToggleEditingButton->setIcon( QgisApp::getThemeIcon( "/mActionToggleEditing.png" ) );
+ mCalculateFieldButton->setIcon( QgisApp::getThemeIcon( "/mActionCalculateField.png" ) );
// Create the Label dialog tab
@@ -356,6 +358,7 @@
int cap = layer->dataProvider()->capabilities();
mAddAttributeButton->setEnabled( cap & QgsVectorDataProvider::AddAttributes );
mDeleteAttributeButton->setEnabled( cap & QgsVectorDataProvider::DeleteAttributes );
+ mCalculateFieldButton->setEnabled(( cap & QgsVectorDataProvider::AddAttributes ) && ( cap & QgsVectorDataProvider::ChangeAttributeValues ) );
mToggleEditingButton->setChecked( true );
}
else
@@ -363,6 +366,7 @@
mAddAttributeButton->setEnabled( false );
mDeleteAttributeButton->setEnabled( false );
mToggleEditingButton->setChecked( false );
+ mCalculateFieldButton->setEnabled( false );
}
}
@@ -1116,6 +1120,17 @@
}
}
+void QgsVectorLayerProperties::on_mCalculateFieldButton_clicked()
+{
+ if ( !layer )
+ {
+ return;
+ }
+
+ QgsFieldCalculator calc( layer );
+ calc.exec();
+}
+
QList<QgsVectorOverlayPlugin*> QgsVectorLayerProperties::overlayPlugins() const
{
QList<QgsVectorOverlayPlugin*> pluginList;
Modified: trunk/qgis/src/app/qgsvectorlayerproperties.h
===================================================================
--- trunk/qgis/src/app/qgsvectorlayerproperties.h 2009-09-29 14:52:50 UTC (rev 11734)
+++ trunk/qgis/src/app/qgsvectorlayerproperties.h 2009-09-30 07:14:54 UTC (rev 11735)
@@ -101,6 +101,7 @@
void on_pbnLoadStyle_clicked();
void on_pbnSaveStyleAs_clicked();
void on_tblAttributes_cellChanged( int row, int column );
+ void on_mCalculateFieldButton_clicked();
void addAttribute();
void deleteAttribute();
Modified: trunk/qgis/src/core/qgssearchstringlexer.ll
===================================================================
--- trunk/qgis/src/core/qgssearchstringlexer.ll 2009-09-29 14:52:50 UTC (rev 11734)
+++ trunk/qgis/src/core/qgssearchstringlexer.ll 2009-09-30 07:14:54 UTC (rev 11735)
@@ -68,8 +68,16 @@
"~" { yylval.op = QgsSearchTreeNode::opRegexp; return COMPARISON; }
"LIKE" { yylval.op = QgsSearchTreeNode::opLike; return COMPARISON; }
-[+-/*] { return yytext[0]; }
+"sqrt" { yylval.op = QgsSearchTreeNode::opSQRT; return FUNCTION;}
+"sin" { yylval.op = QgsSearchTreeNode::opSIN; return FUNCTION;}
+"cos" { yylval.op = QgsSearchTreeNode::opCOS; return FUNCTION;}
+"tan" { yylval.op = QgsSearchTreeNode::opTAN; return FUNCTION;}
+"asin" { yylval.op = QgsSearchTreeNode::opASIN; return FUNCTION;}
+"acos" { yylval.op = QgsSearchTreeNode::opACOS; return FUNCTION;}
+"atan" { yylval.op = QgsSearchTreeNode::opATAN; return FUNCTION;}
+[+-/*^] { return yytext[0]; }
+
[()] { return yytext[0]; }
{number} { yylval.number = atof(yytext); return NUMBER; }
Modified: trunk/qgis/src/core/qgssearchstringparser.yy
===================================================================
--- trunk/qgis/src/core/qgssearchstringparser.yy 2009-09-29 14:52:50 UTC (rev 11734)
+++ trunk/qgis/src/core/qgssearchstringparser.yy 2009-09-30 07:14:54 UTC (rev 11735)
@@ -52,7 +52,7 @@
%}
-%union { QgsSearchTreeNode* node; double number; QgsSearchTreeNode::Operator op; }
+%union { QgsSearchTreeNode* node; double number; QgsSearchTreeNode::Operator op;}
%start root
@@ -60,6 +60,7 @@
%token <number> NUMBER
%token <op> COMPARISON
+%token <op> FUNCTION
%token STRING
%token COLUMN_REF
@@ -82,6 +83,7 @@
// operator precedence
// all operators have left associativity
// (right associtativity is used for assigment)
+%left '^'
%left '*' '/'
%left '+' '-'
%left UMINUS // fictious symbol (for unary minus)
@@ -94,6 +96,7 @@
%%
root: search_cond { /*gParserRootNode = $1;*/ }
+ | scalar_exp {}
;
search_cond:
@@ -114,7 +117,9 @@
;
scalar_exp:
- scalar_exp '*' scalar_exp { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opMUL, $1, $3); joinTmpNodes($$,$1,$3); }
+ FUNCTION '(' scalar_exp ')' {$$ = new QgsSearchTreeNode($1, $3, 0); joinTmpNodes($$, $3, 0);}
+ | scalar_exp '^' scalar_exp { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opPOW, $1, $3); joinTmpNodes($$, $1, $3); }
+ | scalar_exp '*' scalar_exp { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opMUL, $1, $3); joinTmpNodes($$,$1,$3); }
| scalar_exp '/' scalar_exp { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opDIV, $1, $3); joinTmpNodes($$,$1,$3); }
| scalar_exp '+' scalar_exp { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opPLUS, $1, $3); joinTmpNodes($$,$1,$3); }
| scalar_exp '-' scalar_exp { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opMINUS,$1, $3); joinTmpNodes($$,$1,$3); }
Modified: trunk/qgis/src/core/qgssearchtreenode.cpp
===================================================================
--- trunk/qgis/src/core/qgssearchtreenode.cpp 2009-09-29 14:52:50 UTC (rev 11734)
+++ trunk/qgis/src/core/qgssearchtreenode.cpp 2009-09-30 07:14:54 UTC (rev 11735)
@@ -24,7 +24,14 @@
#include <QObject>
#include <iostream>
+#ifndef Q_OS_MACX
+#include <cmath>
+#else
+#include <math.h>
+#endif
+
+
#define EVAL_STR(x) (x.length() ? x : "(empty)")
QgsSearchTreeNode::QgsSearchTreeNode( double number )
@@ -154,7 +161,11 @@
default: str += " ? ";
}
- str += mRight->makeSearchString();
+
+ if ( mRight )
+ {
+ str += mRight->makeSearchString();
+ }
}
else
{
@@ -360,8 +371,14 @@
case tOperator:
{
QgsSearchTreeValue value1, value2;
- if ( !getValue( value1, mLeft, fields, attributes ) ) return value1;
- if ( !getValue( value2, mRight, fields, attributes ) ) return value2;
+ if ( mLeft )
+ {
+ if ( !getValue( value1, mLeft, fields, attributes ) ) return value1;
+ }
+ if ( mRight )
+ {
+ if ( !getValue( value2, mRight, fields, attributes ) ) return value2;
+ }
// convert to numbers if needed
double val1, val2;
@@ -389,6 +406,26 @@
return QgsSearchTreeValue( val1 / val2 );
default:
return QgsSearchTreeValue( 3, QString::number( mOp ) ); // unknown operator
+ case opPOW:
+ if (( val1 == 0 && val2 < 0 ) || ( val2 < 0 && ( val2 - std::floor( val2 ) ) > 0 ) )
+ {
+ return QgsSearchTreeValue( 4, "Error in power function" );
+ }
+ return QgsSearchTreeValue( std::pow( val1, val2 ) );
+ case opSQRT:
+ return QgsSearchTreeValue( std::sqrt( val1 ) );
+ case opSIN:
+ return QgsSearchTreeValue( std::sin( val1 ) );
+ case opCOS:
+ return QgsSearchTreeValue( std::cos( val1 ) );
+ case opTAN:
+ return QgsSearchTreeValue( std::tan( val1 ) );
+ case opASIN:
+ return QgsSearchTreeValue( std::asin( val1 ) );
+ case opACOS:
+ return QgsSearchTreeValue( std::acos( val1 ) );
+ case opATAN:
+ return QgsSearchTreeValue( std::atan( val1 ) );
}
}
Modified: trunk/qgis/src/core/qgssearchtreenode.h
===================================================================
--- trunk/qgis/src/core/qgssearchtreenode.h 2009-09-29 14:52:50 UTC (rev 11734)
+++ trunk/qgis/src/core/qgssearchtreenode.h 2009-09-30 07:14:54 UTC (rev 11735)
@@ -62,6 +62,14 @@
opMINUS,
opMUL,
opDIV,
+ opPOW,
+ opSQRT,
+ opSIN,
+ opCOS,
+ opTAN,
+ opASIN,
+ opACOS,
+ opATAN,
// comparison
opEQ, // =
@@ -118,11 +126,10 @@
//! returns error message
const QString& errorMsg() { return mError; }
- protected:
-
//! returns scalar value of node
QgsSearchTreeValue valueAgainst( const QgsFieldMap& fields, const QgsAttributeMap& attributes );
+ protected:
//! wrapper around valueAgainst()
bool getValue( QgsSearchTreeValue& value, QgsSearchTreeNode* node,
const QgsFieldMap& fields, const QgsAttributeMap& attributes );
Added: trunk/qgis/src/ui/qgsfieldcalculatorbase.ui
===================================================================
--- trunk/qgis/src/ui/qgsfieldcalculatorbase.ui (rev 0)
+++ trunk/qgis/src/ui/qgsfieldcalculatorbase.ui 2009-09-30 07:14:54 UTC (rev 11735)
@@ -0,0 +1,264 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>QgsFieldCalculatorBase</class>
+ <widget class="QDialog" name="QgsFieldCalculatorBase">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>383</width>
+ <height>496</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Field calculator</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_3">
+ <item row="0" column="0">
+ <widget class="QLabel" name="mFieldNameLabel">
+ <property name="text">
+ <string>Output field name:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QLineEdit" name="mOutputFieldNameLineEdit"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="mOutputFieldTypeLabel">
+ <property name="text">
+ <string>Output field type:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QComboBox" name="mOutputFieldTypeComboBox"/>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="mOutputFieldWidthLabel">
+ <property name="text">
+ <string>Output field width:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QSpinBox" name="mOuputFieldWidthSpinBox"/>
+ </item>
+ <item row="2" column="2">
+ <widget class="QLabel" name="mOutputFieldPrecisionLabel">
+ <property name="text">
+ <string>Output field precision:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="3">
+ <widget class="QSpinBox" name="mOutputFieldPrecisionSpinBox"/>
+ </item>
+ <item row="3" column="0" colspan="2">
+ <widget class="QGroupBox" name="mFieldsGroupBox">
+ <property name="title">
+ <string>Fields</string>
+ </property>
+ <widget class="QListWidget" name="mFieldsListWidget">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>20</y>
+ <width>221</width>
+ <height>151</height>
+ </rect>
+ </property>
+ </widget>
+ </widget>
+ </item>
+ <item row="3" column="2" colspan="2">
+ <widget class="QGroupBox" name="mValuesGroupBox">
+ <property name="title">
+ <string>Values</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0" colspan="2">
+ <widget class="QListWidget" name="mValueListWidget"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QPushButton" name="mSamplePushButton">
+ <property name="text">
+ <string>Sample</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QPushButton" name="mAllPushButton">
+ <property name="text">
+ <string>All</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="4" column="0" colspan="4">
+ <widget class="QGroupBox" name="mOperatorsGroupBox">
+ <property name="title">
+ <string>Operators</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QPushButton" name="mPlusPushButton">
+ <property name="text">
+ <string>+</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QPushButton" name="mMultiplyPushButton">
+ <property name="text">
+ <string>*</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QPushButton" name="mSqrtButton">
+ <property name="text">
+ <string>sqrt</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3">
+ <widget class="QPushButton" name="mSinButton">
+ <property name="text">
+ <string>sin</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="4">
+ <widget class="QPushButton" name="mTanButton">
+ <property name="text">
+ <string>tan</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="5">
+ <widget class="QPushButton" name="mACosButton">
+ <property name="text">
+ <string>acos</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="6">
+ <widget class="QPushButton" name="mOpenBracketPushButton">
+ <property name="text">
+ <string>(</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QPushButton" name="mMinusPushButton">
+ <property name="text">
+ <string>-</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QPushButton" name="mDividePushButton">
+ <property name="text">
+ <string>/</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QPushButton" name="mExpButton">
+ <property name="text">
+ <string>^</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3">
+ <widget class="QPushButton" name="mCosButton">
+ <property name="text">
+ <string>cos</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="4">
+ <widget class="QPushButton" name="mASinButton">
+ <property name="text">
+ <string>asin</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="5">
+ <widget class="QPushButton" name="mATanButton">
+ <property name="text">
+ <string>atan</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="6">
+ <widget class="QPushButton" name="mCloseBracketPushButton">
+ <property name="text">
+ <string>)</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="5" column="0" colspan="2">
+ <widget class="QLabel" name="mFieldCalculatorExpressionLabel">
+ <property name="text">
+ <string>Field calculator expression:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0" colspan="4">
+ <widget class="QTextEdit" name="mExpressionTextEdit"/>
+ </item>
+ <item row="7" column="0" colspan="2">
+ <widget class="QDialogButtonBox" name="mButtonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>mButtonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>QgsFieldCalculatorBase</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>mButtonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>QgsFieldCalculatorBase</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
Modified: trunk/qgis/src/ui/qgsvectorlayerpropertiesbase.ui
===================================================================
--- trunk/qgis/src/ui/qgsvectorlayerpropertiesbase.ui 2009-09-29 14:52:50 UTC (rev 11734)
+++ trunk/qgis/src/ui/qgsvectorlayerpropertiesbase.ui 2009-09-30 07:14:54 UTC (rev 11735)
@@ -32,18 +32,9 @@
<property name="spacing" >
<number>3</number>
</property>
- <property name="leftMargin" >
+ <property name="margin" >
<number>1</number>
</property>
- <property name="topMargin" >
- <number>1</number>
- </property>
- <property name="rightMargin" >
- <number>1</number>
- </property>
- <property name="bottomMargin" >
- <number>1</number>
- </property>
<item>
<widget class="QPushButton" name="pbnLoadDefaultStyle" >
<property name="text" >
@@ -80,7 +71,7 @@
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons" >
- <set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
+ <set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
@@ -102,7 +93,7 @@
<enum>QTabWidget::Rounded</enum>
</property>
<property name="currentIndex" >
- <number>3</number>
+ <number>0</number>
</property>
<widget class="QWidget" name="tab1" >
<attribute name="title" >
@@ -167,10 +158,10 @@
</item>
<item row="3" column="2" >
<widget class="QPushButton" name="pbnChangeSpatialRefSys" >
- <property name="toolTip">
+ <property name="toolTip" >
<string>Specify the coordinate reference system of the layer's geometry.</string>
</property>
- <property name="whatsThis">
+ <property name="whatsThis" >
<string>Specify the coordinate reference system of the layer's geometry.</string>
</property>
<property name="text" >
@@ -190,18 +181,9 @@
<bool>true</bool>
</property>
<layout class="QGridLayout" >
- <property name="leftMargin" >
+ <property name="margin" >
<number>11</number>
</property>
- <property name="topMargin" >
- <number>11</number>
- </property>
- <property name="rightMargin" >
- <number>11</number>
- </property>
- <property name="bottomMargin" >
- <number>11</number>
- </property>
<item row="0" column="2" >
<widget class="QLabel" name="textLabel1_2_2" >
<property name="text" >
@@ -257,18 +239,9 @@
<string>Subset</string>
</property>
<layout class="QGridLayout" >
- <property name="leftMargin" >
+ <property name="margin" >
<number>11</number>
</property>
- <property name="topMargin" >
- <number>11</number>
- </property>
- <property name="rightMargin" >
- <number>11</number>
- </property>
- <property name="bottomMargin" >
- <number>11</number>
- </property>
<item row="0" column="0" colspan="2" >
<widget class="QTextEdit" name="txtSubsetSQL" >
<property name="enabled" >
@@ -290,7 +263,7 @@
<property name="sizeType" >
<enum>QSizePolicy::Expanding</enum>
</property>
- <property name="sizeHint" >
+ <property name="sizeHint" stdset="0" >
<size>
<width>480</width>
<height>21</height>
@@ -428,18 +401,9 @@
<string>Metadata</string>
</attribute>
<layout class="QGridLayout" >
- <property name="leftMargin" >
+ <property name="margin" >
<number>11</number>
</property>
- <property name="topMargin" >
- <number>11</number>
- </property>
- <property name="rightMargin" >
- <number>11</number>
- </property>
- <property name="bottomMargin" >
- <number>11</number>
- </property>
<item row="0" column="0" >
<widget class="QTextEdit" name="teMetadata" >
<property name="lineWidth" >
@@ -518,12 +482,9 @@
<attribute name="title" >
<string>Attributes</string>
</attribute>
- <layout class="QVBoxLayout" >
- <item>
- <layout class="QHBoxLayout" >
- <property name="sizeConstraint" >
- <enum>QLayout::SetNoConstraint</enum>
- </property>
+ <layout class="QGridLayout" name="gridLayout" >
+ <item row="0" column="0" >
+ <layout class="QHBoxLayout" name="horizontalLayout" >
<item>
<widget class="QToolButton" name="mAddAttributeButton" >
<property name="sizePolicy" >
@@ -539,7 +500,8 @@
<string/>
</property>
<property name="icon" >
- <iconset>../xpm/new_attribute.png</iconset>
+ <iconset>
+ <normaloff>../xpm/new_attribute.png</normaloff>../xpm/new_attribute.png</iconset>
</property>
<property name="shortcut" >
<string>Ctrl+N</string>
@@ -555,7 +517,8 @@
<string/>
</property>
<property name="icon" >
- <iconset>../xpm/delete_attribute.png</iconset>
+ <iconset>
+ <normaloff>../xpm/delete_attribute.png</normaloff>../xpm/delete_attribute.png</iconset>
</property>
<property name="shortcut" >
<string>Ctrl+X</string>
@@ -579,21 +542,37 @@
</widget>
</item>
<item>
+ <widget class="QToolButton" name="mCalculateFieldButton" >
+ <property name="toolTip" >
+ <string>Field calculator</string>
+ </property>
+ <property name="whatsThis" >
+ <string>Click to toggle table editing</string>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="checkable" >
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
- <property name="sizeHint" >
+ <property name="sizeHint" stdset="0" >
<size>
- <width>40</width>
- <height>20</height>
+ <width>658</width>
+ <height>19</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
- <item>
+ <item row="1" column="0" >
<widget class="QTableWidget" name="tblAttributes" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
More information about the QGIS-commit
mailing list