Skip to content

Commit 5cd7dc5

Browse files
committed
Merge pull request #372 from dakcarto/iface_enviro_3
[FEATURE] Configure custom environment variables
2 parents 2a002c5 + 0595f74 commit 5cd7dc5

File tree

7 files changed

+585
-68
lines changed

7 files changed

+585
-68
lines changed

python/core/qgsapplication.sip

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,10 @@ static void qtgui_UpdatePyArgv(PyObject *argvlist, int argc, char **argv)
152152
//! @note added in 1.4
153153
static const QStringList svgPaths();
154154

155+
//! Returns the system environment variables passed to application.
156+
//! @note added in 1.9
157+
static const QMap<QString, QString> systemEnvVars();
158+
155159
//! Returns the path to the application prefix directory.
156160
static const QString prefixPath();
157161

src/app/main.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,51 @@ int main( int argc, char *argv[] )
569569

570570
QSettings mySettings;
571571

572+
// custom environment variables
573+
QMap<QString, QString> systemEnvVars = QgsApplication::systemEnvVars();
574+
bool useCustomVars = mySettings.value( "qgis/customEnvVarsUse", QVariant( false ) ).toBool();
575+
if ( useCustomVars )
576+
{
577+
QStringList customVarsList = mySettings.value( "qgis/customEnvVars", "" ).toStringList();
578+
if ( !customVarsList.isEmpty() )
579+
{
580+
foreach ( const QString &varStr, customVarsList )
581+
{
582+
int pos = varStr.indexOf( QLatin1Char( '|' ) );
583+
if ( pos == -1 )
584+
continue;
585+
QString envVarApply = varStr.left( pos );
586+
QString varStrNameValue = varStr.mid( pos + 1 );
587+
pos = varStrNameValue.indexOf( QLatin1Char( '=' ) );
588+
if ( pos == -1 )
589+
continue;
590+
QString envVarName = varStrNameValue.left( pos );
591+
QString envVarValue = varStrNameValue.mid( pos + 1 );
592+
593+
if ( systemEnvVars.contains( envVarName ) )
594+
{
595+
if ( envVarApply == "prepend" )
596+
{
597+
envVarValue += systemEnvVars.value( envVarName );
598+
}
599+
else if ( envVarApply == "append" )
600+
{
601+
envVarValue = systemEnvVars.value( envVarName ) + envVarValue;
602+
}
603+
}
604+
605+
if ( systemEnvVars.contains( envVarName ) && envVarApply == "unset" )
606+
{
607+
unsetenv( envVarName.toUtf8().constData() );
608+
}
609+
else
610+
{
611+
setenv( envVarName.toUtf8().constData(), envVarValue.toUtf8().constData(), envVarApply == "undefined" ? 0 : 1 );
612+
}
613+
}
614+
}
615+
}
616+
572617
// Set the application style. If it's not set QT will use the platform style except on Windows
573618
// as it looks really ugly so we use QPlastiqueStyle.
574619
QString style = mySettings.value( "/qgis/style" ).toString();

src/app/qgsoptions.cpp

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include <QSettings>
4040
#include <QColorDialog>
4141
#include <QLocale>
42+
#include <QProcess>
4243
#include <QToolBar>
4344
#include <QSize>
4445
#include <QStyleFactory>
@@ -110,6 +111,97 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WFlags fl ) :
110111
spinBoxIdentifyValue->setMinimum( 0.01 );
111112
spinBoxIdentifyValue->setValue( identifyValue );
112113

