Quantum GIS API Documentation  1.8
src/core/qgsapplication.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002     qgsapplication.cpp - Accessors for application-wide data
00003      --------------------------------------
00004     Date                 : 02-Jan-2006
00005     Copyright            : (C) 2006 by Tom Elwertowski
00006     Email                : telwertowski at users dot sourceforge dot net
00007  ***************************************************************************
00008  *                                                                         *
00009  *   This program is free software; you can redistribute it and/or modify  *
00010  *   it under the terms of the GNU General Public License as published by  *
00011  *   the Free Software Foundation; either version 2 of the License, or     *
00012  *   (at your option) any later version.                                   *
00013  *                                                                         *
00014  ***************************************************************************/
00015 
00016 #include "qgsapplication.h"
00017 #include "qgslogger.h"
00018 #include "qgsmaplayerregistry.h"
00019 #include "qgsproviderregistry.h"
00020 #include "qgsexception.h"
00021 #include "qgsgeometry.h"
00022 
00023 #include <QDir>
00024 #include <QFile>
00025 #include <QFileOpenEvent>
00026 #include <QMessageBox>
00027 #include <QPalette>
00028 #include <QSettings>
00029 
00030 #ifndef Q_WS_WIN
00031 #include <netinet/in.h>
00032 #else
00033 #include <winsock.h>
00034 #endif
00035 
00036 #include "qgsconfig.h"
00037 
00038 #include <gdal.h>
00039 #include <ogr_api.h>
00040 #include <cpl_conv.h> // for setting gdal options
00041 
00042 QObject * ABISYM( QgsApplication::mFileOpenEventReceiver );
00043 QStringList ABISYM( QgsApplication::mFileOpenEventList );
00044 QString ABISYM( QgsApplication::mPrefixPath );
00045 QString ABISYM( QgsApplication::mPluginPath );
00046 QString ABISYM( QgsApplication::mPkgDataPath );
00047 QString ABISYM( QgsApplication::mLibraryPath );
00048 QString ABISYM( QgsApplication::mLibexecPath );
00049 QString ABISYM( QgsApplication::mThemeName );
00050 QStringList ABISYM( QgsApplication::mDefaultSvgPaths );
00051 QString ABISYM( QgsApplication::mConfigPath );
00052 bool ABISYM( QgsApplication::mRunningFromBuildDir ) = false;
00053 QString ABISYM( QgsApplication::mBuildSourcePath );
00054 #ifdef _MSC_VER
00055 QString ABISYM( QgsApplication::mCfgIntDir );
00056 #endif
00057 QString ABISYM( QgsApplication::mBuildOutputPath );
00058 QStringList ABISYM( QgsApplication::mGdalSkipList );
00059 
00073 QgsApplication::QgsApplication( int & argc, char ** argv, bool GUIenabled, QString customConfigPath )
00074     : QApplication( argc, argv, GUIenabled )
00075 {
00076   init( customConfigPath ); // init can also be called directly by e.g. unit tests that don't inherit QApplication.
00077 }
00078 void QgsApplication::init( QString customConfigPath )
00079 {
00080   if ( customConfigPath.isEmpty() )
00081   {
00082     customConfigPath = QDir::homePath() + QString( "/.qgis/" );
00083   }
00084   qRegisterMetaType<QgsGeometry::Error>( "QgsGeometry::Error" );
00085 
00086   // check if QGIS is run from build directory (not the install directory)
00087   QDir appDir( applicationDirPath() );
00088 #ifndef _MSC_VER
00089 #define SOURCE_PATH "source_path.txt"
00090 #else
00091 #define SOURCE_PATH "../source_path.txt"
00092 #endif
00093   if ( appDir.exists( SOURCE_PATH ) )
00094   {
00095     QFile f( applicationDirPath() + "/" + SOURCE_PATH );
00096     if ( f.open( QIODevice::ReadOnly ) )
00097     {
00098       ABISYM( mRunningFromBuildDir ) = true;
00099       ABISYM( mBuildSourcePath ) = f.readAll();
00100 #if _MSC_VER
00101       QStringList elems = applicationDirPath().split( "/", QString::SkipEmptyParts );
00102       ABISYM( mCfgIntDir ) = elems.last();
00103       ABISYM( mBuildOutputPath ) = applicationDirPath() + "/../..";
00104 #elif defined(Q_WS_MACX)
00105       ABISYM( mBuildOutputPath ) = applicationDirPath();
00106 #else
00107       ABISYM( mBuildOutputPath ) = applicationDirPath() + "/.."; // on linux
00108 #endif
00109       qDebug( "Running from build directory!" );
00110       qDebug( "- source directory: %s", ABISYM( mBuildSourcePath ).toAscii().data() );
00111       qDebug( "- output directory of the build: %s", ABISYM( mBuildOutputPath ).toAscii().data() );
00112     }
00113   }
00114 
00115   if ( ABISYM( mRunningFromBuildDir ) )
00116   {
00117     // we run from source directory - not installed to destination (specified prefix)
00118     ABISYM( mPrefixPath ) = QString(); // set invalid path
00119 #ifdef _MSC_VER
00120     setPluginPath( ABISYM( mBuildOutputPath ) + "/" + QString( QGIS_PLUGIN_SUBDIR ) + "/" + ABISYM( mCfgIntDir ) );
00121 #else
00122     setPluginPath( ABISYM( mBuildOutputPath ) + "/" + QString( QGIS_PLUGIN_SUBDIR ) );
00123 #endif
00124     setPkgDataPath( ABISYM( mBuildSourcePath ) ); // directly source path - used for: doc, resources, svg
00125     ABISYM( mLibraryPath ) = ABISYM( mBuildOutputPath ) + "/" + QGIS_LIB_SUBDIR + "/";
00126     ABISYM( mLibexecPath ) = ABISYM( mBuildOutputPath ) + "/" + QGIS_LIBEXEC_SUBDIR + "/";
00127   }
00128   else
00129   {
00130 #if defined(Q_WS_MACX) || defined(Q_WS_WIN32) || defined(WIN32)
00131     setPrefixPath( applicationDirPath(), true );
00132 #else
00133     QDir myDir( applicationDirPath() );
00134     myDir.cdUp();
00135     QString myPrefix = myDir.absolutePath();
00136     setPrefixPath( myPrefix, true );
00137 #endif
00138   }
00139 
00140   if ( !customConfigPath.isEmpty() )
00141   {
00142     ABISYM( mConfigPath ) = customConfigPath + "/"; // make sure trailing slash is included
00143   }
00144 
00145   ABISYM( mDefaultSvgPaths ) << qgisSettingsDirPath() + QString( "svg/" );
00146 
00147   // set a working directory up for gdal to write .aux.xml files into
00148   // for cases where the raster dir is read only to the user
00149   // if the env var is already set it will be used preferentially
00150   QString myPamPath = qgisSettingsDirPath() + QString( "gdal_pam/" );
00151   QDir myDir( myPamPath );
00152   if ( !myDir.exists() )
00153   {
00154     myDir.mkpath( myPamPath ); //fail silently
00155   }
00156 
00157 
00158 #if defined(Q_WS_WIN32) || defined(WIN32)
00159   CPLSetConfigOption( "GDAL_PAM_PROXY_DIR", myPamPath.toUtf8() );
00160 #else
00161   //under other OS's we use an environment var so the user can
00162   //override the path if he likes
00163   int myChangeFlag = 0; //whether we want to force the env var to change
00164   setenv( "GDAL_PAM_PROXY_DIR", myPamPath.toUtf8(), myChangeFlag );
00165 #endif
00166 }
00167 
00168 QgsApplication::~QgsApplication()
00169 {
00170 }
00171 
00172 bool QgsApplication::event( QEvent * event )
00173 {
00174   bool done = false;
00175   if ( event->type() == QEvent::FileOpen )
00176   {
00177     // handle FileOpen event (double clicking a file icon in Mac OS X Finder)
00178     if ( ABISYM( mFileOpenEventReceiver ) )
00179     {
00180       // Forward event to main window.
00181       done = notify( ABISYM( mFileOpenEventReceiver ), event );
00182     }
00183     else
00184     {
00185       // Store filename because receiver has not registered yet.
00186       // If QGIS has been launched by double clicking a file icon, FileOpen will be
00187       // the first event; the main window is not yet ready to handle the event.
00188       ABISYM( mFileOpenEventList ).append( static_cast<QFileOpenEvent *>( event )->file() );
00189       done = true;
00190     }
00191   }
00192   else
00193   {
00194     // pass other events to base class
00195     done = QApplication::event( event );
00196   }
00197   return done;
00198 }
00199 
00200 bool QgsApplication::notify( QObject * receiver, QEvent * event )
00201 {
00202   bool done = false;
00203   // Crashes  in customization (especially on Mac), if we're not in the main/UI thread, see #5597
00204   if ( thread() == receiver->thread() )
00205     emit preNotify( receiver, event, &done );
00206 
00207   if ( done )
00208     return true;
00209 
00210   // Send event to receiver and catch unhandled exceptions
00211   done = true;
00212   try
00213   {
00214     done = QApplication::notify( receiver, event );
00215   }
00216   catch ( QgsException & e )
00217   {
00218     QMessageBox::critical( activeWindow(), tr( "Exception" ), e.what() );
00219   }
00220   catch ( std::exception & e )
00221   {
00222     QMessageBox::critical( activeWindow(), tr( "Exception" ), e.what() );
00223   }
00224   catch ( ... )
00225   {
00226     QMessageBox::critical( activeWindow(), tr( "Exception" ), tr( "unknown exception" ) );
00227   }
00228 
00229   return done;
00230 }
00231 
00232 void QgsApplication::setFileOpenEventReceiver( QObject * receiver )
00233 {
00234   // Set receiver for FileOpen events
00235   ABISYM( mFileOpenEventReceiver ) = receiver;
00236   // Propagate any events collected before the receiver has registered.
00237   if ( ABISYM( mFileOpenEventList ).count() > 0 )
00238   {
00239     QStringListIterator i( ABISYM( mFileOpenEventList ) );
00240     while ( i.hasNext() )
00241     {
00242       QFileOpenEvent foe( i.next() );
00243       QgsApplication::sendEvent( ABISYM( mFileOpenEventReceiver ), &foe );
00244     }
00245     ABISYM( mFileOpenEventList ).clear();
00246   }
00247 }
00248 
00249 void QgsApplication::setPrefixPath( const QString thePrefixPath, bool useDefaultPaths )
00250 {
00251   ABISYM( mPrefixPath ) = thePrefixPath;
00252 #if defined(_MSC_VER)
00253   if ( ABISYM( mPrefixPath ).endsWith( "/bin" ) )
00254   {
00255     ABISYM( mPrefixPath ).chop( 4 );
00256   }
00257 #endif
00258   if ( useDefaultPaths )
00259   {
00260     setPluginPath( ABISYM( mPrefixPath ) + "/" + QString( QGIS_PLUGIN_SUBDIR ) );
00261     setPkgDataPath( ABISYM( mPrefixPath ) + "/" + QString( QGIS_DATA_SUBDIR ) );
00262   }
00263   ABISYM( mLibraryPath ) = ABISYM( mPrefixPath ) + "/" + QGIS_LIB_SUBDIR + "/";
00264   ABISYM( mLibexecPath ) = ABISYM( mPrefixPath ) + "/" + QGIS_LIBEXEC_SUBDIR + "/";
00265 }
00266 
00267 void QgsApplication::setPluginPath( const QString thePluginPath )
00268 {
00269   ABISYM( mPluginPath ) = thePluginPath;
00270 }
00271 
00272 void QgsApplication::setPkgDataPath( const QString thePkgDataPath )
00273 {
00274   ABISYM( mPkgDataPath ) = thePkgDataPath;
00275   QString mySvgPath = thePkgDataPath + ( ABISYM( mRunningFromBuildDir ) ? "/images/svg/" : "/svg/" );
00276   // avoid duplicate entries
00277   if ( !ABISYM( mDefaultSvgPaths ).contains( mySvgPath ) )
00278     ABISYM( mDefaultSvgPaths ) << mySvgPath;
00279 }
00280 
00281 void QgsApplication::setDefaultSvgPaths( const QStringList& pathList )
00282 {
00283   ABISYM( mDefaultSvgPaths ) = pathList;
00284 }
00285 
00286 const QString QgsApplication::prefixPath()
00287 {
00288   if ( ABISYM( mRunningFromBuildDir ) )
00289   {
00290     qWarning( "!!! prefix path was requested, but it is not valid - we do not run from installed path !!!" );
00291   }
00292 
00293   return ABISYM( mPrefixPath );
00294 }
00295 const QString QgsApplication::pluginPath()
00296 {
00297   return ABISYM( mPluginPath );
00298 }
00299 const QString QgsApplication::pkgDataPath()
00300 {
00301   return ABISYM( mPkgDataPath );
00302 }
00303 const QString QgsApplication::defaultThemePath()
00304 {
00305   return ":/images/themes/default/";
00306 }
00307 const QString QgsApplication::activeThemePath()
00308 {
00309   return ":/images/themes/" + themeName() + "/";
00310 }
00311 
00312 
00313 QString QgsApplication::iconPath( QString iconFile )
00314 {
00315   // try active theme
00316   QString path = activeThemePath();
00317   if ( QFile::exists( path + iconFile ) )
00318     return path + iconFile;
00319 
00320   // use default theme
00321   return defaultThemePath() + iconFile;
00322 }
00323 
00327 void QgsApplication::setThemeName( const QString theThemeName )
00328 {
00329   QString myPath = ":/images/themes/" + theThemeName + "/";
00330   //check it exists and if not roll back to default theme
00331   if ( QFile::exists( myPath ) )
00332   {
00333     ABISYM( mThemeName ) = theThemeName;
00334   }
00335   else
00336   {
00337     ABISYM( mThemeName ) = "default";
00338   }
00339 }
00343 const QString QgsApplication::themeName()
00344 {
00345   return ABISYM( mThemeName );
00346 }
00350 const QString QgsApplication::authorsFilePath()
00351 {
00352   return ABISYM( mPkgDataPath ) + QString( "/doc/AUTHORS" );
00353 }
00357 const QString QgsApplication::contributorsFilePath()
00358 {
00359   return ABISYM( mPkgDataPath ) + QString( "/doc/CONTRIBUTORS" );
00360 }
00364 const QString QgsApplication::sponsorsFilePath()
00365 {
00366   return ABISYM( mPkgDataPath ) + QString( "/doc/SPONSORS" );
00367 }
00368 
00372 const QString QgsApplication::donorsFilePath()
00373 {
00374   return ABISYM( mPkgDataPath ) + QString( "/doc/DONORS" );
00375 }
00376 
00381 const QString QgsApplication::translatorsFilePath()
00382 {
00383   return ABISYM( mPkgDataPath ) + QString( "/doc/TRANSLATORS" );
00384 }
00385 
00386 const QString QgsApplication::developerPath()
00387 {
00388   return QString(); // developer images are no longer shipped!
00389 }
00390 
00394 const QString QgsApplication::helpAppPath()
00395 {
00396   QString helpAppPath;
00397 #ifdef Q_OS_MACX
00398   helpAppPath = applicationDirPath() + "/bin/qgis_help.app/Contents/MacOS";
00399 #else
00400   helpAppPath = libexecPath();
00401 #endif
00402   helpAppPath += "/qgis_help";
00403   return helpAppPath;
00404 }
00408 const QString QgsApplication::i18nPath()
00409 {
00410   if ( ABISYM( mRunningFromBuildDir ) )
00411     return ABISYM( mBuildOutputPath ) + QString( "/i18n" );
00412   else
00413     return ABISYM( mPkgDataPath ) + QString( "/i18n/" );
00414 }
00415 
00419 const QString QgsApplication::qgisMasterDbFilePath()
00420 {
00421   return ABISYM( mPkgDataPath ) + QString( "/resources/qgis.db" );
00422 }
00423 
00427 const QString QgsApplication::qgisSettingsDirPath()
00428 {
00429   return ABISYM( mConfigPath );
00430 }
00431 
00435 const QString QgsApplication::qgisUserDbFilePath()
00436 {
00437   return qgisSettingsDirPath() + QString( "qgis.db" );
00438 }
00439 
00443 const QString QgsApplication::splashPath()
00444 {
00445   return QString( ":/images/splash/" );
00446 }
00447 
00451 const QString QgsApplication::iconsPath()
00452 {
00453   return ABISYM( mPkgDataPath ) + QString( "/images/icons/" );
00454 }
00458 const QString QgsApplication::srsDbFilePath()
00459 {
00460   if ( ABISYM( mRunningFromBuildDir ) )
00461   {
00462     QString tempCopy = QDir::tempPath() + "/srs.db";
00463 
00464     if ( !QFile( tempCopy ).exists() )
00465     {
00466       QFile f( ABISYM( mPkgDataPath ) + "/resources/srs.db" );
00467       if ( !f.copy( tempCopy ) )
00468       {
00469         qFatal( "Could not create temporary copy" );
00470       }
00471     }
00472 
00473     return tempCopy;
00474   }
00475   else
00476   {
00477     return ABISYM( mPkgDataPath ) + QString( "/resources/srs.db" );
00478   }
00479 }
00480 
00484 const QStringList QgsApplication::svgPaths()
00485 {
00486   //local directories to search when looking for an SVG with a given basename
00487   //defined by user in options dialog
00488   QSettings settings;
00489   QStringList myPathList;
00490   QString myPaths = settings.value( "svg/searchPathsForSVG", "" ).toString();
00491   if ( !myPaths.isEmpty() )
00492   {
00493     myPathList = myPaths.split( "|" );
00494   }
00495 
00496   myPathList << ABISYM( mDefaultSvgPaths );
00497   return myPathList;
00498 }
00499 
00503 const QString QgsApplication::svgPath()
00504 {
00505   QString svgSubDir( ABISYM( mRunningFromBuildDir ) ? "/images/svg/" : "/svg/" );
00506   return ABISYM( mPkgDataPath ) + svgSubDir;
00507 }
00508 
00509 const QString QgsApplication::userStyleV2Path()
00510 {
00511   return qgisSettingsDirPath() + QString( "symbology-ng-style.xml" );
00512 }
00513 
00514 const QString QgsApplication::defaultStyleV2Path()
00515 {
00516   return ABISYM( mPkgDataPath ) + QString( "/resources/symbology-ng-style.xml" );
00517 }
00518 
00519 const QString QgsApplication::libraryPath()
00520 {
00521   return ABISYM( mLibraryPath );
00522 }
00523 
00524 const QString QgsApplication::libexecPath()
00525 {
00526   return ABISYM( mLibexecPath );
00527 }
00528 
00529 QgsApplication::endian_t QgsApplication::endian()
00530 {
00531   return ( htonl( 1 ) == 1 ) ? XDR : NDR ;
00532 }
00533 
00534 void QgsApplication::initQgis()
00535 {
00536   // set the provider plugin path (this creates provider registry)
00537   QgsProviderRegistry::instance( pluginPath() );
00538 
00539   // create map layer registry if doesn't exist
00540   QgsMapLayerRegistry::instance();
00541 }
00542 
00543 void QgsApplication::exitQgis()
00544 {
00545   delete QgsMapLayerRegistry::instance();
00546   delete QgsProviderRegistry::instance();
00547 }
00548 
00549 QString QgsApplication::showSettings()
00550 {
00551   QString myState = tr( "Application state:\n"
00552                         "Prefix:\t\t%1\n"
00553                         "Plugin Path:\t\t%2\n"
00554                         "Package Data Path:\t%3\n"
00555                         "Active Theme Name:\t%4\n"
00556                         "Active Theme Path:\t%5\n"
00557                         "Default Theme Path:\t%6\n"
00558                         "SVG Search Paths:\t%7\n"
00559                         "User DB Path:\t%8\n" )
00560                     .arg( prefixPath() )
00561                     .arg( pluginPath() )
00562                     .arg( pkgDataPath() )
00563                     .arg( themeName() )
00564                     .arg( activeThemePath() )
00565                     .arg( defaultThemePath() )
00566                     .arg( svgPaths().join( tr( "\n\t\t", "match indentation of application state" ) ) )
00567                     .arg( qgisMasterDbFilePath() );
00568   return myState;
00569 }
00570 
00571 QString QgsApplication::reportStyleSheet()
00572 {
00573   //
00574   // Make the style sheet desktop preferences aware by using qappliation
00575   // palette as a basis for colors where appropriate
00576   //
00577   QColor myColor1 = palette().highlight().color();
00578   QColor myColor2 = myColor1;
00579   myColor2 = myColor2.lighter( 110 ); //10% lighter
00580   QString myStyle;
00581   myStyle = "p.glossy{ background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, "
00582             "stop: 0 " + myColor1.name()  + ","
00583             "stop: 0.1 " + myColor2.name() + ","
00584             "stop: 0.5 " + myColor1.name()  + ","
00585             "stop: 0.9 " + myColor2.name() + ","
00586             "stop: 1 " + myColor1.name() + ");"
00587             "color: white;"
00588             "padding-left: 4px;"
00589             "padding-top: 20px;"
00590             "padding-bottom: 8px;"
00591             "border: 1px solid #6c6c6c;"
00592             "}"
00593             "th.glossy{ background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, "
00594             "stop: 0 " + myColor1.name()  + ","
00595             "stop: 0.1 " + myColor2.name() + ","
00596             "stop: 0.5 " + myColor1.name()  + ","
00597             "stop: 0.9 " + myColor2.name() + ","
00598             "stop: 1 " + myColor1.name() + ");"
00599             "color: white;"
00600             "border: 1px solid #6c6c6c;"
00601             "}"
00602             ".overview{ font: 1.82em; font-weight: bold;}"
00603             "body{  background: white;"
00604             "  color: black;"
00605             "  font-family: arial,sans-serif;"
00606             "}"
00607             "h1{  background-color: #F6F6F6;"
00608             "  color: #8FB171; "
00609             "  font-size: x-large;  "
00610             "  font-weight: normal;"
00611             "  font-family: luxi serif, georgia, times new roman, times, serif;"
00612             "  background: none;"
00613             "  padding: 0.75em 0 0;"
00614             "  margin: 0;"
00615             "  line-height: 3em;"
00616             "}"
00617             "h2{  background-color: #F6F6F6;"
00618             "  color: #8FB171; "
00619             "  font-size: medium;  "
00620             "  font-weight: normal;"
00621             "  font-family: luxi serif, georgia, times new roman, times, serif;"
00622             "  background: none;"
00623             "  padding: 0.75em 0 0;"
00624             "  margin: 0;"
00625             "  line-height: 1.1em;"
00626             "}"
00627             "h3{  background-color: #F6F6F6;"
00628             "  color: #729FCF;"
00629             "  font-family: luxi serif, georgia, times new roman, times, serif;"
00630             "  font-weight: bold;"
00631             "  font-size: large;"
00632             "  text-align: right;"
00633             "  border-bottom: 5px solid #DCEB5C;"
00634             "}"
00635             "h4{  background-color: #F6F6F6;"
00636             "  color: #729FCF;"
00637             "  font-family: luxi serif, georgia, times new roman, times, serif;"
00638             "  font-weight: bold;"
00639             "  font-size: medium;"
00640             "  text-align: right;"
00641             "}"
00642             "h5{    background-color: #F6F6F6;"
00643             "   color: #729FCF;"
00644             "   font-family: luxi serif, georgia, times new roman, times, serif;"
00645             "   font-weight: bold;"
00646             "   font-size: small;"
00647             "   text-align: right;"
00648             "}"
00649             "a{  color: #729FCF;"
00650             "  font-family: arial,sans-serif;"
00651             "  font-size: small;"
00652             "}"
00653             "label{  background-color: #FFFFCC;"
00654             "  border: 1px solid black;"
00655             "  margin: 1px;"
00656             "  padding: 0px 3px; "
00657             "  font-size: small;"
00658             "}";
00659   return myStyle;
00660 }
00661 
00662 void QgsApplication::registerOgrDrivers()
00663 {
00664   if ( 0 >= OGRGetDriverCount() )
00665   {
00666     OGRRegisterAll();
00667   }
00668 }
00669 
00670 QString QgsApplication::absolutePathToRelativePath( QString aPath, QString targetPath )
00671 {
00672 #if defined( Q_OS_WIN )
00673   const Qt::CaseSensitivity cs = Qt::CaseInsensitive;
00674 
00675   aPath.replace( "\\", "/" );
00676   if ( aPath.startsWith( "//" ) )
00677   {
00678     // keep UNC prefix
00679     aPath = "\\\\" + aPath.mid( 2 );
00680   }
00681 
00682   targetPath.replace( "\\", "/" );
00683   if ( targetPath.startsWith( "//" ) )
00684   {
00685     // keep UNC prefix
00686     targetPath = "\\\\" + targetPath.mid( 2 );
00687   }
00688 #else
00689   const Qt::CaseSensitivity cs = Qt::CaseSensitive;
00690 #endif
00691 
00692   QStringList targetElems = targetPath.split( "/", QString::SkipEmptyParts );
00693   QStringList aPathElems = aPath.split( "/", QString::SkipEmptyParts );
00694 
00695   targetElems.removeAll( "." );
00696   aPathElems.removeAll( "." );
00697 
00698   // remove common part
00699   int n = 0;
00700   while ( aPathElems.size() > 0 &&
00701           targetElems.size() > 0 &&
00702           aPathElems[0].compare( targetElems[0], cs ) == 0 )
00703   {
00704     aPathElems.removeFirst();
00705     targetElems.removeFirst();
00706     n++;
00707   }
00708 
00709   if ( n == 0 )
00710   {
00711     // no common parts; might not even be a file
00712     return aPath;
00713   }
00714 
00715   if ( targetElems.size() > 0 )
00716   {
00717     // go up to the common directory
00718     for ( int i = 0; i < targetElems.size(); i++ )
00719     {
00720       aPathElems.insert( 0, ".." );
00721     }
00722   }
00723   else
00724   {
00725     // let it start with . nevertheless,
00726     // so relative path always start with either ./ or ../
00727     aPathElems.insert( 0, "." );
00728   }
00729 
00730   return aPathElems.join( "/" );
00731 }
00732 
00733 QString QgsApplication::relativePathToAbsolutePath( QString rpath, QString targetPath )
00734 {
00735   // relative path should always start with ./ or ../
00736   if ( !rpath.startsWith( "./" ) && !rpath.startsWith( "../" ) )
00737   {
00738     return rpath;
00739   }
00740 
00741 #if defined(Q_OS_WIN)
00742   rpath.replace( "\\", "/" );
00743   targetPath.replace( "\\", "/" );
00744 
00745   bool uncPath = targetPath.startsWith( "//" );
00746 #endif
00747 
00748   QStringList srcElems = rpath.split( "/", QString::SkipEmptyParts );
00749   QStringList targetElems = targetPath.split( "/", QString::SkipEmptyParts );
00750 
00751 #if defined(Q_OS_WIN)
00752   if ( uncPath )
00753   {
00754     targetElems.insert( 0, "" );
00755     targetElems.insert( 0, "" );
00756   }
00757 #endif
00758 
00759   // append source path elements
00760   targetElems << srcElems;
00761   targetElems.removeAll( "." );
00762 
00763   // resolve ..
00764   int pos;
00765   while (( pos = targetElems.indexOf( ".." ) ) > 0 )
00766   {
00767     // remove preceding element and ..
00768     targetElems.removeAt( pos - 1 );
00769     targetElems.removeAt( pos - 1 );
00770   }
00771 
00772 #if !defined(Q_OS_WIN)
00773   // make path absolute
00774   targetElems.prepend( "" );
00775 #endif
00776 
00777   return targetElems.join( "/" );
00778 }
00779 
00780 void QgsApplication::skipGdalDriver( QString theDriver )
00781 {
00782   if ( ABISYM( mGdalSkipList ).contains( theDriver ) || theDriver.isEmpty() )
00783   {
00784     return;
00785   }
00786   ABISYM( mGdalSkipList ) << theDriver;
00787   applyGdalSkippedDrivers();
00788 }
00789 
00790 void QgsApplication::restoreGdalDriver( QString theDriver )
00791 {
00792   if ( !ABISYM( mGdalSkipList ).contains( theDriver ) )
00793   {
00794     return;
00795   }
00796   int myPos = ABISYM( mGdalSkipList ).indexOf( theDriver );
00797   if ( myPos >= 0 )
00798   {
00799     ABISYM( mGdalSkipList ).removeAt( myPos );
00800   }
00801   applyGdalSkippedDrivers();
00802 }
00803 
00804 void QgsApplication::applyGdalSkippedDrivers()
00805 {
00806   ABISYM( mGdalSkipList ).removeDuplicates();
00807   QString myDriverList = ABISYM( mGdalSkipList ).join( " " );
00808   QgsDebugMsg( "Gdal Skipped driver list set to:" );
00809   QgsDebugMsg( myDriverList );
00810   CPLSetConfigOption( "GDAL_SKIP", myDriverList.toUtf8() );
00811   GDALAllRegister(); //to update driver list and skip missing ones
00812 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines