From 4073676f7b71a7b3c2eb78b9ee64656310ddb1c7 Mon Sep 17 00:00:00 2001 From: akl Date: Mon, 16 Feb 2009 13:10:05 +0000 Subject: [PATCH] Fix of bug 20878 (5x regressions of "Quick directory list"): correct processing of paths if there are environment variables. --- src/Qtx/Qtx.cxx | 93 +++++++++++++++++++++++++++++++++++++ src/Qtx/Qtx.h | 9 ++++ src/Qtx/QtxPathEdit.cxx | 4 +- src/Qtx/QtxPathListEdit.cxx | 9 ++-- src/Qtx/QtxResourceMgr.cxx | 51 +------------------- 5 files changed, 110 insertions(+), 56 deletions(-) diff --git a/src/Qtx/Qtx.cxx b/src/Qtx/Qtx.cxx index c60344a4f..b6ce38713 100755 --- a/src/Qtx/Qtx.cxx +++ b/src/Qtx/Qtx.cxx @@ -627,6 +627,99 @@ QCompleter* Qtx::pathCompleter( const PathType type, const QString& filter ) return cmp; } +/*! + \brief Parse given string to retrieve environment variable. + + Looks through the string for the patterns: ${name} or $(name) or %name%. + If string contains variable satisfying any pattern, the variable name + is returned, start index of the variable is returned in the \a start parameter, + and length of the variable is returned in the \a len parameter. + + \param str string being processed + \param start if variable is found, this parameter contains its starting + position in the \a str + \param len if variable is found, this parameter contains its length + \return first found variable or null QString if there is no ones +*/ +QString Qtx::findEnvVar( const QString& str, int& start, int& len ) +{ + QString varName; + len = 0; + + QRegExp rx( "(^\\$\\{|[^\\$]\\$\\{)([a-zA-Z]+[a-zA-Z0-9_]*)(\\})|(^\\$\\(|[^\\$]\\$\\()([a-zA-Z]+[a-zA-Z0-9_]*)(\\))|(^\\$|[^\\$]\\$)([a-zA-Z]+[a-zA-Z0-9_]*)|(^%|[^%]%)([a-zA-Z]+[a-zA-Z0-9_]*)(%[^%]|%$)" ); + + int pos = rx.indexIn( str, start ); + if ( pos != -1 ) + { + int i = 1; + while ( i <= rx.numCaptures() && varName.isEmpty() ) + { + QString capStr = rx.cap( i ); + if ( !capStr.contains( "%" ) && !capStr.contains( "$" ) ) + varName = capStr; + i++; + } + + if ( !varName.isEmpty() ) + { + int capIdx = i - 1; + start = rx.pos( capIdx ); + int end = start + varName.length(); + if ( capIdx > 1 && rx.cap( capIdx - 1 ).contains( QRegExp( "\\$|%" ) ) ) + start = rx.pos( capIdx - 1 ) + rx.cap( capIdx - 1 ).indexOf( QRegExp( "\\$|%" ) ); + if ( capIdx < rx.numCaptures() && !rx.cap( capIdx - 1 ).isEmpty() ) + end++; + len = end - start; + } + } + return varName; +} + +/*! + \brief Substitute environment variables by their values. + + Environment variable is substituted by its value. + + \param str string to be processed + \return processed string (with all substitutions made) +*/ +QString Qtx::makeEnvVarSubst( const QString& str, const SubstMode mode ) +{ + QString res = str; + if ( mode != Never ) + { + QMap ignoreMap; + + int start( 0 ), len( 0 ); + while ( true ) + { + QString envName = findEnvVar( res, start, len ); + if ( envName.isNull() ) + break; + + QString newStr; + if ( ::getenv( envName.toLatin1() ) || mode == Always ) + newStr = QString( ::getenv( envName.toLatin1() ) ); + + if ( newStr.isNull() ) + { + if ( ignoreMap.contains( envName ) ) + { + start += len; + continue; + } + ignoreMap.insert( envName, 0 ); + } + res.replace( start, len, newStr ); + } + + res.replace( "$$", "$" ); + res.replace( "%%", "%" ); + } + + return res; +} + /*! \brief Pack the specified color into integer RGB set. \param c unpacked color diff --git a/src/Qtx/Qtx.h b/src/Qtx/Qtx.h index 6960d4d96..19f6faf27 100755 --- a/src/Qtx/Qtx.h +++ b/src/Qtx/Qtx.h @@ -105,6 +105,13 @@ public: Toggled //!< it should be possible to show/hide the column with help of popup menu } Appropriate; //!< appropriate status + //! Environment variables substitution mode + typedef enum { + Always, //!< substitute environment variable by it's value if variable exists, and "" otherwise + Never, //!< keep environment variable as is without any substitution + Auto //!< substitute environment variable by it's value if variable exists, and keep it as is otherwise + } SubstMode; + static QString toQString( const char*, const int = -1 ); static QString toQString( const short*, const int = -1 ); static QString toQString( const unsigned char*, const int = -1 ); @@ -132,6 +139,8 @@ public: static QString addSlash( const QString& ); static QCompleter* pathCompleter( const PathType, const QString& = QString() ); + static QString findEnvVar( const QString&, int&, int& ); + static QString makeEnvVarSubst( const QString&, const SubstMode = Auto ); static int rgbSet( const QColor& ); static int rgbSet( const int, const int, const int ); diff --git a/src/Qtx/QtxPathEdit.cxx b/src/Qtx/QtxPathEdit.cxx index 1504448d6..6075340fc 100644 --- a/src/Qtx/QtxPathEdit.cxx +++ b/src/Qtx/QtxPathEdit.cxx @@ -190,7 +190,7 @@ void QtxPathEdit::setPathFilter( const QString& f ) void QtxPathEdit::onBrowse( bool /*on*/ ) { QString path; - QString initial = QFileInfo( myPath->text() ).path(); + QString initial = QFileInfo( Qtx::makeEnvVarSubst( myPath->text() ) ).filePath(); switch ( pathType() ) { case Qtx::PT_OpenFile: @@ -229,7 +229,7 @@ void QtxPathEdit::initialize() base->setSpacing( 5 ); base->addWidget( myPath = new QLineEdit( this ) ); - myPath->setValidator( new QRegExpValidator( QRegExp( "^([\\w/]{2}|[A-Z]:)[^:;\\*\\?]*[\\w\\\\/\\.]$" ), myPath ) ); + myPath->setValidator( new QRegExpValidator( QRegExp( "^([\\$]|[\\%]|[\\w/]{2}|[A-Z]:)[^:;\\*\\?]*[\\w\\\\/\\.]$" ), myPath ) ); QToolButton* browse = new QToolButton( this ); browse->setIcon( QPixmap( browse_icon ) ); diff --git a/src/Qtx/QtxPathListEdit.cxx b/src/Qtx/QtxPathListEdit.cxx index 37c33aa0c..e15173b89 100644 --- a/src/Qtx/QtxPathListEdit.cxx +++ b/src/Qtx/QtxPathListEdit.cxx @@ -764,22 +764,23 @@ bool QtxPathListEdit::checkExistance( const QString& str, const bool msg ) if ( pathType() == Qtx::PT_SaveFile ) return true; - bool ok = QFileInfo( str ).exists(); + QFileInfo aFI = QFileInfo( Qtx::makeEnvVarSubst( str ) ); + bool ok = aFI.exists(); if ( !ok && msg ) ok = QMessageBox::question( this, tr( "Warning" ), tr( "Path \"%1\" doesn't exist. Add it to list anyway?" ).arg( str ), QMessageBox::Yes, QMessageBox::No ) == QMessageBox::Yes; - if ( ok && QFileInfo( str ).exists() ) + if ( ok && aFI.exists() ) { switch ( pathType() ) { case Qtx::PT_OpenFile: - ok = QFileInfo( str ).isFile(); + ok = aFI.isFile(); if ( !ok && msg ) QMessageBox::warning( this, tr( "Error" ), tr( "Location \"%1\" doesn't point to file" ).arg( str ) ); break; case Qtx::PT_Directory: - ok = QFileInfo( str ).isDir(); + ok = aFI.isDir(); if ( !ok && msg ) QMessageBox::warning( this, tr( "Error" ), tr( "Location \"%1\" doesn't point to directory" ).arg( str ) ); break; diff --git a/src/Qtx/QtxResourceMgr.cxx b/src/Qtx/QtxResourceMgr.cxx index cf91632aa..a273d8bce 100644 --- a/src/Qtx/QtxResourceMgr.cxx +++ b/src/Qtx/QtxResourceMgr.cxx @@ -65,7 +65,6 @@ public: QPixmap loadPixmap( const QString&, const QString&, const QString& ) const; QTranslator* loadTranslator( const QString&, const QString&, const QString& ) const; - QString environmentVariable( const QString&, int&, int& ) const; QString makeSubstitution( const QString&, const QString&, const QString& ) const; void clear(); @@ -398,54 +397,6 @@ QTranslator* QtxResourceMgr::Resources::loadTranslator( const QString& sect, con return trans; } -/*! - \brief Parse given string to retrieve environment variable. - - Looks through the string for the patterns: ${name} or $(name) or %name%. - If string contains variable satisfying any pattern, the variable name - is returned, start index of the variable is returned in the \a start parameter, - and length of the variable is returned in the \a len parameter. - - \param str string being processed - \param start if variable is found, this parameter contains its starting - position in the \a str - \param len if variable is found, this parameter contains its length - \return first found variable or null QString if there is no ones -*/ -QString QtxResourceMgr::Resources::environmentVariable( const QString& str, int& start, int& len ) const -{ - QString varName; - len = 0; - - QRegExp rx( "(^\\$\\{|[^\\$]\\$\\{)([a-zA-Z]+[a-zA-Z0-9_]*)(\\})|(^\\$\\(|[^\\$]\\$\\()([a-zA-Z]+[a-zA-Z0-9_]*)(\\))|(^\\$|[^\\$]\\$)([a-zA-Z]+[a-zA-Z0-9_]*)|(^%|[^%]%)([a-zA-Z]+[a-zA-Z0-9_]*)(%[^%]|%$)" ); - - int pos = rx.indexIn( str, start ); - if ( pos != -1 ) - { - int i = 1; - while ( i <= rx.numCaptures() && varName.isEmpty() ) - { - QString capStr = rx.cap( i ); - if ( !capStr.contains( "%" ) && !capStr.contains( "$" ) ) - varName = capStr; - i++; - } - - if ( !varName.isEmpty() ) - { - int capIdx = i - 1; - start = rx.pos( capIdx ); - int end = start + varName.length(); - if ( capIdx > 1 && rx.cap( capIdx - 1 ).contains( QRegExp( "\\$|%" ) ) ) - start = rx.pos( capIdx - 1 ) + rx.cap( capIdx - 1 ).indexOf( QRegExp( "\\$|%" ) ); - if ( capIdx < rx.numCaptures() && !rx.cap( capIdx - 1 ).isEmpty() ) - end++; - len = end - start; - } - } - return varName; -} - /*! \brief Substitute variables by their values. @@ -467,7 +418,7 @@ QString QtxResourceMgr::Resources::makeSubstitution( const QString& str, const Q int start( 0 ), len( 0 ); while ( true ) { - QString envName = environmentVariable( res, start, len ); + QString envName = Qtx::findEnvVar( res, start, len ); if ( envName.isNull() ) break; -- 2.39.2