114+
// custom environment variables
115+
bool useCustomVars = settings.value( "qgis/customEnvVarsUse", QVariant( false ) ).toBool();
116+
mCustomVariablesChkBx->setChecked( useCustomVars );
117+
if ( !useCustomVars )
118+
{
119+
mAddCustomVarBtn->setEnabled( false );
120+
mRemoveCustomVarBtn->setEnabled( false );
121+
mCustomVariablesTable->setEnabled( false );
122+
}
123+
QStringList customVarsList = settings.value( "qgis/customEnvVars", "" ).toStringList();
124+
foreach ( const QString &varStr, customVarsList )
125+
{
126+
int pos = varStr.indexOf( QLatin1Char( '|' ) );
127+
if ( pos == -1 )
128+
continue;
129+
QString varStrApply = varStr.left( pos );
130+
QString varStrNameValue = varStr.mid( pos + 1 );
131+
pos = varStrNameValue.indexOf( QLatin1Char( '=' ) );
132+
if ( pos == -1 )
133+
continue;
134+
QString varStrName = varStrNameValue.left( pos );
135+
QString varStrValue = varStrNameValue.mid( pos + 1 );
136+
137+
addCustomEnvVarRow( varStrName, varStrValue, varStrApply );
138+
}
139+
QFontMetrics fmCustomVar( mCustomVariablesTable->horizontalHeader()->font() );
140+
int fmCustomVarH = fmCustomVar.height() + 2;
141+
mCustomVariablesTable->horizontalHeader()->setFixedHeight( fmCustomVarH );
142+
143+
mCustomVariablesTable->setColumnWidth( 0, 120 );
144+
if ( mCustomVariablesTable->rowCount() > 0 )
145+
{
146+
mCustomVariablesTable->resizeColumnToContents( 1 );
147+
}
148+
else
149+
{
150+
mCustomVariablesTable->setColumnWidth( 1, 120 );
151+
}
152+
153+
// current environment variables
154+
mCurrentVariablesTable->horizontalHeader()->setFixedHeight( fmCustomVarH );
155+
QMap<QString, QString> sysVarsMap = QgsApplication::systemEnvVars();
156+
QStringList currentVarsList = QProcess::systemEnvironment();
157+
158+
foreach ( const QString &varStr, currentVarsList )
159+
{
160+
int pos = varStr.indexOf( QLatin1Char( '=' ) );
161+
if ( pos == -1 )
162+
continue;
163+
QStringList varStrItms;
164+
QString varStrName = varStr.left( pos );
165+
QString varStrValue = varStr.mid( pos + 1 );
166+
varStrItms << varStrName << varStrValue;
167+
168+
// check if different than system variable
169+
QString sysVarVal = QString( "" );
170+
bool sysVarMissing = !sysVarsMap.contains( varStrName );
171+
if ( sysVarMissing )
172+
sysVarVal = tr( "not present" );
173+
174+
if ( !sysVarMissing && sysVarsMap.value( varStrName ) != varStrValue )
175+
sysVarVal = sysVarsMap.value( varStrName );
176+
177+
if ( !sysVarVal.isEmpty() )
178+
sysVarVal = tr( "System value: %1" ).arg( sysVarVal );
179+
180+
int rowCnt = mCurrentVariablesTable->rowCount();
181+
mCurrentVariablesTable->insertRow( rowCnt );
182+
183+
QFont fItm;
184+
for ( int i = 0; i < varStrItms.size(); ++i )
185+
{
186+
QTableWidgetItem* varNameItm = new QTableWidgetItem( varStrItms.at( i ) );
187+
varNameItm->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable
188+
| Qt::ItemIsEditable | Qt::ItemIsDragEnabled );
189+
fItm = varNameItm->font();
190+
if ( !sysVarVal.isEmpty() )
191+
{
192+
fItm.setBold( true );
193+
varNameItm->setFont( fItm );
194+
varNameItm->setToolTip( sysVarVal );
195+
}
196+
mCurrentVariablesTable->setItem( rowCnt, i, varNameItm );
197+
}
198+
fItm.setBold( true );
199+
QFontMetrics fmRow( fItm );
200+
mCurrentVariablesTable->setRowHeight( rowCnt, fmRow.height() + 6 );
201+
}
202+
if ( mCurrentVariablesTable->rowCount() > 0 )
203+
mCurrentVariablesTable->resizeColumnToContents( 0 );
204+
113205
//local directories to search when loading c++ plugins
114206
QString myPaths = settings.value( "plugins/searchPathsForPlugins", "" ).toString();
115207
if ( !myPaths.isEmpty() )
@@ -781,6 +873,23 @@ void QgsOptions::saveOptions()
781873
{
782874
QSettings settings;
783875

876+
// custom environment variables
877+
settings.setValue( "qgis/customEnvVarsUse", QVariant( mCustomVariablesChkBx->isChecked() ) );
878+
QStringList customVars;
879+
for ( int i = 0; i < mCustomVariablesTable->rowCount(); ++i )
880+
{
881+
if ( mCustomVariablesTable->item( i, 1 )->text().isEmpty() )
882+
continue;
883+
QComboBox* varApplyCmbBx = qobject_cast<QComboBox*>( mCustomVariablesTable->cellWidget( i, 0 ) );
884+
QString customVar = varApplyCmbBx->itemData( varApplyCmbBx->currentIndex() ).toString();
885+
customVar += "|";
886+
customVar += mCustomVariablesTable->item( i, 1 )->text();
887+
customVar += "=";
888+
customVar += mCustomVariablesTable->item( i, 2 )->text();
889+
customVars << customVar;
890+
}
891+
settings.setValue( "qgis/customEnvVars", QVariant( customVars ) );
892+
784893
//search directories for user plugins
785894
QString myPaths;
786895
for ( int i = 0; i < mListPluginPaths->count(); ++i )
@@ -1211,6 +1320,74 @@ QStringList QgsOptions::i18nList()
12111320
return myList;
12121321
}
12131322

