|
25 | 25 | #include <QFile>
|
26 | 26 | #include <QTextStream>
|
27 | 27 | #include <QSettings>
|
| 28 | +#include <QDir> |
| 29 | +#include <QComboBox> |
28 | 30 |
|
29 | 31 | QgsExpressionBuilderWidget::QgsExpressionBuilderWidget( QWidget *parent )
|
30 | 32 | : QWidget( parent )
|
@@ -54,71 +56,27 @@ QgsExpressionBuilderWidget::QgsExpressionBuilderWidget( QWidget *parent )
|
54 | 56 | connect( button, SIGNAL( pressed() ), this, SLOT( operatorButtonClicked() ) );
|
55 | 57 | }
|
56 | 58 |
|
57 |
| - // TODO Can we move this stuff to QgsExpression, like the functions? |
58 |
| - registerItem( "Operators", "+", " + ", tr( "Addition operator" ) ); |
59 |
| - registerItem( "Operators", "-", " - ", tr( "Subtraction operator" ) ); |
60 |
| - registerItem( "Operators", "*", " * ", tr( "Multiplication operator" ) ); |
61 |
| - registerItem( "Operators", "/", " / ", tr( "Division operator" ) ); |
62 |
| - registerItem( "Operators", "%", " % ", tr( "Modulo operator" ) ); |
63 |
| - registerItem( "Operators", "^", " ^ ", tr( "Power operator" ) ); |
64 |
| - registerItem( "Operators", "=", " = ", tr( "Equal operator" ) ); |
65 |
| - registerItem( "Operators", ">", " > ", tr( "Greater as operator" ) ); |
66 |
| - registerItem( "Operators", "<", " < ", tr( "Less than operator" ) ); |
67 |
| - registerItem( "Operators", "<>", " <> ", tr( "Unequal operator" ) ); |
68 |
| - registerItem( "Operators", "<=", " <= ", tr( "Less or equal operator" ) ); |
69 |
| - registerItem( "Operators", ">=", " >= ", tr( "Greater or equal operator" ) ); |
70 |
| - registerItem( "Operators", "||", " || ", |
71 |
| - QString( "<b>|| %1</b><br><i>%2</i><br><i>%3:</i>%4" ) |
72 |
| - .arg( tr( "(String Concatenation)" ) ) |
73 |
| - .arg( tr( "Joins two values together into a string" ) ) |
74 |
| - .arg( tr( "Usage" ) ) |
75 |
| - .arg( tr( "'Dia' || Diameter" ) ) ); |
76 |
| - registerItem( "Operators", "IN", " IN " ); |
77 |
| - registerItem( "Operators", "LIKE", " LIKE " ); |
78 |
| - registerItem( "Operators", "ILIKE", " ILIKE " ); |
79 |
| - registerItem( "Operators", "IS", " IS " ); |
80 |
| - registerItem( "Operators", "OR", " OR " ); |
81 |
| - registerItem( "Operators", "AND", " AND " ); |
82 |
| - registerItem( "Operators", "NOT", " NOT " ); |
83 |
| - |
84 |
| - QString casestring = "CASE WHEN condition THEN result END"; |
85 |
| - QString caseelsestring = "CASE WHEN condition THEN result ELSE result END"; |
86 |
| - registerItem( "Conditionals", "CASE", casestring ); |
87 |
| - registerItem( "Conditionals", "CASE ELSE", caseelsestring ); |
88 |
| - |
89 |
| - // Load the functions from the QgsExpression class |
90 |
| - int count = QgsExpression::functionCount(); |
91 |
| - for ( int i = 0; i < count; i++ ) |
92 |
| - { |
93 |
| - QgsExpression::Function* func = QgsExpression::Functions()[i]; |
94 |
| - QString name = func->name(); |
95 |
| - if ( name.startsWith( "_" ) ) // do not display private functions |
96 |
| - continue; |
97 |
| - if ( func->params() != 0 ) |
98 |
| - name += "("; |
99 |
| - registerItem( func->group(), func->name(), " " + name + " ", func->helptext() ); |
100 |
| - } |
101 |
| - |
102 |
| - QList<QgsExpression::Function*> specials = QgsExpression::specialColumns(); |
103 |
| - for ( int i = 0; i < specials.size(); ++i ) |
104 |
| - { |
105 |
| - QString name = specials[i]->name(); |
106 |
| - registerItem( specials[i]->group(), name, " " + name + " " ); |
107 |
| - } |
108 |
| - |
109 | 59 | txtSearchEdit->setPlaceholderText( tr( "Search" ) );
|
110 | 60 |
|
111 | 61 | QSettings settings;
|
112 | 62 | splitter->restoreState( settings.value( "/windows/QgsExpressionBuilderWidget/splitter" ).toByteArray() );
|
113 |
| -// splitter_2->restoreState( settings.value( "/windows/QgsExpressionBuilderWidget/splitter2" ).toByteArray() ); |
114 | 63 |
|
115 | 64 | txtExpressionString->setFoldingVisible( false );
|
116 |
| -// customFunctionBotton->setVisible( QgsPythonRunner::isValid() ); |
117 |
| - txtPython->setVisible( false ); |
118 |
| - cgbCustomFunction->setCollapsed( true ); |
119 |
| - txtPython->setText( "@qgsfunction(args=-1, group='Custom')\n" |
120 |
| - "def func(values, feature, parent):\n" |
121 |
| - " return str(values)" ); |
| 65 | + |
| 66 | + updateFunctionTree(); |
| 67 | + |
| 68 | + if ( QgsPythonRunner::isValid() ) |
| 69 | + { |
| 70 | + QgsPythonRunner::eval( "qgis.user.expressionspath", mFunctionsPath ); |
| 71 | + newFunctionFile(); |
| 72 | + // The scratch file gets written each time the widget opens. |
| 73 | + saveFunctionFile("scratch"); |
| 74 | + updateFunctionFileList( mFunctionsPath ); |
| 75 | + } |
| 76 | + else |
| 77 | + { |
| 78 | + tab_2->setEnabled( false ); |
| 79 | + } |
122 | 80 | }
|
123 | 81 |
|
124 | 82 |
|
@@ -156,6 +114,113 @@ void QgsExpressionBuilderWidget::currentChanged( const QModelIndex &index, const
|
156 | 114 | txtHelpText->setToolTip( txtHelpText->toPlainText() );
|
157 | 115 | }
|
158 | 116 |
|
| 117 | +void QgsExpressionBuilderWidget::on_btnRun_pressed() |
| 118 | +{ |
| 119 | + saveFunctionFile( cmbFileNames->currentText() ); |
| 120 | + runPythonCode( txtPython->text() ); |
| 121 | +} |
| 122 | + |
| 123 | +void QgsExpressionBuilderWidget::runPythonCode( QString code ) |
| 124 | +{ |
| 125 | + if ( QgsPythonRunner::isValid() ) |
| 126 | + { |
| 127 | + QString pythontext = code; |
| 128 | + QgsPythonRunner::run( pythontext ); |
| 129 | + } |
| 130 | + updateFunctionTree(); |
| 131 | +} |
| 132 | + |
| 133 | +void QgsExpressionBuilderWidget::saveFunctionFile( QString fileName ) |
| 134 | +{ |
| 135 | + QDir myDir( mFunctionsPath ); |
| 136 | + if ( !myDir.exists() ) |
| 137 | + { |
| 138 | + myDir.mkpath( mFunctionsPath ); |
| 139 | + } |
| 140 | + |
| 141 | + if ( !fileName.endsWith( ".py" ) ) |
| 142 | + { |
| 143 | + fileName.append( ".py" ); |
| 144 | + } |
| 145 | + |
| 146 | + fileName = mFunctionsPath + QDir::separator() + fileName; |
| 147 | + QFile myFile( fileName ); |
| 148 | + if ( myFile.open( QIODevice::WriteOnly | QIODevice::Text ) ) |
| 149 | + { |
| 150 | + QTextStream myFileStream( &myFile ); |
| 151 | + myFileStream << txtPython->text() << endl; |
| 152 | + myFile.close(); |
| 153 | + } |
| 154 | +} |
| 155 | + |
| 156 | +void QgsExpressionBuilderWidget::updateFunctionFileList( QString path ) |
| 157 | +{ |
| 158 | + mFunctionsPath = path; |
| 159 | + QDir dir( path ); |
| 160 | + dir.setNameFilters( QStringList() << "*.py" ); |
| 161 | + QStringList files = dir.entryList( QDir::Files ); |
| 162 | + cmbFileNames->clear(); |
| 163 | + foreach ( QString name, files ) |
| 164 | + { |
| 165 | + QFileInfo info( mFunctionsPath + QDir::separator() + name ); |
| 166 | + if ( info.baseName() == "__init__" ) continue; |
| 167 | + cmbFileNames->addItem( info.baseName() ); |
| 168 | + } |
| 169 | +} |
| 170 | + |
| 171 | +void QgsExpressionBuilderWidget::newFunctionFile( QString fileName ) |
| 172 | +{ |
| 173 | + txtPython->setText( "from qgis.core import *\n" |
| 174 | + "from qgis.gui import *\n\n" |
| 175 | + "@qgsfunction(args=-1, group='Custom')\n" |
| 176 | + "def func(values, feature, parent):\n" |
| 177 | + " return str(values)" ); |
| 178 | + int index = cmbFileNames->findText( fileName ); |
| 179 | + if ( index == -1 ) |
| 180 | + cmbFileNames->setEditText( fileName ); |
| 181 | + else |
| 182 | + cmbFileNames->setCurrentIndex( index ); |
| 183 | +} |
| 184 | + |
| 185 | +void QgsExpressionBuilderWidget::on_btnNewFile_pressed() |
| 186 | +{ |
| 187 | + newFunctionFile(); |
| 188 | +} |
| 189 | + |
| 190 | +void QgsExpressionBuilderWidget::on_cmbFileNames_currentIndexChanged( int index ) |
| 191 | +{ |
| 192 | + if ( index == -1 ) |
| 193 | + return; |
| 194 | + |
| 195 | + QString path = mFunctionsPath + QDir::separator() + cmbFileNames->currentText(); |
| 196 | + loadCodeFromFile( path ); |
| 197 | +} |
| 198 | + |
| 199 | +void QgsExpressionBuilderWidget::loadCodeFromFile( QString path ) |
| 200 | +{ |
| 201 | + if ( !path.endsWith( ".py" ) ) |
| 202 | + path.append( ".py" ); |
| 203 | + |
| 204 | + txtPython->loadScript( path ); |
| 205 | +} |
| 206 | + |
| 207 | +void QgsExpressionBuilderWidget::loadFunctionCode( QString code ) |
| 208 | +{ |
| 209 | + txtPython->setText( code ); |
| 210 | +} |
| 211 | + |
| 212 | +void QgsExpressionBuilderWidget::on_btnSaveFile_pressed() |
| 213 | +{ |
| 214 | + QString name = cmbFileNames->currentText(); |
| 215 | + saveFunctionFile( name ); |
| 216 | + int index = cmbFileNames->findText( name ); |
| 217 | + if ( index == -1 ) |
| 218 | + { |
| 219 | + cmbFileNames->addItem( name ); |
| 220 | + cmbFileNames->setCurrentIndex( cmbFileNames->count() - 1 ); |
| 221 | + } |
| 222 | +} |
| 223 | + |
159 | 224 | void QgsExpressionBuilderWidget::on_expressionTree_doubleClicked( const QModelIndex &index )
|
160 | 225 | {
|
161 | 226 | QModelIndex idx = mProxyModel->mapToSource( index );
|
@@ -292,18 +357,70 @@ void QgsExpressionBuilderWidget::loadRecent( QString key )
|
292 | 357 | }
|
293 | 358 | }
|
294 | 359 |
|
| 360 | +void QgsExpressionBuilderWidget::updateFunctionTree() |
| 361 | +{ |
| 362 | + mModel->clear(); |
| 363 | + mExpressionGroups.clear(); |
| 364 | + // TODO Can we move this stuff to QgsExpression, like the functions? |
| 365 | + registerItem( "Operators", "+", " + ", tr( "Addition operator" ) ); |
| 366 | + registerItem( "Operators", "-", " - ", tr( "Subtraction operator" ) ); |
| 367 | + registerItem( "Operators", "*", " * ", tr( "Multiplication operator" ) ); |
| 368 | + registerItem( "Operators", "/", " / ", tr( "Division operator" ) ); |
| 369 | + registerItem( "Operators", "%", " % ", tr( "Modulo operator" ) ); |
| 370 | + registerItem( "Operators", "^", " ^ ", tr( "Power operator" ) ); |
| 371 | + registerItem( "Operators", "=", " = ", tr( "Equal operator" ) ); |
| 372 | + registerItem( "Operators", ">", " > ", tr( "Greater as operator" ) ); |
| 373 | + registerItem( "Operators", "<", " < ", tr( "Less than operator" ) ); |
| 374 | + registerItem( "Operators", "<>", " <> ", tr( "Unequal operator" ) ); |
| 375 | + registerItem( "Operators", "<=", " <= ", tr( "Less or equal operator" ) ); |
| 376 | + registerItem( "Operators", ">=", " >= ", tr( "Greater or equal operator" ) ); |
| 377 | + registerItem( "Operators", "||", " || ", |
| 378 | + QString( "<b>|| %1</b><br><i>%2</i><br><i>%3:</i>%4" ) |
| 379 | + .arg( tr( "(String Concatenation)" ) ) |
| 380 | + .arg( tr( "Joins two values together into a string" ) ) |
| 381 | + .arg( tr( "Usage" ) ) |
| 382 | + .arg( tr( "'Dia' || Diameter" ) ) ); |
| 383 | + registerItem( "Operators", "IN", " IN " ); |
| 384 | + registerItem( "Operators", "LIKE", " LIKE " ); |
| 385 | + registerItem( "Operators", "ILIKE", " ILIKE " ); |
| 386 | + registerItem( "Operators", "IS", " IS " ); |
| 387 | + registerItem( "Operators", "OR", " OR " ); |
| 388 | + registerItem( "Operators", "AND", " AND " ); |
| 389 | + registerItem( "Operators", "NOT", " NOT " ); |
| 390 | + |
| 391 | + QString casestring = "CASE WHEN condition THEN result END"; |
| 392 | + QString caseelsestring = "CASE WHEN condition THEN result ELSE result END"; |
| 393 | + registerItem( "Conditionals", "CASE", casestring ); |
| 394 | + registerItem( "Conditionals", "CASE ELSE", caseelsestring ); |
| 395 | + |
| 396 | + // Load the functions from the QgsExpression class |
| 397 | + int count = QgsExpression::functionCount(); |
| 398 | + for ( int i = 0; i < count; i++ ) |
| 399 | + { |
| 400 | + QgsExpression::Function* func = QgsExpression::Functions()[i]; |
| 401 | + QString name = func->name(); |
| 402 | + if ( name.startsWith( "_" ) ) // do not display private functions |
| 403 | + continue; |
| 404 | + if ( func->params() != 0 ) |
| 405 | + name += "("; |
| 406 | + registerItem( func->group(), func->name(), " " + name + " ", func->helptext() ); |
| 407 | + } |
| 408 | + |
| 409 | + QList<QgsExpression::Function*> specials = QgsExpression::specialColumns(); |
| 410 | + for ( int i = 0; i < specials.size(); ++i ) |
| 411 | + { |
| 412 | + QString name = specials[i]->name(); |
| 413 | + registerItem( specials[i]->group(), name, " " + name + " " ); |
| 414 | + } |
| 415 | +} |
| 416 | + |
295 | 417 | void QgsExpressionBuilderWidget::setGeomCalculator( const QgsDistanceArea & da )
|
296 | 418 | {
|
297 | 419 | mDa = da;
|
298 | 420 | }
|
299 | 421 |
|
300 | 422 | QString QgsExpressionBuilderWidget::expressionText()
|
301 | 423 | {
|
302 |
| - if ( QgsPythonRunner::isValid() ) |
303 |
| - { |
304 |
| - QString pythontext = txtPython->text(); |
305 |
| - QgsPythonRunner::run( pythontext ); |
306 |
| - } |
307 | 424 | return txtExpressionString->text();
|
308 | 425 | }
|
309 | 426 |
|
|
0 commit comments