QGIS API Documentation  2.2.0-Valmiera
 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 = QString( "%1/.qgis%2/" ).arg( QDir::homePath() ).arg( 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  // QgsDebugMsg( QString( "prefixPath(): %1" ).arg( prefixPath ) );
95 
96  // check if QGIS is run from build directory (not the install directory)
97  QFile f;
98  // "/../../.." is for Mac bundled app in build directory
99  foreach ( QString path, QStringList() << "" << "/.." << "/bin" << "/../../.." )
100  {
101  f.setFileName( prefixPath + path + "/qgisbuildpath.txt" );
102  if ( f.exists() )
103  break;
104  }
105  if ( f.exists() && f.open( QIODevice::ReadOnly ) )
106  {
107  ABISYM( mRunningFromBuildDir ) = true;
108  ABISYM( mBuildSourcePath ) = f.readLine().trimmed();
109  ABISYM( mBuildOutputPath ) = f.readLine().trimmed();
110  qDebug( "Running from build directory!" );
111  qDebug( "- source directory: %s", ABISYM( mBuildSourcePath ).toUtf8().data() );
112  qDebug( "- output directory of the build: %s", ABISYM( mBuildOutputPath ).toUtf8().data() );
113 #ifdef _MSC_VER
114  ABISYM( mCfgIntDir ) = prefixPath.split( "/", QString::SkipEmptyParts ).last();
115  qDebug( "- cfg: %s", ABISYM( mCfgIntDir ).toUtf8().data() );
116 #endif
117  }
118 
119  if ( ABISYM( mRunningFromBuildDir ) )
120  {
121  // we run from source directory - not installed to destination (specified prefix)
122  ABISYM( mPrefixPath ) = QString(); // set invalid path
123 #if defined(_MSC_VER) && !defined(USING_NMAKE)
124  setPluginPath( ABISYM( mBuildOutputPath ) + "/" + QString( QGIS_PLUGIN_SUBDIR ) + "/" + ABISYM( mCfgIntDir ) );
125 #else
126  setPluginPath( ABISYM( mBuildOutputPath ) + "/" + QString( QGIS_PLUGIN_SUBDIR ) );
127 #endif
128  setPkgDataPath( ABISYM( mBuildSourcePath ) ); // directly source path - used for: doc, resources, svg
129  ABISYM( mLibraryPath ) = ABISYM( mBuildOutputPath ) + "/" + QGIS_LIB_SUBDIR + "/";
130 #if defined(_MSC_VER) && !defined(USING_NMAKE)
131  ABISYM( mLibexecPath ) = ABISYM( mBuildOutputPath ) + "/" + QGIS_LIBEXEC_SUBDIR + "/" + ABISYM( mCfgIntDir ) + "/";
132 #else
133  ABISYM( mLibexecPath ) = ABISYM( mBuildOutputPath ) + "/" + QGIS_LIBEXEC_SUBDIR + "/";
134 #endif
135  }
136  else
137  {
138  char *prefixPath = getenv( "QGIS_PREFIX_PATH" );
139  if ( !prefixPath )
140  {
141 #if defined(Q_WS_MACX) || defined(Q_WS_WIN32) || defined(WIN32)
142  setPrefixPath( applicationDirPath(), true );
143 #elif defined(ANDROID)
144  // this is "/data/data/org.qgis.qgis" in android
145  QDir myDir( QDir::homePath() );
146  myDir.cdUp();
147  QString myPrefix = myDir.absolutePath();
148  setPrefixPath( myPrefix, true );
149 #else
150  QDir myDir( applicationDirPath() );
151  myDir.cdUp();
152  QString myPrefix = myDir.absolutePath();
153  setPrefixPath( myPrefix, true );
154 #endif
155  }
156  else
157  {
158  setPrefixPath( prefixPath, true );
159  }
160  }
161 
162  if ( !customConfigPath.isEmpty() )
163  {
164  ABISYM( mConfigPath ) = customConfigPath + "/"; // make sure trailing slash is included
165  }
166 
167  ABISYM( mDefaultSvgPaths ) << qgisSettingsDirPath() + QString( "svg/" );
168 
169  // store system environment variables passed to application, before they are adjusted
170  QMap<QString, QString> systemEnvVarMap;
171  foreach ( const QString &varStr, QProcess::systemEnvironment() )
172  {
173  int pos = varStr.indexOf( QLatin1Char( '=' ) );
174  if ( pos == -1 )
175  continue;
176  QString varStrName = varStr.left( pos );
177  QString varStrValue = varStr.mid( pos + 1 );
178  systemEnvVarMap.insert( varStrName, varStrValue );
179  }
180  ABISYM( mSystemEnvVars ) = systemEnvVarMap;
181 
182 }
183 
185 {
186 }
187 
188 bool QgsApplication::event( QEvent * event )
189 {
190  bool done = false;
191  if ( event->type() == QEvent::FileOpen )
192  {
193  // handle FileOpen event (double clicking a file icon in Mac OS X Finder)
194  if ( ABISYM( mFileOpenEventReceiver ) )
195  {
196  // Forward event to main window.
197  done = notify( ABISYM( mFileOpenEventReceiver ), event );
198  }
199  else
200  {
201  // Store filename because receiver has not registered yet.
202  // If QGIS has been launched by double clicking a file icon, FileOpen will be
203  // the first event; the main window is not yet ready to handle the event.
204  ABISYM( mFileOpenEventList ).append( static_cast<QFileOpenEvent *>( event )->file() );
205  done = true;
206  }
207  }
208  else
209  {
210  // pass other events to base class
211  done = QApplication::event( event );
212  }
213  return done;
214 }
215 
216 bool QgsApplication::notify( QObject * receiver, QEvent * event )
217 {
218  bool done = false;
219  // Crashes in customization (especially on Mac), if we're not in the main/UI thread, see #5597
220  if ( thread() == receiver->thread() )
221  emit preNotify( receiver, event, &done );
222 
223  if ( done )
224  return true;
225 
226  // Send event to receiver and catch unhandled exceptions
227  done = true;
228  try
229  {
230  done = QApplication::notify( receiver, event );
231  }
232  catch ( QgsException & e )
233  {
234  QMessageBox::critical( activeWindow(), tr( "Exception" ), e.what() );
235  }
236  catch ( std::exception & e )
237  {
238  QMessageBox::critical( activeWindow(), tr( "Exception" ), e.what() );
239  }
240  catch ( ... )
241  {
242  QMessageBox::critical( activeWindow(), tr( "Exception" ), tr( "unknown exception" ) );
243  }
244 
245  return done;
246 }
247 
249 {
250  // Set receiver for FileOpen events
251  ABISYM( mFileOpenEventReceiver ) = receiver;
252  // Propagate any events collected before the receiver has registered.
253  if ( ABISYM( mFileOpenEventList ).count() > 0 )
254  {
255  QStringListIterator i( ABISYM( mFileOpenEventList ) );
256  while ( i.hasNext() )
257  {
258  QFileOpenEvent foe( i.next() );
259  QgsApplication::sendEvent( ABISYM( mFileOpenEventReceiver ), &foe );
260  }
261  ABISYM( mFileOpenEventList ).clear();
262  }
263 }
264 
265 void QgsApplication::setPrefixPath( const QString &thePrefixPath, bool useDefaultPaths )
266 {
267  ABISYM( mPrefixPath ) = thePrefixPath;
268 #if defined(_MSC_VER)
269  if ( ABISYM( mPrefixPath ).endsWith( "/bin" ) )
270  {
271  ABISYM( mPrefixPath ).chop( 4 );
272  }
273 #endif
274  if ( useDefaultPaths && !ABISYM( mRunningFromBuildDir ) )
275  {
276  setPluginPath( ABISYM( mPrefixPath ) + "/" + QString( QGIS_PLUGIN_SUBDIR ) );
277  setPkgDataPath( ABISYM( mPrefixPath ) + "/" + QString( QGIS_DATA_SUBDIR ) );
278  }
279  ABISYM( mLibraryPath ) = ABISYM( mPrefixPath ) + "/" + QGIS_LIB_SUBDIR + "/";
280  ABISYM( mLibexecPath ) = ABISYM( mPrefixPath ) + "/" + QGIS_LIBEXEC_SUBDIR + "/";
281 }
282 
283 void QgsApplication::setPluginPath( const QString &thePluginPath )
284 {
285  ABISYM( mPluginPath ) = thePluginPath;
286 }
287 
288 void QgsApplication::setPkgDataPath( const QString &thePkgDataPath )
289 {
290  ABISYM( mPkgDataPath ) = thePkgDataPath;
291  QString mySvgPath = thePkgDataPath + ( ABISYM( mRunningFromBuildDir ) ? "/images/svg/" : "/svg/" );
292  // avoid duplicate entries
293  if ( !ABISYM( mDefaultSvgPaths ).contains( mySvgPath ) )
294  ABISYM( mDefaultSvgPaths ) << mySvgPath;
295 }
296 
297 void QgsApplication::setDefaultSvgPaths( const QStringList& pathList )
298 {
299  ABISYM( mDefaultSvgPaths ) = pathList;
300 }
301 
303 {
304  if ( ABISYM( mRunningFromBuildDir ) )
305  {
306  qWarning( "!!! prefix path was requested, but it is not valid - we do not run from installed path !!!" );
307  }
308 
309  return ABISYM( mPrefixPath );
310 }
312 {
313  return ABISYM( mPluginPath );
314 }
316 {
317  return ABISYM( mPkgDataPath );
318 }
320 {
321  return ":/images/themes/default/";
322 }
324 {
325  return ":/images/themes/" + themeName() + "/";
326 }
327 
328 
329 QString QgsApplication::iconPath( QString iconFile )
330 {
331  // try active theme
332  QString path = activeThemePath();
333  if ( QFile::exists( path + iconFile ) )
334  return path + iconFile;
335 
336  // use default theme
337  return defaultThemePath() + iconFile;
338 }
339 
340 QIcon QgsApplication::getThemeIcon( const QString &theName )
341 {
342  QString myPreferredPath = activeThemePath() + QDir::separator() + theName;
343  QString myDefaultPath = defaultThemePath() + QDir::separator() + theName;
344  if ( QFile::exists( myPreferredPath ) )
345  {
346  return QIcon( myPreferredPath );
347  }
348  else if ( QFile::exists( myDefaultPath ) )
349  {
350  //could still return an empty icon if it
351  //doesnt exist in the default theme either!
352  return QIcon( myDefaultPath );
353  }
354  else
355  {
356  return QIcon();
357  }
358 }
359 
360 // TODO: add some caching mechanism ?
361 QPixmap QgsApplication::getThemePixmap( const QString &theName )
362 {
363  QString myPreferredPath = activeThemePath() + QDir::separator() + theName;
364  QString myDefaultPath = defaultThemePath() + QDir::separator() + theName;
365  if ( QFile::exists( myPreferredPath ) )
366  {
367  return QPixmap( myPreferredPath );
368  }
369  else
370  {
371  //could still return an empty icon if it
372  //doesnt exist in the default theme either!
373  return QPixmap( myDefaultPath );
374  }
375 }
376 
380 void QgsApplication::setThemeName( const QString &theThemeName )
381 {
382  QString myPath = ":/images/themes/" + theThemeName + "/";
383  //check it exists and if not roll back to default theme
384  if ( QFile::exists( myPath ) )
385  {
386  ABISYM( mThemeName ) = theThemeName;
387  }
388  else
389  {
390  ABISYM( mThemeName ) = "default";
391  }
392 }
397 {
398  return ABISYM( mThemeName );
399 }
404 {
405  return ABISYM( mPkgDataPath ) + QString( "/doc/AUTHORS" );
406 }
411 {
412  return ABISYM( mPkgDataPath ) + QString( "/doc/CONTRIBUTORS" );
413 }
418 {
419  return ABISYM( mPkgDataPath ) + QString( "/doc/SPONSORS" );
420 }
421 
426 {
427  return ABISYM( mPkgDataPath ) + QString( "/doc/DONORS" );
428 }
429 
435 {
436  return ABISYM( mPkgDataPath ) + QString( "/doc/TRANSLATORS" );
437 }
438 
443 {
444  return ABISYM( mPkgDataPath ) + QString( "/doc/LICENSE" );
445 }
446 
451 {
452  QString helpAppPath;
453 #ifdef Q_OS_MACX
454  helpAppPath = applicationDirPath() + "/bin/qgis_help.app/Contents/MacOS";
455 #else
456  helpAppPath = libexecPath();
457 #endif
458  helpAppPath += "/qgis_help";
459 #ifdef Q_OS_WIN
460  helpAppPath += ".exe";
461 #endif
462  return helpAppPath;
463 }
468 {
469  if ( ABISYM( mRunningFromBuildDir ) )
470  return ABISYM( mBuildOutputPath ) + QString( "/i18n" );
471  else
472  return ABISYM( mPkgDataPath ) + QString( "/i18n/" );
473 }
474 
479 {
480  return ABISYM( mPkgDataPath ) + QString( "/resources/qgis.db" );
481 }
482 
487 {
488  return ABISYM( mConfigPath );
489 }
490 
495 {
496  return qgisSettingsDirPath() + QString( "qgis.db" );
497 }
498 
503 {
504  return QString( ":/images/splash/" );
505 }
506 
511 {
512  return ABISYM( mPkgDataPath ) + QString( "/images/icons/" );
513 }
518 {
519  if ( ABISYM( mRunningFromBuildDir ) )
520  {
521  QString tempCopy = QDir::tempPath() + "/srs.db";
522 
523  if ( !QFile( tempCopy ).exists() )
524  {
525  QFile f( ABISYM( mPkgDataPath ) + "/resources/srs.db" );
526  if ( !f.copy( tempCopy ) )
527  {
528  qFatal( "Could not create temporary copy" );
529  }
530  }
531 
532  return tempCopy;
533  }
534  else
535  {
536  return ABISYM( mPkgDataPath ) + QString( "/resources/srs.db" );
537  }
538 }
539 
543 const QStringList QgsApplication::svgPaths()
544 {
545  //local directories to search when looking for an SVG with a given basename
546  //defined by user in options dialog
547  QSettings settings;
548  QStringList myPathList;
549  QString myPaths = settings.value( "svg/searchPathsForSVG", "" ).toString();
550  if ( !myPaths.isEmpty() )
551  {
552  myPathList = myPaths.split( "|" );
553  }
554 
555  myPathList << ABISYM( mDefaultSvgPaths );
556  return myPathList;
557 }
558 
560 {
561  return qgisSettingsDirPath() + QString( "symbology-ng-style.db" );
562 }
563 
565 {
566  return ABISYM( mPkgDataPath ) + QString( "/resources/symbology-ng-style.db" );
567 }
568 
570 {
571  return ABISYM( mLibraryPath );
572 }
573 
575 {
576  return ABISYM( mLibexecPath );
577 }
578 
580 {
581  return ( htonl( 1 ) == 1 ) ? XDR : NDR ;
582 }
583 
585 {
586  // set the provider plugin path (this creates provider registry)
588 
589  // create map layer registry if doesn't exist
591 }
592 
594 {
596 }
597 
599 {
600  QString myEnvironmentVar( getenv( "QGIS_PREFIX_PATH" ) );
601  QString myState = tr( "Application state:\n"
602  "QGIS_PREFIX_PATH env var:\t\t%1\n"
603  "Prefix:\t\t%2\n"
604  "Plugin Path:\t\t%3\n"
605  "Package Data Path:\t%4\n"
606  "Active Theme Name:\t%5\n"
607  "Active Theme Path:\t%6\n"
608  "Default Theme Path:\t%7\n"
609  "SVG Search Paths:\t%8\n"
610  "User DB Path:\t%9\n" )
611  .arg( myEnvironmentVar )
612  .arg( prefixPath() )
613  .arg( pluginPath() )
614  .arg( pkgDataPath() )
615  .arg( themeName() )
616  .arg( activeThemePath() )
617  .arg( defaultThemePath() )
618  .arg( svgPaths().join( tr( "\n\t\t", "match indentation of application state" ) ) )
619  .arg( qgisMasterDbFilePath() );
620  return myState;
621 }
622 
624 {
625  //
626  // Make the style sheet desktop preferences aware by using qappliation
627  // palette as a basis for colors where appropriate
628  //
629 // QColor myColor1 = palette().highlight().color();
630  QColor myColor1( Qt::lightGray );
631  QColor myColor2 = myColor1;
632  myColor2 = myColor2.lighter( 110 ); //10% lighter
633  QString myStyle;
634  myStyle = "p.glossy{ background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, "
635  " stop: 0 " + myColor1.name() + ","
636  " stop: 0.1 " + myColor2.name() + ","
637  " stop: 0.5 " + myColor1.name() + ","
638  " stop: 0.9 " + myColor2.name() + ","
639  " stop: 1 " + myColor1.name() + ");"
640  " color: black;"
641  " padding-left: 4px;"
642  " padding-top: 20px;"
643  " padding-bottom: 8px;"
644  " border: 1px solid #6c6c6c;"
645  "}"
646  "p.subheaderglossy{ background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, "
647  " stop: 0 " + myColor1.name() + ","
648  " stop: 0.1 " + myColor2.name() + ","
649  " stop: 0.5 " + myColor1.name() + ","
650  " stop: 0.9 " + myColor2.name() + ","
651  " stop: 1 " + myColor1.name() + ");"
652  " font-weight: bold;"
653  " font-size: medium;"
654  " line-height: 1.1em;"
655  " width: 100%;"
656  " color: black;"
657  " padding-left: 4px;"
658  " padding-right: 4px;"
659  " padding-top: 20px;"
660  " padding-bottom: 8px;"
661  " border: 1px solid #6c6c6c;"
662  "}"
663  "th.glossy{ background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, "
664  " stop: 0 " + myColor1.name() + ","
665  " stop: 0.1 " + myColor2.name() + ","
666  " stop: 0.5 " + myColor1.name() + ","
667  " stop: 0.9 " + myColor2.name() + ","
668  " stop: 1 " + myColor1.name() + ");"
669  " color: black;"
670  " border: 1px solid #6c6c6c;"
671  "}"
672  ".overview{ font: 1.82em; font-weight: bold;}"
673  "body{ background: white;"
674  " color: black;"
675  " font-family: arial,sans-serif;"
676  "}"
677  "h1{ background-color: #F6F6F6;"
678  " color: #8FB171; "
679  " font-size: x-large; "
680  " font-weight: normal;"
681  " font-family: luxi serif, georgia, times new roman, times, serif;"
682  " background: none;"
683  " padding: 0.75em 0 0;"
684  " margin: 0;"
685  " line-height: 3em;"
686  "}"
687  "h2{ background-color: #F6F6F6;"
688  " color: #8FB171; "
689  " font-size: medium; "
690  " font-weight: normal;"
691  " font-family: luxi serif, georgia, times new roman, times, serif;"
692  " background: none;"
693  " padding: 0.75em 0 0;"
694  " margin: 0;"
695  " line-height: 1.1em;"
696  "}"
697  "h3{ background-color: #F6F6F6;"
698  " color: #729FCF;"
699  " font-family: luxi serif, georgia, times new roman, times, serif;"
700  " font-weight: bold;"
701  " font-size: large;"
702  " text-align: right;"
703  " border-bottom: 5px solid #DCEB5C;"
704  "}"
705  "h4{ background-color: #F6F6F6;"
706  " color: #729FCF;"
707  " font-family: luxi serif, georgia, times new roman, times, serif;"
708  " font-weight: bold;"
709  " font-size: medium;"
710  " text-align: right;"
711  "}"
712  "h5{ background-color: #F6F6F6;"
713  " color: #729FCF;"
714  " font-family: luxi serif, georgia, times new roman, times, serif;"
715  " font-weight: bold;"
716  " font-size: small;"
717  " text-align: right;"
718  "}"
719  "a{ color: #729FCF;"
720  " font-family: arial,sans-serif;"
721  " font-size: small;"
722  "}"
723  "label{ background-color: #FFFFCC;"
724  " border: 1px solid black;"
725  " margin: 1px;"
726  " padding: 0px 3px; "
727  " font-size: small;"
728  "}";
729  return myStyle;
730 }
731 
733 {
734  if ( 0 >= OGRGetDriverCount() )
735  {
736  OGRRegisterAll();
737  }
738 }
739 
740 QString QgsApplication::absolutePathToRelativePath( QString aPath, QString targetPath )
741 {
742 #if defined( Q_OS_WIN )
743  const Qt::CaseSensitivity cs = Qt::CaseInsensitive;
744 
745  aPath.replace( "\\", "/" );
746  if ( aPath.startsWith( "//" ) )
747  {
748  // keep UNC prefix
749  aPath = "\\\\" + aPath.mid( 2 );
750  }
751 
752  targetPath.replace( "\\", "/" );
753  if ( targetPath.startsWith( "//" ) )
754  {
755  // keep UNC prefix
756  targetPath = "\\\\" + targetPath.mid( 2 );
757  }
758 #else
759  const Qt::CaseSensitivity cs = Qt::CaseSensitive;
760 #endif
761 
762  QStringList targetElems = targetPath.split( "/", QString::SkipEmptyParts );
763  QStringList aPathElems = aPath.split( "/", QString::SkipEmptyParts );
764 
765  targetElems.removeAll( "." );
766  aPathElems.removeAll( "." );
767 
768  // remove common part
769  int n = 0;
770  while ( aPathElems.size() > 0 &&
771  targetElems.size() > 0 &&
772  aPathElems[0].compare( targetElems[0], cs ) == 0 )
773  {
774  aPathElems.removeFirst();
775  targetElems.removeFirst();
776  n++;
777  }
778 
779  if ( n == 0 )
780  {
781  // no common parts; might not even be a file
782  return aPath;
783  }
784 
785  if ( targetElems.size() > 0 )
786  {
787  // go up to the common directory
788  for ( int i = 0; i < targetElems.size(); i++ )
789  {
790  aPathElems.insert( 0, ".." );
791  }
792  }
793  else
794  {
795  // let it start with . nevertheless,
796  // so relative path always start with either ./ or ../
797  aPathElems.insert( 0, "." );
798  }
799 
800  return aPathElems.join( "/" );
801 }
802 
803 QString QgsApplication::relativePathToAbsolutePath( QString rpath, QString targetPath )
804 {
805  // relative path should always start with ./ or ../
806  if ( !rpath.startsWith( "./" ) && !rpath.startsWith( "../" ) )
807  {
808  return rpath;
809  }
810 
811 #if defined(Q_OS_WIN)
812  rpath.replace( "\\", "/" );
813  targetPath.replace( "\\", "/" );
814 
815  bool uncPath = targetPath.startsWith( "//" );
816 #endif
817 
818  QStringList srcElems = rpath.split( "/", QString::SkipEmptyParts );
819  QStringList targetElems = targetPath.split( "/", QString::SkipEmptyParts );
820 
821 #if defined(Q_OS_WIN)
822  if ( uncPath )
823  {
824  targetElems.insert( 0, "" );
825  targetElems.insert( 0, "" );
826  }
827 #endif
828 
829  // append source path elements
830  targetElems << srcElems;
831  targetElems.removeAll( "." );
832 
833  // resolve ..
834  int pos;
835  while (( pos = targetElems.indexOf( ".." ) ) > 0 )
836  {
837  // remove preceding element and ..
838  targetElems.removeAt( pos - 1 );
839  targetElems.removeAt( pos - 1 );
840  }
841 
842 #if !defined(Q_OS_WIN)
843  // make path absolute
844  targetElems.prepend( "" );
845 #endif
846 
847  return targetElems.join( "/" );
848 }
849 
850 void QgsApplication::skipGdalDriver( QString theDriver )
851 {
852  if ( ABISYM( mGdalSkipList ).contains( theDriver ) || theDriver.isEmpty() )
853  {
854  return;
855  }
856  ABISYM( mGdalSkipList ) << theDriver;
858 }
859 
860 void QgsApplication::restoreGdalDriver( QString theDriver )
861 {
862  if ( !ABISYM( mGdalSkipList ).contains( theDriver ) )
863  {
864  return;
865  }
866  int myPos = ABISYM( mGdalSkipList ).indexOf( theDriver );
867  if ( myPos >= 0 )
868  {
869  ABISYM( mGdalSkipList ).removeAt( myPos );
870  }
872 }
873 
875 {
876  ABISYM( mGdalSkipList ).removeDuplicates();
877  QString myDriverList = ABISYM( mGdalSkipList ).join( " " );
878  QgsDebugMsg( "Gdal Skipped driver list set to:" );
879  QgsDebugMsg( myDriverList );
880  CPLSetConfigOption( "GDAL_SKIP", myDriverList.toUtf8() );
881  GDALAllRegister(); //to update driver list and skip missing ones
882 }
883 
884 bool QgsApplication::createDB( QString *errorMessage )
885 {
886  // set a working directory up for gdal to write .aux.xml files into
887  // for cases where the raster dir is read only to the user
888  // if the env var is already set it will be used preferentially
889  QString myPamPath = qgisSettingsDirPath() + QString( "gdal_pam/" );
890  QDir myDir( myPamPath );
891  if ( !myDir.exists() )
892  {
893  myDir.mkpath( myPamPath ); //fail silently
894  }
895 
896 #if defined(Q_WS_WIN32) || defined(WIN32)
897  CPLSetConfigOption( "GDAL_PAM_PROXY_DIR", myPamPath.toUtf8() );
898 #else
899  //under other OS's we use an environment var so the user can
900  //override the path if he likes
901  int myChangeFlag = 0; //whether we want to force the env var to change
902  setenv( "GDAL_PAM_PROXY_DIR", myPamPath.toUtf8(), myChangeFlag );
903 #endif
904 
905  // Check qgis.db and make private copy if necessary
906  QFile qgisPrivateDbFile( QgsApplication::qgisUserDbFilePath() );
907 
908  // first we look for ~/.qgis/qgis.db
909  if ( !qgisPrivateDbFile.exists() )
910  {
911  // if it doesnt exist we copy it in from the global resources dir
912  QString qgisMasterDbFileName = QgsApplication::qgisMasterDbFilePath();
913  QFile masterFile( qgisMasterDbFileName );
914 
915  // Must be sure there is destination directory ~/.qgis
916  QDir().mkpath( QgsApplication::qgisSettingsDirPath() );
917 
918  //now copy the master file into the users .qgis dir
919  bool isDbFileCopied = masterFile.copy( qgisPrivateDbFile.fileName() );
920 
921  if ( !isDbFileCopied )
922  {
923  if ( errorMessage )
924  {
925  *errorMessage = tr( "[ERROR] Can not make qgis.db private copy" );
926  }
927  return false;
928  }
929  }
930  else
931  {
932  // migrate if necessary
933  sqlite3 *db;
934  if ( sqlite3_open( QgsApplication::qgisUserDbFilePath().toUtf8().constData(), &db ) != SQLITE_OK )
935  {
936  if ( errorMessage )
937  {
938  *errorMessage = tr( "Could not open qgis.db" );
939  }
940  return false;
941  }
942 
943  char *errmsg;
944  int res = sqlite3_exec( db, "SELECT epsg FROM tbl_srs LIMIT 0", 0, 0, &errmsg );
945  if ( res == SQLITE_OK )
946  {
947  // epsg column exists => need migration
948  if ( sqlite3_exec( db,
949  "ALTER TABLE tbl_srs RENAME TO tbl_srs_bak;"
950  "CREATE TABLE tbl_srs ("
951  "srs_id INTEGER PRIMARY KEY,"
952  "description text NOT NULL,"
953  "projection_acronym text NOT NULL,"
954  "ellipsoid_acronym NOT NULL,"
955  "parameters text NOT NULL,"
956  "srid integer,"
957  "auth_name varchar,"
958  "auth_id varchar,"
959  "is_geo integer NOT NULL,"
960  "deprecated boolean);"
961  "CREATE INDEX idx_srsauthid on tbl_srs(auth_name,auth_id);"
962  "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;"
963  "DROP TABLE tbl_srs_bak", 0, 0, &errmsg ) != SQLITE_OK
964  )
965  {
966  if ( errorMessage )
967  {
968  *errorMessage = tr( "Migration of private qgis.db failed.\n%1" ).arg( QString::fromUtf8( errmsg ) );
969  }
970  sqlite3_free( errmsg );
971  sqlite3_close( db );
972  return false;
973  }
974  }
975  else
976  {
977  sqlite3_free( errmsg );
978  }
979 
980  if ( sqlite3_exec( db, "DROP VIEW vw_srs", 0, 0, &errmsg ) != SQLITE_OK )
981  {
982  QgsDebugMsg( QString( "vw_srs didn't exists in private qgis.db: %1" ).arg( errmsg ) );
983  }
984 
985  if ( sqlite3_exec( db,
986  "CREATE VIEW vw_srs AS"
987  " SELECT"
988  " a.description AS description"
989  ",a.srs_id AS srs_id"
990  ",a.is_geo AS is_geo"
991  ",coalesce(b.name,a.projection_acronym) AS name"
992  ",a.parameters AS parameters"
993  ",a.auth_name AS auth_name"
994  ",a.auth_id AS auth_id"
995  ",a.deprecated AS deprecated"
996  " FROM tbl_srs a"
997  " LEFT OUTER JOIN tbl_projection b ON a.projection_acronym=b.acronym"
998  " ORDER BY coalesce(b.name,a.projection_acronym),a.description", 0, 0, &errmsg ) != SQLITE_OK
999  )
1000  {
1001  if ( errorMessage )
1002  {
1003  *errorMessage = tr( "Update of view in private qgis.db failed.\n%1" ).arg( QString::fromUtf8( errmsg ) );
1004  }
1005  sqlite3_free( errmsg );
1006  sqlite3_close( db );
1007  return false;
1008  }
1009 
1010  sqlite3_close( db );
1011  }
1012  return true;
1013 }
1014 
1015 
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
static void setPrefixPath(const QString &thePrefixPath, bool useDefaultPaths=false)
Alters prefix path - used by 3rd party apps.
#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 QIcon getThemeIcon(const QString &theName)
Helper to get a theme icon.
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 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.
static QPixmap getThemePixmap(const QString &theName)
Helper to get a theme icon as a pixmap.
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 void setThemeName(const QString &theThemeName)
Set the active theme to the specified theme.
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 setPkgDataPath(const QString &thePkgDataPath)
Alters pkg data path - used by 3rd party apps.
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 void setPluginPath(const QString &thePluginPath)
Alters plugin path - used by 3rd party apps.
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:76
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 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.
static const int QGIS_VERSION_INT
Definition: qgis.h:42
Defines a qgis exception class.
Definition: qgsexception.h:25
void preNotify(QObject *receiver, QEvent *event, bool *done)
#define tr(sourceText)