Quantum GIS API Documentation  1.7.4
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 /* $Id$ */
00016 
00017 #include "qgsapplication.h"
00018 #include "qgsmaplayerregistry.h"
00019 #include "qgsproviderregistry.h"
00020 #include "qgsexception.h"
00021 
00022 #include <QDir>
00023 #include <QFileOpenEvent>
00024 #include <QMessageBox>
00025 #include <QPalette>
00026 #include <QSettings>
00027 
00028 #ifndef Q_WS_WIN
00029 #include <netinet/in.h>
00030 #else
00031 #include <winsock.h>
00032 #endif
00033 
00034 #include "qgsconfig.h"
00035 
00036 #include <ogr_api.h>
00037 
00038 QObject * QgsApplication::mFileOpenEventReceiver;
00039 QStringList QgsApplication::mFileOpenEventList;
00040 QString QgsApplication::mPrefixPath;
00041 QString QgsApplication::mPluginPath;
00042 QString QgsApplication::mPkgDataPath;
00043 QString QgsApplication::mThemeName;
00044 QStringList QgsApplication::mDefaultSvgPaths;
00045 QString QgsApplication::mConfigPath = QDir::homePath() + QString( "/.qgis/" );
00046 
00060 QgsApplication::QgsApplication( int & argc, char ** argv, bool GUIenabled, QString customConfigPath )
00061     : QApplication( argc, argv, GUIenabled )
00062 {
00063 #if defined(Q_WS_MACX) || defined(Q_WS_WIN32) || defined(WIN32)
00064   setPrefixPath( applicationDirPath(), true );
00065 #else
00066   QDir myDir( applicationDirPath() );
00067   myDir.cdUp();
00068   QString myPrefix = myDir.absolutePath();
00069   setPrefixPath( myPrefix, true );
00070 #endif
00071 
00072   if ( !customConfigPath.isEmpty() )
00073   {
00074     mConfigPath = customConfigPath + "/"; // make sure trailing slash is included
00075   }
00076 
00077   mDefaultSvgPaths << qgisSettingsDirPath() + QString( "svg/" );
00078 }
00079 
00080 QgsApplication::~QgsApplication()
00081 {
00082 }
00083 
00084 bool QgsApplication::event( QEvent * event )
00085 {
00086   bool done = false;
00087   if ( event->type() == QEvent::FileOpen )
00088   {
00089     // handle FileOpen event (double clicking a file icon in Mac OS X Finder)
00090     if ( mFileOpenEventReceiver )
00091     {
00092       // Forward event to main window.
00093       done = notify( mFileOpenEventReceiver, event );
00094     }
00095     else
00096     {
00097       // Store filename because receiver has not registered yet.
00098       // If QGIS has been launched by double clicking a file icon, FileOpen will be
00099       // the first event; the main window is not yet ready to handle the event.
00100       mFileOpenEventList.append( static_cast<QFileOpenEvent *>( event )->file() );
00101       done = true;
00102     }
00103   }
00104   else
00105   {
00106     // pass other events to base class
00107     done = QApplication::event( event );
00108   }
00109   return done;
00110 }
00111 
00112 bool QgsApplication::notify( QObject * receiver, QEvent * event )
00113 {
00114   // Send event to receiver and catch unhandled exceptions
00115   bool done = true;
00116   try
00117   {
00118     done = QApplication::notify( receiver, event );
00119   }
00120   catch ( QgsException & e )
00121   {
00122     QMessageBox::critical( activeWindow(), tr( "Exception" ), e.what() );
00123   }
00124   catch ( std::exception & e )
00125   {
00126     QMessageBox::critical( activeWindow(), tr( "Exception" ), e.what() );
00127   }
00128   catch ( ... )
00129   {
00130     QMessageBox::critical( activeWindow(), tr( "Exception" ), tr( "unknown exception" ) );
00131   }
00132   return done;
00133 }
00134 
00135 void QgsApplication::setFileOpenEventReceiver( QObject * receiver )
00136 {
00137   // Set receiver for FileOpen events
00138   mFileOpenEventReceiver = receiver;
00139   // Propagate any events collected before the receiver has registered.
00140   if ( mFileOpenEventList.count() > 0 )
00141   {
00142     QStringListIterator i( mFileOpenEventList );
00143     while ( i.hasNext() )
00144     {
00145       QFileOpenEvent foe( i.next() );
00146       QgsApplication::sendEvent( mFileOpenEventReceiver, &foe );
00147     }
00148     mFileOpenEventList.clear();
00149   }
00150 }
00151 
00152 void QgsApplication::setPrefixPath( const QString thePrefixPath, bool useDefaultPaths )
00153 {
00154   mPrefixPath = thePrefixPath;
00155 #if defined(_MSC_VER)
00156   if ( mPrefixPath.endsWith( "/bin" ) )
00157   {
00158     mPrefixPath.chop( 4 );
00159   }
00160 #endif
00161   if ( useDefaultPaths )
00162   {
00163     setPluginPath( mPrefixPath + "/" + QString( QGIS_PLUGIN_SUBDIR ) );
00164     setPkgDataPath( mPrefixPath + "/" + QString( QGIS_DATA_SUBDIR ) );
00165   }
00166 }
00167 
00168 void QgsApplication::setPluginPath( const QString thePluginPath )
00169 {
00170   mPluginPath = thePluginPath;
00171 }
00172 
00173 void QgsApplication::setPkgDataPath( const QString thePkgDataPath )
00174 {
00175   mPkgDataPath = thePkgDataPath;
00176   QString svgPath = mPkgDataPath + QString( "/svg/" );
00177   // avoid duplicate entries
00178   if ( !mDefaultSvgPaths.contains( svgPath ) )
00179     mDefaultSvgPaths << svgPath;
00180 }
00181 
00182 void QgsApplication::setDefaultSvgPaths( const QStringList& pathList )
00183 {
00184   mDefaultSvgPaths = pathList;
00185 }
00186 
00187 const QString QgsApplication::prefixPath()
00188 {
00189   return mPrefixPath;
00190 }
00191 const QString QgsApplication::pluginPath()
00192 {
00193   return mPluginPath;
00194 }
00195 const QString QgsApplication::pkgDataPath()
00196 {
00197   return mPkgDataPath;
00198 }
00199 const QString QgsApplication::defaultThemePath()
00200 {
00201   return ":/images/themes/default/";
00202 }
00203 const QString QgsApplication::activeThemePath()
00204 {
00205   return ":/images/themes/" + mThemeName + "/";
00206 }
00207 
00208 
00209 QString QgsApplication::iconPath( QString iconFile )
00210 {
00211   // try active theme
00212   QString path = activeThemePath();
00213   if ( QFile::exists( path + iconFile ) )
00214     return path + iconFile;
00215 
00216   // use default theme
00217   return defaultThemePath() + iconFile;
00218 }
00219 
00223 void QgsApplication::setThemeName( const QString theThemeName )
00224 {
00225   QString myPath = ":/images/themes/" + theThemeName + "/";
00226   //check it exists and if not roll back to default theme
00227   if ( QFile::exists( myPath ) )
00228   {
00229     mThemeName = theThemeName;
00230   }
00231   else
00232   {
00233     mThemeName = "default";
00234   }
00235 }
00239 const QString QgsApplication::themeName()
00240 {
00241   return mThemeName;
00242 }
00246 const QString QgsApplication::authorsFilePath()
00247 {
00248   return mPkgDataPath + QString( "/doc/AUTHORS" );
00249 }
00253 const QString QgsApplication::contributorsFilePath()
00254 {
00255   return mPkgDataPath + QString( "/doc/CONTRIBUTORS" );
00256 }
00260 const QString QgsApplication::sponsorsFilePath()
00261 {
00262   return mPkgDataPath + QString( "/doc/SPONSORS" );
00263 }
00264 
00268 const QString QgsApplication::donorsFilePath()
00269 {
00270   return mPkgDataPath + QString( "/doc/DONORS" );
00271 }
00272 
00277 const QString QgsApplication::translatorsFilePath()
00278 {
00279   return mPkgDataPath + QString( "/doc/TRANSLATORS" );
00280 }
00284 const QString QgsApplication::developerPath()
00285 {
00286   return mPkgDataPath + QString( "/images/developers/" );
00287 }
00288 
00292 const QString QgsApplication::helpAppPath()
00293 {
00294   QString helpAppPath;
00295 #ifdef Q_OS_MACX
00296   helpAppPath = applicationDirPath() + "/bin/qgis_help.app/Contents/MacOS";
00297 #else
00298   helpAppPath = prefixPath() + "/" QGIS_LIBEXEC_SUBDIR;
00299 #endif
00300   helpAppPath += "/qgis_help";
00301   return helpAppPath;
00302 }
00306 const QString QgsApplication::i18nPath()
00307 {
00308   return mPkgDataPath + QString( "/i18n/" );
00309 }
00310 
00314 const QString QgsApplication::qgisMasterDbFilePath()
00315 {
00316   return mPkgDataPath + QString( "/resources/qgis.db" );
00317 }
00318 
00322 const QString QgsApplication::qgisSettingsDirPath()
00323 {
00324   return mConfigPath;
00325 }
00326 
00330 const QString QgsApplication::qgisUserDbFilePath()
00331 {
00332   return qgisSettingsDirPath() + QString( "qgis.db" );
00333 }
00334 
00338 const QString QgsApplication::splashPath()
00339 {
00340   return mPkgDataPath + QString( "/images/splash/" );
00341 }
00342 
00346 const QString QgsApplication::iconsPath()
00347 {
00348   return mPkgDataPath + QString( "/images/icons/" );
00349 }
00353 const QString QgsApplication::srsDbFilePath()
00354 {
00355   return mPkgDataPath + QString( "/resources/srs.db" );
00356 }
00357 
00361 const QStringList QgsApplication::svgPaths()
00362 {
00363   //local directories to search when looking for an SVG with a given basename
00364   //defined by user in options dialog
00365   QSettings settings;
00366   QStringList myPathList;
00367   QString myPaths = settings.value( "svg/searchPathsForSVG", "" ).toString();
00368   if ( !myPaths.isEmpty() )
00369   {
00370     myPathList = myPaths.split( "|" );
00371   }
00372 
00373   myPathList << mDefaultSvgPaths;
00374   return myPathList;
00375 }
00376 
00380 const QString QgsApplication::svgPath()
00381 {
00382   return mPkgDataPath + QString( "/svg/" );
00383 }
00384 
00385 const QString QgsApplication::userStyleV2Path()
00386 {
00387   return qgisSettingsDirPath() + QString( "symbology-ng-style.xml" );
00388 }
00389 
00390 const QString QgsApplication::defaultStyleV2Path()
00391 {
00392   return mPkgDataPath + QString( "/resources/symbology-ng-style.xml" );
00393 }
00394 
00395 QgsApplication::endian_t QgsApplication::endian()
00396 {
00397   return ( htonl( 1 ) == 1 ) ? XDR : NDR ;
00398 }
00399 
00400 void QgsApplication::initQgis()
00401 {
00402   // set the provider plugin path (this creates provider registry)
00403   QgsProviderRegistry::instance( pluginPath() );
00404 
00405   // create map layer registry if doesn't exist
00406   QgsMapLayerRegistry::instance();
00407 }
00408 
00409 void QgsApplication::exitQgis()
00410 {
00411   delete QgsMapLayerRegistry::instance();
00412   delete QgsProviderRegistry::instance();
00413 }
00414 
00415 QString QgsApplication::showSettings()
00416 {
00417   QString myState = QString( "Application state:\n"
00418                              "Prefix              : %1\n"
00419                              "Plugin Path         : %2\n"
00420                              "Package Data Path   : %3\n"
00421                              "Active Theme Name   : %4\n"
00422                              "Active Theme Path   : %5\n"
00423                              "Default Theme Path  : %6\n"
00424                              "SVG Search Paths    : %7\n"
00425                              "User DB Path        : %8\n" )
00426                     .arg( mPrefixPath )
00427                     .arg( mPluginPath )
00428                     .arg( mPkgDataPath )
00429                     .arg( themeName() )
00430                     .arg( activeThemePath() )
00431                     .arg( defaultThemePath() )
00432                     .arg( svgPaths().join( "\n" ) )
00433                     .arg( qgisMasterDbFilePath() );
00434   return myState;
00435 }
00436 
00437 QString QgsApplication::reportStyleSheet()
00438 {
00439   //
00440   // Make the style sheet desktop preferences aware by using qappliation
00441   // palette as a basis for colors where appropriate
00442   //
00443   QColor myColor1 = palette().highlight().color();
00444   QColor myColor2 = myColor1;
00445   myColor2 = myColor2.lighter( 110 ); //10% lighter
00446   QString myStyle;
00447   myStyle = ".glossy{ background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, "
00448             "stop: 0 " + myColor1.name()  + ","
00449             "stop: 0.1 " + myColor2.name() + ","
00450             "stop: 0.5 " + myColor1.name()  + ","
00451             "stop: 0.9 " + myColor2.name() + ","
00452             "stop: 1 " + myColor1.name() + ");"
00453             "color: white;"
00454             "padding-left: 4px;"
00455             "padding-top: 20px;"
00456             "padding-bottom: 8px;"
00457             "border: 1px solid #6c6c6c;"
00458             "}"
00459             ".overview{ font: 1.82em; font-weight: bold;}"
00460             "body{  background: white;"
00461             "  color: black;"
00462             "  font-family: arial,sans-serif;"
00463             "}"
00464             "h2{  background-color: #F6F6F6;"
00465             "  color: #8FB171; "
00466             "  font-size: medium;  "
00467             "  font-weight: normal;"
00468             "  font-family: luxi serif, georgia, times new roman, times, serif;"
00469             "  background: none;"
00470             "  padding: 0.75em 0 0;"
00471             "  margin: 0;"
00472             "  line-height: 1.1em;"
00473             "}"
00474             "h3{  background-color: #F6F6F6;"
00475             "  color: #729FCF;"
00476             "  font-family: luxi serif, georgia, times new roman, times, serif;"
00477             "  font-weight: bold;"
00478             "  font-size: large;"
00479             "  text-align: right;"
00480             "  border-bottom: 5px solid #DCEB5C;"
00481             "}"
00482             "h4{  background-color: #F6F6F6;"
00483             "  color: #729FCF;"
00484             "  font-family: luxi serif, georgia, times new roman, times, serif;"
00485             "  font-weight: bold;"
00486             "  font-size: medium;"
00487             "  text-align: right;"
00488             "}"
00489             "h5{    background-color: #F6F6F6;"
00490             "   color: #729FCF;"
00491             "   font-family: luxi serif, georgia, times new roman, times, serif;"
00492             "   font-weight: bold;"
00493             "   font-size: small;"
00494             "   text-align: right;"
00495             "}"
00496             "a{  color: #729FCF;"
00497             "  font-family: arial,sans-serif;"
00498             "  font-size: small;"
00499             "}"
00500             "label{  background-color: #FFFFCC;"
00501             "  border: 1px solid black;"
00502             "  margin: 1px;"
00503             "  padding: 0px 3px; "
00504             "  font-size: small;"
00505             "}";
00506   return myStyle;
00507 }
00508 
00509 void QgsApplication::registerOgrDrivers()
00510 {
00511   if ( 0 >= OGRGetDriverCount() )
00512   {
00513     OGRRegisterAll();
00514   }
00515 }
00516 
00517 QString QgsApplication::absolutePathToRelativePath( QString aPath, QString targetPath )
00518 {
00519 #if defined( Q_OS_WIN )
00520   const Qt::CaseSensitivity cs = Qt::CaseInsensitive;
00521 
00522   aPath.replace( "\\", "/" );
00523   if ( aPath.startsWith( "//" ) )
00524   {
00525     // keep UNC prefix
00526     aPath = "\\\\" + aPath.mid( 2 );
00527   }
00528 
00529   targetPath.replace( "\\", "/" );
00530   if ( targetPath.startsWith( "//" ) )
00531   {
00532     // keep UNC prefix
00533     targetPath = "\\\\" + targetPath.mid( 2 );
00534   }
00535 #else
00536   const Qt::CaseSensitivity cs = Qt::CaseSensitive;
00537 #endif
00538 
00539   QStringList targetElems = targetPath.split( "/", QString::SkipEmptyParts );
00540   QStringList aPathElems = aPath.split( "/", QString::SkipEmptyParts );
00541 
00542   targetElems.removeAll( "." );
00543   aPathElems.removeAll( "." );
00544 
00545   // remove common part
00546   int n = 0;
00547   while ( aPathElems.size() > 0 &&
00548           targetElems.size() > 0 &&
00549           aPathElems[0].compare( targetElems[0], cs ) == 0 )
00550   {
00551     aPathElems.removeFirst();
00552     targetElems.removeFirst();
00553     n++;
00554   }
00555 
00556   if ( n == 0 )
00557   {
00558     // no common parts; might not even be a file
00559     return aPath;
00560   }
00561 
00562   if ( targetElems.size() > 0 )
00563   {
00564     // go up to the common directory
00565     for ( int i = 0; i < targetElems.size(); i++ )
00566     {
00567       aPathElems.insert( 0, ".." );
00568     }
00569   }
00570   else
00571   {
00572     // let it start with . nevertheless,
00573     // so relative path always start with either ./ or ../
00574     aPathElems.insert( 0, "." );
00575   }
00576 
00577   return aPathElems.join( "/" );
00578 }
00579 
00580 QString QgsApplication::relativePathToAbsolutePath( QString rpath, QString targetPath )
00581 {
00582   // relative path should always start with ./ or ../
00583   if ( !rpath.startsWith( "./" ) && !rpath.startsWith( "../" ) )
00584   {
00585     return rpath;
00586   }
00587 
00588 #if defined(Q_OS_WIN)
00589   rpath.replace( "\\", "/" );
00590   targetPath.replace( "\\", "/" );
00591 
00592   bool uncPath = targetPath.startsWith( "//" );
00593 #endif
00594 
00595   QStringList srcElems = rpath.split( "/", QString::SkipEmptyParts );
00596   QStringList targetElems = targetPath.split( "/", QString::SkipEmptyParts );
00597 
00598 #if defined(Q_OS_WIN)
00599   if ( uncPath )
00600   {
00601     targetElems.insert( 0, "" );
00602     targetElems.insert( 0, "" );
00603   }
00604 #endif
00605 
00606   // append source path elements
00607   targetElems << srcElems;
00608   targetElems.removeAll( "." );
00609 
00610   // resolve ..
00611   int pos;
00612   while (( pos = targetElems.indexOf( ".." ) ) > 0 )
00613   {
00614     // remove preceding element and ..
00615     targetElems.removeAt( pos - 1 );
00616     targetElems.removeAt( pos - 1 );
00617   }
00618 
00619 #if !defined(Q_OS_WIN)
00620   // make path absolute
00621   targetElems.prepend( "" );
00622 #endif
00623 
00624   return targetElems.join( "/" );
00625 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines