Quantum GIS API Documentation
1.7.4
|
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 }