QGIS API Documentation  3.4.3-Madeira (2f64a3c)
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 "qgslayoutitemregistry.h"
22 #include "qgslogger.h"
23 #include "qgsproject.h"
26 #include "qgsproviderregistry.h"
27 #include "qgsexpression.h"
28 #include "qgsactionscoperegistry.h"
29 #include "qgsruntimeprofiler.h"
30 #include "qgstaskmanager.h"
32 #include "qgssvgcache.h"
33 #include "qgscolorschemeregistry.h"
34 #include "qgspainteffectregistry.h"
37 #include "qgsrendererregistry.h"
38 #include "qgssymbollayerregistry.h"
39 #include "qgspluginlayerregistry.h"
40 #include "qgsmessagelog.h"
41 #include "qgsannotationregistry.h"
42 #include "qgssettings.h"
43 #include "qgsunittypes.h"
44 #include "qgsuserprofile.h"
45 #include "qgsuserprofilemanager.h"
46 #include "qgsreferencedgeometry.h"
47 #include "qgs3drendererregistry.h"
48 #include "qgslayoutrendercontext.h"
49 #include "qgssqliteutils.h"
50 #include "qgsstyle.h"
51 
54 
56 
57 #include <QDir>
58 #include <QFile>
59 #include <QFileInfo>
60 #include <QFileOpenEvent>
61 #include <QMessageBox>
62 #include <QPalette>
63 #include <QProcess>
64 #include <QIcon>
65 #include <QPixmap>
66 #include <QThreadPool>
67 #include <QLocale>
68 #include <QStyle>
69 
70 #ifndef Q_OS_WIN
71 #include <netinet/in.h>
72 #include <pwd.h>
73 #else
74 #include <winsock.h>
75 #include <windows.h>
76 #include <lmcons.h>
77 #define SECURITY_WIN32
78 #include <security.h>
79 #pragma comment( lib, "Secur32.lib" )
80 #endif
81 
82 #include "qgsconfig.h"
83 
84 #include <gdal.h>
85 #include <ogr_api.h>
86 #include <cpl_conv.h> // for setting gdal options
87 #include <sqlite3.h>
88 
89 #define CONN_POOL_MAX_CONCURRENT_CONNS 4
90 
91 QObject *ABISYM( QgsApplication::mFileOpenEventReceiver );
92 QStringList ABISYM( QgsApplication::mFileOpenEventList );
93 QString ABISYM( QgsApplication::mPrefixPath );
94 QString ABISYM( QgsApplication::mPluginPath );
95 QString ABISYM( QgsApplication::mPkgDataPath );
96 QString ABISYM( QgsApplication::mLibraryPath );
97 QString ABISYM( QgsApplication::mLibexecPath );
98 QString ABISYM( QgsApplication::mQmlImportPath );
99 QString ABISYM( QgsApplication::mThemeName );
100 QString ABISYM( QgsApplication::mUIThemeName );
101 QString ABISYM( QgsApplication::mProfilePath );
102 
103 QStringList ABISYM( QgsApplication::mDefaultSvgPaths );
104 QMap<QString, QString> ABISYM( QgsApplication::mSystemEnvVars );
105 QString ABISYM( QgsApplication::mConfigPath );
106 
107 bool ABISYM( QgsApplication::mInitialized ) = false;
108 bool ABISYM( QgsApplication::mRunningFromBuildDir ) = false;
109 QString ABISYM( QgsApplication::mBuildSourcePath );
110 #if defined(_MSC_VER) && !defined(USING_NMAKE) && !defined(USING_NINJA)
111 QString ABISYM( QgsApplication::mCfgIntDir );
112 #endif
113 QString ABISYM( QgsApplication::mBuildOutputPath );
114 QStringList ABISYM( QgsApplication::mGdalSkipList );
115 int ABISYM( QgsApplication::mMaxThreads );
116 QString ABISYM( QgsApplication::mAuthDbDirPath );
117 
118 QString QgsApplication::sUserName;
119 QString QgsApplication::sUserFullName;
120 QString QgsApplication::sPlatformName = QStringLiteral( "desktop" );
121 QString QgsApplication::sTranslation;
122 
123 const char *QgsApplication::QGIS_ORGANIZATION_NAME = "QGIS";
124 const char *QgsApplication::QGIS_ORGANIZATION_DOMAIN = "qgis.org";
125 const char *QgsApplication::QGIS_APPLICATION_NAME = "QGIS3";
126 
127 QgsApplication::ApplicationMembers *QgsApplication::sApplicationMembers = nullptr;
128 
129 QgsApplication::QgsApplication( int &argc, char **argv, bool GUIenabled, const QString &profileFolder, const QString &platformName )
130  : QApplication( argc, argv, GUIenabled )
131 {
132  sPlatformName = platformName;
133 
134  if ( sTranslation != QLatin1String( "C" ) )
135  {
136  mQgisTranslator = new QTranslator();
137  if ( mQgisTranslator->load( QStringLiteral( "qgis_" ) + sTranslation, i18nPath() ) )
138  {
139  installTranslator( mQgisTranslator );
140  }
141  else
142  {
143  QgsDebugMsg( QStringLiteral( "loading of qgis translation failed %1/qgis_%2" ).arg( i18nPath(), sTranslation ) );
144  }
145 
146  /* Translation file for Qt.
147  * The strings from the QMenuBar context section are used by Qt/Mac to shift
148  * the About, Preferences and Quit items to the Mac Application menu.
149  * These items must be translated identically in both qt_ and qgis_ files.
150  */
151  mQtTranslator = new QTranslator();
152  if ( mQtTranslator->load( QStringLiteral( "qt_" ) + sTranslation, QLibraryInfo::location( QLibraryInfo::TranslationsPath ) ) )
153  {
154  installTranslator( mQtTranslator );
155  }
156  else
157  {
158  QgsDebugMsg( QStringLiteral( "loading of qt translation failed %1/qt_%2" ).arg( QLibraryInfo::location( QLibraryInfo::TranslationsPath ), sTranslation ) );
159  }
160  }
161 
162  mApplicationMembers = new ApplicationMembers();
163 
164  ABISYM( mProfilePath ) = profileFolder;
165 }
166 
167 void QgsApplication::init( QString profileFolder )
168 {
169  if ( profileFolder.isEmpty() )
170  {
171  if ( getenv( "QGIS_CUSTOM_CONFIG_PATH" ) )
172  {
173  QString envProfileFolder = getenv( "QGIS_CUSTOM_CONFIG_PATH" );
174  profileFolder = envProfileFolder + QDir::separator() + "profiles";
175  }
176  else
177  {
178  profileFolder = QStandardPaths::standardLocations( QStandardPaths::AppDataLocation ).value( 0 );
179  }
180  // This will normally get here for custom scripts that use QgsApplication.
181  // This doesn't get this hit for QGIS Desktop because we setup the profile via main
182  QString rootProfileFolder = QgsUserProfileManager::resolveProfilesFolder( profileFolder );
183  QgsUserProfileManager manager( rootProfileFolder );
184  QgsUserProfile *profile = manager.getProfile();
185  profileFolder = profile->folder();
186  delete profile;
187  }
188 
189  ABISYM( mProfilePath ) = profileFolder;
190 
191  qRegisterMetaType<QgsGeometry::Error>( "QgsGeometry::Error" );
192  qRegisterMetaType<QgsProcessingFeatureSourceDefinition>( "QgsProcessingFeatureSourceDefinition" );
193  qRegisterMetaType<QgsProcessingOutputLayerDefinition>( "QgsProcessingOutputLayerDefinition" );
194  qRegisterMetaType<QgsUnitTypes::LayoutUnit>( "QgsUnitTypes::LayoutUnit" );
195  qRegisterMetaType<QgsFeatureId>( "QgsFeatureId" );
196  qRegisterMetaType<QgsFeatureIds>( "QgsFeatureIds" );
197  qRegisterMetaType<QgsProperty>( "QgsProperty" );
198  qRegisterMetaType<Qgis::MessageLevel>( "Qgis::MessageLevel" );
199  qRegisterMetaType<QgsReferencedRectangle>( "QgsReferencedRectangle" );
200  qRegisterMetaType<QgsReferencedPointXY>( "QgsReferencedPointXY" );
201  qRegisterMetaType<QgsLayoutRenderContext::Flags>( "QgsLayoutRenderContext::Flags" );
202  qRegisterMetaType<QgsStyle::StyleEntity>( "QgsStyle::StyleEntity" );
203  qRegisterMetaType<QgsCoordinateReferenceSystem>( "QgsCoordinateReferenceSystem" );
204  qRegisterMetaType<QgsAuthManager::MessageLevel>( "QgsAuthManager::MessageLevel" );
205 
206  ( void ) resolvePkgPath();
207 
208  if ( ABISYM( mRunningFromBuildDir ) )
209  {
210  // we run from source directory - not installed to destination (specified prefix)
211  ABISYM( mPrefixPath ) = QString(); // set invalid path
212 #if defined(_MSC_VER) && !defined(USING_NMAKE) && !defined(USING_NINJA)
213  setPluginPath( ABISYM( mBuildOutputPath ) + '/' + QString( QGIS_PLUGIN_SUBDIR ) + '/' + ABISYM( mCfgIntDir ) );
214 #else
215  setPluginPath( ABISYM( mBuildOutputPath ) + '/' + QStringLiteral( QGIS_PLUGIN_SUBDIR ) );
216 #endif
217  setPkgDataPath( ABISYM( mBuildSourcePath ) ); // directly source path - used for: doc, resources, svg
218  ABISYM( mLibraryPath ) = ABISYM( mBuildOutputPath ) + '/' + QGIS_LIB_SUBDIR + '/';
219 #if defined(_MSC_VER) && !defined(USING_NMAKE) && !defined(USING_NINJA)
220  ABISYM( mLibexecPath ) = ABISYM( mBuildOutputPath ) + '/' + QGIS_LIBEXEC_SUBDIR + '/' + ABISYM( mCfgIntDir ) + '/';
221 #else
222  ABISYM( mLibexecPath ) = ABISYM( mBuildOutputPath ) + '/' + QGIS_LIBEXEC_SUBDIR + '/';
223 #endif
224 #if defined( HAVE_QUICK )
225  ABISYM( mQmlImportPath ) = ABISYM( mBuildOutputPath ) + '/' + QGIS_QML_SUBDIR + '/';
226 #endif
227  }
228  else
229  {
230  char *prefixPath = getenv( "QGIS_PREFIX_PATH" );
231  if ( !prefixPath )
232  {
233  if ( ABISYM( mPrefixPath ).isNull() )
234  {
235 #if defined(Q_OS_MACX) || defined(Q_OS_WIN)
236  setPrefixPath( applicationDirPath(), true );
237 #elif defined(ANDROID)
238  // this is "/data/data/org.qgis.qgis" in android
239  QDir myDir( QDir::homePath() );
240  myDir.cdUp();
241  QString myPrefix = myDir.absolutePath();
242  setPrefixPath( myPrefix, true );
243 #else
244  QDir myDir( applicationDirPath() );
245  // Fix for server which is one level deeper in /usr/lib/cgi-bin
246  if ( applicationDirPath().contains( QStringLiteral( "cgi-bin" ) ) )
247  {
248  myDir.cdUp();
249  }
250  myDir.cdUp(); // Go from /usr/bin or /usr/lib (for server) to /usr
251  QString myPrefix = myDir.absolutePath();
252  setPrefixPath( myPrefix, true );
253 #endif
254  }
255  }
256  else
257  {
258  setPrefixPath( prefixPath, true );
259  }
260  }
261 
262  ABISYM( mConfigPath ) = profileFolder + '/'; // make sure trailing slash is included
263  ABISYM( mDefaultSvgPaths ) << qgisSettingsDirPath() + QStringLiteral( "svg/" );
264 
265  ABISYM( mAuthDbDirPath ) = qgisSettingsDirPath();
266  if ( getenv( "QGIS_AUTH_DB_DIR_PATH" ) )
267  {
268  setAuthDatabaseDirPath( getenv( "QGIS_AUTH_DB_DIR_PATH" ) );
269  }
270 
271  // store system environment variables passed to application, before they are adjusted
272  QMap<QString, QString> systemEnvVarMap;
273  QString passfile( QStringLiteral( "QGIS_AUTH_PASSWORD_FILE" ) ); // QString, for comparison
274  Q_FOREACH ( const QString &varStr, QProcess::systemEnvironment() )
275  {
276  int pos = varStr.indexOf( QLatin1Char( '=' ) );
277  if ( pos == -1 )
278  continue;
279  QString varStrName = varStr.left( pos );
280  QString varStrValue = varStr.mid( pos + 1 );
281  if ( varStrName != passfile )
282  {
283  systemEnvVarMap.insert( varStrName, varStrValue );
284  }
285  }
286  ABISYM( mSystemEnvVars ) = systemEnvVarMap;
287 
288  // allow Qt to search for Qt plugins (e.g. sqldrivers) in our plugin directory
289  QCoreApplication::addLibraryPath( pluginPath() );
290 
291  // set max. thread count to -1
292  // this should be read from QgsSettings but we don't know where they are at this point
293  // so we read actual value in main.cpp
294  ABISYM( mMaxThreads ) = -1;
295 
298 
299  ABISYM( mInitialized ) = true;
300 }
301 
303 {
304  delete mDataItemProviderRegistry;
305  delete mApplicationMembers;
306  delete mQgisTranslator;
307  delete mQtTranslator;
308 }
309 
311 {
312  return qobject_cast<QgsApplication *>( QCoreApplication::instance() );
313 }
314 
316 {
317  bool done = false;
318  if ( event->type() == QEvent::FileOpen )
319  {
320  // handle FileOpen event (double clicking a file icon in Mac OS X Finder)
321  if ( ABISYM( mFileOpenEventReceiver ) )
322  {
323  // Forward event to main window.
324  done = notify( ABISYM( mFileOpenEventReceiver ), event );
325  }
326  else
327  {
328  // Store filename because receiver has not registered yet.
329  // If QGIS has been launched by double clicking a file icon, FileOpen will be
330  // the first event; the main window is not yet ready to handle the event.
331  ABISYM( mFileOpenEventList ).append( static_cast<QFileOpenEvent *>( event )->file() );
332  done = true;
333  }
334  }
335  else
336  {
337  // pass other events to base class
338  done = QApplication::event( event );
339  }
340  return done;
341 }
342 
343 bool QgsApplication::notify( QObject *receiver, QEvent *event )
344 {
345  bool done = false;
346  // Crashes in customization (especially on Mac), if we're not in the main/UI thread, see #5597
347  if ( thread() == receiver->thread() )
348  emit preNotify( receiver, event, &done );
349 
350  if ( done )
351  return true;
352 
353  // Send event to receiver and catch unhandled exceptions
354  done = true;
355  try
356  {
357  done = QApplication::notify( receiver, event );
358  }
359  catch ( QgsException &e )
360  {
361  QgsDebugMsg( "Caught unhandled QgsException: " + e.what() );
362  if ( qApp->thread() == QThread::currentThread() )
363  QMessageBox::critical( activeWindow(), tr( "Exception" ), e.what() );
364  }
365  catch ( std::exception &e )
366  {
367  QgsDebugMsg( "Caught unhandled std::exception: " + QString::fromLatin1( e.what() ) );
368  if ( qApp->thread() == QThread::currentThread() )
369  QMessageBox::critical( activeWindow(), tr( "Exception" ), e.what() );
370  }
371  catch ( ... )
372  {
373  QgsDebugMsg( QStringLiteral( "Caught unhandled unknown exception" ) );
374  if ( qApp->thread() == QThread::currentThread() )
375  QMessageBox::critical( activeWindow(), tr( "Exception" ), tr( "unknown exception" ) );
376  }
377 
378  return done;
379 }
380 
382 {
383  return members()->mProfiler;
384 }
385 
387 {
388  // Set receiver for FileOpen events
389  ABISYM( mFileOpenEventReceiver ) = receiver;
390  // Propagate any events collected before the receiver has registered.
391  if ( ABISYM( mFileOpenEventList ).count() > 0 )
392  {
393  QStringListIterator i( ABISYM( mFileOpenEventList ) );
394  while ( i.hasNext() )
395  {
396  QFileOpenEvent foe( i.next() );
397  QgsApplication::sendEvent( ABISYM( mFileOpenEventReceiver ), &foe );
398  }
399  ABISYM( mFileOpenEventList ).clear();
400  }
401 }
402 
403 void QgsApplication::setPrefixPath( const QString &prefixPath, bool useDefaultPaths )
404 {
405  ABISYM( mPrefixPath ) = prefixPath;
406 #if defined(_MSC_VER)
407  if ( ABISYM( mPrefixPath ).endsWith( "/bin" ) )
408  {
409  ABISYM( mPrefixPath ).chop( 4 );
410  }
411 #endif
412  if ( useDefaultPaths && !ABISYM( mRunningFromBuildDir ) )
413  {
414  setPluginPath( ABISYM( mPrefixPath ) + '/' + QStringLiteral( QGIS_PLUGIN_SUBDIR ) );
415  setPkgDataPath( ABISYM( mPrefixPath ) + '/' + QStringLiteral( QGIS_DATA_SUBDIR ) );
416  }
417  ABISYM( mLibraryPath ) = ABISYM( mPrefixPath ) + '/' + QGIS_LIB_SUBDIR + '/';
418  ABISYM( mLibexecPath ) = ABISYM( mPrefixPath ) + '/' + QGIS_LIBEXEC_SUBDIR + '/';
419 #if defined( HAVE_QUICK )
420  ABISYM( mQmlImportPath ) = ABISYM( mPrefixPath ) + '/' + QGIS_QML_SUBDIR + '/';
421 #endif
422 }
423 
425 {
426  ABISYM( mPluginPath ) = pluginPath;
427 }
428 
430 {
431  ABISYM( mPkgDataPath ) = pkgDataPath;
432  QString mySvgPath = pkgDataPath + ( ABISYM( mRunningFromBuildDir ) ? "/images/svg/" : "/svg/" );
433  // avoid duplicate entries
434  if ( !ABISYM( mDefaultSvgPaths ).contains( mySvgPath ) )
435  ABISYM( mDefaultSvgPaths ) << mySvgPath;
436 }
437 
438 void QgsApplication::setDefaultSvgPaths( const QStringList &pathList )
439 {
440  ABISYM( mDefaultSvgPaths ) = pathList;
441 }
442 
443 void QgsApplication::setAuthDatabaseDirPath( const QString &authDbDirPath )
444 {
445  QFileInfo fi( authDbDirPath );
446  if ( fi.exists() && fi.isDir() && fi.isWritable() )
447  {
448  ABISYM( mAuthDbDirPath ) = fi.canonicalFilePath() + QDir::separator();
449  }
450 }
451 
453 {
454  if ( ABISYM( mRunningFromBuildDir ) )
455  {
456  static bool sOnce = true;
457  if ( sOnce )
458  {
459  QgsMessageLogNotifyBlocker blockNotifications;
460  ( void ) blockNotifications;
461  qWarning( "!!! prefix path was requested, but it is not valid - we do not run from installed path !!!" );
462  }
463  sOnce = false;
464  }
465 
466  return ABISYM( mPrefixPath );
467 }
469 {
470  return ABISYM( mPluginPath );
471 }
473 {
474  if ( ABISYM( mPkgDataPath ).isNull() )
475  return resolvePkgPath();
476  else
477  return ABISYM( mPkgDataPath );
478 }
480 {
481  return QStringLiteral( ":/images/themes/default/" );
482 }
484 {
485  QString usersThemes = userThemesFolder() + QDir::separator() + themeName() + QDir::separator() + "icons/";
486  QDir dir( usersThemes );
487  if ( dir.exists() )
488  {
489  return usersThemes;
490  }
491  else
492  {
493  QString defaultThemes = defaultThemesFolder() + QDir::separator() + themeName() + QDir::separator() + "icons/";
494  return defaultThemes;
495  }
496 }
497 
499 {
500  return iconsPath() + QStringLiteral( "qgis-icon-60x60.png" );
501 }
502 
503 QString QgsApplication::iconPath( const QString &iconFile )
504 {
505  // try active theme
506  QString path = activeThemePath();
507  if ( QFile::exists( path + iconFile ) )
508  return path + iconFile;
509 
510  // use default theme
511  return defaultThemePath() + iconFile;
512 }
513 
514 QIcon QgsApplication::getThemeIcon( const QString &name )
515 {
516  QgsApplication *app = instance();
517  if ( app && app->mIconCache.contains( name ) )
518  return app->mIconCache.value( name );
519 
520  QIcon icon;
521 
522  QString myPreferredPath = activeThemePath() + QDir::separator() + name;
523  QString myDefaultPath = defaultThemePath() + QDir::separator() + name;
524  if ( QFile::exists( myPreferredPath ) )
525  {
526  icon = QIcon( myPreferredPath );
527  }
528  else if ( QFile::exists( myDefaultPath ) )
529  {
530  //could still return an empty icon if it
531  //doesn't exist in the default theme either!
532  icon = QIcon( myDefaultPath );
533  }
534  else
535  {
536  icon = QIcon();
537  }
538 
539  if ( app )
540  app->mIconCache.insert( name, icon );
541  return icon;
542 }
543 
545 {
546  QgsApplication *app = instance();
547  if ( app && app->mCursorCache.contains( cursor ) )
548  return app->mCursorCache.value( cursor );
549 
550  // All calculations are done on 32x32 icons
551  // Defaults to center, individual cursors may override
552  int activeX = 16;
553  int activeY = 16;
554 
555  QString name;
556  switch ( cursor )
557  {
558  case ZoomIn:
559  name = QStringLiteral( "mZoomIn.svg" );
560  activeX = 13;
561  activeY = 13;
562  break;
563  case ZoomOut:
564  name = QStringLiteral( "mZoomOut.svg" );
565  activeX = 13;
566  activeY = 13;
567  break;
568  case Identify:
569  activeX = 3;
570  activeY = 6;
571  name = QStringLiteral( "mIdentify.svg" );
572  break;
573  case CrossHair:
574  name = QStringLiteral( "mCrossHair.svg" );
575  break;
576  case CapturePoint:
577  name = QStringLiteral( "mCapturePoint.svg" );
578  break;
579  case Select:
580  name = QStringLiteral( "mSelect.svg" );
581  activeX = 6;
582  activeY = 6;
583  break;
584  case Sampler:
585  activeX = 5;
586  activeY = 5;
587  name = QStringLiteral( "mSampler.svg" );
588  break;
589  // No default
590  }
591  // It should never get here!
592  Q_ASSERT( ! name.isEmpty( ) );
593 
594  QIcon icon = getThemeIcon( QStringLiteral( "cursors" ) + QDir::separator() + name );
595  QCursor cursorIcon;
596  // Check if an icon exists for this cursor (the O.S. default cursor will be used if it does not)
597  if ( ! icon.isNull( ) )
598  {
599  // Apply scaling
600  float scale = Qgis::UI_SCALE_FACTOR * app->fontMetrics().height() / 32.0;
601  cursorIcon = QCursor( icon.pixmap( std::ceil( scale * 32 ), std::ceil( scale * 32 ) ), std::ceil( scale * activeX ), std::ceil( scale * activeY ) );
602  }
603  if ( app )
604  app->mCursorCache.insert( cursor, cursorIcon );
605  return cursorIcon;
606 }
607 
608 // TODO: add some caching mechanism ?
609 QPixmap QgsApplication::getThemePixmap( const QString &name )
610 {
611  QString myPreferredPath = activeThemePath() + QDir::separator() + name;
612  QString myDefaultPath = defaultThemePath() + QDir::separator() + name;
613  if ( QFile::exists( myPreferredPath ) )
614  {
615  return QPixmap( myPreferredPath );
616  }
617  else
618  {
619  //could still return an empty icon if it
620  //doesn't exist in the default theme either!
621  return QPixmap( myDefaultPath );
622  }
623 }
624 
626 {
627  ABISYM( mThemeName ) = themeName;
628 }
629 
631 {
632  static QString appPath;
633  if ( appPath.isNull() )
634  {
635  if ( QCoreApplication::instance() )
636  {
637  appPath = applicationDirPath();
638  }
639  else
640  {
641  qWarning( "Application path not initialized" );
642  }
643  }
644 
645  if ( !appPath.isNull() || getenv( "QGIS_PREFIX_PATH" ) )
646  {
647  QString prefix = getenv( "QGIS_PREFIX_PATH" ) ? getenv( "QGIS_PREFIX_PATH" ) : appPath;
648 
649  // check if QGIS is run from build directory (not the install directory)
650  QFile f;
651  // "/../../.." is for Mac bundled app in build directory
652  Q_FOREACH ( const QString &path, QStringList() << "" << "/.." << "/bin" << "/../../.." )
653  {
654  f.setFileName( prefix + path + "/qgisbuildpath.txt" );
655  if ( f.exists() )
656  break;
657  }
658  if ( f.exists() && f.open( QIODevice::ReadOnly ) )
659  {
660  ABISYM( mRunningFromBuildDir ) = true;
661  ABISYM( mBuildSourcePath ) = f.readLine().trimmed();
662  ABISYM( mBuildOutputPath ) = f.readLine().trimmed();
663  QgsDebugMsgLevel( QStringLiteral( "Running from build directory!" ), 4 );
664  QgsDebugMsgLevel( QStringLiteral( "- source directory: %1" ).arg( ABISYM( mBuildSourcePath ).toUtf8().constData() ), 4 );
665  QgsDebugMsgLevel( QStringLiteral( "- output directory of the build: %1" ).arg( ABISYM( mBuildOutputPath ).toUtf8().constData() ), 4 );
666 #if defined(_MSC_VER) && !defined(USING_NMAKE) && !defined(USING_NINJA)
667  ABISYM( mCfgIntDir ) = appPath.split( '/', QString::SkipEmptyParts ).last();
668  qDebug( "- cfg: %s", ABISYM( mCfgIntDir ).toUtf8().constData() );
669 #endif
670  }
671  }
672 
673  QString prefixPath;
674  if ( getenv( "QGIS_PREFIX_PATH" ) )
675  prefixPath = getenv( "QGIS_PREFIX_PATH" );
676  else
677  {
678 #if defined(ANDROID)
679  // this is "/data/data/org.qgis.qgis" in android
680  QDir dir( QDir::homePath() );
681  dir.cdUp();
682  prefixPath = dir.absolutePath();
683 #else
684 
685 #if defined(Q_OS_MACX) || defined(Q_OS_WIN)
686  prefixPath = appPath;
687 #if defined(_MSC_VER)
688  if ( prefixPath.endsWith( "/bin" ) )
689  prefixPath.chop( 4 );
690 #endif
691 #else
692  QDir dir( appPath );
693  // Fix for server which is one level deeper in /usr/lib/cgi-bin
694  if ( appPath.contains( QStringLiteral( "cgi-bin" ) ) )
695  {
696  dir.cdUp();
697  }
698  dir.cdUp(); // Go from /usr/bin or /usr/lib (for server) to /usr
699  prefixPath = dir.absolutePath();
700 #endif
701 #endif
702  }
703 
704  if ( ABISYM( mRunningFromBuildDir ) )
705  return ABISYM( mBuildSourcePath );
706  else
707  return prefixPath + '/' + QStringLiteral( QGIS_DATA_SUBDIR );
708 }
709 
711 {
712  return ABISYM( mThemeName );
713 }
714 
715 void QgsApplication::setUITheme( const QString &themeName )
716 {
717  // Loop all style sheets, find matching name, load it.
718  QHash<QString, QString> themes = QgsApplication::uiThemes();
719  if ( themeName == QStringLiteral( "default" ) || !themes.contains( themeName ) )
720  {
721  setThemeName( QStringLiteral( "default" ) );
722  qApp->setStyleSheet( QString() );
723  return;
724  }
725 
726  QString path = themes.value( themeName );
727  QString stylesheetname = path + "/style.qss";
728 
729  QFile file( stylesheetname );
730  QFile variablesfile( path + "/variables.qss" );
731 
732  QFileInfo variableInfo( variablesfile );
733 
734  if ( !file.open( QIODevice::ReadOnly ) || ( variableInfo.exists() && !variablesfile.open( QIODevice::ReadOnly ) ) )
735  {
736  return;
737  }
738 
739  QString styledata = file.readAll();
740  styledata.replace( QStringLiteral( "@theme_path" ), path );
741 
742  if ( variableInfo.exists() )
743  {
744  QTextStream in( &variablesfile );
745  while ( !in.atEnd() )
746  {
747  QString line = in.readLine();
748  // This is a variable
749  if ( line.startsWith( '@' ) )
750  {
751  int index = line.indexOf( ':' );
752  QString name = line.mid( 0, index );
753  QString value = line.mid( index + 1, line.length() );
754  styledata.replace( name, value );
755  }
756  }
757  variablesfile.close();
758  }
759  file.close();
760 
761  qApp->setStyleSheet( styledata );
762  setThemeName( themeName );
763 }
764 
765 QHash<QString, QString> QgsApplication::uiThemes()
766 {
767  QStringList paths = QStringList() << userThemesFolder() << defaultThemesFolder();
768  QHash<QString, QString> mapping;
769  mapping.insert( QStringLiteral( "default" ), QString() );
770  Q_FOREACH ( const QString &path, paths )
771  {
772  QDir folder( path );
773  QFileInfoList styleFiles = folder.entryInfoList( QDir::Dirs | QDir::NoDotAndDotDot );
774  Q_FOREACH ( const QFileInfo &info, styleFiles )
775  {
776  QFileInfo styleFile( info.absoluteFilePath() + "/style.qss" );
777  if ( !styleFile.exists() )
778  continue;
779 
780  QString name = info.baseName();
781  QString path = info.absoluteFilePath();
782  mapping.insert( name, path );
783  }
784  }
785  return mapping;
786 }
787 
789 {
790  return pkgDataPath() + QStringLiteral( "/doc/AUTHORS" );
791 }
792 
794 {
795  return pkgDataPath() + QStringLiteral( "/doc/CONTRIBUTORS" );
796 }
798 {
799  return pkgDataPath() + QStringLiteral( "/doc/developersmap.html" );
800 }
801 
803 {
804  return pkgDataPath() + QStringLiteral( "/doc/SPONSORS" );
805 }
806 
808 {
809  return pkgDataPath() + QStringLiteral( "/doc/DONORS" );
810 }
811 
813 {
814  return pkgDataPath() + QStringLiteral( "/doc/TRANSLATORS" );
815 }
816 
818 {
819  return pkgDataPath() + QStringLiteral( "/doc/LICENSE" );
820 }
821 
823 {
824  if ( ABISYM( mRunningFromBuildDir ) )
825  return ABISYM( mBuildOutputPath ) + QStringLiteral( "/i18n/" );
826  else
827  return pkgDataPath() + QStringLiteral( "/i18n/" );
828 }
829 
831 {
832  return pkgDataPath() + QStringLiteral( "/resources/metadata-ISO/" );
833 }
834 
836 {
837  return pkgDataPath() + QStringLiteral( "/resources/qgis.db" );
838 }
839 
841 {
842  return ABISYM( mConfigPath );
843 }
844 
846 {
847  return qgisSettingsDirPath() + QStringLiteral( "qgis.db" );
848 }
849 
851 {
852  return ABISYM( mAuthDbDirPath ) + QStringLiteral( "qgis-auth.db" );
853 }
854 
856 {
857  return QStringLiteral( ":/images/splash/" );
858 }
859 
861 {
862  return pkgDataPath() + QStringLiteral( "/images/icons/" );
863 }
864 
866 {
867  if ( ABISYM( mRunningFromBuildDir ) )
868  {
869  QString tempCopy = QDir::tempPath() + "/srs.db";
870 
871  if ( !QFile( tempCopy ).exists() )
872  {
873  QFile f( pkgDataPath() + "/resources/srs.db" );
874  if ( !f.copy( tempCopy ) )
875  {
876  qFatal( "Could not create temporary copy" );
877  }
878  }
879 
880  return tempCopy;
881  }
882  else
883  {
884  return pkgDataPath() + QStringLiteral( "/resources/srs.db" );
885  }
886 }
887 
889 {
890  //local directories to search when looking for an SVG with a given basename
891  //defined by user in options dialog
892  QgsSettings settings;
893  QStringList pathList = settings.value( QStringLiteral( "svg/searchPathsForSVG" ) ).toStringList();
894 
895  // maintain user set order while stripping duplicates
896  QStringList paths;
897  Q_FOREACH ( const QString &path, pathList )
898  {
899  if ( !paths.contains( path ) )
900  paths.append( path );
901  }
902  Q_FOREACH ( const QString &path, ABISYM( mDefaultSvgPaths ) )
903  {
904  if ( !paths.contains( path ) )
905  paths.append( path );
906  }
907 
908  return paths;
909 }
910 
912 {
913  //local directories to search when looking for an template with a given basename
914  //defined by user in options dialog
915  QgsSettings settings;
916  QStringList pathList = settings.value( QStringLiteral( "Layout/searchPathsForTemplates" ), QVariant(), QgsSettings::Core ).toStringList();
917 
918  return pathList;
919 }
920 
922 {
923  return qgisSettingsDirPath() + QStringLiteral( "symbology-style.db" );
924 }
925 
927 {
928  return QRegExp( "^[A-Za-z][A-Za-z0-9\\._-]*" );
929 }
930 
932 {
933  if ( !sUserName.isEmpty() )
934  return sUserName;
935 
936 #ifdef _MSC_VER
937  TCHAR name [ UNLEN + 1 ];
938  DWORD size = UNLEN + 1;
939 
940  if ( GetUserName( ( TCHAR * )name, &size ) )
941  {
942  sUserName = QString( name );
943  }
944 
945 #else
946  QProcess process;
947 
948  process.start( QStringLiteral( "whoami" ) );
949  process.waitForFinished();
950  sUserName = process.readAllStandardOutput().trimmed();
951 #endif
952 
953  if ( !sUserName.isEmpty() )
954  return sUserName;
955 
956  //backup plan - use environment variables
957  sUserName = qgetenv( "USER" );
958  if ( !sUserName.isEmpty() )
959  return sUserName;
960 
961  //last resort
962  sUserName = qgetenv( "USERNAME" );
963  return sUserName;
964 }
965 
967 {
968  if ( !sUserFullName.isEmpty() )
969  return sUserFullName;
970 
971 #ifdef _MSC_VER
972  TCHAR name [ UNLEN + 1 ];
973  DWORD size = UNLEN + 1;
974 
975  //note - this only works for accounts connected to domain
976  if ( GetUserNameEx( NameDisplay, ( TCHAR * )name, &size ) )
977  {
978  sUserFullName = QString( name );
979  }
980 
981  //fall back to login name
982  if ( sUserFullName.isEmpty() )
983  sUserFullName = userLoginName();
984 #elif defined(Q_OS_ANDROID) || defined(__MINGW32__)
985  sUserFullName = "Not available";
986 #else
987  struct passwd *p = getpwuid( getuid() );
988 
989  if ( p )
990  {
991  QString gecosName = QString( p->pw_gecos );
992  sUserFullName = gecosName.left( gecosName.indexOf( ',', 0 ) );
993  }
994 
995 #endif
996 
997  return sUserFullName;
998 }
999 
1001 {
1002 #if defined(Q_OS_ANDROID)
1003  return QLatin1String( "android" );
1004 #elif defined(Q_OS_MAC)
1005  return QLatin1String( "osx" );
1006 #elif defined(Q_OS_WIN)
1007  return QLatin1String( "windows" );
1008 #elif defined(Q_OS_LINUX)
1009  return QStringLiteral( "linux" );
1010 #else
1011  return QLatin1String( "unknown" );
1012 #endif
1013 }
1014 
1016 {
1017  return sPlatformName;
1018 }
1019 
1021 {
1022  QgsSettings settings;
1023  bool overrideLocale = settings.value( QStringLiteral( "locale/overrideFlag" ), false ).toBool();
1024  if ( overrideLocale )
1025  {
1026  QString locale = settings.value( QStringLiteral( "locale/userLocale" ), QString() ).toString();
1027  // don't differentiate en_US and en_GB
1028  if ( locale.startsWith( QLatin1String( "en" ), Qt::CaseInsensitive ) )
1029  {
1030  return locale.left( 2 );
1031  }
1032 
1033  return locale;
1034  }
1035  else
1036  {
1037  return QLocale().name().left( 2 );
1038  }
1039 }
1040 
1042 {
1043  return qgisSettingsDirPath() + QStringLiteral( "/themes" );
1044 }
1045 
1047 {
1048  return pkgDataPath() + QStringLiteral( "/resources/symbology-style.xml" );
1049 }
1050 
1052 {
1053  return pkgDataPath() + QStringLiteral( "/resources/themes" );
1054 }
1055 
1057 {
1058  return pkgDataPath() + QStringLiteral( "/resources/server/" );
1059 }
1060 
1062 {
1063  return ABISYM( mLibraryPath );
1064 }
1065 
1067 {
1068  return ABISYM( mLibexecPath );
1069 }
1070 
1072 {
1073  return ABISYM( mQmlImportPath );
1074 }
1075 
1077 {
1078  return ( htonl( 1 ) == 1 ) ? XDR : NDR;
1079 }
1080 
1082 {
1083  if ( !ABISYM( mInitialized ) && QgsApplication::instance() )
1084  {
1085  init( ABISYM( mProfilePath ) );
1086  }
1087 
1088  // set the provider plugin path (this creates provider registry)
1090 
1091  // create data item provider registry
1093 
1094  // create project instance if doesn't exist
1096 
1097  // Initialize authentication manager and connect to database
1099 
1100  // Make sure we have a NAM created on the main thread.
1101  // Note that this might call QgsApplication::authManager to
1102  // setup the proxy configuration that's why it needs to be
1103  // called after the QgsAuthManager instance has been created
1105 
1106 }
1107 
1108 
1110 {
1111  if ( instance() )
1112  {
1113  if ( !instance()->mAuthManager )
1114  {
1115  instance()->mAuthManager = QgsAuthManager::instance();
1116  }
1117  return instance()->mAuthManager;
1118  }
1119  else
1120  {
1121  // no QgsApplication instance
1122  static QgsAuthManager *sAuthManager = nullptr;
1123  if ( !sAuthManager )
1124  sAuthManager = QgsAuthManager::instance();
1125  return sAuthManager;
1126  }
1127 }
1128 
1129 
1131 {
1132  delete QgsApplication::authManager();
1133 
1134  //Ensure that all remaining deleteLater QObjects are actually deleted before we exit.
1135  //This isn't strictly necessary (since we're exiting anyway) but doing so prevents a lot of
1136  //LeakSanitiser noise which hides real issues
1137  QgsApplication::sendPostedEvents( nullptr, QEvent::DeferredDelete );
1138 
1139  //delete all registered functions from expression engine (see above comment)
1141 
1142  delete QgsProject::instance();
1143 
1145 
1146  // invalidate coordinate cache while the PROJ context held by the thread-locale
1147  // QgsProjContextStore object is still alive. Otherwise if this later object
1148  // is destroyed before the static variables of the cache, we might use freed memory.
1150 
1152 
1153  // tear-down GDAL/OGR
1154  OGRCleanupAll();
1155  GDALDestroyDriverManager();
1156 }
1157 
1159 {
1160  QString myEnvironmentVar( getenv( "QGIS_PREFIX_PATH" ) );
1161  QString myState = tr( "Application state:\n"
1162  "QGIS_PREFIX_PATH env var:\t\t%1\n"
1163  "Prefix:\t\t%2\n"
1164  "Plugin Path:\t\t%3\n"
1165  "Package Data Path:\t%4\n"
1166  "Active Theme Name:\t%5\n"
1167  "Active Theme Path:\t%6\n"
1168  "Default Theme Path:\t%7\n"
1169  "SVG Search Paths:\t%8\n"
1170  "User DB Path:\t%9\n"
1171  "Auth DB Path:\t%10\n" )
1172  .arg( myEnvironmentVar,
1173  prefixPath(),
1174  pluginPath(),
1175  pkgDataPath(),
1176  themeName(),
1177  activeThemePath(),
1178  defaultThemePath(),
1179  svgPaths().join( tr( "\n\t\t", "match indentation of application state" ) ),
1181  .arg( qgisAuthDatabaseFilePath() );
1182  return myState;
1183 }
1184 
1186 {
1187  //
1188  // Make the style sheet desktop preferences aware by using qappliation
1189  // palette as a basis for colors where appropriate
1190  //
1191 // QColor myColor1 = palette().highlight().color();
1192  QColor myColor1( Qt::lightGray );
1193  QColor myColor2 = myColor1;
1194  myColor2 = myColor2.lighter( 110 ); //10% lighter
1195  QString myStyle;
1196  myStyle = ".overview{"
1197  " font: 1.82em;"
1198  " font-weight: bold;"
1199  "}"
1200  "body{"
1201  " background: white;"
1202  " color: black;"
1203  " font-family: 'Lato', 'Ubuntu', 'Lucida Grande', 'Segoe UI', 'Arial', sans-serif;"
1204  " width: 100%;"
1205  "}"
1206  "h1{ background-color: #F6F6F6;"
1207  " color: #589632; " // from http://qgis.org/en/site/getinvolved/styleguide.html
1208  " font-size: x-large; "
1209  " font-weight: normal;"
1210  " background: none;"
1211  " padding: 0.75em 0 0;"
1212  " margin: 0;"
1213  " line-height: 3em;"
1214  "}"
1215  "h2{ background-color: #F6F6F6;"
1216  " color: #589632; " // from http://qgis.org/en/site/getinvolved/styleguide.html
1217  " font-size: medium; "
1218  " font-weight: normal;"
1219  " background: none;"
1220  " padding: 0.75em 0 0;"
1221  " margin: 0;"
1222  " line-height: 1.1em;"
1223  "}"
1224  "h3{ background-color: #F6F6F6;"
1225  " color: #93b023;" // from http://qgis.org/en/site/getinvolved/styleguide.html
1226  " font-weight: bold;"
1227  " font-size: large;"
1228  " text-align: right;"
1229  " border-bottom: 5px solid #DCEB5C;"
1230  "}"
1231  "h4{ background-color: #F6F6F6;"
1232  " color: #93b023;" // from http://qgis.org/en/site/getinvolved/styleguide.html
1233  " font-weight: bold;"
1234  " font-size: medium;"
1235  " text-align: right;"
1236  "}"
1237  "h5{ background-color: #F6F6F6;"
1238  " color: #93b023;" // from http://qgis.org/en/site/getinvolved/styleguide.html
1239  " font-weight: bold;"
1240  " font-size: small;"
1241  " text-align: right;"
1242  "}"
1243  "a{ color: #729FCF;"
1244  " font-family: arial,sans-serif;"
1245  "}"
1246  "label{ background-color: #FFFFCC;"
1247  " border: 1px solid black;"
1248  " margin: 1px;"
1249  " padding: 0px 3px; "
1250  " font-size: small;"
1251  "}"
1252  ".section {"
1253  " font-weight: bold;"
1254  " padding-top:25px;"
1255  "}"
1256  ".list-view .highlight {"
1257  " text-align: right;"
1258  " border: 0px;"
1259  " width: 20%;"
1260  " padding-right: 15px;"
1261  " padding-left: 20px;"
1262  " font-weight: bold;"
1263  "}"
1264  "th .strong {"
1265  " font-weight: bold;"
1266  "}"
1267  ".tabular-view{ "
1268  " border-collapse: collapse;"
1269  " width: 95%;"
1270  "}"
1271  ".tabular-view th, .tabular-view td { "
1272  " border:10px solid black;"
1273  "}"
1274  ".tabular-view .odd-row{"
1275  " background-color: #f9f9f9;"
1276  "}"
1277  "hr {"
1278  " border: 0;"
1279  " height: 0;"
1280  " border-top: 1px solid black;"
1281  "}";
1282  return myStyle;
1283 }
1284 
1286 {
1287  if ( 0 >= OGRGetDriverCount() )
1288  {
1289  OGRRegisterAll();
1290  }
1291 }
1292 
1293 QString QgsApplication::absolutePathToRelativePath( const QString &aPath, const QString &targetPath )
1294 {
1295  QString aPathUrl = aPath;
1296  QString tPathUrl = targetPath;
1297 #if defined( Q_OS_WIN )
1298  const Qt::CaseSensitivity cs = Qt::CaseInsensitive;
1299 
1300  aPathUrl.replace( '\\', '/' );
1301  if ( aPathUrl.startsWith( "//" ) )
1302  {
1303  // keep UNC prefix
1304  aPathUrl = "\\\\" + aPathUrl.mid( 2 );
1305  }
1306 
1307  tPathUrl.replace( '\\', '/' );
1308  if ( tPathUrl.startsWith( "//" ) )
1309  {
1310  // keep UNC prefix
1311  tPathUrl = "\\\\" + tPathUrl.mid( 2 );
1312  }
1313 #else
1314  const Qt::CaseSensitivity cs = Qt::CaseSensitive;
1315 #endif
1316 
1317  QStringList targetElems = tPathUrl.split( '/', QString::SkipEmptyParts );
1318  QStringList aPathElems = aPathUrl.split( '/', QString::SkipEmptyParts );
1319 
1320  targetElems.removeAll( QStringLiteral( "." ) );
1321  aPathElems.removeAll( QStringLiteral( "." ) );
1322 
1323  // remove common part
1324  int n = 0;
1325  while ( !aPathElems.isEmpty() &&
1326  !targetElems.isEmpty() &&
1327  aPathElems[0].compare( targetElems[0], cs ) == 0 )
1328  {
1329  aPathElems.removeFirst();
1330  targetElems.removeFirst();
1331  n++;
1332  }
1333 
1334  if ( n == 0 )
1335  {
1336  // no common parts; might not even be a file
1337  return aPathUrl;
1338  }
1339 
1340  if ( !targetElems.isEmpty() )
1341  {
1342  // go up to the common directory
1343  for ( int i = 0; i < targetElems.size(); i++ )
1344  {
1345  aPathElems.insert( 0, QStringLiteral( ".." ) );
1346  }
1347  }
1348  else
1349  {
1350  // let it start with . nevertheless,
1351  // so relative path always start with either ./ or ../
1352  aPathElems.insert( 0, QStringLiteral( "." ) );
1353  }
1354 
1355  return aPathElems.join( QStringLiteral( "/" ) );
1356 }
1357 
1358 QString QgsApplication::relativePathToAbsolutePath( const QString &rpath, const QString &targetPath )
1359 {
1360  // relative path should always start with ./ or ../
1361  if ( !rpath.startsWith( QLatin1String( "./" ) ) && !rpath.startsWith( QLatin1String( "../" ) ) )
1362  {
1363  return rpath;
1364  }
1365 
1366  QString rPathUrl = rpath;
1367  QString targetPathUrl = targetPath;
1368 
1369 #if defined(Q_OS_WIN)
1370  rPathUrl.replace( '\\', '/' );
1371  targetPathUrl.replace( '\\', '/' );
1372 
1373  bool uncPath = targetPathUrl.startsWith( "//" );
1374 #endif
1375 
1376  QStringList srcElems = rPathUrl.split( '/', QString::SkipEmptyParts );
1377  QStringList targetElems = targetPathUrl.split( '/', QString::SkipEmptyParts );
1378 
1379 #if defined(Q_OS_WIN)
1380  if ( uncPath )
1381  {
1382  targetElems.insert( 0, "" );
1383  targetElems.insert( 0, "" );
1384  }
1385 #endif
1386 
1387  // append source path elements
1388  targetElems << srcElems;
1389  targetElems.removeAll( QStringLiteral( "." ) );
1390 
1391  // resolve ..
1392  int pos;
1393  while ( ( pos = targetElems.indexOf( QStringLiteral( ".." ) ) ) > 0 )
1394  {
1395  // remove preceding element and ..
1396  targetElems.removeAt( pos - 1 );
1397  targetElems.removeAt( pos - 1 );
1398  }
1399 
1400 #if !defined(Q_OS_WIN)
1401  // make path absolute
1402  targetElems.prepend( QString() );
1403 #endif
1404 
1405  return targetElems.join( QStringLiteral( "/" ) );
1406 }
1407 
1408 void QgsApplication::skipGdalDriver( const QString &driver )
1409 {
1410  if ( ABISYM( mGdalSkipList ).contains( driver ) || driver.isEmpty() )
1411  {
1412  return;
1413  }
1414  ABISYM( mGdalSkipList ) << driver;
1416 }
1417 
1418 void QgsApplication::restoreGdalDriver( const QString &driver )
1419 {
1420  if ( !ABISYM( mGdalSkipList ).contains( driver ) )
1421  {
1422  return;
1423  }
1424  int myPos = ABISYM( mGdalSkipList ).indexOf( driver );
1425  if ( myPos >= 0 )
1426  {
1427  ABISYM( mGdalSkipList ).removeAt( myPos );
1428  }
1430 }
1431 
1433 {
1434  ABISYM( mGdalSkipList ).removeDuplicates();
1435  QString myDriverList = ABISYM( mGdalSkipList ).join( QStringLiteral( " " ) );
1436  QgsDebugMsg( QStringLiteral( "Gdal Skipped driver list set to:" ) );
1437  QgsDebugMsg( myDriverList );
1438  CPLSetConfigOption( "GDAL_SKIP", myDriverList.toUtf8() );
1439  GDALAllRegister(); //to update driver list and skip missing ones
1440 }
1441 
1443 {
1444  QString folder = userThemesFolder();
1445  QDir myDir( folder );
1446  if ( !myDir.exists() )
1447  {
1448  myDir.mkpath( folder );
1449  }
1450 
1451  return true;
1452 }
1453 
1454 void QgsApplication::copyPath( const QString &src, const QString &dst )
1455 {
1456  QDir dir( src );
1457  if ( ! dir.exists() )
1458  return;
1459 
1460  Q_FOREACH ( const QString &d, dir.entryList( QDir::Dirs | QDir::NoDotAndDotDot ) )
1461  {
1462  QString dst_path = dst + QDir::separator() + d;
1463  dir.mkpath( dst_path );
1464  copyPath( src + QDir::separator() + d, dst_path );
1465  }
1466 
1467  Q_FOREACH ( const QString &f, dir.entryList( QDir::Files ) )
1468  {
1469  QFile::copy( src + QDir::separator() + f, dst + QDir::separator() + f );
1470  }
1471 }
1472 
1474 {
1475  //read values from QgsSettings
1476  QgsSettings settings;
1477 
1478  QVariantMap variables;
1479 
1480  //check if settings contains any variables
1481  settings.beginGroup( "variables" );
1482  QStringList childKeys = settings.childKeys();
1483  for ( QStringList::const_iterator it = childKeys.constBegin(); it != childKeys.constEnd(); ++it )
1484  {
1485  QString name = *it;
1486  variables.insert( name, settings.value( name ) );
1487  }
1488 
1489  return variables;
1490 }
1491 
1492 void QgsApplication::setCustomVariables( const QVariantMap &variables )
1493 {
1494  QgsSettings settings;
1495 
1496  QVariantMap::const_iterator it = variables.constBegin();
1497  settings.beginGroup( "variables" );
1498  settings.remove( "" );
1499  for ( ; it != variables.constEnd(); ++it )
1500  {
1501  settings.setValue( it.key(), it.value() );
1502  }
1503 
1504  emit instance()->customVariablesChanged();
1505 }
1506 
1507 void QgsApplication::setCustomVariable( const QString &name, const QVariant &value )
1508 {
1509  // save variable to settings
1510  QgsSettings settings;
1511 
1512  settings.setValue( QStringLiteral( "variables/" ) + name, value );
1513 
1514  emit instance()->customVariablesChanged();
1515 }
1516 
1518 {
1520 }
1521 
1523 {
1524  emit requestForTranslatableObjects( translationContext );
1525 }
1526 
1528 {
1529  ApplicationMembers *appMembers = members();
1530  if ( appMembers->mNullRepresentation.isNull() )
1531  {
1532  appMembers->mNullRepresentation = QgsSettings().value( QStringLiteral( "qgis/nullValue" ), QStringLiteral( "NULL" ) ).toString();
1533  }
1534  return appMembers->mNullRepresentation;
1535 }
1536 
1538 {
1539  ApplicationMembers *appMembers = members();
1540  if ( !appMembers || appMembers->mNullRepresentation == nullRepresentation )
1541  return;
1542 
1543  appMembers->mNullRepresentation = nullRepresentation;
1544  QgsSettings().setValue( QStringLiteral( "qgis/nullValue" ), nullRepresentation );
1545 
1546  QgsApplication *app = instance();
1547  if ( app )
1548  emit app->nullRepresentationChanged();
1549 }
1550 
1552 {
1553  return members()->mActionScopeRegistry;
1554 }
1555 
1556 bool QgsApplication::createDatabase( QString *errorMessage )
1557 {
1558  // set a working directory up for gdal to write .aux.xml files into
1559  // for cases where the raster dir is read only to the user
1560  // if the env var is already set it will be used preferentially
1561  QString myPamPath = qgisSettingsDirPath() + QStringLiteral( "gdal_pam/" );
1562  QDir myDir( myPamPath );
1563  if ( !myDir.exists() )
1564  {
1565  myDir.mkpath( myPamPath ); //fail silently
1566  }
1567 
1568 #if defined(Q_OS_WIN)
1569  CPLSetConfigOption( "GDAL_PAM_PROXY_DIR", myPamPath.toUtf8() );
1570 #else
1571  //under other OS's we use an environment var so the user can
1572  //override the path if he likes
1573  int myChangeFlag = 0; //whether we want to force the env var to change
1574  setenv( "GDAL_PAM_PROXY_DIR", myPamPath.toUtf8(), myChangeFlag );
1575 #endif
1576 
1577  // Check qgis.db and make private copy if necessary
1578  QFile qgisPrivateDbFile( QgsApplication::qgisUserDatabaseFilePath() );
1579 
1580  // first we look for ~/.qgis/qgis.db
1581  if ( !qgisPrivateDbFile.exists() )
1582  {
1583  // if it doesn't exist we copy it in from the global resources dir
1584  QString qgisMasterDbFileName = QgsApplication::qgisMasterDatabaseFilePath();
1585  QFile masterFile( qgisMasterDbFileName );
1586 
1587  // Must be sure there is destination directory ~/.qgis
1588  QDir().mkpath( QgsApplication::qgisSettingsDirPath() );
1589 
1590  //now copy the master file into the users .qgis dir
1591  bool isDbFileCopied = masterFile.copy( qgisPrivateDbFile.fileName() );
1592 
1593  if ( !isDbFileCopied )
1594  {
1595  if ( errorMessage )
1596  {
1597  *errorMessage = tr( "[ERROR] Can not make qgis.db private copy" );
1598  }
1599  return false;
1600  }
1601 
1602  QFile::Permissions perms = QFile( qgisPrivateDbFile.fileName() ).permissions();
1603  if ( !( perms & QFile::WriteOwner ) )
1604  {
1605  if ( !qgisPrivateDbFile.setPermissions( perms | QFile::WriteOwner ) )
1606  {
1607  if ( errorMessage )
1608  {
1609  *errorMessage = tr( "Can not make '%1' user writable" ).arg( qgisPrivateDbFile.fileName() );
1610  }
1611  return false;
1612  }
1613  }
1614  }
1615  else
1616  {
1617  // migrate if necessary
1618  sqlite3_database_unique_ptr database;
1619  if ( database.open( QgsApplication::qgisUserDatabaseFilePath() ) != SQLITE_OK )
1620  {
1621  if ( errorMessage )
1622  {
1623  *errorMessage = tr( "Could not open qgis.db" );
1624  }
1625  return false;
1626  }
1627 
1628  char *errmsg = nullptr;
1629  int res = sqlite3_exec( database.get(), "SELECT epsg FROM tbl_srs LIMIT 0", nullptr, nullptr, &errmsg );
1630  if ( res == SQLITE_OK )
1631  {
1632  // epsg column exists => need migration
1633  if ( sqlite3_exec( database.get(),
1634  "ALTER TABLE tbl_srs RENAME TO tbl_srs_bak;"
1635  "CREATE TABLE tbl_srs ("
1636  "srs_id INTEGER PRIMARY KEY,"
1637  "description text NOT NULL,"
1638  "projection_acronym text NOT NULL,"
1639  "ellipsoid_acronym NOT NULL,"
1640  "parameters text NOT NULL,"
1641  "srid integer,"
1642  "auth_name varchar,"
1643  "auth_id varchar,"
1644  "is_geo integer NOT NULL,"
1645  "deprecated boolean);"
1646  "CREATE INDEX idx_srsauthid on tbl_srs(auth_name,auth_id);"
1647  "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;"
1648  "DROP TABLE tbl_srs_bak", nullptr, nullptr, &errmsg ) != SQLITE_OK
1649  )
1650  {
1651  if ( errorMessage )
1652  {
1653  *errorMessage = tr( "Migration of private qgis.db failed.\n%1" ).arg( QString::fromUtf8( errmsg ) );
1654  }
1655  sqlite3_free( errmsg );
1656  return false;
1657  }
1658  }
1659  else
1660  {
1661  sqlite3_free( errmsg );
1662  }
1663 
1664  if ( sqlite3_exec( database.get(), "DROP VIEW vw_srs", nullptr, nullptr, &errmsg ) != SQLITE_OK )
1665  {
1666  QgsDebugMsg( QStringLiteral( "vw_srs didn't exists in private qgis.db: %1" ).arg( errmsg ) );
1667  }
1668 
1669  if ( sqlite3_exec( database.get(),
1670  "CREATE VIEW vw_srs AS"
1671  " SELECT"
1672  " a.description AS description"
1673  ",a.srs_id AS srs_id"
1674  ",a.is_geo AS is_geo"
1675  ",coalesce(b.name,a.projection_acronym) AS name"
1676  ",a.parameters AS parameters"
1677  ",a.auth_name AS auth_name"
1678  ",a.auth_id AS auth_id"
1679  ",a.deprecated AS deprecated"
1680  " FROM tbl_srs a"
1681  " LEFT OUTER JOIN tbl_projection b ON a.projection_acronym=b.acronym"
1682  " ORDER BY coalesce(b.name,a.projection_acronym),a.description", nullptr, nullptr, &errmsg ) != SQLITE_OK
1683  )
1684  {
1685  if ( errorMessage )
1686  {
1687  *errorMessage = tr( "Update of view in private qgis.db failed.\n%1" ).arg( QString::fromUtf8( errmsg ) );
1688  }
1689  sqlite3_free( errmsg );
1690  return false;
1691  }
1692  }
1693  return true;
1694 }
1695 
1697 {
1698  QgsDebugMsg( QStringLiteral( "maxThreads: %1" ).arg( maxThreads ) );
1699 
1700  // make sure value is between 1 and #cores, if not set to -1 (use #cores)
1701  // 0 could be used to disable any parallel processing
1702  if ( maxThreads < 1 || maxThreads > QThread::idealThreadCount() )
1703  maxThreads = -1;
1704 
1705  // save value
1706  ABISYM( mMaxThreads ) = maxThreads;
1707 
1708  // if -1 use #cores
1709  if ( maxThreads == -1 )
1710  maxThreads = QThread::idealThreadCount();
1711 
1712  // set max thread count in QThreadPool
1713  QThreadPool::globalInstance()->setMaxThreadCount( maxThreads );
1714  QgsDebugMsg( QStringLiteral( "set QThreadPool max thread count to %1" ).arg( QThreadPool::globalInstance()->maxThreadCount() ) );
1715 }
1716 
1718 {
1719  return members()->mTaskManager;
1720 }
1721 
1723 {
1724  return members()->mColorSchemeRegistry;
1725 }
1726 
1728 {
1729  return members()->mPaintEffectRegistry;
1730 }
1731 
1733 {
1734  return members()->mRendererRegistry;
1735 }
1736 
1738 {
1739  return members()->mRasterRendererRegistry;
1740 }
1741 
1743 {
1744  if ( instance() )
1745  {
1746  if ( !instance()->mDataItemProviderRegistry )
1747  {
1748  instance()->mDataItemProviderRegistry = new QgsDataItemProviderRegistry();
1749  }
1750  return instance()->mDataItemProviderRegistry;
1751  }
1752  else
1753  {
1754  // no QgsApplication instance
1755  static QgsDataItemProviderRegistry *sDataItemProviderRegistry = nullptr;
1756  if ( !sDataItemProviderRegistry )
1757  sDataItemProviderRegistry = new QgsDataItemProviderRegistry();
1758  return sDataItemProviderRegistry;
1759  }
1760 }
1761 
1763 {
1764  return members()->mSvgCache;
1765 }
1766 
1768 {
1769  return members()->mNetworkContentFetcherRegistry;
1770 }
1771 
1773 {
1774  return members()->mSymbolLayerRegistry;
1775 }
1776 
1778 {
1779  return members()->mLayoutItemRegistry;
1780 }
1781 
1783 {
1784  return members()->mGpsConnectionRegistry;
1785 }
1786 
1788 {
1789  return members()->mPluginLayerRegistry;
1790 }
1791 
1793 {
1794  return members()->mMessageLog;
1795 }
1796 
1798 {
1799  return members()->mProcessingRegistry;
1800 }
1801 
1803 {
1804  return members()->mPageSizeRegistry;
1805 }
1806 
1807 QgsAnnotationRegistry *QgsApplication::annotationRegistry()
1808 {
1809  return members()->mAnnotationRegistry;
1810 }
1811 
1813 {
1814  return members()->mFieldFormatterRegistry;
1815 }
1816 
1818 {
1819  return members()->m3DRendererRegistry;
1820 }
1821 
1823 {
1824  return members()->mProjectStorageRegistry;
1825 }
1826 
1827 QgsApplication::ApplicationMembers::ApplicationMembers()
1828 {
1829  // don't use initializer lists or scoped pointers - as more objects are added here we
1830  // will need to be careful with the order of creation/destruction
1831  mMessageLog = new QgsMessageLog();
1832  mProfiler = new QgsRuntimeProfiler();
1833  mTaskManager = new QgsTaskManager();
1834  mActionScopeRegistry = new QgsActionScopeRegistry();
1835  mFieldFormatterRegistry = new QgsFieldFormatterRegistry();
1836  mSvgCache = new QgsSvgCache();
1837  mColorSchemeRegistry = new QgsColorSchemeRegistry();
1838  mPaintEffectRegistry = new QgsPaintEffectRegistry();
1839  mSymbolLayerRegistry = new QgsSymbolLayerRegistry();
1840  mRendererRegistry = new QgsRendererRegistry();
1841  mRasterRendererRegistry = new QgsRasterRendererRegistry();
1842  mGpsConnectionRegistry = new QgsGpsConnectionRegistry();
1843  mPluginLayerRegistry = new QgsPluginLayerRegistry();
1844  mProcessingRegistry = new QgsProcessingRegistry();
1845  mPageSizeRegistry = new QgsPageSizeRegistry();
1846  mLayoutItemRegistry = new QgsLayoutItemRegistry();
1847  mLayoutItemRegistry->populate();
1848  mAnnotationRegistry = new QgsAnnotationRegistry();
1849  m3DRendererRegistry = new Qgs3DRendererRegistry();
1850  mProjectStorageRegistry = new QgsProjectStorageRegistry();
1851  mNetworkContentFetcherRegistry = new QgsNetworkContentFetcherRegistry();
1852 }
1853 
1854 QgsApplication::ApplicationMembers::~ApplicationMembers()
1855 {
1856  delete mActionScopeRegistry;
1857  delete m3DRendererRegistry;
1858  delete mAnnotationRegistry;
1859  delete mColorSchemeRegistry;
1860  delete mFieldFormatterRegistry;
1861  delete mGpsConnectionRegistry;
1862  delete mMessageLog;
1863  delete mPaintEffectRegistry;
1864  delete mPluginLayerRegistry;
1865  delete mProcessingRegistry;
1866  delete mProjectStorageRegistry;
1867  delete mPageSizeRegistry;
1868  delete mLayoutItemRegistry;
1869  delete mProfiler;
1870  delete mRasterRendererRegistry;
1871  delete mRendererRegistry;
1872  delete mSvgCache;
1873  delete mSymbolLayerRegistry;
1874  delete mTaskManager;
1875  delete mNetworkContentFetcherRegistry;
1876 }
1877 
1878 QgsApplication::ApplicationMembers *QgsApplication::members()
1879 {
1880  if ( instance() )
1881  {
1882  return instance()->mApplicationMembers;
1883  }
1884  else
1885  {
1886  static QMutex sMemberMutex( QMutex::Recursive );
1887  QMutexLocker lock( &sMemberMutex );
1888  if ( !sApplicationMembers )
1889  sApplicationMembers = new ApplicationMembers();
1890  return sApplicationMembers;
1891  }
1892 }
static QStringList layoutTemplatePaths()
Returns the paths to layout template directories.
Singleton offering an interface to manage the authentication configuration database and to utilize co...
QgsApplication(int &argc, char **argv, bool GUIenabled, const QString &profileFolder=QString(), const QString &platformName="desktop")
static QString locale()
Returns the QGIS locale.
static QgsSymbolLayerRegistry * symbolLayerRegistry()
Returns the application&#39;s symbol layer registry, used for managing symbol layers. ...
static QgsSvgCache * svgCache()
Returns the application&#39;s SVG cache, used for caching SVG images and handling parameter replacement w...
This class keeps a list of data item providers that may add items to the browser tree.
static void setThemeName(const QString &themeName)
Set the active theme to the specified theme.
void addDefaultSchemes()
Adds all default color schemes to this color scheme.
static Qgs3DRendererRegistry * renderer3DRegistry()
Returns registry of available 3D renderers.
static QString resolveProfilesFolder(const QString &basePath=QString())
Resolves the profiles folder for the given path.
static QgsAnnotationRegistry * annotationRegistry()
Returns the application&#39;s annotation registry, used for managing annotation types.
Extends QApplication to provide access to QGIS specific resources such as theme paths, database paths etc.
static QgsFieldFormatterRegistry * fieldFormatterRegistry()
Gets the registry of available field formatters.
Cursor
The Cursor enum defines constants for QGIS custom cursors.
static QString userStylePath()
Returns the path to user&#39;s style.
Registry of color schemes.
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 void setPrefixPath(const QString &prefixPath, bool useDefaultPaths=false)
Alters prefix path - used by 3rd party apps.
A registry of plugin layers types.
static QString qgisSettingsDirPath()
Returns the path to the settings directory in user&#39;s home dir.
static void setCustomVariables(const QVariantMap &customVariables)
Custom expression variables for this application.
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.
static const double UI_SCALE_FACTOR
UI scaling factor.
Definition: qgis.h:152
This class is a composition of two QSettings instances:
Definition: qgssettings.h:58
static QString qgisMasterDatabaseFilePath()
Returns the path to the master qgis.db file.
void customVariablesChanged()
Emitted whenever a custom global variable changes.
static QString qgisUserDatabaseFilePath()
Returns the path to the user qgis.db file.
bool event(QEvent *event) override
Watch for QFileOpenEvent.
void requestForTranslatableObjects(QgsTranslationContext *translationContext)
Emitted when project strings which require translation are being collected for inclusion in a ...
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.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
int maxConcurrentConnectionsPerPool() const
The maximum number of concurrent connections per connections pool.
void nullRepresentationChanged()
This string is used to represent the value NULL throughout QGIS.
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).
void initStyleScheme()
Initializes the default random style color scheme for the user.
QStringList childKeys() const
Returns a list of all top-level keys that can be read using the QSettings object. ...
static void restoreGdalDriver(const QString &driver)
Sets the GDAL_SKIP environment variable to exclude the specified driver and then calls GDALDriverMana...
static QString iconPath(const QString &iconFile)
Returns path to the desired icon file.
A cache for images / pictures derived from svg files.
Definition: qgssvgcache.h:130
void remove(const QString &key, QgsSettings::Section section=QgsSettings::NoSection)
Removes the setting key and any sub-settings of key in a section.
Registry of renderers.
static QString resolvePkgPath()
Calculate the application pkg path.
Registry for raster renderers.
static void registerOgrDrivers()
Register OGR drivers ensuring this only happens once.
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
User profile contains information about the user profile folders on the machine.
Precisely identify a point on the canvas.
static QgsPluginLayerRegistry * pluginLayerRegistry()
Returns the application&#39;s plugin layer registry, used for managing plugin layer types.
static QVariantMap customVariables()
Custom expression variables for this application.
The QgsFieldFormatterRegistry manages registered classes of QgsFieldFormatter.
Color/Value picker.
static void setFileOpenEventReceiver(QObject *receiver)
Sets the FileOpen event receiver.
static QString reportStyleSheet()
Returns a standard css style sheet for reports.
static int maxThreads()
Gets maximum concurrent thread count.
static endian_t endian()
Returns whether this machine uses big or little endian.
static QPixmap getThemePixmap(const QString &name)
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 QgsPaintEffectRegistry * paintEffectRegistry()
Returns the application&#39;s paint effect registry, used for managing paint effects. ...
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:48
static QString defaultStylePath()
Returns the path to default style (works as a starting point).
static QgsTaskManager * taskManager()
Returns the application&#39;s task manager, used for managing application wide background task handling...
static QgsMessageLog * messageLog()
Returns the application&#39;s message log.
static void applyGdalSkippedDrivers()
Apply the skipped drivers list to gdal.
#define CONN_POOL_MAX_CONCURRENT_CONNS
endian_t
Constants for endian-ness.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
static QgsLayoutItemRegistry * layoutItemRegistry()
Returns the application&#39;s layout item registry, used for layout item types.
static void setNullRepresentation(const QString &nullRepresentation)
This string is used to represent the value NULL throughout QGIS.
static QString pluginPath()
Returns the path to the application plugin directory.
Keeps track of available 3D renderers.
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
Registry of available symbol layer classes.
Registry for temporary fetched files.
static bool createThemeFolder()
Create the users theme folder.
static bool createDatabase(QString *errorMessage=nullptr)
initialize qgis.db
static void cleanRegisteredFunctions()
Deletes all registered functions whose ownership have been transferred to the expression engine...
static QString i18nPath()
Returns the path to the translation directory.
static void cleanDefaultStyle()
Deletes the default style. Only to be used by QgsApplication::exitQgis()
Definition: qgsstyle.cpp:71
static QString nullRepresentation()
This string is used to represent the value NULL throughout QGIS.
static QString splashPath()
Returns the path to the splash screen image directory.
static void setCustomVariable(const QString &name, const QVariant &value)
Set a single custom expression variable.
static QgsGpsConnectionRegistry * gpsConnectionRegistry()
Returns the application&#39;s GPS connection registry, used for managing GPS connections.
A registry for known page sizes.
static const char * QGIS_ORGANIZATION_NAME
int open(const QString &path)
Opens the database at the specified file path.
static QgsProjectStorageRegistry * projectStorageRegistry()
Returns registry of available project storage implementations.
Task manager for managing a set of long-running QgsTask tasks.
Used for the collecting of strings from projects for translation and creation of ts files...
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.
static QString osName()
Returns a string name of the operating system QGIS is running on.
static void initQgis()
loads providers
Select a rectangle.
static void setDefaultSvgPaths(const QStringList &pathList)
Alters default svg paths - used by 3rd party apps.
Unique pointer for sqlite3 databases, which automatically closes the database when the pointer goes o...
static void skipGdalDriver(const QString &driver)
Sets the GDAL_SKIP environment variable to include the specified driver and then calls GDALDriverMana...
void beginGroup(const QString &prefix, QgsSettings::Section section=QgsSettings::NoSection)
Appends prefix to the current group.
Definition: qgssettings.cpp:86
static QgsAuthManager * authManager()
Returns the application&#39;s authentication manager instance.
static QRegExp shortNameRegExp()
Returns the short name regular expression for line edit validator.
static QgsNetworkAccessManager * instance(Qt::ConnectionType connectionType=Qt::BlockingQueuedConnection)
Returns a pointer to the active QgsNetworkAccessManager for the current thread.
Identify: obtain information about the object.
Registry for various processing components, including providers, algorithms and various parameters an...
static QString showSettings()
Convenience function to get a summary of the paths used in this application instance useful for debug...
static QString appIconPath()
Gets application icon.
static QgsColorSchemeRegistry * colorSchemeRegistry()
Returns the application&#39;s color scheme registry, used for managing color schemes. ...
static const char * QGIS_ORGANIZATION_DOMAIN
bool notify(QObject *receiver, QEvent *event) override
Catch exceptions when sending event to receiver.
Registry of available layout item types.
static void setPkgDataPath(const QString &pkgDataPath)
Alters pkg data path - used by 3rd party apps.
static QgsPageSizeRegistry * pageSizeRegistry()
Returns the application&#39;s page size registry, used for managing layout page sizes.
static QString contributorsFilePath()
Returns the path to the contributors file.
static QString activeThemePath()
Returns the path to the currently active theme directory.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
static void init(QString profileFolder=QString())
This method initializes paths etc for QGIS.
static void setPluginPath(const QString &pluginPath)
Alters plugin path - used by 3rd party apps.
static void invalidateCache()
Clears the internal cache used to initialize QgsCoordinateTransform objects.
QgsUserProfile * getProfile(const QString &defaultProfile="default", bool createNew=true, bool initSettings=true)
Returns the profile from the given root profile location.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:411
A class to register / unregister existing GPS connections such that the information is available to a...
static QgsNetworkContentFetcherRegistry * networkContentFetcherRegistry()
Returns the application&#39;s network content registry used for fetching temporary files during QGIS sess...
bool init(const QString &pluginPath=QString(), const QString &authDatabasePath=QString())
init initialize QCA, prioritize qca-ossl plugin and optionally set up the authentication database ...
static QString platform()
Returns the QGIS platform name, e.g., "desktop" or "server".
static QString srsDatabaseFilePath()
Returns the path to the srs.db file.
QObject * ABISYM(QgsApplication::mFileOpenEventReceiver)
static void exitQgis()
deletes provider registry and map layer registry
Temporarily blocks the application QgsMessageLog (see QgsApplication::messageLog()) from emitting the...
static QStringList svgPaths()
Returns the paths to svg directories.
static QString sponsorsFilePath()
Returns the path to the sponsors file.
Registry of storage backends that QgsProject may use.
static QCursor getThemeCursor(Cursor cursor)
Helper to get a theme cursor.
static QString qgisAuthDatabaseFilePath()
Returns the path to the user authentication database file: qgis-auth.db.
const QString folder() const
The base folder for the user profile.
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
void collectTranslatableObjects(QgsTranslationContext *translationContext)
Emits the signal to collect all the strings of .qgs to be included in ts file.
~QgsApplication() override
static QString serverResourcesPath()
Returns the path to the server resources directory.
static QgsActionScopeRegistry * actionScopeRegistry()
Returns the action scope registry.
User profile manager is used to manager list, and manage user profiles on the users machine...
static QString metadataPath()
Returns the path to the metadata directory.
Defines a QGIS exception class.
Definition: qgsexception.h:34
static QgsRasterRendererRegistry * rasterRendererRegistry()
Returns the application&#39;s raster renderer registry, used for managing raster layer renderers...
static QgsDataItemProviderRegistry * dataItemProviderRegistry()
Returns the application&#39;s data item provider registry, which keeps a list of data item providers that...
static QgsRendererRegistry * rendererRegistry()
Returns the application&#39;s renderer registry, used for managing vector layer renderers.
Interface for logging messages from QGIS in GUI independent way.
Definition: qgsmessagelog.h:38
static QString qmlImportPath()
Returns the path where QML components are installed for QGIS Quick library.
static void setMaxThreads(int maxThreads)
Set maximum concurrent thread count.
Select and capture a point or a feature.
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.
Registry of available paint effects.
static QgsProcessingRegistry * processingRegistry()
Returns the application&#39;s processing registry, used for managing processing providers, algorithms, and various parameters and outputs.
static QString userThemesFolder()
Returns the path to user&#39;s themes folder.
void preNotify(QObject *receiver, QEvent *event, bool *done)
static void setAuthDatabaseDirPath(const QString &authDbDirPath)
Alters authentication data base directory path - used by 3rd party apps.