diff --git a/python/core/qgsapplication.sip b/python/core/qgsapplication.sip index c70decca86a..d8c91709b6b 100644 --- a/python/core/qgsapplication.sip +++ b/python/core/qgsapplication.sip @@ -152,6 +152,10 @@ static void qtgui_UpdatePyArgv(PyObject *argvlist, int argc, char **argv) //! @note added in 1.4 static const QStringList svgPaths(); + //! Returns the system environment variables passed to application. + //! @note added in 1.9 + static const QMap systemEnvVars(); + //! Returns the path to the application prefix directory. static const QString prefixPath(); diff --git a/src/app/main.cpp b/src/app/main.cpp index 17d77cd9404..3114400b4c0 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -569,6 +569,51 @@ int main( int argc, char *argv[] ) QSettings mySettings; + // custom environment variables + QMap systemEnvVars = QgsApplication::systemEnvVars(); + bool useCustomVars = mySettings.value( "qgis/customEnvVarsUse", QVariant( false ) ).toBool(); + if ( useCustomVars ) + { + QStringList customVarsList = mySettings.value( "qgis/customEnvVars", "" ).toStringList(); + if ( !customVarsList.isEmpty() ) + { + foreach ( const QString &varStr, customVarsList ) + { + int pos = varStr.indexOf( QLatin1Char( '|' ) ); + if ( pos == -1 ) + continue; + QString envVarApply = varStr.left( pos ); + QString varStrNameValue = varStr.mid( pos + 1 ); + pos = varStrNameValue.indexOf( QLatin1Char( '=' ) ); + if ( pos == -1 ) + continue; + QString envVarName = varStrNameValue.left( pos ); + QString envVarValue = varStrNameValue.mid( pos + 1 ); + + if ( systemEnvVars.contains( envVarName ) ) + { + if ( envVarApply == "prepend" ) + { + envVarValue += systemEnvVars.value( envVarName ); + } + else if ( envVarApply == "append" ) + { + envVarValue = systemEnvVars.value( envVarName ) + envVarValue; + } + } + + if ( systemEnvVars.contains( envVarName ) && envVarApply == "unset" ) + { + unsetenv( envVarName.toUtf8().constData() ); + } + else + { + setenv( envVarName.toUtf8().constData(), envVarValue.toUtf8().constData(), envVarApply == "undefined" ? 0 : 1 ); + } + } + } + } + // Set the application style. If it's not set QT will use the platform style except on Windows // as it looks really ugly so we use QPlastiqueStyle. QString style = mySettings.value( "/qgis/style" ).toString(); diff --git a/src/app/qgsoptions.cpp b/src/app/qgsoptions.cpp index e3574508137..5d23861b529 100644 --- a/src/app/qgsoptions.cpp +++ b/src/app/qgsoptions.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -110,6 +111,99 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WFlags fl ) : spinBoxIdentifyValue->setMinimum( 0.01 ); spinBoxIdentifyValue->setValue( identifyValue ); + // custom environment variables + bool useCustomVars = settings.value( "qgis/customEnvVarsUse", QVariant( false ) ).toBool(); + mCustomVariablesChkBx->setChecked( useCustomVars ); + if ( !useCustomVars ) + { + mAddCustomVarBtn->setEnabled( false ); + mRemoveCustomVarBtn->setEnabled( false ); + mCustomVariablesTable->setEnabled( false ); + } + QStringList customVarsList = settings.value( "qgis/customEnvVars", "" ).toStringList(); + mCustomVariablesTable->clearContents(); + foreach ( const QString &varStr, customVarsList ) + { + int pos = varStr.indexOf( QLatin1Char( '|' ) ); + if ( pos == -1 ) + continue; + QString varStrApply = varStr.left( pos ); + QString varStrNameValue = varStr.mid( pos + 1 ); + pos = varStrNameValue.indexOf( QLatin1Char( '=' ) ); + if ( pos == -1 ) + continue; + QString varStrName = varStrNameValue.left( pos ); + QString varStrValue = varStrNameValue.mid( pos + 1 ); + + addCustomEnvVarRow( varStrName, varStrValue, varStrApply ); + } + QFontMetrics fmCustomVar( mCustomVariablesTable->horizontalHeader()->font() ); + int fmCustomVarH = fmCustomVar.height() + 2; + mCustomVariablesTable->horizontalHeader()->setFixedHeight( fmCustomVarH ); + + mCustomVariablesTable->setColumnWidth( 0, 120 ); + if ( mCustomVariablesTable->rowCount() > 0 ) + { + mCustomVariablesTable->resizeColumnToContents( 1 ); + } + else + { + mCustomVariablesTable->setColumnWidth( 1, 120 ); + } + + // current environment variables + mCurrentVariablesTable->horizontalHeader()->setFixedHeight( fmCustomVarH ); + QMap sysVarsMap = QgsApplication::systemEnvVars(); + QStringList currentVarsList = QProcess::systemEnvironment(); + mCurrentVariablesTable->clearContents(); + + foreach ( const QString &varStr, currentVarsList ) + { + int pos = varStr.indexOf( QLatin1Char( '=' ) ); + if ( pos == -1 ) + continue; + QStringList varStrItms; + QString varStrName = varStr.left( pos ); + QString varStrValue = varStr.mid( pos + 1 ); + varStrItms << varStrName << varStrValue; + + // check if different than system variable + QString sysVarVal = QString( "" ); + bool sysVarMissing = !sysVarsMap.contains( varStrName ); + if ( sysVarMissing ) + sysVarVal = tr( "not present" ); + + if ( !sysVarMissing && sysVarsMap.value( varStrName ) != varStrValue ) + sysVarVal = sysVarsMap.value( varStrName ); + + if ( !sysVarVal.isEmpty() ) + sysVarVal = tr( "System value: %1" ).arg( sysVarVal ); + + int rowCnt = mCurrentVariablesTable->rowCount(); + mCurrentVariablesTable->insertRow( rowCnt ); + + QFont fItm; + for ( int i = 0; i < varStrItms.size(); ++i ) + { + QTableWidgetItem* varNameItm = new QTableWidgetItem( varStrItms.at( i ) ); + varNameItm->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable + | Qt::ItemIsEditable | Qt::ItemIsDragEnabled ); + fItm = varNameItm->font(); + if ( !sysVarVal.isEmpty() ) + { + fItm.setBold( true ); + varNameItm->setFont( fItm ); + varNameItm->setToolTip( sysVarVal ); + } + mCurrentVariablesTable->setItem( rowCnt, i, varNameItm ); + } + fItm.setBold( true ); + QFontMetrics fmRow( fItm ); + mCurrentVariablesTable->setRowHeight( rowCnt, fmRow.height() + 6 ); + } + if ( mCurrentVariablesTable->rowCount() > 0 ) + mCurrentVariablesTable->resizeColumnToContents( 0 ); + //local directories to search when loading c++ plugins QString myPaths = settings.value( "plugins/searchPathsForPlugins", "" ).toString(); if ( !myPaths.isEmpty() ) @@ -781,6 +875,23 @@ void QgsOptions::saveOptions() { QSettings settings; + // custom environment variables + settings.setValue( "qgis/customEnvVarsUse", QVariant( mCustomVariablesChkBx->isChecked() ) ); + QStringList customVars; + for ( int i = 0; i < mCustomVariablesTable->rowCount(); ++i ) + { + if ( mCustomVariablesTable->item( i, 1 )->text().isEmpty() ) + continue; + QComboBox* varApplyCmbBx = qobject_cast( mCustomVariablesTable->cellWidget( i, 0 ) ); + QString customVar = varApplyCmbBx->itemData( varApplyCmbBx->currentIndex() ).toString(); + customVar += "|"; + customVar += mCustomVariablesTable->item( i, 1 )->text(); + customVar += "="; + customVar += mCustomVariablesTable->item( i, 2 )->text(); + customVars << customVar; + } + settings.setValue( "qgis/customEnvVars", QVariant( customVars ) ); + //search directories for user plugins QString myPaths; for ( int i = 0; i < mListPluginPaths->count(); ++i ) @@ -1211,6 +1322,52 @@ QStringList QgsOptions::i18nList() return myList; } +void QgsOptions::addCustomEnvVarRow( QString varName, QString varVal, QString varApply ) +{ + int rowCnt = mCustomVariablesTable->rowCount(); + mCustomVariablesTable->insertRow( rowCnt ); + + QComboBox* varApplyCmbBx = new QComboBox( this ); + varApplyCmbBx->addItem( tr( "Overwrite" ), QVariant( "overwrite" ) ); + varApplyCmbBx->addItem( tr( "If Undefined" ), QVariant( "undefined" ) ); + varApplyCmbBx->addItem( tr( "Unset" ), QVariant( "unset" ) ); + varApplyCmbBx->addItem( tr( "Prepend" ), QVariant( "prepend" ) ); + varApplyCmbBx->addItem( tr( "Append" ), QVariant( "append" ) ); + varApplyCmbBx->setCurrentIndex( varApply.isEmpty() ? 0 : varApplyCmbBx->findData( QVariant( varApply ) ) ); + + QFont cbf = varApplyCmbBx->font(); + QFontMetrics cbfm = QFontMetrics( cbf ); + cbf.setPointSize( cbf.pointSize() - 2 ); + varApplyCmbBx->setFont( cbf ); + mCustomVariablesTable->setCellWidget( rowCnt, 0, varApplyCmbBx ); + + Qt::ItemFlags itmFlags = Qt::ItemIsEnabled | Qt::ItemIsSelectable + | Qt::ItemIsEditable | Qt::ItemIsDropEnabled; + + QTableWidgetItem* varNameItm = new QTableWidgetItem( varName ); + varNameItm->setFlags( itmFlags ); + mCustomVariablesTable->setItem( rowCnt, 1, varNameItm ); + + QTableWidgetItem* varValueItm = new QTableWidgetItem( varVal ); + varNameItm->setFlags( itmFlags ); + mCustomVariablesTable->setItem( rowCnt, 2, varValueItm ); + + mCustomVariablesTable->setRowHeight( rowCnt, cbfm.height() + 8 ); +} + +void QgsOptions::on_mAddCustomVarBtn_clicked() +{ + addCustomEnvVarRow( QString( "" ), QString( "" ) ); + mCustomVariablesTable->setFocus(); + mCustomVariablesTable->setCurrentCell( mCustomVariablesTable->rowCount() - 1, 1 ); + mCustomVariablesTable->edit( mCustomVariablesTable->currentIndex() ); +} + +void QgsOptions::on_mRemoveCustomVarBtn_clicked() +{ + mCustomVariablesTable->removeRow( mCustomVariablesTable->currentRow() ); +} + void QgsOptions::on_mBtnAddPluginPath_clicked() { QString myDir = QFileDialog::getExistingDirectory( diff --git a/src/app/qgsoptions.h b/src/app/qgsoptions.h index d337f991ec9..83f4f6c7271 100644 --- a/src/app/qgsoptions.h +++ b/src/app/qgsoptions.h @@ -117,6 +117,16 @@ class QgsOptions : public QDialog, private Ui::QgsOptionsBase /**Remove an URL to exclude from Proxy*/ void on_mRemoveUrlPushButton_clicked(); + /** Slot to add a custom environment variable to the app + * @note added in QGIS 1.9 + */ + void on_mAddCustomVarBtn_clicked(); + + /** Slot to remove a custom environment variable from the app + * @note added in QGIS 1.9 + */ + void on_mRemoveCustomVarBtn_clicked(); + /* Let the user add a path to the list of search paths * used for finding user Plugin libs. * @note added in QGIS 1.7 @@ -197,6 +207,10 @@ class QgsOptions : public QDialog, private Ui::QgsOptionsBase QgsCoordinateReferenceSystem mLayerDefaultCrs; bool mLoadedGdalDriverList; + /** Generate table row for custom environment variables + * @note added in QGIS 1.9 + */ + void addCustomEnvVarRow( QString varName, QString varVal, QString varApply = QString() ); }; #endif // #ifndef QGSOPTIONS_H diff --git a/src/core/qgsapplication.cpp b/src/core/qgsapplication.cpp index c8f36906ca3..ce3e2227736 100644 --- a/src/core/qgsapplication.cpp +++ b/src/core/qgsapplication.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -50,6 +51,7 @@ QString ABISYM( QgsApplication::mLibraryPath ); QString ABISYM( QgsApplication::mLibexecPath ); QString ABISYM( QgsApplication::mThemeName ); QStringList ABISYM( QgsApplication::mDefaultSvgPaths ); +QMap ABISYM( QgsApplication::mSystemEnvVars ); QString ABISYM( QgsApplication::mConfigPath ); bool ABISYM( QgsApplication::mRunningFromBuildDir ) = false; QString ABISYM( QgsApplication::mBuildSourcePath ); @@ -152,6 +154,19 @@ void QgsApplication::init( QString customConfigPath ) ABISYM( mDefaultSvgPaths ) << qgisSettingsDirPath() + QString( "svg/" ); + // store system environment variables passed to application, before they are adjusted + QMap systemEnvVarMap; + foreach ( const QString &varStr, QProcess::systemEnvironment() ) + { + int pos = varStr.indexOf( QLatin1Char( '=' ) ); + if ( pos == -1 ) + continue; + QString varStrName = varStr.left( pos ); + QString varStrValue = varStr.mid( pos + 1 ); + systemEnvVarMap.insert( varStrName, varStrValue ); + } + ABISYM( mSystemEnvVars ) = systemEnvVarMap; + // set a working directory up for gdal to write .aux.xml files into // for cases where the raster dir is read only to the user // if the env var is already set it will be used preferentially diff --git a/src/core/qgsapplication.h b/src/core/qgsapplication.h index 5d1407f82c0..e384426d829 100644 --- a/src/core/qgsapplication.h +++ b/src/core/qgsapplication.h @@ -120,6 +120,10 @@ class CORE_EXPORT QgsApplication: public QApplication //! @note added in 1.4 static const QStringList svgPaths(); + //! Returns the system environment variables passed to application. + //! @note added in 1.9 + static const QMap systemEnvVars() { return ABISYM( mSystemEnvVars ); } + //! Returns the path to the application prefix directory. static const QString prefixPath(); @@ -253,7 +257,7 @@ class CORE_EXPORT QgsApplication: public QApplication * GDAL_SKIP environment variable) * @note added in 2.0 */ - static QStringList skippedGdalDrivers( ) { return ABISYM( mGdalSkipList ); }; + static QStringList skippedGdalDrivers( ) { return ABISYM( mGdalSkipList ); } /** Apply the skipped drivers list to gdal * @see skipGdalDriver @@ -277,6 +281,7 @@ class CORE_EXPORT QgsApplication: public QApplication static QString ABISYM( mLibexecPath ); static QString ABISYM( mThemeName ); static QStringList ABISYM( mDefaultSvgPaths ); + static QMap ABISYM( mSystemEnvVars ); static QString ABISYM( mConfigPath ); diff --git a/src/ui/qgsoptionsbase.ui b/src/ui/qgsoptionsbase.ui index 9601ae87773..39f3c34587b 100644 --- a/src/ui/qgsoptionsbase.ui +++ b/src/ui/qgsoptionsbase.ui @@ -6,7 +6,7 @@ 0 0 - 808 + 816 674 @@ -33,7 +33,7 @@ - 4 + 0 @@ -66,8 +66,8 @@ 0 0 - 770 - 1062 + 771 + 1020 @@ -966,56 +966,247 @@ - :/images/themes/default/mActionShowPluginManager.png:/images/themes/default/mActionShowPluginManager.png + :/images/themes/default/propertyicons/action.png:/images/themes/default/propertyicons/action.png - Plugins + System - + + + 0 + - - - Plugin paths + + + QFrame::NoFrame - - - - - Path(s) to search for additional C++ plugins libraries - - - - - - - Qt::Horizontal - - - - 31 - 20 - - - - - - - - Add - - - - - - - Remove - - - - - - - + + true + + + + + 0 + 0 + 786 + 588 + + + + + + + + 0 + 0 + + + + Environment + + + + + + + 0 + 120 + + + + QAbstractItemView::SingleSelection + + + true + + + false + + + false + + + 4 + + + true + + + true + + + false + + + + Apply + + + + + Variable + + + + + Value + + + + + + + + + 0 + 0 + + + + Remove + + + + + + + + 0 + 0 + + + + Add + + + + + + + + 0 + 0 + + + + Current environment variables (read-only - bold indicates modified at startup) + + + + + + true + + + QAbstractItemView::DragOnly + + + QAbstractItemView::SingleSelection + + + true + + + false + + + 100 + + + true + + + true + + + false + + + + Variable + + + + + Value + + + + + + + + + + + Use custom environment variables (restart required - include separators) + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + Plugin paths + + + + + + Path(s) to search for additional C++ plugins libraries + + + + + + + Qt::Horizontal + + + + 31 + 20 + + + + + + + + Add + + + + + + + Remove + + + + + + + + + + + @@ -1045,8 +1236,8 @@ 0 0 - 1010 - 815 + 963 + 826 @@ -1560,8 +1751,8 @@ 0 0 - 770 - 691 + 771 + 717 @@ -1920,8 +2111,8 @@ 0 0 - 274 - 87 + 786 + 588 @@ -2001,8 +2192,8 @@ 0 0 - 581 - 606 + 771 + 618 @@ -2377,8 +2568,8 @@ 0 0 - 653 - 415 + 786 + 588 @@ -2564,8 +2755,8 @@ 0 0 - 519 - 565 + 786 + 588 @@ -2661,8 +2852,8 @@ 0 0 - 505 - 573 + 771 + 598 @@ -2902,6 +3093,12 @@ + + QgsCollapsibleGroupBox + QGroupBox +
qgscollapsiblegroupbox.h
+ 1 +
QgsColorButton QToolButton @@ -3036,12 +3233,60 @@ setEnabled(bool) - 450 - 508 + 371 + 517 - 518 - 508 + 546 + 521 + + + + + mCustomVariablesChkBx + toggled(bool) + mAddCustomVarBtn + setEnabled(bool) + + + 100 + 79 + + + 651 + 92 + + + + + mCustomVariablesChkBx + toggled(bool) + mRemoveCustomVarBtn + setEnabled(bool) + + + 68 + 76 + + + 754 + 89 + + + + + mCustomVariablesChkBx + toggled(bool) + mCustomVariablesTable + setEnabled(bool) + + + 81 + 82 + + + 180 + 179