QGIS API Documentation  2.99.0-Master (6a61179)
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 "qgsauthmanager.h"
19 #include "qgsexception.h"
20 #include "qgsgeometry.h"
21 #include "qgslogger.h"
22 #include "qgsmaplayerregistry.h"
24 #include "qgsproviderregistry.h"
25 #include "qgsexpression.h"
26 #include "qgsactionscoperegistry.h"
27 #include "qgsruntimeprofiler.h"
28 
29 #include <QDir>
30 #include <QFile>
31 #include <QFileInfo>
32 #include <QFileOpenEvent>
33 #include <QMessageBox>
34 #include <QPalette>
35 #include <QProcess>
36 #include <QSettings>
37 #include <QIcon>
38 #include <QPixmap>
39 #include <QThreadPool>
40 
41 #ifndef Q_OS_WIN
42 #include <netinet/in.h>
43 #include <pwd.h>
44 #else
45 #include <winsock.h>
46 #include <windows.h>
47 #include <Lmcons.h>
48 #define SECURITY_WIN32
49 #include <Security.h>
50 #pragma comment( lib, "Secur32.lib" )
51 #endif
52 
53 #include "qgsconfig.h"
54 
55 #include <gdal.h>
56 #include <ogr_api.h>
57 #include <cpl_conv.h> // for setting gdal options
58 #include <sqlite3.h>
59 
60 QObject * ABISYM( QgsApplication::mFileOpenEventReceiver );
61 QStringList ABISYM( QgsApplication::mFileOpenEventList );
62 QString ABISYM( QgsApplication::mPrefixPath );
63 QString ABISYM( QgsApplication::mPluginPath );
64 QString ABISYM( QgsApplication::mPkgDataPath );
65 QString ABISYM( QgsApplication::mLibraryPath );
66 QString ABISYM( QgsApplication::mLibexecPath );
67 QString ABISYM( QgsApplication::mThemeName );
68 QString ABISYM( QgsApplication::mUIThemeName );
69 QStringList ABISYM( QgsApplication::mDefaultSvgPaths );
70 QMap<QString, QString> ABISYM( QgsApplication::mSystemEnvVars );
71 QString ABISYM( QgsApplication::mConfigPath );
72 bool ABISYM( QgsApplication::mRunningFromBuildDir ) = false;
73 QString ABISYM( QgsApplication::mBuildSourcePath );
74 #ifdef _MSC_VER
75 QString ABISYM( QgsApplication::mCfgIntDir );
76 #endif
77 QString ABISYM( QgsApplication::mBuildOutputPath );
78 QStringList ABISYM( QgsApplication::mGdalSkipList );
79 int ABISYM( QgsApplication::mMaxThreads );
80 QString ABISYM( QgsApplication::mAuthDbDirPath );
81 
82 QString QgsApplication::sUserName;
83 QString QgsApplication::sUserFullName;
84 QString QgsApplication::sPlatformName = QStringLiteral( "desktop" );
85 
86 const char* QgsApplication::QGIS_ORGANIZATION_NAME = "QGIS";
87 const char* QgsApplication::QGIS_ORGANIZATION_DOMAIN = "qgis.org";
88 const char* QgsApplication::QGIS_APPLICATION_NAME = "QGIS3";
89 
103 QgsApplication::QgsApplication( int & argc, char ** argv, bool GUIenabled, const QString& customConfigPath, const QString& platformName )
104  : QApplication( argc, argv, GUIenabled )
105 {
106  sPlatformName = platformName;
107 
108  mProfiler = new QgsRuntimeProfiler();
109  mActionScopeRegistry = new QgsActionScopeRegistry();
110 
111  init( customConfigPath ); // init can also be called directly by e.g. unit tests that don't inherit QApplication.
112 }
113 
114 void QgsApplication::init( QString customConfigPath )
115 {
116  if ( customConfigPath.isEmpty() )
117  {
118  if ( getenv( "QGIS_CUSTOM_CONFIG_PATH" ) )
119  {
120  customConfigPath = getenv( "QGIS_CUSTOM_CONFIG_PATH" );
121  }
122  else
123  {
124  customConfigPath = QStringLiteral( "%1/.qgis3/" ).arg( QDir::homePath() );
125  }
126  }
127 
128  qRegisterMetaType<QgsGeometry::Error>( "QgsGeometry::Error" );
129 
130  QString prefixPath( getenv( "QGIS_PREFIX_PATH" ) ? getenv( "QGIS_PREFIX_PATH" ) : applicationDirPath() );
131  // QgsDebugMsg( QString( "prefixPath(): %1" ).arg( prefixPath ) );
132 
133  // check if QGIS is run from build directory (not the install directory)
134  QFile f;
135  // "/../../.." is for Mac bundled app in build directory
136  Q_FOREACH ( const QString& path, QStringList() << "" << "/.." << "/bin" << "/../../.." )
137  {
138  f.setFileName( prefixPath + path + "/qgisbuildpath.txt" );
139  if ( f.exists() )
140  break;
141  }
142  if ( f.exists() && f.open( QIODevice::ReadOnly ) )
143  {
144  ABISYM( mRunningFromBuildDir ) = true;
145  ABISYM( mBuildSourcePath ) = f.readLine().trimmed();
146  ABISYM( mBuildOutputPath ) = f.readLine().trimmed();
147  qDebug( "Running from build directory!" );
148  qDebug( "- source directory: %s", ABISYM( mBuildSourcePath ).toUtf8().data() );
149  qDebug( "- output directory of the build: %s", ABISYM( mBuildOutputPath ).toUtf8().data() );
150 #ifdef _MSC_VER
151  ABISYM( mCfgIntDir ) = prefixPath.split( '/', QString::SkipEmptyParts ).last();
152  qDebug( "- cfg: %s", ABISYM( mCfgIntDir ).toUtf8().data() );
153 #endif
154  }
155 
156  if ( ABISYM( mRunningFromBuildDir ) )
157  {
158  // we run from source directory - not installed to destination (specified prefix)
159  ABISYM( mPrefixPath ) = QString(); // set invalid path
160 #if defined(_MSC_VER) && !defined(USING_NMAKE) && !defined(USING_NINJA)
161  setPluginPath( ABISYM( mBuildOutputPath ) + '/' + QString( QGIS_PLUGIN_SUBDIR ) + '/' + ABISYM( mCfgIntDir ) );
162 #else
163  setPluginPath( ABISYM( mBuildOutputPath ) + '/' + QStringLiteral( QGIS_PLUGIN_SUBDIR ) );
164 #endif
165  setPkgDataPath( ABISYM( mBuildSourcePath ) ); // directly source path - used for: doc, resources, svg
166  ABISYM( mLibraryPath ) = ABISYM( mBuildOutputPath ) + '/' + QGIS_LIB_SUBDIR + '/';
167 #if defined(_MSC_VER) && !defined(USING_NMAKE) && !defined(USING_NINJA)
168  ABISYM( mLibexecPath ) = ABISYM( mBuildOutputPath ) + '/' + QGIS_LIBEXEC_SUBDIR + '/' + ABISYM( mCfgIntDir ) + '/';
169 #else
170  ABISYM( mLibexecPath ) = ABISYM( mBuildOutputPath ) + '/' + QGIS_LIBEXEC_SUBDIR + '/';
171 #endif
172  }
173  else
174  {
175  char *prefixPath = getenv( "QGIS_PREFIX_PATH" );
176  if ( !prefixPath )
177  {
178 #if defined(Q_OS_MACX) || defined(Q_OS_WIN)
179  setPrefixPath( applicationDirPath(), true );
180 #elif defined(ANDROID)
181  // this is "/data/data/org.qgis.qgis" in android
182  QDir myDir( QDir::homePath() );
183  myDir.cdUp();
184  QString myPrefix = myDir.absolutePath();
185  setPrefixPath( myPrefix, true );
186 #else
187  QDir myDir( applicationDirPath() );
188  myDir.cdUp();
189  QString myPrefix = myDir.absolutePath();
190  setPrefixPath( myPrefix, true );
191 #endif
192  }
193  else
194  {
195  setPrefixPath( prefixPath, true );
196  }
197  }
198 
199  if ( !customConfigPath.isEmpty() )
200  {
201  ABISYM( mConfigPath ) = customConfigPath + '/'; // make sure trailing slash is included
202  }
203 
204  ABISYM( mDefaultSvgPaths ) << qgisSettingsDirPath() + QStringLiteral( "svg/" );
205 
206  ABISYM( mAuthDbDirPath ) = qgisSettingsDirPath();
207  if ( getenv( "QGIS_AUTH_DB_DIR_PATH" ) )
208  {
209  setAuthDbDirPath( getenv( "QGIS_AUTH_DB_DIR_PATH" ) );
210  }
211 
212 
213  // store system environment variables passed to application, before they are adjusted
214  QMap<QString, QString> systemEnvVarMap;
215  QString passfile( QStringLiteral( "QGIS_AUTH_PASSWORD_FILE" ) ); // QString, for comparison
216  Q_FOREACH ( const QString &varStr, QProcess::systemEnvironment() )
217  {
218  int pos = varStr.indexOf( QLatin1Char( '=' ) );
219  if ( pos == -1 )
220  continue;
221  QString varStrName = varStr.left( pos );
222  QString varStrValue = varStr.mid( pos + 1 );
223  if ( varStrName != passfile )
224  {
225  systemEnvVarMap.insert( varStrName, varStrValue );
226  }
227  }
228  ABISYM( mSystemEnvVars ) = systemEnvVarMap;
229 
230  // allow Qt to search for Qt plugins (e.g. sqldrivers) in our plugin directory
231  QCoreApplication::addLibraryPath( pluginPath() );
232 
233  // set max. thread count to -1
234  // this should be read from QSettings but we don't know where they are at this point
235  // so we read actual value in main.cpp
236  ABISYM( mMaxThreads ) = -1;
237 }
238 
240 {
241  delete mActionScopeRegistry;
242  delete mProfiler;
243 }
244 
246 {
247  return qobject_cast<QgsApplication*>( QCoreApplication::instance() );
248 }
249 
250 bool QgsApplication::event( QEvent * event )
251 {
252  bool done = false;
253  if ( event->type() == QEvent::FileOpen )
254  {
255  // handle FileOpen event (double clicking a file icon in Mac OS X Finder)
256  if ( ABISYM( mFileOpenEventReceiver ) )
257  {
258  // Forward event to main window.
259  done = notify( ABISYM( mFileOpenEventReceiver ), event );
260  }
261  else
262  {
263  // Store filename because receiver has not registered yet.
264  // If QGIS has been launched by double clicking a file icon, FileOpen will be
265  // the first event; the main window is not yet ready to handle the event.
266  ABISYM( mFileOpenEventList ).append( static_cast<QFileOpenEvent *>( event )->file() );
267  done = true;
268  }
269  }
270  else
271  {
272  // pass other events to base class
273  done = QApplication::event( event );
274  }
275  return done;
276 }
277 
278 bool QgsApplication::notify( QObject * receiver, QEvent * event )
279 {
280  bool done = false;
281  // Crashes in customization (especially on Mac), if we're not in the main/UI thread, see #5597
282  if ( thread() == receiver->thread() )
283  emit preNotify( receiver, event, &done );
284 
285  if ( done )
286  return true;
287 
288  // Send event to receiver and catch unhandled exceptions
289  done = true;
290  try
291  {
292  done = QApplication::notify( receiver, event );
293  }
294  catch ( QgsException & e )
295  {
296  QgsDebugMsg( "Caught unhandled QgsException: " + e.what() );
297  if ( qApp->thread() == QThread::currentThread() )
298  QMessageBox::critical( activeWindow(), tr( "Exception" ), e.what() );
299  }
300  catch ( std::exception & e )
301  {
302  QgsDebugMsg( "Caught unhandled std::exception: " + QString::fromAscii( e.what() ) );
303  if ( qApp->thread() == QThread::currentThread() )
304  QMessageBox::critical( activeWindow(), tr( "Exception" ), e.what() );
305  }
306  catch ( ... )
307  {
308  QgsDebugMsg( "Caught unhandled unknown exception" );
309  if ( qApp->thread() == QThread::currentThread() )
310  QMessageBox::critical( activeWindow(), tr( "Exception" ), tr( "unknown exception" ) );
311  }
312 
313  return done;
314 }
315 
317 {
318  return instance()->mProfiler;
319 }
320 
322 {
323  // Set receiver for FileOpen events
324  ABISYM( mFileOpenEventReceiver ) = receiver;
325  // Propagate any events collected before the receiver has registered.
326  if ( ABISYM( mFileOpenEventList ).count() > 0 )
327  {
328  QStringListIterator i( ABISYM( mFileOpenEventList ) );
329  while ( i.hasNext() )
330  {
331  QFileOpenEvent foe( i.next() );
332  QgsApplication::sendEvent( ABISYM( mFileOpenEventReceiver ), &foe );
333  }
334  ABISYM( mFileOpenEventList ).clear();
335  }
336 }
337 
338 void QgsApplication::setPrefixPath( const QString &thePrefixPath, bool useDefaultPaths )
339 {
340  ABISYM( mPrefixPath ) = thePrefixPath;
341 #if defined(_MSC_VER)
342  if ( ABISYM( mPrefixPath ).endsWith( "/bin" ) )
343  {
344  ABISYM( mPrefixPath ).chop( 4 );
345  }
346 #endif
347  if ( useDefaultPaths && !ABISYM( mRunningFromBuildDir ) )
348  {
349  setPluginPath( ABISYM( mPrefixPath ) + '/' + QStringLiteral( QGIS_PLUGIN_SUBDIR ) );
350  setPkgDataPath( ABISYM( mPrefixPath ) + '/' + QStringLiteral( QGIS_DATA_SUBDIR ) );
351  }
352  ABISYM( mLibraryPath ) = ABISYM( mPrefixPath ) + '/' + QGIS_LIB_SUBDIR + '/';
353  ABISYM( mLibexecPath ) = ABISYM( mPrefixPath ) + '/' + QGIS_LIBEXEC_SUBDIR + '/';
354 }
355 
356 void QgsApplication::setPluginPath( const QString &thePluginPath )
357 {
358  ABISYM( mPluginPath ) = thePluginPath;
359 }
360 
361 void QgsApplication::setPkgDataPath( const QString &thePkgDataPath )
362 {
363  ABISYM( mPkgDataPath ) = thePkgDataPath;
364  QString mySvgPath = thePkgDataPath + ( ABISYM( mRunningFromBuildDir ) ? "/images/svg/" : "/svg/" );
365  // avoid duplicate entries
366  if ( !ABISYM( mDefaultSvgPaths ).contains( mySvgPath ) )
367  ABISYM( mDefaultSvgPaths ) << mySvgPath;
368 }
369 
370 void QgsApplication::setDefaultSvgPaths( const QStringList& pathList )
371 {
372  ABISYM( mDefaultSvgPaths ) = pathList;
373 }
374 
375 void QgsApplication::setAuthDbDirPath( const QString& theAuthDbDirPath )
376 {
377  QFileInfo fi( theAuthDbDirPath );
378  if ( fi.exists() && fi.isDir() && fi.isWritable() )
379  {
380  ABISYM( mAuthDbDirPath ) = fi.canonicalFilePath() + QDir::separator();
381  }
382 }
383 
385 {
386  if ( ABISYM( mRunningFromBuildDir ) )
387  {
388  static bool once = true;
389  if ( once )
390  qWarning( "!!! prefix path was requested, but it is not valid - we do not run from installed path !!!" );
391  once = false;
392  }
393 
394  return ABISYM( mPrefixPath );
395 }
397 {
398  return ABISYM( mPluginPath );
399 }
401 {
402  return ABISYM( mPkgDataPath );
403 }
405 {
406  return QStringLiteral( ":/images/themes/default/" );
407 }
409 {
410  return userThemesFolder() + QDir::separator() + themeName() + QDir::separator() + "icons/";
411 }
412 
414 {
415  return iconsPath() + ( QDate::currentDate().month() == 12 ? tr( "qgis-icon-60x60_xmas.png", "December application icon" ) : QStringLiteral( "qgis-icon-60x60.png" ) );
416 }
417 
418 QString QgsApplication::iconPath( const QString& iconFile )
419 {
420  // try active theme
421  QString path = activeThemePath();
422  if ( QFile::exists( path + iconFile ) )
423  return path + iconFile;
424 
425  // use default theme
426  return defaultThemePath() + iconFile;
427 }
428 
429 QIcon QgsApplication::getThemeIcon( const QString &theName )
430 {
431  QgsApplication* app = instance();
432  if ( app && app->mIconCache.contains( theName ) )
433  return app->mIconCache.value( theName );
434 
435  QIcon icon;
436 
437  QString myPreferredPath = activeThemePath() + QDir::separator() + theName;
438  QString myDefaultPath = defaultThemePath() + QDir::separator() + theName;
439  if ( QFile::exists( myPreferredPath ) )
440  {
441  icon = QIcon( myPreferredPath );
442  }
443  else if ( QFile::exists( myDefaultPath ) )
444  {
445  //could still return an empty icon if it
446  //doesnt exist in the default theme either!
447  icon = QIcon( myDefaultPath );
448  }
449  else
450  {
451  icon = QIcon();
452  }
453 
454  if ( app )
455  app->mIconCache.insert( theName, icon );
456  return icon;
457 }
458 
459 // TODO: add some caching mechanism ?
460 QPixmap QgsApplication::getThemePixmap( const QString &theName )
461 {
462  QString myPreferredPath = activeThemePath() + QDir::separator() + theName;
463  QString myDefaultPath = defaultThemePath() + QDir::separator() + theName;
464  if ( QFile::exists( myPreferredPath ) )
465  {
466  return QPixmap( myPreferredPath );
467  }
468  else
469  {
470  //could still return an empty icon if it
471  //doesnt exist in the default theme either!
472  return QPixmap( myDefaultPath );
473  }
474 }
475 
479 void QgsApplication::setThemeName( const QString &theThemeName )
480 {
481  ABISYM( mThemeName ) = theThemeName;
482 }
487 {
488  return ABISYM( mThemeName );
489 }
490 
491 void QgsApplication::setUITheme( const QString &themeName )
492 {
493  // Loop all style sheets, find matching name, load it.
494  QHash<QString, QString> themes = QgsApplication::uiThemes();
495  QString themename = themeName;
496  if ( !themes.contains( themename ) )
497  themename = QStringLiteral( "default" );
498 
499  QString path = themes[themename];
500  QString stylesheetname = path + "/style.qss";
501  QString autostylesheet = stylesheetname + ".auto";
502 
503  QFile file( stylesheetname );
504  QFile variablesfile( path + "/variables.qss" );
505  QFile fileout( autostylesheet );
506 
507  QFileInfo variableInfo( variablesfile );
508 
509  if ( variableInfo.exists() && variablesfile.open( QIODevice::ReadOnly ) )
510  {
511  if ( !file.open( QIODevice::ReadOnly ) || !fileout.open( QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate ) )
512  {
513  return;
514  }
515 
516  QHash<QString, QString> variables;
517  QString styledata = file.readAll();
518  QTextStream in( &variablesfile );
519  while ( !in.atEnd() )
520  {
521  QString line = in.readLine();
522  // This is is a variable
523  if ( line.startsWith( '@' ) )
524  {
525  int index = line.indexOf( ':' );
526  QString name = line.mid( 0, index );
527  QString value = line.mid( index + 1, line.length() );
528  styledata.replace( name, value );
529  }
530  }
531  variablesfile.close();
532  QTextStream out( &fileout );
533  out << styledata;
534  fileout.close();
535  file.close();
536  stylesheetname = autostylesheet;
537  }
538 
539  QString styleSheet = QStringLiteral( "file:///" );
540  styleSheet.append( stylesheetname );
541  qApp->setStyleSheet( styleSheet );
542  setThemeName( themename );
543 }
544 
545 QHash<QString, QString> QgsApplication::uiThemes()
546 {
547  QStringList paths = QStringList() << userThemesFolder();
548  QHash<QString, QString> mapping;
549  mapping.insert( QStringLiteral( "default" ), QLatin1String( "" ) );
550  Q_FOREACH ( const QString& path, paths )
551  {
552  QDir folder( path );
553  QFileInfoList styleFiles = folder.entryInfoList( QDir::Dirs | QDir::NoDotAndDotDot );
554  Q_FOREACH ( const QFileInfo& info, styleFiles )
555  {
556  QFileInfo styleFile( info.absoluteFilePath() + "/style.qss" );
557  if ( !styleFile.exists() )
558  continue;
559 
560  QString name = info.baseName();
561  QString path = info.absoluteFilePath();
562  mapping.insert( name, path );
563  }
564  }
565  return mapping;
566 }
567 
572 {
573  return ABISYM( mPkgDataPath ) + QStringLiteral( "/doc/AUTHORS" );
574 }
579 {
580  return ABISYM( mPkgDataPath ) + QStringLiteral( "/doc/CONTRIBUTORS" );
581 }
583 {
584  return ABISYM( mPkgDataPath ) + QStringLiteral( "/doc/developersmap.html" );
585 }
586 
591 {
592  return ABISYM( mPkgDataPath ) + QStringLiteral( "/doc/SPONSORS" );
593 }
594 
599 {
600  return ABISYM( mPkgDataPath ) + QStringLiteral( "/doc/DONORS" );
601 }
602 
605 {
606  return ABISYM( mPkgDataPath ) + QStringLiteral( "/doc/TRANSLATORS" );
607 }
608 
611 {
612  return ABISYM( mPkgDataPath ) + QStringLiteral( "/doc/LICENSE" );
613 }
614 
619 {
620  QString helpAppPath;
621 #ifdef Q_OS_MACX
622  helpAppPath = applicationDirPath() + "/bin/qgis_help.app/Contents/MacOS";
623 #else
624  helpAppPath = libexecPath();
625 #endif
626  helpAppPath += QLatin1String( "/qgis_help" );
627 #ifdef Q_OS_WIN
628  helpAppPath += ".exe";
629 #endif
630  return helpAppPath;
631 }
636 {
637  if ( ABISYM( mRunningFromBuildDir ) )
638  return ABISYM( mBuildOutputPath ) + QStringLiteral( "/i18n" );
639  else
640  return ABISYM( mPkgDataPath ) + QStringLiteral( "/i18n/" );
641 }
642 
647 {
648  return ABISYM( mPkgDataPath ) + QStringLiteral( "/resources/qgis.db" );
649 }
650 
655 {
656  return ABISYM( mConfigPath );
657 }
658 
663 {
664  return qgisSettingsDirPath() + QStringLiteral( "qgis.db" );
665 }
666 
671 {
672  return ABISYM( mAuthDbDirPath ) + QStringLiteral( "qgis-auth.db" );
673 }
674 
679 {
680  return QStringLiteral( ":/images/splash/" );
681 }
682 
687 {
688  return ABISYM( mPkgDataPath ) + QStringLiteral( "/images/icons/" );
689 }
694 {
695  if ( ABISYM( mRunningFromBuildDir ) )
696  {
697  QString tempCopy = QDir::tempPath() + "/srs.db";
698 
699  if ( !QFile( tempCopy ).exists() )
700  {
701  QFile f( ABISYM( mPkgDataPath ) + "/resources/srs.db" );
702  if ( !f.copy( tempCopy ) )
703  {
704  qFatal( "Could not create temporary copy" );
705  }
706  }
707 
708  return tempCopy;
709  }
710  else
711  {
712  return ABISYM( mPkgDataPath ) + QStringLiteral( "/resources/srs.db" );
713  }
714 }
715 
720 {
721  //local directories to search when looking for an SVG with a given basename
722  //defined by user in options dialog
723  QSettings settings;
724  QStringList myPathList;
725  QString myPaths = settings.value( QStringLiteral( "svg/searchPathsForSVG" ), QString() ).toString();
726  if ( !myPaths.isEmpty() )
727  {
728  myPathList = myPaths.split( '|' );
729  }
730 
731  // maintain user set order while stripping duplicates
732  QStringList paths;
733  Q_FOREACH ( const QString& path, myPathList )
734  {
735  if ( !paths.contains( path ) )
736  paths.append( path );
737  }
738  Q_FOREACH ( const QString& path, ABISYM( mDefaultSvgPaths ) )
739  {
740  if ( !paths.contains( path ) )
741  paths.append( path );
742  }
743 
744  return paths;
745 }
746 
751 {
752  //local directories to search when looking for an SVG with a given basename
753  //defined by user in options dialog
754  QSettings settings;
755  QStringList myPathList;
756  QString myPaths = settings.value( QStringLiteral( "composer/searchPathsForTemplates" ), QString() ).toString();
757  if ( !myPaths.isEmpty() )
758  {
759  myPathList = myPaths.split( '|' );
760  }
761 
762  return myPathList;
763 }
764 
766 {
767  return qgisSettingsDirPath() + QStringLiteral( "symbology-ng-style.db" );
768 }
769 
771 {
772  return QRegExp( "^[A-Za-z][A-Za-z0-9\\._-]*" );
773 }
774 
776 {
777  if ( !sUserName.isEmpty() )
778  return sUserName;
779 
780 #ifdef Q_OS_WIN
781  TCHAR name [ UNLEN + 1 ];
782  DWORD size = UNLEN + 1;
783 
784  if ( GetUserName(( TCHAR* )name, &size ) )
785  {
786  sUserName = QString( name );
787  }
788 
789 #else
790  QProcess process;
791 
792  process.start( QStringLiteral( "whoami" ) );
793  process.waitForFinished();
794  sUserName = process.readAllStandardOutput().trimmed();
795 #endif
796 
797  if ( !sUserName.isEmpty() )
798  return sUserName;
799 
800  //backup plan - use environment variables
801  sUserName = qgetenv( "USER" );
802  if ( !sUserName.isEmpty() )
803  return sUserName;
804 
805  //last resort
806  sUserName = qgetenv( "USERNAME" );
807  return sUserName;
808 }
809 
811 {
812  if ( !sUserFullName.isEmpty() )
813  return sUserFullName;
814 
815 #ifdef Q_OS_WIN
816  TCHAR name [ UNLEN + 1 ];
817  DWORD size = UNLEN + 1;
818 
819  //note - this only works for accounts connected to domain
820  if ( GetUserNameEx( NameDisplay, ( TCHAR* )name, &size ) )
821  {
822  sUserFullName = QString( name );
823  }
824 
825  //fall back to login name
826  if ( sUserFullName.isEmpty() )
827  sUserFullName = userLoginName();
828 #elif defined(Q_OS_ANDROID)
829  sUserFullName = "Not available";
830 #else
831  struct passwd *p = getpwuid( getuid() );
832 
833  if ( p )
834  {
835  QString gecosName = QString( p->pw_gecos );
836  sUserFullName = gecosName.left( gecosName.indexOf( ',', 0 ) );
837  }
838 
839 #endif
840 
841  return sUserFullName;
842 }
843 
845 {
846 #if defined(Q_OS_ANDROID)
847  return QLatin1String( "android" );
848 #elif defined(Q_OS_MAC)
849  return QLatin1String( "osx" );
850 #elif defined(Q_OS_WIN)
851  return QLatin1String( "windows" );
852 #elif defined(Q_OS_LINUX)
853  return QStringLiteral( "linux" );
854 #else
855  return QLatin1String( "unknown" );
856 #endif
857 }
858 
860 {
861  return sPlatformName;
862 }
863 
865 {
866  return qgisSettingsDirPath() + QStringLiteral( "/themes" );
867 }
868 
870 {
871  return ABISYM( mPkgDataPath ) + QStringLiteral( "/resources/symbology-ng-style.xml" );
872 }
873 
875 {
876  return ABISYM( mPkgDataPath ) + QStringLiteral( "/resources/themes" );
877 }
878 
880 {
881  return ABISYM( mLibraryPath );
882 }
883 
885 {
886  return ABISYM( mLibexecPath );
887 }
888 
890 {
891  return ( htonl( 1 ) == 1 ) ? XDR : NDR;
892 }
893 
895 {
896  // set the provider plugin path (this creates provider registry)
898 
899  // create map layer registry if doesn't exist
901 
902  // Make sure we have a NAM created on the main thread.
904 
905  // initialize authentication manager and connect to database
907 }
908 
910 {
911  delete QgsAuthManager::instance();
912 
913  //Ensure that all remaining deleteLater QObjects are actually deleted before we exit.
914  //This isn't strictly necessary (since we're exiting anyway) but doing so prevents a lot of
915  //LeakSanitiser noise which hides real issues
916  QgsApplication::sendPostedEvents( nullptr, QEvent::DeferredDelete );
917 
919 
920  //delete all registered functions from expression engine (see above comment)
922 
923  // tear-down GDAL/OGR
924  OGRCleanupAll();
925  GDALDestroyDriverManager();
926 }
927 
929 {
930  QString myEnvironmentVar( getenv( "QGIS_PREFIX_PATH" ) );
931  QString myState = tr( "Application state:\n"
932  "QGIS_PREFIX_PATH env var:\t\t%1\n"
933  "Prefix:\t\t%2\n"
934  "Plugin Path:\t\t%3\n"
935  "Package Data Path:\t%4\n"
936  "Active Theme Name:\t%5\n"
937  "Active Theme Path:\t%6\n"
938  "Default Theme Path:\t%7\n"
939  "SVG Search Paths:\t%8\n"
940  "User DB Path:\t%9\n"
941  "Auth DB Path:\t%10\n" )
942  .arg( myEnvironmentVar,
943  prefixPath(),
944  pluginPath(),
945  pkgDataPath(),
946  themeName(),
947  activeThemePath(),
949  svgPaths().join( tr( "\n\t\t", "match indentation of application state" ) ),
951  .arg( qgisAuthDbFilePath() );
952  return myState;
953 }
954 
956 {
957  //
958  // Make the style sheet desktop preferences aware by using qappliation
959  // palette as a basis for colors where appropriate
960  //
961 // QColor myColor1 = palette().highlight().color();
962  QColor myColor1( Qt::lightGray );
963  QColor myColor2 = myColor1;
964  myColor2 = myColor2.lighter( 110 ); //10% lighter
965  QString myStyle;
966  myStyle = "p.glossy{ background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, "
967  " stop: 0 " + myColor1.name() + ","
968  " stop: 0.1 " + myColor2.name() + ","
969  " stop: 0.5 " + myColor1.name() + ","
970  " stop: 0.9 " + myColor2.name() + ","
971  " stop: 1 " + myColor1.name() + ");"
972  " color: black;"
973  " padding-left: 4px;"
974  " padding-top: 20px;"
975  " padding-bottom: 8px;"
976  " border: 1px solid #6c6c6c;"
977  "}"
978  "p.subheaderglossy{ background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, "
979  " stop: 0 " + myColor1.name() + ","
980  " stop: 0.1 " + myColor2.name() + ","
981  " stop: 0.5 " + myColor1.name() + ","
982  " stop: 0.9 " + myColor2.name() + ","
983  " stop: 1 " + myColor1.name() + ");"
984  " font-weight: bold;"
985  " font-size: medium;"
986  " line-height: 1.1em;"
987  " width: 100%;"
988  " color: black;"
989  " padding-left: 4px;"
990  " padding-right: 4px;"
991  " padding-top: 20px;"
992  " padding-bottom: 8px;"
993  " border: 1px solid #6c6c6c;"
994  "}"
995  "th.glossy{ background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, "
996  " stop: 0 " + myColor1.name() + ","
997  " stop: 0.1 " + myColor2.name() + ","
998  " stop: 0.5 " + myColor1.name() + ","
999  " stop: 0.9 " + myColor2.name() + ","
1000  " stop: 1 " + myColor1.name() + ");"
1001  " color: black;"
1002  " border: 1px solid #6c6c6c;"
1003  "}"
1004  ".overview{ font: 1.82em; font-weight: bold;}"
1005  "body{ background: white;"
1006  " color: black;"
1007  " font-family: arial,sans-serif;"
1008  "}"
1009  "h1{ background-color: #F6F6F6;"
1010  " color: #8FB171; "
1011  " font-size: x-large; "
1012  " font-weight: normal;"
1013  " font-family: luxi serif, georgia, times new roman, times, serif;"
1014  " background: none;"
1015  " padding: 0.75em 0 0;"
1016  " margin: 0;"
1017  " line-height: 3em;"
1018  "}"
1019  "h2{ background-color: #F6F6F6;"
1020  " color: #8FB171; "
1021  " font-size: medium; "
1022  " font-weight: normal;"
1023  " font-family: luxi serif, georgia, times new roman, times, serif;"
1024  " background: none;"
1025  " padding: 0.75em 0 0;"
1026  " margin: 0;"
1027  " line-height: 1.1em;"
1028  "}"
1029  "h3{ background-color: #F6F6F6;"
1030  " color: #729FCF;"
1031  " font-family: luxi serif, georgia, times new roman, times, serif;"
1032  " font-weight: bold;"
1033  " font-size: large;"
1034  " text-align: right;"
1035  " border-bottom: 5px solid #DCEB5C;"
1036  "}"
1037  "h4{ background-color: #F6F6F6;"
1038  " color: #729FCF;"
1039  " font-family: luxi serif, georgia, times new roman, times, serif;"
1040  " font-weight: bold;"
1041  " font-size: medium;"
1042  " text-align: right;"
1043  "}"
1044  "h5{ background-color: #F6F6F6;"
1045  " color: #729FCF;"
1046  " font-family: luxi serif, georgia, times new roman, times, serif;"
1047  " font-weight: bold;"
1048  " font-size: small;"
1049  " text-align: right;"
1050  "}"
1051  "a{ color: #729FCF;"
1052  " font-family: arial,sans-serif;"
1053  " font-size: small;"
1054  "}"
1055  "label{ background-color: #FFFFCC;"
1056  " border: 1px solid black;"
1057  " margin: 1px;"
1058  " padding: 0px 3px; "
1059  " font-size: small;"
1060  "}";
1061  return myStyle;
1062 }
1063 
1065 {
1066  if ( 0 >= OGRGetDriverCount() )
1067  {
1068  OGRRegisterAll();
1069  }
1070 }
1071 
1072 QString QgsApplication::absolutePathToRelativePath( const QString& aPath, const QString& targetPath )
1073 {
1074  QString aPathUrl = aPath;
1075  QString tPathUrl = targetPath;
1076 #if defined( Q_OS_WIN )
1077  const Qt::CaseSensitivity cs = Qt::CaseInsensitive;
1078 
1079  aPathUrl.replace( '\\', '/' );
1080  if ( aPathUrl.startsWith( "//" ) )
1081  {
1082  // keep UNC prefix
1083  aPathUrl = "\\\\" + aPathUrl.mid( 2 );
1084  }
1085 
1086  tPathUrl.replace( '\\', '/' );
1087  if ( tPathUrl.startsWith( "//" ) )
1088  {
1089  // keep UNC prefix
1090  tPathUrl = "\\\\" + tPathUrl.mid( 2 );
1091  }
1092 #else
1093  const Qt::CaseSensitivity cs = Qt::CaseSensitive;
1094 #endif
1095 
1096  QStringList targetElems = tPathUrl.split( '/', QString::SkipEmptyParts );
1097  QStringList aPathElems = aPathUrl.split( '/', QString::SkipEmptyParts );
1098 
1099  targetElems.removeAll( QStringLiteral( "." ) );
1100  aPathElems.removeAll( QStringLiteral( "." ) );
1101 
1102  // remove common part
1103  int n = 0;
1104  while ( !aPathElems.isEmpty() &&
1105  !targetElems.isEmpty() &&
1106  aPathElems[0].compare( targetElems[0], cs ) == 0 )
1107  {
1108  aPathElems.removeFirst();
1109  targetElems.removeFirst();
1110  n++;
1111  }
1112 
1113  if ( n == 0 )
1114  {
1115  // no common parts; might not even be a file
1116  return aPathUrl;
1117  }
1118 
1119  if ( !targetElems.isEmpty() )
1120  {
1121  // go up to the common directory
1122  for ( int i = 0; i < targetElems.size(); i++ )
1123  {
1124  aPathElems.insert( 0, QStringLiteral( ".." ) );
1125  }
1126  }
1127  else
1128  {
1129  // let it start with . nevertheless,
1130  // so relative path always start with either ./ or ../
1131  aPathElems.insert( 0, QStringLiteral( "." ) );
1132  }
1133 
1134  return aPathElems.join( QStringLiteral( "/" ) );
1135 }
1136 
1137 QString QgsApplication::relativePathToAbsolutePath( const QString& rpath, const QString& targetPath )
1138 {
1139  // relative path should always start with ./ or ../
1140  if ( !rpath.startsWith( QLatin1String( "./" ) ) && !rpath.startsWith( QLatin1String( "../" ) ) )
1141  {
1142  return rpath;
1143  }
1144 
1145  QString rPathUrl = rpath;
1146  QString targetPathUrl = targetPath;
1147 
1148 #if defined(Q_OS_WIN)
1149  rPathUrl.replace( '\\', '/' );
1150  targetPathUrl.replace( '\\', '/' );
1151 
1152  bool uncPath = targetPathUrl.startsWith( "//" );
1153 #endif
1154 
1155  QStringList srcElems = rPathUrl.split( '/', QString::SkipEmptyParts );
1156  QStringList targetElems = targetPathUrl.split( '/', QString::SkipEmptyParts );
1157 
1158 #if defined(Q_OS_WIN)
1159  if ( uncPath )
1160  {
1161  targetElems.insert( 0, "" );
1162  targetElems.insert( 0, "" );
1163  }
1164 #endif
1165 
1166  // append source path elements
1167  targetElems << srcElems;
1168  targetElems.removeAll( QStringLiteral( "." ) );
1169 
1170  // resolve ..
1171  int pos;
1172  while (( pos = targetElems.indexOf( QStringLiteral( ".." ) ) ) > 0 )
1173  {
1174  // remove preceding element and ..
1175  targetElems.removeAt( pos - 1 );
1176  targetElems.removeAt( pos - 1 );
1177  }
1178 
1179 #if !defined(Q_OS_WIN)
1180  // make path absolute
1181  targetElems.prepend( QLatin1String( "" ) );
1182 #endif
1183 
1184  return targetElems.join( QStringLiteral( "/" ) );
1185 }
1186 
1187 void QgsApplication::skipGdalDriver( const QString& theDriver )
1188 {
1189  if ( ABISYM( mGdalSkipList ).contains( theDriver ) || theDriver.isEmpty() )
1190  {
1191  return;
1192  }
1193  ABISYM( mGdalSkipList ) << theDriver;
1195 }
1196 
1197 void QgsApplication::restoreGdalDriver( const QString& theDriver )
1198 {
1199  if ( !ABISYM( mGdalSkipList ).contains( theDriver ) )
1200  {
1201  return;
1202  }
1203  int myPos = ABISYM( mGdalSkipList ).indexOf( theDriver );
1204  if ( myPos >= 0 )
1205  {
1206  ABISYM( mGdalSkipList ).removeAt( myPos );
1207  }
1209 }
1210 
1212 {
1213  ABISYM( mGdalSkipList ).removeDuplicates();
1214  QString myDriverList = ABISYM( mGdalSkipList ).join( QStringLiteral( " " ) );
1215  QgsDebugMsg( "Gdal Skipped driver list set to:" );
1216  QgsDebugMsg( myDriverList );
1217  CPLSetConfigOption( "GDAL_SKIP", myDriverList.toUtf8() );
1218  GDALAllRegister(); //to update driver list and skip missing ones
1219 }
1220 
1222 {
1223  QString folder = userThemesFolder();
1224  QDir myDir( folder );
1225  if ( !myDir.exists() )
1226  {
1227  myDir.mkpath( folder );
1228  }
1229 
1230  copyPath( defaultThemesFolder(), userThemesFolder() );
1231  return true;
1232 }
1233 
1234 void QgsApplication::copyPath( const QString& src, const QString& dst )
1235 {
1236  QDir dir( src );
1237  if ( ! dir.exists() )
1238  return;
1239 
1240  Q_FOREACH ( const QString& d, dir.entryList( QDir::Dirs | QDir::NoDotAndDotDot ) )
1241  {
1242  QString dst_path = dst + QDir::separator() + d;
1243  dir.mkpath( dst_path );
1244  copyPath( src + QDir::separator() + d, dst_path );
1245  }
1246 
1247  Q_FOREACH ( const QString& f, dir.entryList( QDir::Files ) )
1248  {
1249  QFile::copy( src + QDir::separator() + f, dst + QDir::separator() + f );
1250  }
1251 }
1252 
1254 {
1255  return instance()->mActionScopeRegistry;
1256 }
1257 
1258 bool QgsApplication::createDB( QString *errorMessage )
1259 {
1260  // set a working directory up for gdal to write .aux.xml files into
1261  // for cases where the raster dir is read only to the user
1262  // if the env var is already set it will be used preferentially
1263  QString myPamPath = qgisSettingsDirPath() + QStringLiteral( "gdal_pam/" );
1264  QDir myDir( myPamPath );
1265  if ( !myDir.exists() )
1266  {
1267  myDir.mkpath( myPamPath ); //fail silently
1268  }
1269 
1270 #if defined(Q_OS_WIN)
1271  CPLSetConfigOption( "GDAL_PAM_PROXY_DIR", myPamPath.toUtf8() );
1272 #else
1273  //under other OS's we use an environment var so the user can
1274  //override the path if he likes
1275  int myChangeFlag = 0; //whether we want to force the env var to change
1276  setenv( "GDAL_PAM_PROXY_DIR", myPamPath.toUtf8(), myChangeFlag );
1277 #endif
1278 
1279  // Check qgis.db and make private copy if necessary
1280  QFile qgisPrivateDbFile( QgsApplication::qgisUserDbFilePath() );
1281 
1282  // first we look for ~/.qgis/qgis.db
1283  if ( !qgisPrivateDbFile.exists() )
1284  {
1285  // if it doesnt exist we copy it in from the global resources dir
1286  QString qgisMasterDbFileName = QgsApplication::qgisMasterDbFilePath();
1287  QFile masterFile( qgisMasterDbFileName );
1288 
1289  // Must be sure there is destination directory ~/.qgis
1290  QDir().mkpath( QgsApplication::qgisSettingsDirPath() );
1291 
1292  //now copy the master file into the users .qgis dir
1293  bool isDbFileCopied = masterFile.copy( qgisPrivateDbFile.fileName() );
1294 
1295  if ( !isDbFileCopied )
1296  {
1297  if ( errorMessage )
1298  {
1299  *errorMessage = tr( "[ERROR] Can not make qgis.db private copy" );
1300  }
1301  return false;
1302  }
1303  }
1304  else
1305  {
1306  // migrate if necessary
1307  sqlite3 *db;
1308  if ( sqlite3_open( QgsApplication::qgisUserDbFilePath().toUtf8().constData(), &db ) != SQLITE_OK )
1309  {
1310  if ( errorMessage )
1311  {
1312  *errorMessage = tr( "Could not open qgis.db" );
1313  }
1314  return false;
1315  }
1316 
1317  char *errmsg;
1318  int res = sqlite3_exec( db, "SELECT epsg FROM tbl_srs LIMIT 0", nullptr, nullptr, &errmsg );
1319  if ( res == SQLITE_OK )
1320  {
1321  // epsg column exists => need migration
1322  if ( sqlite3_exec( db,
1323  "ALTER TABLE tbl_srs RENAME TO tbl_srs_bak;"
1324  "CREATE TABLE tbl_srs ("
1325  "srs_id INTEGER PRIMARY KEY,"
1326  "description text NOT NULL,"
1327  "projection_acronym text NOT NULL,"
1328  "ellipsoid_acronym NOT NULL,"
1329  "parameters text NOT NULL,"
1330  "srid integer,"
1331  "auth_name varchar,"
1332  "auth_id varchar,"
1333  "is_geo integer NOT NULL,"
1334  "deprecated boolean);"
1335  "CREATE INDEX idx_srsauthid on tbl_srs(auth_name,auth_id);"
1336  "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;"
1337  "DROP TABLE tbl_srs_bak", nullptr, nullptr, &errmsg ) != SQLITE_OK
1338  )
1339  {
1340  if ( errorMessage )
1341  {
1342  *errorMessage = tr( "Migration of private qgis.db failed.\n%1" ).arg( QString::fromUtf8( errmsg ) );
1343  }
1344  sqlite3_free( errmsg );
1345  sqlite3_close( db );
1346  return false;
1347  }
1348  }
1349  else
1350  {
1351  sqlite3_free( errmsg );
1352  }
1353 
1354  if ( sqlite3_exec( db, "DROP VIEW vw_srs", nullptr, nullptr, &errmsg ) != SQLITE_OK )
1355  {
1356  QgsDebugMsg( QString( "vw_srs didn't exists in private qgis.db: %1" ).arg( errmsg ) );
1357  }
1358 
1359  if ( sqlite3_exec( db,
1360  "CREATE VIEW vw_srs AS"
1361  " SELECT"
1362  " a.description AS description"
1363  ",a.srs_id AS srs_id"
1364  ",a.is_geo AS is_geo"
1365  ",coalesce(b.name,a.projection_acronym) AS name"
1366  ",a.parameters AS parameters"
1367  ",a.auth_name AS auth_name"
1368  ",a.auth_id AS auth_id"
1369  ",a.deprecated AS deprecated"
1370  " FROM tbl_srs a"
1371  " LEFT OUTER JOIN tbl_projection b ON a.projection_acronym=b.acronym"
1372  " ORDER BY coalesce(b.name,a.projection_acronym),a.description", nullptr, nullptr, &errmsg ) != SQLITE_OK
1373  )
1374  {
1375  if ( errorMessage )
1376  {
1377  *errorMessage = tr( "Update of view in private qgis.db failed.\n%1" ).arg( QString::fromUtf8( errmsg ) );
1378  }
1379  sqlite3_free( errmsg );
1380  sqlite3_close( db );
1381  return false;
1382  }
1383 
1384  sqlite3_close( db );
1385  }
1386  return true;
1387 }
1388 
1390 {
1391  QgsDebugMsg( QString( "maxThreads: %1" ).arg( maxThreads ) );
1392 
1393  // make sure value is between 1 and #cores, if not set to -1 (use #cores)
1394  // 0 could be used to disable any parallel processing
1395  if ( maxThreads < 1 || maxThreads > QThread::idealThreadCount() )
1396  maxThreads = -1;
1397 
1398  // save value
1399  ABISYM( mMaxThreads ) = maxThreads;
1400 
1401  // if -1 use #cores
1402  if ( maxThreads == -1 )
1403  maxThreads = QThread::idealThreadCount();
1404 
1405  // set max thread count in QThreadPool
1406  QThreadPool::globalInstance()->setMaxThreadCount( maxThreads );
1407  QgsDebugMsg( QString( "set QThreadPool max thread count to %1" ).arg( QThreadPool::globalInstance()->maxThreadCount() ) );
1408 }
1409 
1411 {
1412  emit settingsChanged();
1413 }
1414 
static bool createDB(QString *errorMessage=nullptr)
initialise qgis.db
static void init(QString customConfigPath=QString())
This method initialises paths etc for QGIS.
static unsigned index
static QgsProviderRegistry * instance(const QString &pluginPath=QString::null)
Means of accessing canonical single instance.
Extends QApplication to provide access to QGIS specific resources such as theme paths, database paths etc.
static void skipGdalDriver(const QString &theDriver)
Sets the GDAL_SKIP environment variable to include the specified driver and then calls GDALDriverMana...
static QString userStylePath()
Returns the path to user&#39;s style.
static QgsAuthManager * instance()
Enforce singleton pattern.
static QgsApplication * instance()
Returns the singleton instance of the QgsApplication.
static QString authorsFilePath()
Returns the path to the authors file.
static QString qgisSettingsDirPath()
Returns the path to the settings directory in user&#39;s home dir.
static QString qgisUserDbFilePath()
Returns the path to the user qgis.db file.
static QString libraryPath()
Returns the path containing qgis_core, qgis_gui, qgispython (and other) libraries.
static QgsRuntimeProfiler * profiler()
Returns the application runtime profiler.
static QString defaultThemePath()
Returns the path to the default theme directory.
virtual bool event(QEvent *event) override
Watch for QFileOpenEvent.
static QString qgisAuthDbFilePath()
Returns the path to the user authentication database file: qgis-auth.db.
static QString donorsFilePath()
Returns the path to the donors file.
static QString relativePathToAbsolutePath(const QString &rpath, const QString &targetPath)
Converts path relative to target to an absolute path.
static void setPrefixPath(const QString &thePrefixPath, bool useDefaultPaths=false)
Alters prefix path - used by 3rd party apps.
QgsApplication(int &argc, char **argv, bool GUIenabled, const QString &customConfigPath=QString(), const QString &platformName="desktop")
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
static QIcon getThemeIcon(const QString &theName)
Helper to get a theme icon.
static QString themeName()
Set the active theme to the specified theme.
static QString defaultThemesFolder()
Returns the path to default themes folder from install (works as a starting point).
static QString iconPath(const QString &iconFile)
Returns path to the desired icon file.
static void registerOgrDrivers()
Register OGR drivers ensuring this only happens once.
static void setFileOpenEventReceiver(QObject *receiver)
Set the FileOpen event receiver.
static QString reportStyleSheet()
get a standard css style sheet for reports.
static int maxThreads()
Get maximum concurrent thread count.
static endian_t endian()
Returns whether this machine uses big or little endian.
static QPixmap getThemePixmap(const QString &theName)
Helper to get a theme icon as a pixmap.
static QString userFullName()
Returns the user&#39;s operating system login account full display name.
static QString developersMapFilePath()
Returns the path to the developers map file.
static QString absolutePathToRelativePath(const QString &apath, const QString &targetPath)
Converts absolute path to path relative to target.
QString what() const
Definition: qgsexception.h:36
void emitSettingsChanged()
Causes the application instance to emit the settingsChanged() signal.
static QString defaultStylePath()
Returns the path to default style (works as a starting point).
static void applyGdalSkippedDrivers()
Apply the skipped drivers list to gdal.
endian_t
Constants for endian-ness.
static QString pluginPath()
Returns the path to the application plugin directory.
static void setThemeName(const QString &theThemeName)
Set the active theme to the specified theme.
bool init(const QString &pluginPath=QString::null)
Initialize QCA, prioritize qca-ossl plugin and optionally set up the authentication database...
static QString helpAppPath()
Returns the path to the help application.
static bool createThemeFolder()
Create the users theme folder.
static void cleanRegisteredFunctions()
Deletes all registered functions whose ownership have been transferred to the expression engine...
virtual ~QgsApplication()
static QString i18nPath()
Returns the path to the translation directory.
static void setPkgDataPath(const QString &thePkgDataPath)
Alters pkg data path - used by 3rd party apps.
static QString splashPath()
Returns the path to the splash screen image directory.
static const char * QGIS_ORGANIZATION_NAME
static QString qgisMasterDbFilePath()
Returns the path to the master qgis.db file.
static void setPluginPath(const QString &thePluginPath)
Alters plugin path - used by 3rd party apps.
static void restoreGdalDriver(const QString &theDriver)
Sets the GDAL_SKIP environment variable to exclude the specified driver and then calls GDALDriverMana...
static QString userLoginName()
Returns the user&#39;s operating system login account name.
static QString pkgDataPath()
Returns the common root path of all application data directories.
struct sqlite3 sqlite3
static QString osName()
Returns a string name of the operating system QGIS is running on.
static void initQgis()
loads providers
static void setDefaultSvgPaths(const QStringList &pathList)
Alters default svg paths - used by 3rd party apps.
static void setAuthDbDirPath(const QString &theAuthDbDirPath)
Alters authentication data base directory path - used by 3rd party apps.
static QRegExp shortNameRegExp()
Returns the short name regular expression for line edit validator.
static QString showSettings()
Convenience function to get a summary of the paths used in this application instance useful for debug...
static QString appIconPath()
get application icon
static const char * QGIS_ORGANIZATION_DOMAIN
static QgsMapLayerRegistry * instance()
Returns the instance pointer, creating the object on the first call.
virtual bool notify(QObject *receiver, QEvent *event) override
Catch exceptions when sending event to receiver.
static QString contributorsFilePath()
Returns the path to the contributors file.
static QString activeThemePath()
Returns the path to the currently active theme directory.
static QgsNetworkAccessManager * instance()
returns a pointer to the single instance
static QString platform()
Returns the QGIS platform name, eg "desktop" or "server".
QObject * ABISYM(QgsApplication::mFileOpenEventReceiver)
static void exitQgis()
deletes provider registry and map layer registry
static QStringList svgPaths()
Returns the pathes to svg directories.
static QString sponsorsFilePath()
Returns the path to the sponsors file.
static QStringList composerTemplatePaths()
Returns the pathes to composer template directories.
static QString srsDbFilePath()
Returns the path to the srs.db file.
The action scope registry is an application wide registry that contains a list of available action sc...
static QHash< QString, QString > uiThemes()
All themes found in ~/.qgis3/themes folder.
static QString libexecPath()
Returns the path with utility executables (help viewer, crssync, ...)
static QString prefixPath()
Returns the path to the application prefix directory.
static QString iconsPath()
Returns the path to the icons image directory.
static QString translatorsFilePath()
Returns the path to the sponsors file.
static const char * QGIS_APPLICATION_NAME
static QgsActionScopeRegistry * actionScopeRegistry()
Returns the action scope registry.
Defines a qgis exception class.
Definition: qgsexception.h:25
void settingsChanged()
Emitted whenever any global, application-wide settings are changed.
static void setMaxThreads(int maxThreads)
Set maximum concurrent thread count.
static void setUITheme(const QString &themeName)
Set the current UI theme used to style the interface.
static QString licenceFilePath()
Returns the path to the licence file.
static QString userThemesFolder()
Returns the path to user&#39;s themes folder.
void preNotify(QObject *receiver, QEvent *event, bool *done)