1323+
void QgsOptions::addCustomEnvVarRow( QString varName, QString varVal, QString varApply )
1324+
{
1325+
int rowCnt = mCustomVariablesTable->rowCount();
1326+
mCustomVariablesTable->insertRow( rowCnt );
1327+
1328+
QComboBox* varApplyCmbBx = new QComboBox( this );
1329+
varApplyCmbBx->addItem( tr( "Overwrite" ), QVariant( "overwrite" ) );
1330+
varApplyCmbBx->addItem( tr( "If Undefined" ), QVariant( "undefined" ) );
1331+
varApplyCmbBx->addItem( tr( "Unset" ), QVariant( "unset" ) );
1332+
varApplyCmbBx->addItem( tr( "Prepend" ), QVariant( "prepend" ) );
1333+
varApplyCmbBx->addItem( tr( "Append" ), QVariant( "append" ) );
1334+
varApplyCmbBx->setCurrentIndex( varApply.isEmpty() ? 0 : varApplyCmbBx->findData( QVariant( varApply ) ) );
1335+
1336+
QFont cbf = varApplyCmbBx->font();
1337+
QFontMetrics cbfm = QFontMetrics( cbf );
1338+
cbf.setPointSize( cbf.pointSize() - 2 );
1339+
varApplyCmbBx->setFont( cbf );
1340+
mCustomVariablesTable->setCellWidget( rowCnt, 0, varApplyCmbBx );
1341+
1342+
Qt::ItemFlags itmFlags = Qt::ItemIsEnabled | Qt::ItemIsSelectable
1343+
| Qt::ItemIsEditable | Qt::ItemIsDropEnabled;
1344+
1345+
QTableWidgetItem* varNameItm = new QTableWidgetItem( varName );
1346+
varNameItm->setFlags( itmFlags );
1347+
mCustomVariablesTable->setItem( rowCnt, 1, varNameItm );
1348+
1349+
QTableWidgetItem* varValueItm = new QTableWidgetItem( varVal );
1350+
varNameItm->setFlags( itmFlags );
1351+
mCustomVariablesTable->setItem( rowCnt, 2, varValueItm );
1352+
1353+
mCustomVariablesTable->setRowHeight( rowCnt, cbfm.height() + 8 );
1354+
}
1355+
1356+
void QgsOptions::on_mAddCustomVarBtn_clicked()
1357+
{
1358+
addCustomEnvVarRow( QString( "" ), QString( "" ) );
1359+
mCustomVariablesTable->setFocus();
1360+
mCustomVariablesTable->setCurrentCell( mCustomVariablesTable->rowCount() - 1, 1 );
1361+
mCustomVariablesTable->edit( mCustomVariablesTable->currentIndex() );
1362+
}
1363+
1364+
void QgsOptions::on_mRemoveCustomVarBtn_clicked()
1365+
{
1366+
mCustomVariablesTable->removeRow( mCustomVariablesTable->currentRow() );
1367+
}
1368+
1369+
void QgsOptions::on_mCurrentVariablesQGISChxBx_toggled( bool qgisSpecific )
1370+
{
1371+
for ( int i = mCurrentVariablesTable->rowCount() - 1; i >= 0; --i )
1372+
{
1373+
if ( qgisSpecific )
1374+
{
1375+
QString itmTxt = mCurrentVariablesTable->item( i, 0 )->text();
1376+
if ( !itmTxt.startsWith( "QGIS", Qt::CaseInsensitive ) )
1377+
mCurrentVariablesTable->hideRow( i );
1378+
}
1379+
else
1380+
{
1381+
mCurrentVariablesTable->showRow( i );
1382+
}
1383+
}
1384+
if ( mCurrentVariablesTable->rowCount() > 0 )
1385+
{
1386+
mCurrentVariablesTable->sortByColumn( 0, Qt::AscendingOrder );
1387+
mCurrentVariablesTable->resizeColumnToContents( 0 );
1388+
}
1389+
}
1390+
12141391
void QgsOptions::on_mBtnAddPluginPath_clicked()
12151392
{
12161393
QString myDir = QFileDialog::getExistingDirectory(

src/app/qgsoptions.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,21 @@ class QgsOptions : public QDialog, private Ui::QgsOptionsBase
117117
/**Remove an URL to exclude from Proxy*/
118118
void on_mRemoveUrlPushButton_clicked();
119119

120+
/** Slot to add a custom environment variable to the app
121+
* @note added in QGIS 1.9
122+
*/
123+
void on_mAddCustomVarBtn_clicked();
124+
125+
/** Slot to remove a custom environment variable from the app
126+
* @note added in QGIS 1.9
127+
*/
128+
void on_mRemoveCustomVarBtn_clicked();
129+
130+
/** Slot to filter out current environment variables not specific to QGIS
131+
* @note added in QGIS 1.9
132+
*/
133+
void on_mCurrentVariablesQGISChxBx_toggled( bool qgisSpecific );
134+
120135
/* Let the user add a path to the list of search paths
121136
* used for finding user Plugin libs.
122137
* @note added in QGIS 1.7
@@ -197,6 +212,10 @@ class QgsOptions : public QDialog, private Ui::QgsOptionsBase
197212
QgsCoordinateReferenceSystem mLayerDefaultCrs;
198213
bool mLoadedGdalDriverList;
199214

215+
/** Generate table row for custom environment variables
216+
* @note added in QGIS 1.9
217+
*/
218+
void addCustomEnvVarRow( QString varName, QString varVal, QString varApply = QString() );
200219
};
201220

202221
#endif // #ifndef QGSOPTIONS_H

src/core/qgsapplication.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <QFileOpenEvent>
2626
#include <QMessageBox>
2727
#include <QPalette>
28+
#include <QProcess>
2829
#include <QSettings>
2930
#include <QIcon>
3031
#include <QPixmap>
@@ -50,6 +51,7 @@ QString ABISYM( QgsApplication::mLibraryPath );
5051
QString ABISYM( QgsApplication::mLibexecPath );
5152
QString ABISYM( QgsApplication::mThemeName );
5253
QStringList ABISYM( QgsApplication::mDefaultSvgPaths );
54+
QMap<QString, QString> ABISYM( QgsApplication::mSystemEnvVars );
5355
QString ABISYM( QgsApplication::mConfigPath );
5456
bool ABISYM( QgsApplication::mRunningFromBuildDir ) = false;
5557
QString ABISYM( QgsApplication::mBuildSourcePath );
@@ -152,6 +154,19 @@ void QgsApplication::init( QString customConfigPath )
152154

153155
ABISYM( mDefaultSvgPaths ) << qgisSettingsDirPath() + QString( "svg/" );
154156

157+
// store system environment variables passed to application, before they are adjusted
158+
QMap<QString, QString> systemEnvVarMap;
159+
foreach ( const QString &varStr, QProcess::systemEnvironment() )
160+
{
161+
int pos = varStr.indexOf( QLatin1Char( '=' ) );
162+
if ( pos == -1 )
163+
continue;
164+
QString varStrName = varStr.left( pos );
165+
QString varStrValue = varStr.mid( pos + 1 );
166+
systemEnvVarMap.insert( varStrName, varStrValue );
167+
}
168+
ABISYM( mSystemEnvVars ) = systemEnvVarMap;
169+
155170
// set a working directory up for gdal to write .aux.xml files into
156171
// for cases where the raster dir is read only to the user
157172
// if the env var is already set it will be used preferentially

src/core/qgsapplication.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,10 @@ class CORE_EXPORT QgsApplication: public QApplication
120120
//! @note added in 1.4
121121
static const QStringList svgPaths();
122122

123+
//! Returns the system environment variables passed to application.
124+
//! @note added in 1.9
125+
static const QMap<QString, QString> systemEnvVars() { return ABISYM( mSystemEnvVars ); }
126+
123127
//! Returns the path to the application prefix directory.
124128
static const QString prefixPath();
125129

@@ -253,7 +257,7 @@ class CORE_EXPORT QgsApplication: public QApplication
253257
* GDAL_SKIP environment variable)
254258
* @note added in 2.0
255259
*/
256-
static QStringList skippedGdalDrivers( ) { return ABISYM( mGdalSkipList ); };
260+
static QStringList skippedGdalDrivers( ) { return ABISYM( mGdalSkipList ); }
257261

258262
/** Apply the skipped drivers list to gdal
259263
* @see skipGdalDriver
@@ -277,6 +281,7 @@ class CORE_EXPORT QgsApplication: public QApplication
277281
static QString ABISYM( mLibexecPath );
278282
static QString ABISYM( mThemeName );
279283
static QStringList ABISYM( mDefaultSvgPaths );
284+
static QMap<QString, QString> ABISYM( mSystemEnvVars );
280285

281286
static QString ABISYM( mConfigPath );
282287

0 commit comments

Comments
 (0)