QGIS API Documentation  2.0.1-Dufour
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
qgsapplication.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsapplication.cpp - Accessors for application-wide data
3  --------------------------------------
4  Date : 02-Jan-2006
5  Copyright : (C) 2006 by Tom Elwertowski
6  Email : telwertowski at users dot sourceforge dot net
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "qgsapplication.h"
17 #include "qgslogger.h"
18 #include "qgsmaplayerregistry.h"
19 #include "qgsproviderregistry.h"
20 #include "qgsexception.h"
21 #include "qgsgeometry.h"
22 
23 #include <QDir>
24 #include <QFile>
25 #include <QFileOpenEvent>
26 #include <QMessageBox>
27 #include <QPalette>
28 #include <QProcess>
29 #include <QSettings>
30 #include <QIcon>
31 #include <QPixmap>
32 
33 #ifndef Q_WS_WIN
34 #include <netinet/in.h>
35 #else
36 #include <winsock.h>
37 #endif
38 
39 #include "qgsconfig.h"
40 
41 #include <gdal.h>
42 #include <ogr_api.h>
43 #include <cpl_conv.h> // for setting gdal options
44 #include <sqlite3.h>
45 
46 QObject * ABISYM( QgsApplication::mFileOpenEventReceiver );
47 QStringList ABISYM( QgsApplication::mFileOpenEventList );
48 QString ABISYM( QgsApplication::mPrefixPath );
49 QString ABISYM( QgsApplication::mPluginPath );
50 QString ABISYM( QgsApplication::mPkgDataPath );
51 QString ABISYM( QgsApplication::mLibraryPath );
52 QString ABISYM( QgsApplication::mLibexecPath );
53 QString ABISYM( QgsApplication::mThemeName );
54 QStringList ABISYM( QgsApplication::mDefaultSvgPaths );
55 QMap<QString, QString> ABISYM( QgsApplication::mSystemEnvVars );
56 QString ABISYM( QgsApplication::mConfigPath );
57 bool ABISYM( QgsApplication::mRunningFromBuildDir ) = false;
58 QString ABISYM( QgsApplication::mBuildSourcePath );
59 #ifdef _MSC_VER
60 QString ABISYM( QgsApplication::mCfgIntDir );
61 #endif
62 QString ABISYM( QgsApplication::mBuildOutputPath );
63 QStringList ABISYM( QgsApplication::mGdalSkipList );
64 
78 QgsApplication::QgsApplication( int & argc, char ** argv, bool GUIenabled, QString customConfigPath )
79  : QApplication( argc, argv, GUIenabled )
80 {
81  init( customConfigPath ); // init can also be called directly by e.g. unit tests that don't inherit QApplication.
82 }
83 
84 void QgsApplication::init( QString customConfigPath )
85 {
86  if ( customConfigPath.isEmpty() )
87  {
88  customConfigPath = QDir::homePath() + QString( "/.qgis%1/" ).arg( 2 /* FIXME QGis::QGIS_VERSION_INT / 10000 */ );
89  }
90 
91  qRegisterMetaType<QgsGeometry::Error>( "QgsGeometry::Error" );
92 
93  QString prefixPath( getenv( "QGIS_PREFIX_PATH" ) ? getenv( "QGIS_PREFIX_PATH" ) : applicationDirPath() );
94 
95  // check if QGIS is run from build directory (not the install directory)
96  QFile f;
97  // "/../../.." is for Mac bundled app in build directory
98  foreach ( QString path, QStringList() << "" << "/.." << "/bin" << "/../../.." )
99  {
100  f.setFileName( prefixPath + path + "/qgisbuildpath.txt" );
101  if ( f.exists() )
102  break;
103  }
104  if ( f.exists() && f.open( QIODevice::ReadOnly ) )
105  {
106  ABISYM( mRunningFromBuildDir ) = true;
107  ABISYM( mBuildSourcePath ) = f.readLine().trimmed();
108  ABISYM( mBuildOutputPath ) = f.readLine().trimmed();
109  qDebug( "Running from build directory!" );
110  qDebug( "- source directory: %s", ABISYM( mBuildSourcePath ).toUtf8().data() );
111  qDebug( "- output directory of the build: %s", ABISYM( mBuildOutputPath ).toUtf8().data() );
112 #ifdef _MSC_VER
113  ABISYM( mCfgIntDir ) = prefixPath.split( "/", QString::SkipEmptyParts ).last();
114  qDebug( "- cfg: %s", ABISYM( mCfgIntDir ).toUtf8().data() );
115 #endif
116  }
117 
118  if ( ABISYM( mRunningFromBuildDir ) )
119  {
120  // we run from source directory - not installed to destination (specified prefix)
121  ABISYM( mPrefixPath ) = QString(); // set invalid path
122 #if defined(_MSC_VER) && !defined(USING_NMAKE)
123  setPluginPath( ABISYM( mBuildOutputPath ) + "/" + QString( QGIS_PLUGIN_SUBDIR ) + "/" + ABISYM( mCfgIntDir ) );
124 #else
125  setPluginPath( ABISYM( mBuildOutputPath ) + "/" + QString( QGIS_PLUGIN_SUBDIR ) );
126 #endif
127  setPkgDataPath( ABISYM( mBuildSourcePath ) ); // directly source path - used for: doc, resources, svg
128  ABISYM( mLibraryPath ) = ABISYM( mBuildOutputPath ) + "/" + QGIS_LIB_SUBDIR + "/";
129 #if defined(_MSC_VER) && !defined(USING_NMAKE)
130  ABISYM( mLibexecPath ) = ABISYM( mBuildOutputPath ) + "/" + QGIS_LIBEXEC_SUBDIR + "/" + ABISYM( mCfgIntDir ) + "/";
131 #else
132  ABISYM( mLibexecPath ) = ABISYM( mBuildOutputPath ) + "/" + QGIS_LIBEXEC_SUBDIR + "/";
133 #endif
134  }
135  else
136  {
137  char *prefixPath = getenv( "QGIS_PREFIX_PATH" );
138  if ( !prefixPath )
139  {
140 #if defined(Q_WS_MACX) || defined(Q_WS_WIN32) || defined(WIN32)
141  setPrefixPath( applicationDirPath(), true );
142 #else
143  QDir myDir( applicationDirPath() );
144  myDir.cdUp();
145  QString myPrefix = myDir.absolutePath();
146  setPrefixPath( myPrefix, true );
147 #endif
148  }
149  else
150  {
151  setPrefixPath( prefixPath, true );
152  }
153  }
154 
155  if ( !customConfigPath.isEmpty() )
156  {
157  ABISYM( mConfigPath ) = customConfigPath + "/"; // make sure trailing slash is included
158  }
159 
160  ABISYM( mDefaultSvgPaths ) << qgisSettingsDirPath() + QString( "svg/" );
161 
162  // store system environment variables passed to application, before they are adjusted
163  QMap<QString, QString> systemEnvVarMap;
164  foreach ( const QString &varStr, QProcess::systemEnvironment() )
165  {
166  int pos = varStr.indexOf( QLatin1Char( '=' ) );
167  if ( pos == -1 )
168  continue;
169  QString varStrName = varStr.left( pos );
170  QString varStrValue = varStr.mid( pos + 1 );
171  systemEnvVarMap.insert( varStrName, varStrValue );
172  }
173  ABISYM( mSystemEnvVars ) = systemEnvVarMap;
174 
175 }
176 
178 {
179 }
180 
181 bool QgsApplication::event( QEvent * event )
182 {
183  bool done = false;
184  if ( event->type() == QEvent::FileOpen )
185  {
186  // handle FileOpen event (double clicking a file icon in Mac OS X Finder)
187  if ( ABISYM( mFileOpenEventReceiver ) )
188  {
189  // Forward event to main window.
190  done = notify( ABISYM( mFileOpenEventReceiver ), event );
191  }
192  else
193  {
194  // Store filename because receiver has not registered yet.
195  // If QGIS has been launched by double clicking a file icon, FileOpen will be
196  // the first event; the main window is not yet ready to handle the event.
197  ABISYM( mFileOpenEventList ).append( static_cast<QFileOpenEvent *>( event )->file() );
198  done = true;
199  }
200  }
201  else
202  {
203  // pass other events to base class
204  done = QApplication::event( event );
205  }
206  return done;
207 }
208 
209 bool QgsApplication::notify( QObject * receiver, QEvent * event )
210 {
211  bool done = false;
212  // Crashes in customization (especially on Mac), if we're not in the main/UI thread, see #5597
213  if ( thread() == receiver->thread() )
214  emit preNotify( receiver, event, &done );
215 
216  if ( done )
217  return true;
218 
219  // Send event to receiver and catch unhandled exceptions
220  done = true;
221  try
222  {
223  done = QApplication::notify( receiver, event );
224  }
225  catch ( QgsException & e )
226  {
227  QMessageBox::critical( activeWindow(), tr( "Exception" ), e.what() );
228  }
229  catch ( std::exception & e )
230  {
231  QMessageBox::critical( activeWindow(), tr( "Exception" ), e.what() );
232  }
233  catch ( ... )
234  {
235  QMessageBox::critical( activeWindow(), tr( "Exception" ), tr( "unknown exception" ) );
236  }
237 
238  return done;
239 }
240 
242 {
243  // Set receiver for FileOpen events
244  ABISYM( mFileOpenEventReceiver ) = receiver;
245  // Propagate any events collected before the receiver has registered.
246  if ( ABISYM( mFileOpenEventList ).count() > 0 )
247  {
248  QStringListIterator i( ABISYM( mFileOpenEventList ) );
249  while ( i.hasNext() )
250  {
251  QFileOpenEvent foe( i.next() );
252  QgsApplication::sendEvent( ABISYM( mFileOpenEventReceiver ), &foe );
253  }
254  ABISYM( mFileOpenEventList ).clear();
255  }
256 }
257 
258 void QgsApplication::setPrefixPath( const QString thePrefixPath, bool useDefaultPaths )
259 {
260  ABISYM( mPrefixPath ) = thePrefixPath;
261 #if defined(_MSC_VER)
262  if ( ABISYM( mPrefixPath ).endsWith( "/bin" ) )
263  {
264  ABISYM( mPrefixPath ).chop( 4 );
265  }
266 #endif
267  if ( useDefaultPaths && !ABISYM( mRunningFromBuildDir ) )
268  {
269  setPluginPath( ABISYM( mPrefixPath ) + "/" + QString( QGIS_PLUGIN_SUBDIR ) );
270  setPkgDataPath( ABISYM( mPrefixPath ) + "/" + QString( QGIS_DATA_SUBDIR ) );
271  }
272  ABISYM( mLibraryPath ) = ABISYM( mPrefixPath ) + "/" + QGIS_LIB_SUBDIR + "/";
273  ABISYM( mLibexecPath ) = ABISYM( mPrefixPath ) + "/" + QGIS_LIBEXEC_SUBDIR + "/";
274 }
275 
276 void QgsApplication::setPluginPath( const QString thePluginPath )
277 {
278  ABISYM( mPluginPath ) = thePluginPath;
279 }
280 
281 void QgsApplication::setPkgDataPath( const QString thePkgDataPath )
282 {
283  ABISYM( mPkgDataPath ) = thePkgDataPath;
284  QString mySvgPath = thePkgDataPath + ( ABISYM( mRunningFromBuildDir ) ? "/images/svg/" : "/svg/" );
285  // avoid duplicate entries
286  if ( !ABISYM( mDefaultSvgPaths ).contains( mySvgPath ) )
287  ABISYM( mDefaultSvgPaths ) << mySvgPath;
288 }
289 
290 void QgsApplication::setDefaultSvgPaths( const QStringList& pathList )
291 {
292  ABISYM( mDefaultSvgPaths ) = pathList;
293 }
294 
296 {
297  if ( ABISYM( mRunningFromBuildDir ) )
298  {
299  qWarning( "!!! prefix path was requested, but it is not valid - we do not run from installed path !!!" );
300  }
301 
302  return ABISYM( mPrefixPath );
303 }
305 {
306  return ABISYM( mPluginPath );
307 }
309 {
310  return ABISYM( mPkgDataPath );
311 }
313 {
314  return ":/images/themes/default/";
315 }
317 {
318  return ":/images/themes/" + themeName() + "/";
319 }
320 
321 
322 QString QgsApplication::iconPath( QString iconFile )
323 {
324  // try active theme
325  QString path = activeThemePath();
326  if ( QFile::exists( path + iconFile ) )
327  return path + iconFile;
328 
329  // use default theme
330  return defaultThemePath() + iconFile;
331 }
332 
333 QIcon QgsApplication::getThemeIcon( const QString theName )
334 {
335  QString myPreferredPath = activeThemePath() + QDir::separator() + theName;
336  QString myDefaultPath = defaultThemePath() + QDir::separator() + theName;
337  if ( QFile::exists( myPreferredPath ) )
338  {
339  return QIcon( myPreferredPath );
340  }
341  else if ( QFile::exists( myDefaultPath ) )
342  {
343  //could still return an empty icon if it
344  //doesnt exist in the default theme either!
345  return QIcon( myDefaultPath );
346  }
347  else
348  {
349  return QIcon();
350  }
351 }
352 
353 // TODO: add some caching mechanism ?
354 QPixmap QgsApplication::getThemePixmap( const QString theName )
355 {
356  QString myPreferredPath = activeThemePath() + QDir::separator() + theName;
357  QString myDefaultPath = defaultThemePath() + QDir::separator() + theName;
358  if ( QFile::exists( myPreferredPath ) )
359  {
360  return QPixmap( myPreferredPath );
361  }
362  else
363  {
364  //could still return an empty icon if it
365  //doesnt exist in the default theme either!
366  return QPixmap( myDefaultPath );
367  }
368 }
369 
373 void QgsApplication::setThemeName( const QString theThemeName )
374 {
375  QString myPath = ":/images/themes/" + theThemeName + "/";
376  //check it exists and if not roll back to default theme
377  if ( QFile::exists( myPath ) )
378  {
379  ABISYM( mThemeName ) = theThemeName;
380  }
381  else
382  {
383  ABISYM( mThemeName ) = "default";
384  }
385 }
390 {
391  return ABISYM( mThemeName );
392 }
397 {
398  return ABISYM( mPkgDataPath ) + QString( "/doc/AUTHORS" );
399 }
404 {
405  return ABISYM( mPkgDataPath ) + QString( "/doc/CONTRIBUTORS" );
406 }
411 {
412  return ABISYM( mPkgDataPath ) + QString( "/doc/SPONSORS" );
413 }
414 
419 {
420  return ABISYM( mPkgDataPath ) + QString( "/doc/DONORS" );
421 }
422 
428 {
429  return ABISYM( mPkgDataPath ) + QString( "/doc/TRANSLATORS" );
430 }
431 
436 {
437  return ABISYM( mPkgDataPath ) + QString( "/doc/LICENCE" );
438 }
439 
444 {
445  QString helpAppPath;
446 #ifdef Q_OS_MACX
447  helpAppPath = applicationDirPath() + "/bin/qgis_help.app/Contents/MacOS";
448 #else
449  helpAppPath = libexecPath();
450 #endif
451  helpAppPath += "/qgis_help";
452 #ifdef Q_OS_WIN
453  helpAppPath += ".exe";
454 #endif
455  return helpAppPath;
456 }
461 {
462  if ( ABISYM( mRunningFromBuildDir ) )
463  return ABISYM( mBuildOutputPath ) + QString( "/i18n" );
464  else
465  return ABISYM( mPkgDataPath ) + QString( "/i18n/" );
466 }
467 
472 {
473  return ABISYM( mPkgDataPath ) + QString( "/resources/qgis.db" );
474 }
475 
480 {
481  return ABISYM( mConfigPath );
482 }
483 
488 {
489  return qgisSettingsDirPath() + QString( "qgis.db" );
490 }
491 
496 {
497  return QString( ":/images/splash/" );
498 }
499 
504 {
505  return ABISYM( mPkgDataPath ) + QString( "/images/icons/" );
506 }
511 {
512  if ( ABISYM( mRunningFromBuildDir ) )
513  {
514  QString tempCopy = QDir::tempPath() + "/srs.db";
515 
516  if ( !QFile( tempCopy ).exists() )
517  {
518  QFile f( ABISYM( mPkgDataPath ) + "/resources/srs.db" );
519  if ( !f.copy( tempCopy ) )
520  {
521  qFatal( "Could not create temporary copy" );
522  }
523  }
524 
525  return tempCopy;
526  }
527  else
528  {
529  return ABISYM( mPkgDataPath ) + QString( "/resources/srs.db" );
530  }
531 }
532 
536 const QStringList QgsApplication::svgPaths()
537 {
538  //local directories to search when looking for an SVG with a given basename
539  //defined by user in options dialog
540  QSettings settings;
541  QStringList myPathList;
542  QString myPaths = settings.value( "svg/searchPathsForSVG", "" ).toString();
543  if ( !myPaths.isEmpty() )
544  {
545  myPathList = myPaths.split( "|" );
546  }
547 
548  myPathList << ABISYM( mDefaultSvgPaths );
549  return myPathList;
550 }
551 
553 {
554  return qgisSettingsDirPath() + QString( "symbology-ng-style.db" );
555 }
556 
558 {
559  return ABISYM( mPkgDataPath ) + QString( "/resources/symbology-ng-style.db" );
560 }
561 
563 {
564  return ABISYM( mLibraryPath );
565 }
566 
568 {
569  return ABISYM( mLibexecPath );
570 }
571 
573 {
574  return ( htonl( 1 ) == 1 ) ? XDR : NDR ;
575 }
576 
578 {
579  // set the provider plugin path (this creates provider registry)
581 
582  // create map layer registry if doesn't exist
584 }
585 
587 {
590 }
591 
593 {
594  QString myEnvironmentVar( getenv( "QGIS_PREFIX_PATH" ) );
595  QString myState = tr( "Application state:\n"
596  "QGIS_PREFIX_PATH env var:\t\t%1\n"
597  "Prefix:\t\t%2\n"
598  "Plugin Path:\t\t%3\n"
599  "Package Data Path:\t%4\n"
600  "Active Theme Name:\t%5\n"
601  "Active Theme Path:\t%6\n"
602  "Default Theme Path:\t%7\n"
603  "SVG Search Paths:\t%8\n"
604  "User DB Path:\t%9\n" )
605  .arg( myEnvironmentVar )
606  .arg( prefixPath() )
607  .arg( pluginPath() )
608  .arg( pkgDataPath() )
609  .arg( themeName() )
610  .arg( activeThemePath() )
611  .arg( defaultThemePath() )
612  .arg( svgPaths().join( tr( "\n\t\t", "match indentation of application state" ) ) )
613  .arg( qgisMasterDbFilePath() );
614  return myState;
615 }
616 
618 {
619  //
620  // Make the style sheet desktop preferences aware by using qappliation
621  // palette as a basis for colors where appropriate
622  //
623 // QColor myColor1 = palette().highlight().color();
624  QColor myColor1( Qt::lightGray );
625  QColor myColor2 = myColor1;
626  myColor2 = myColor2.lighter( 110 ); //10% lighter
627  QString myStyle;
628  myStyle = "p.glossy{ background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, "
629  " stop: 0 " + myColor1.name() + ","
630  " stop: 0.1 " + myColor2.name() + ","
631  " stop: 0.5 " + myColor1.name() + ","
632  " stop: 0.9 " + myColor2.name() + ","
633  " stop: 1 " + myColor1.name() + ");"
634  " color: black;"
635  " padding-left: 4px;"
636  " padding-top: 20px;"
637  " padding-bottom: 8px;"
638  " border: 1px solid #6c6c6c;"
639  "}"
640  "p.subheaderglossy{ background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, "
641  " stop: 0 " + myColor1.name() + ","
642  " stop: 0.1 " + myColor2.name() + ","
643  " stop: 0.5 " + myColor1.name() + ","
644  " stop: 0.9 " + myColor2.name() + ","
645  " stop: 1 " + myColor1.name() + ");"
646  " font-weight: bold;"
647  " font-size: medium;"
648  " line-height: 1.1em;"
649  " width: 100%;"
650  " color: black;"
651  " padding-left: 4px;"
652  " padding-right: 4px;"
653  " padding-top: 20px;"
654  " padding-bottom: 8px;"
655  " border: 1px solid #6c6c6c;"
656  "}"
657  "th.glossy{ background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, "
658  " stop: 0 " + myColor1.name() + ","
659  " stop: 0.1 " + myColor2.name() + ","
660  " stop: 0.5 " + myColor1.name() + ","
661  " stop: 0.9 " + myColor2.name() + ","
662  " stop: 1 " + myColor1.name() + ");"
663  " color: black;"
664  " border: 1px solid #6c6c6c;"
665  "}"
666  ".overview{ font: 1.82em; font-weight: bold;}"
667  "body{ background: white;"
668  " color: black;"
669  " font-family: arial,sans-serif;"
670  "}"
671  "h1{ background-color: #F6F6F6;"
672  " color: #8FB171; "
673  " font-size: x-large; "
674  " font-weight: normal;"
675  " font-family: luxi serif, georgia, times new roman, times, serif;"
676  " background: none;"
677  " padding: 0.75em 0 0;"
678  " margin: 0;"
679  " line-height: 3em;"
680  "}"
681  "h2{ background-color: #F6F6F6;"
682  " color: #8FB171; "
683  " font-size: medium; "
684  " font-weight: normal;"
685  " font-family: luxi serif, georgia, times new roman, times, serif;"
686  " background: none;"
687  " padding: 0.75em 0 0;"
688  " margin: 0;"
689  " line-height: 1.1em;"
690  "}"
691  "h3{ background-color: #F6F6F6;"
692  " color: #729FCF;"
693  " font-family: luxi serif, georgia, times new roman, times, serif;"
694  " font-weight: bold;"
695  " font-size: large;"
696  " text-align: right;"
697  " border-bottom: 5px solid #DCEB5C;"
698  "}"
699  "h4{ background-color: #F6F6F6;"
700  " color: #729FCF;"
701  " font-family: luxi serif, georgia, times new roman, times, serif;"
702  " font-weight: bold;"
703  " font-size: medium;"
704  " text-align: right;"
705  "}"
706  "h5{ background-color: #F6F6F6;"
707  " color: #729FCF;"
708  " font-family: luxi serif, georgia, times new roman, times, serif;"
709  " font-weight: bold;"
710  " font-size: small;"
711  " text-align: right;"
712  "}"
713  "a{ color: #729FCF;"
714  " font-family: arial,sans-serif;"
715  " font-size: small;"
716  "}"
717  "label{ background-color: #FFFFCC;"
718  " border: 1px solid black;"
719  " margin: 1px;"
720  " padding: 0px 3px; "
721  " font-size: small;"
722  "}";
723  return myStyle;
724 }
725 
727 {
728  if ( 0 >= OGRGetDriverCount() )
729  {
730  OGRRegisterAll();
731  }
732 }
733 
734 QString QgsApplication::absolutePathToRelativePath( QString aPath, QString targetPath )
735 {
736 #if defined( Q_OS_WIN )
737  const Qt::CaseSensitivity cs = Qt::CaseInsensitive;
738 
739  aPath.replace( "\\", "/" );
740  if ( aPath.startsWith( "//" ) )
741  {
742  // keep UNC prefix
743  aPath = "\\\\" + aPath.mid( 2 );
744  }
745 
746  targetPath.replace( "\\", "/" );
747  if ( targetPath.startsWith( "//" ) )
748  {
749  // keep UNC prefix
750  targetPath = "\\\\" + targetPath.mid( 2 );
751  }
752 #else
753  const Qt::CaseSensitivity cs = Qt::CaseSensitive;
754 #endif
755 
756  QStringList targetElems = targetPath.split( "/", QString::SkipEmptyParts );
757  QStringList aPathElems = aPath.split( "/", QString::SkipEmptyParts );
758 
759  targetElems.removeAll( "." );
760  aPathElems.removeAll( "." );
761 
762  // remove common part
763  int n = 0;
764  while ( aPathElems.size() > 0 &&
765  targetElems.size() > 0 &&
766  aPathElems[0].compare( targetElems[0], cs ) == 0 )
767  {
768  aPathElems.removeFirst();
769  targetElems.removeFirst();
770  n++;
771  }
772 
773  if ( n == 0 )
774  {
775  // no common parts; might not even be a file
776  return aPath;
777  }
778 
779  if ( targetElems.size() > 0 )
780  {
781  // go up to the common directory
782  for ( int i = 0; i < targetElems.size(); i++ )
783  {
784  aPathElems.insert( 0, ".." );
785  }
786  }
787  else
788  {
789  // let it start with . nevertheless,
790  // so relative path always start with either ./ or ../
791  aPathElems.insert( 0, "." );
792  }
793 
794  return aPathElems.join( "/" );
795 }
796 
797 QString QgsApplication::relativePathToAbsolutePath( QString rpath, QString targetPath )
798 {
799  // relative path should always start with ./ or ../
800  if ( !rpath.startsWith( "./" ) && !rpath.startsWith( "../" ) )
801  {
802  return rpath;
803  }
804 
805 #if defined(Q_OS_WIN)
806  rpath.replace( "\\", "/" );
807  targetPath.replace( "\\", "/" );
808 
809  bool uncPath = targetPath.startsWith( "//" );
810 #endif
811 
812  QStringList srcElems = rpath.split( "/", QString::SkipEmptyParts );
813  QStringList targetElems = targetPath.split( "/", QString::SkipEmptyParts );
814 
815 #if defined(Q_OS_WIN)
816  if ( uncPath )
817  {
818  targetElems.insert( 0, "" );
819  targetElems.insert( 0, "" );
820  }
821 #endif
822 
823  // append source path elements
824  targetElems << srcElems;
825  targetElems.removeAll( "." );
826 
827  // resolve ..
828  int pos;
829  while (( pos = targetElems.indexOf( ".." ) ) > 0 )
830  {
831  // remove preceding element and ..
832  targetElems.removeAt( pos - 1 );
833  targetElems.removeAt( pos - 1 );
834  }
835 
836 #if !defined(Q_OS_WIN)
837  // make path absolute
838  targetElems.prepend( "" );
839 #endif
840 
841  return targetElems.join( "/" );
842 }
843 
844 void QgsApplication::skipGdalDriver( QString theDriver )
845 {
846  if ( ABISYM( mGdalSkipList ).contains( theDriver ) || theDriver.isEmpty() )
847  {
848  return;
849  }
850  ABISYM( mGdalSkipList ) << theDriver;
852 }
853 
854 void QgsApplication::restoreGdalDriver( QString theDriver )
855 {
856  if ( !ABISYM( mGdalSkipList ).contains( theDriver ) )
857  {
858  return;
859  }
860  int myPos = ABISYM( mGdalSkipList ).indexOf( theDriver );
861  if ( myPos >= 0 )
862  {
863  ABISYM( mGdalSkipList ).removeAt( myPos );
864  }
866 }
867 
869 {
870  ABISYM( mGdalSkipList ).removeDuplicates();
871  QString myDriverList = ABISYM( mGdalSkipList ).join( " " );
872  QgsDebugMsg( "Gdal Skipped driver list set to:" );
873  QgsDebugMsg( myDriverList );
874  CPLSetConfigOption( "GDAL_SKIP", myDriverList.toUtf8() );
875  GDALAllRegister(); //to update driver list and skip missing ones
876 }
877 
878 bool QgsApplication::createDB( QString *errorMessage )
879 {
880  // set a working directory up for gdal to write .aux.xml files into
881  // for cases where the raster dir is read only to the user
882  // if the env var is already set it will be used preferentially
883  QString myPamPath = qgisSettingsDirPath() + QString( "gdal_pam/" );
884  QDir myDir( myPamPath );
885  if ( !myDir.exists() )
886  {
887  myDir.mkpath( myPamPath ); //fail silently
888  }
889 
890 #if defined(Q_WS_WIN32) || defined(WIN32)
891  CPLSetConfigOption( "GDAL_PAM_PROXY_DIR", myPamPath.toUtf8() );
892 #else
893  //under other OS's we use an environment var so the user can
894  //override the path if he likes
895  int myChangeFlag = 0; //whether we want to force the env var to change
896  setenv( "GDAL_PAM_PROXY_DIR", myPamPath.toUtf8(), myChangeFlag );
897 #endif
898 
899  // Check qgis.db and make private copy if necessary
900  QFile qgisPrivateDbFile( QgsApplication::qgisUserDbFilePath() );
901 
902  // first we look for ~/.qgis/qgis.db
903  if ( !qgisPrivateDbFile.exists() )
904  {
905  // if it doesnt exist we copy it in from the global resources dir
906  QString qgisMasterDbFileName = QgsApplication::qgisMasterDbFilePath();
907  QFile masterFile( qgisMasterDbFileName );
908 
909  // Must be sure there is destination directory ~/.qgis
910  QDir().mkpath( QgsApplication::qgisSettingsDirPath() );
911 
912  //now copy the master file into the users .qgis dir
913  bool isDbFileCopied = masterFile.copy( qgisPrivateDbFile.fileName() );
914 
915  if ( !isDbFileCopied )
916  {
917  if ( errorMessage )
918  {
919  *errorMessage = tr( "[ERROR] Can not make qgis.db private copy" );
920  }
921  return false;
922  }
923  }
924  else
925  {
926  // migrate if necessary
927  sqlite3 *db;
928  if ( sqlite3_open( QgsApplication::qgisUserDbFilePath().toUtf8().constData(), &db ) != SQLITE_OK )
929  {
930  if ( errorMessage )
931  {
932  *errorMessage = tr( "Could not open qgis.db" );
933  }
934  return false;
935  }
936 
937  char *errmsg;
938  int res = sqlite3_exec( db, "SELECT epsg FROM tbl_srs LIMIT 0", 0, 0, &errmsg );
939  if ( res == SQLITE_OK )
940  {
941  // epsg column exists => need migration
942  if ( sqlite3_exec( db,
943  "ALTER TABLE tbl_srs RENAME TO tbl_srs_bak;"
944  "CREATE TABLE tbl_srs ("
945  "srs_id INTEGER PRIMARY KEY,"
946  "description text NOT NULL,"
947  "projection_acronym text NOT NULL,"
948  "ellipsoid_acronym NOT NULL,"
949  "parameters text NOT NULL,"
950  "srid integer,"
951  "auth_name varchar,"
952  "auth_id varchar,"
953  "is_geo integer NOT NULL,"
954  "deprecated boolean);"
955  "CREATE INDEX idx_srsauthid on tbl_srs(auth_name,auth_id);"
956  "INSERT INTO tbl_srs(srs_id,description,projection_acronym,ellipsoid_acronym,parameters,srid,auth_name,auth_id,is_geo,deprecated) SELECT srs_id,description,projection_acronym,ellipsoid_acronym,parameters,srid,'','',is_geo,0 FROM tbl_srs_bak;"
957  "DROP TABLE tbl_srs_bak", 0, 0, &errmsg ) != SQLITE_OK
958  )
959  {
960  if ( errorMessage )
961  {
962  *errorMessage = tr( "Migration of private qgis.db failed.\n%1" ).arg( QString::fromUtf8( errmsg ) );
963  }
964  sqlite3_free( errmsg );
965  sqlite3_close( db );
966  return false;
967  }
968  }
969  else
970  {
971  sqlite3_free( errmsg );
972  }
973 
974  if ( sqlite3_exec( db, "DROP VIEW vw_srs", 0, 0, &errmsg ) != SQLITE_OK )
975  {
976  QgsDebugMsg( QString( "vw_srs didn't exists in private qgis.db: %1" ).arg( errmsg ) );
977  }
978 
979  if ( sqlite3_exec( db,
980  "CREATE VIEW vw_srs AS"
981  " SELECT"
982  " a.description AS description"
983  ",a.srs_id AS srs_id"
984  ",a.is_geo AS is_geo"
985  ",coalesce(b.name,a.projection_acronym) AS name"
986  ",a.parameters AS parameters"
987  ",a.auth_name AS auth_name"
988  ",a.auth_id AS auth_id"
989  ",a.deprecated AS deprecated"
990  " FROM tbl_srs a"
991  " LEFT OUTER JOIN tbl_projection b ON a.projection_acronym=b.acronym"
992  " ORDER BY coalesce(b.name,a.projection_acronym),a.description", 0, 0, &errmsg ) != SQLITE_OK
993  )
994  {
995  if ( errorMessage )
996  {
997  *errorMessage = tr( "Update of view in private qgis.db failed.\n%1" ).arg( QString::fromUtf8( errmsg ) );
998  }
999  sqlite3_free( errmsg );
1000  sqlite3_close( db );
1001  return false;
1002  }
1003 
1004  sqlite3_close( db );
1005  }
1006  return true;
1007 }
1008 
1009 
static void setPkgDataPath(const QString thePkgDataPath)
Alters pkg data path - used by 3rd party apps.
static const QString pkgDataPath()
Returns the common root path of all application data directories.
static void init(QString customConfigPath=QString())
This method initialises paths etc for QGIS.
static const QString i18nPath()
Returns the path to the translation directory.
static const QString contributorsFilePath()
Returns the path to the contributors file.
enum QgsApplication::ENDIAN endian_t
constants for endian-ness
static const QString qgisMasterDbFilePath()
Returns the path to the master qgis.db file.
static const QString libexecPath()
Returns the path with utility executables (help viewer, crssync, ...)
static const QString activeThemePath()
Returns the path to the currently active theme directory.
static QObject * ABISYM(mFileOpenEventReceiver)
static const QString prefixPath()
Returns the path to the application prefix directory.
static const QString helpAppPath()
Returns the path to the help application.
static const QStringList svgPaths()
Returns the pathes to svg directories.
static const QString licenceFilePath()
static QgsProviderRegistry * instance(QString pluginPath=QString::null)
means of accessing canonical single instance
#define QgsDebugMsg(str)
Definition: qgslogger.h:36
static QString iconPath(QString iconFile)
Returns path to the desired icon file.
static const QString libraryPath()
Returns the path containing qgis_core, qgis_gui, qgispython (and other) libraries.
static void setThemeName(const QString theThemeName)
Set the active theme to the specified theme.
static void registerOgrDrivers()
Register OGR drivers ensuring this only happens once.
static const QString translatorsFilePath()
Returns the path to the sponsors file.
static const QString authorsFilePath()
Returns the path to the authors file.
static void setPrefixPath(const QString thePrefixPath, bool useDefaultPaths=false)
Alters prefix path - used by 3rd party apps.
static QString absolutePathToRelativePath(QString apath, QString targetPath)
Converts absolute path to path relative to target.
static void setFileOpenEventReceiver(QObject *receiver)
Set the FileOpen event receiver.
static QString reportStyleSheet()
get a standard css style sheet for reports.
static endian_t endian()
Returns whether this machine uses big or little endian.
static const QString qgisSettingsDirPath()
Returns the path to the settings directory in user's home dir.
virtual bool notify(QObject *receiver, QEvent *event)
Catch exceptions when sending event to receiver.
static void applyGdalSkippedDrivers()
Apply the skipped drivers list to gdal.
static QPixmap getThemePixmap(const QString theName)
Helper to get a theme icon as a pixmap.
static const QString iconsPath()
Returns the path to the icons image directory.
virtual ~QgsApplication()
static const QString splashPath()
Returns the path to the splash screen image directory.
static const QString defaultThemePath()
Returns the path to the default theme directory.
static void restoreGdalDriver(QString theDriver)
Sets the GDAL_SKIP environment variable to exclude the specified driver and then calls GDALDriverMana...
static bool createDB(QString *errorMessage=0)
initialise qgis.db
static const QString defaultStyleV2Path()
Returns the path to default style (works as a starting point). Added in QGIS 1.4. ...
struct sqlite3 sqlite3
static void initQgis()
loads providers
static void setDefaultSvgPaths(const QStringList &pathList)
Alters default svg paths - used by 3rd party apps. Added in QGIS 1.5.
static QString relativePathToAbsolutePath(QString rpath, QString targetPath)
Converts path relative to target to an absolute path.
static void skipGdalDriver(QString theDriver)
Sets the GDAL_SKIP environment variable to include the specified driver and then calls GDALDriverMana...
QString file
Definition: qgssvgcache.cpp:74
static QString showSettings()
Convenience function to get a summary of the paths used in this application instance useful for debug...
QString what() const
Definition: qgsexception.h:35
static QgsMapLayerRegistry * instance()
Returns the instance pointer, creating the object on the first call.
static const QString donorsFilePath()
Returns the path to the donors file.
static const QString srsDbFilePath()
Returns the path to the srs.db file.
QObject * ABISYM(QgsApplication::mFileOpenEventReceiver)
static void exitQgis()
deletes provider registry and map layer registry
static void setPluginPath(const QString thePluginPath)
Alters plugin path - used by 3rd party apps.
static const QString sponsorsFilePath()
Returns the path to the sponsors file.
QgsApplication(int &argc, char **argv, bool GUIenabled, QString customConfigPath=QString())
virtual bool event(QEvent *event)
Watch for QFileOpenEvent.
static const QString qgisUserDbFilePath()
Returns the path to the user qgis.db file.
static const QString pluginPath()
Returns the path to the application plugin directory.
static const QString userStyleV2Path()
Returns the path to user's style. Added in QGIS 1.4.
static const QString themeName()
Set the active theme to the specified theme.
Defines a qgis exception class.
Definition: qgsexception.h:25
void preNotify(QObject *receiver, QEvent *event, bool *done)
static QIcon getThemeIcon(const QString theName)
Helper to get a theme icon.
#define tr(sourceText)