QGIS API Documentation  3.13.0-Master (9729a43df7)
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"
20 #include "qgsexception.h"
21 #include "qgsgeometry.h"
22 #include "qgslayoutitemregistry.h"
23 #include "qgslogger.h"
24 #include "qgsproject.h"
27 #include "qgsnetworkreply.h"
28 #include "qgsproviderregistry.h"
29 #include "qgsexpression.h"
30 #include "qgsactionscoperegistry.h"
31 #include "qgsruntimeprofiler.h"
32 #include "qgstaskmanager.h"
36 #include "qgssvgcache.h"
37 #include "qgsimagecache.h"
38 #include "qgscolorschemeregistry.h"
39 #include "qgspainteffectregistry.h"
42 #include "qgsrendererregistry.h"
43 #include "qgssymbollayerregistry.h"
44 #include "qgssymbollayerutils.h"
45 #include "qgscalloutsregistry.h"
46 #include "qgspluginlayerregistry.h"
48 #include "qgsmessagelog.h"
49 #include "qgsannotationregistry.h"
50 #include "qgssettings.h"
51 #include "qgsunittypes.h"
52 #include "qgsuserprofile.h"
53 #include "qgsuserprofilemanager.h"
54 #include "qgsreferencedgeometry.h"
55 #include "qgs3drendererregistry.h"
56 #include "qgslayoutrendercontext.h"
57 #include "qgssqliteutils.h"
58 #include "qgsstyle.h"
59 #include "qgsprojutils.h"
61 #include "qgsnewsfeedparser.h"
62 #include "qgsbookmarkmanager.h"
63 #include "qgsstylemodel.h"
64 #include "qgsconnectionregistry.h"
66 
69 #include "processing/models/qgsprocessingmodelchildparametersource.h"
70 #include "processing/models/qgsprocessingmodelchilddependency.h"
71 
73 
74 #include <QDir>
75 #include <QFile>
76 #include <QFileInfo>
77 #include <QFileOpenEvent>
78 #include <QMessageBox>
79 #include <QPalette>
80 #include <QProcess>
81 #include <QProcessEnvironment>
82 #include <QIcon>
83 #include <QPixmap>
84 #include <QThreadPool>
85 #include <QLocale>
86 #include <QStyle>
87 
88 #ifndef Q_OS_WIN
89 #include <netinet/in.h>
90 #include <pwd.h>
91 #else
92 #include <winsock.h>
93 #include <windows.h>
94 #include <lmcons.h>
95 #define SECURITY_WIN32
96 #include <security.h>
97 #pragma comment( lib, "Secur32.lib" )
98 #endif
99 
100 #include "qgsconfig.h"
101 
102 #include <gdal.h>
103 #include <ogr_api.h>
104 #include <cpl_conv.h> // for setting gdal options
105 #include <sqlite3.h>
106 
107 #if PROJ_VERSION_MAJOR>=6
108 #include <proj.h>
109 #endif
110 
111 
112 #define CONN_POOL_MAX_CONCURRENT_CONNS 4
113 
114 QObject *ABISYM( QgsApplication::mFileOpenEventReceiver ) = nullptr;
115 bool ABISYM( QgsApplication::mInitialized ) = false;
116 bool ABISYM( QgsApplication::mRunningFromBuildDir ) = false;
117 const char *QgsApplication::QGIS_ORGANIZATION_NAME = "QGIS";
118 const char *QgsApplication::QGIS_ORGANIZATION_DOMAIN = "qgis.org";
119 const char *QgsApplication::QGIS_APPLICATION_NAME = "QGIS3";
120 QgsApplication::ApplicationMembers *QgsApplication::sApplicationMembers = nullptr;
121 QgsAuthManager *QgsApplication::sAuthManager = nullptr;
122 int ABISYM( QgsApplication::sMaxThreads ) = -1;
123 
124 Q_GLOBAL_STATIC( QStringList, sFileOpenEventList )
125 Q_GLOBAL_STATIC( QString, sPrefixPath )
126 Q_GLOBAL_STATIC( QString, sPluginPath )
127 Q_GLOBAL_STATIC( QString, sPkgDataPath )
128 Q_GLOBAL_STATIC( QString, sLibraryPath )
129 Q_GLOBAL_STATIC( QString, sLibexecPath )
130 Q_GLOBAL_STATIC( QString, sQmlImportPath )
131 Q_GLOBAL_STATIC( QString, sThemeName )
132 Q_GLOBAL_STATIC( QString, sProfilePath )
133 
134 Q_GLOBAL_STATIC( QStringList, sDefaultSvgPaths )
135 Q_GLOBAL_STATIC( QgsStringMap, sSystemEnvVars )
136 Q_GLOBAL_STATIC( QString, sConfigPath )
137 
138 Q_GLOBAL_STATIC( QString, sBuildSourcePath )
139 #if defined(_MSC_VER) && !defined(USING_NMAKE) && !defined(USING_NINJA)
140 Q_GLOBAL_STATIC( QString, sCfgIntDir )
141 #endif
142 Q_GLOBAL_STATIC( QString, sBuildOutputPath )
143 Q_GLOBAL_STATIC( QStringList, sGdalSkipList )
144 Q_GLOBAL_STATIC( QStringList, sDeferredSkippedGdalDrivers )
145 Q_GLOBAL_STATIC( QString, sAuthDbDirPath )
146 
147 Q_GLOBAL_STATIC( QString, sUserName )
148 Q_GLOBAL_STATIC( QString, sUserFullName )
149 Q_GLOBAL_STATIC_WITH_ARGS( QString, sPlatformName, ( "desktop" ) )
150 Q_GLOBAL_STATIC( QString, sTranslation )
151 
152 QgsApplication::QgsApplication( int &argc, char **argv, bool GUIenabled, const QString &profileFolder, const QString &platformName )
153  : QApplication( argc, argv, GUIenabled )
154 {
155  *sPlatformName() = platformName;
156 
157  if ( *sTranslation() != QLatin1String( "C" ) )
158  {
159  mQgisTranslator = new QTranslator();
160  if ( mQgisTranslator->load( QStringLiteral( "qgis_" ) + *sTranslation(), i18nPath() ) )
161  {
162  installTranslator( mQgisTranslator );
163  }
164  else
165  {
166  QgsDebugMsgLevel( QStringLiteral( "loading of qgis translation failed %1/qgis_%2" ).arg( i18nPath(), *sTranslation() ), 2 );
167  }
168 
169  /* Translation file for Qt.
170  * The strings from the QMenuBar context section are used by Qt/Mac to shift
171  * the About, Preferences and Quit items to the Mac Application menu.
172  * These items must be translated identically in both qt_ and qgis_ files.
173  */
174  mQtTranslator = new QTranslator();
175  if ( mQtTranslator->load( QStringLiteral( "qt_" ) + *sTranslation(), QLibraryInfo::location( QLibraryInfo::TranslationsPath ) ) )
176  {
177  installTranslator( mQtTranslator );
178  }
179  else
180  {
181  QgsDebugMsgLevel( QStringLiteral( "loading of qt translation failed %1/qt_%2" ).arg( QLibraryInfo::location( QLibraryInfo::TranslationsPath ), *sTranslation() ), 2 );
182  }
183  }
184 
185  mApplicationMembers = new ApplicationMembers();
186 
187  *sProfilePath() = profileFolder;
188 }
189 
190 void QgsApplication::init( QString profileFolder )
191 {
192  if ( profileFolder.isEmpty() )
193  {
194  if ( getenv( "QGIS_CUSTOM_CONFIG_PATH" ) )
195  {
196  profileFolder = getenv( "QGIS_CUSTOM_CONFIG_PATH" );
197  }
198  else
199  {
200  profileFolder = QStandardPaths::standardLocations( QStandardPaths::AppDataLocation ).value( 0 );
201  }
202  // This will normally get here for custom scripts that use QgsApplication.
203  // This doesn't get this hit for QGIS Desktop because we setup the profile via main
204  QString rootProfileFolder = QgsUserProfileManager::resolveProfilesFolder( profileFolder );
205  QgsUserProfileManager manager( rootProfileFolder );
206  QgsUserProfile *profile = manager.getProfile();
207  profileFolder = profile->folder();
208  delete profile;
209  }
210 
211  *sProfilePath() = profileFolder;
212 
213  qRegisterMetaType<QgsGeometry::Error>( "QgsGeometry::Error" );
214  qRegisterMetaType<QgsProcessingFeatureSourceDefinition>( "QgsProcessingFeatureSourceDefinition" );
215  qRegisterMetaType<QgsProcessingOutputLayerDefinition>( "QgsProcessingOutputLayerDefinition" );
216  qRegisterMetaType<QgsUnitTypes::LayoutUnit>( "QgsUnitTypes::LayoutUnit" );
217  qRegisterMetaType<QgsFeatureId>( "QgsFeatureId" );
218  qRegisterMetaType<QgsFeatureIds>( "QgsFeatureIds" );
219  qRegisterMetaType<QgsProperty>( "QgsProperty" );
220  qRegisterMetaType<Qgis::MessageLevel>( "Qgis::MessageLevel" );
221  qRegisterMetaType<QgsReferencedRectangle>( "QgsReferencedRectangle" );
222  qRegisterMetaType<QgsReferencedPointXY>( "QgsReferencedPointXY" );
223  qRegisterMetaType<QgsLayoutRenderContext::Flags>( "QgsLayoutRenderContext::Flags" );
224  qRegisterMetaType<QgsStyle::StyleEntity>( "QgsStyle::StyleEntity" );
225  qRegisterMetaType<QgsCoordinateReferenceSystem>( "QgsCoordinateReferenceSystem" );
226  qRegisterMetaType<QgsAuthManager::MessageLevel>( "QgsAuthManager::MessageLevel" );
227  qRegisterMetaType<QgsNetworkRequestParameters>( "QgsNetworkRequestParameters" );
228  qRegisterMetaType<QgsNetworkReplyContent>( "QgsNetworkReplyContent" );
229  qRegisterMetaType<QgsGeometry>( "QgsGeometry" );
230  qRegisterMetaType<QgsDatumTransform::GridDetails>( "QgsDatumTransform::GridDetails" );
231  qRegisterMetaType<QgsDatumTransform::TransformDetails>( "QgsDatumTransform::TransformDetails" );
232  qRegisterMetaType<QgsNewsFeedParser::Entry>( "QgsNewsFeedParser::Entry" );
233  qRegisterMetaType<QgsRectangle>( "QgsRectangle" );
234  qRegisterMetaType<QgsProcessingModelChildParameterSource>( "QgsProcessingModelChildParameterSource" );
235  qRegisterMetaTypeStreamOperators<QgsProcessingModelChildParameterSource>( "QgsProcessingModelChildParameterSource" );
236  qRegisterMetaType<QgsRemappingSinkDefinition>( "QgsRemappingSinkDefinition" );
237  qRegisterMetaType<QgsProcessingModelChildDependency>( "QgsProcessingModelChildDependency" );
238  QMetaType::registerComparators<QgsProcessingModelChildDependency>();
239 
240  ( void ) resolvePkgPath();
241 
242  if ( ABISYM( mRunningFromBuildDir ) )
243  {
244  // we run from source directory - not installed to destination (specified prefix)
245  *sPrefixPath() = QString(); // set invalid path
246 #if defined(_MSC_VER) && !defined(USING_NMAKE) && !defined(USING_NINJA)
247  setPluginPath( *sBuildOutputPath() + '/' + QString( QGIS_PLUGIN_SUBDIR ) + '/' + *sCfgIntDir() );
248 #else
249  setPluginPath( *sBuildOutputPath() + '/' + QStringLiteral( QGIS_PLUGIN_SUBDIR ) );
250 #endif
251  setPkgDataPath( *sBuildOutputPath() + QStringLiteral( "/data" ) ); // in buildDir/data - used for: doc, resources, svg
252  *sLibraryPath() = *sBuildOutputPath() + '/' + QGIS_LIB_SUBDIR + '/';
253 #if defined(_MSC_VER) && !defined(USING_NMAKE) && !defined(USING_NINJA)
254  *sLibexecPath() = *sBuildOutputPath() + '/' + QGIS_LIBEXEC_SUBDIR + '/' + *sCfgIntDir() + '/';
255 #else
256  *sLibexecPath() = *sBuildOutputPath() + '/' + QGIS_LIBEXEC_SUBDIR + '/';
257 #endif
258 #if defined( HAVE_QUICK )
259  *sQmlImportPath() = *sBuildOutputPath() + '/' + QGIS_QML_SUBDIR + '/';
260 #endif
261  }
262  else
263  {
264  char *prefixPath = getenv( "QGIS_PREFIX_PATH" );
265  if ( !prefixPath )
266  {
267  if ( sPrefixPath()->isNull() )
268  {
269 #if defined(Q_OS_MACX) || defined(Q_OS_WIN)
270  setPrefixPath( applicationDirPath(), true );
271 #elif defined(ANDROID)
272  // this is "/data/data/org.qgis.qgis" in android
273  QDir myDir( QDir::homePath() );
274  myDir.cdUp();
275  QString myPrefix = myDir.absolutePath();
276  setPrefixPath( myPrefix, true );
277 #else
278  QDir myDir( applicationDirPath() );
279  // Fix for server which is one level deeper in /usr/lib/cgi-bin
280  if ( applicationDirPath().contains( QStringLiteral( "cgi-bin" ) ) )
281  {
282  myDir.cdUp();
283  }
284  myDir.cdUp(); // Go from /usr/bin or /usr/lib (for server) to /usr
285  QString myPrefix = myDir.absolutePath();
286  setPrefixPath( myPrefix, true );
287 #endif
288  }
289  }
290  else
291  {
292  setPrefixPath( prefixPath, true );
293  }
294  }
295 
296  *sConfigPath() = profileFolder + '/'; // make sure trailing slash is included
297  *sDefaultSvgPaths() << qgisSettingsDirPath() + QStringLiteral( "svg/" );
298 
299  *sAuthDbDirPath() = qgisSettingsDirPath();
300  if ( getenv( "QGIS_AUTH_DB_DIR_PATH" ) )
301  {
302  setAuthDatabaseDirPath( getenv( "QGIS_AUTH_DB_DIR_PATH" ) );
303  }
304 
305  // store system environment variables passed to application, before they are adjusted
306  QMap<QString, QString> systemEnvVarMap;
307  QString passfile( QStringLiteral( "QGIS_AUTH_PASSWORD_FILE" ) ); // QString, for comparison
308 
309  const auto systemEnvironment = QProcessEnvironment::systemEnvironment().toStringList();
310  for ( const QString &varStr : systemEnvironment )
311  {
312  int pos = varStr.indexOf( QLatin1Char( '=' ) );
313  if ( pos == -1 )
314  continue;
315  QString varStrName = varStr.left( pos );
316  QString varStrValue = varStr.mid( pos + 1 );
317  if ( varStrName != passfile )
318  {
319  systemEnvVarMap.insert( varStrName, varStrValue );
320  }
321  }
322  *sSystemEnvVars() = systemEnvVarMap;
323 
324 #if PROJ_VERSION_MAJOR>=6
325  // append local user-writable folder as a proj search path
326  QStringList currentProjSearchPaths = QgsProjUtils::searchPaths();
327  currentProjSearchPaths.append( qgisSettingsDirPath() + QStringLiteral( "proj" ) );
328  char **newPaths = new char *[currentProjSearchPaths.length()];
329  for ( int i = 0; i < currentProjSearchPaths.count(); ++i )
330  {
331  newPaths[i] = CPLStrdup( currentProjSearchPaths.at( i ).toUtf8().constData() );
332  }
333  proj_context_set_search_paths( nullptr, currentProjSearchPaths.count(), newPaths );
334  for ( int i = 0; i < currentProjSearchPaths.count(); ++i )
335  {
336  CPLFree( newPaths[i] );
337  }
338  delete [] newPaths;
339 #endif
340 
341 
342  // allow Qt to search for Qt plugins (e.g. sqldrivers) in our plugin directory
343  QCoreApplication::addLibraryPath( pluginPath() );
344 
345  // set max. thread count to -1
346  // this should be read from QgsSettings but we don't know where they are at this point
347  // so we read actual value in main.cpp
348  ABISYM( sMaxThreads ) = -1;
349 
350  {
351  QgsScopedRuntimeProfile profile( tr( "Load color schemes" ) );
354  }
355 
356  {
357  QgsScopedRuntimeProfile profile( tr( "Load bookmarks" ) );
359  }
360 
361  if ( !members()->mStyleModel )
362  members()->mStyleModel = new QgsStyleModel( QgsStyle::defaultStyle() );
363 
364  ABISYM( mInitialized ) = true;
365 }
366 
368 {
369  delete mDataItemProviderRegistry;
370  delete mApplicationMembers;
371  delete mQgisTranslator;
372  delete mQtTranslator;
373 
374  // we do this here as well as in exitQgis() -- it's safe to call as often as we want,
375  // and there's just a *chance* that someone hasn't properly called exitQgis prior to
376  // this destructor...
377  invalidateCaches();
378 }
379 
380 void QgsApplication::invalidateCaches()
381 {
382  // invalidate coordinate cache while the PROJ context held by the thread-locale
383  // QgsProjContextStore object is still alive. Otherwise if this later object
384  // is destroyed before the static variables of the cache, we might use freed memory.
388 }
389 
391 {
392  return qobject_cast<QgsApplication *>( QCoreApplication::instance() );
393 }
394 
396 {
397  bool done = false;
398  if ( event->type() == QEvent::FileOpen )
399  {
400  // handle FileOpen event (double clicking a file icon in Mac OS X Finder)
401  if ( ABISYM( mFileOpenEventReceiver ) )
402  {
403  // Forward event to main window.
404  done = notify( ABISYM( mFileOpenEventReceiver ), event );
405  }
406  else
407  {
408  // Store filename because receiver has not registered yet.
409  // If QGIS has been launched by double clicking a file icon, FileOpen will be
410  // the first event; the main window is not yet ready to handle the event.
411  sFileOpenEventList()->append( static_cast<QFileOpenEvent *>( event )->file() );
412  done = true;
413  }
414  }
415  else
416  {
417  // pass other events to base class
418  done = QApplication::event( event );
419  }
420  return done;
421 }
422 
423 bool QgsApplication::notify( QObject *receiver, QEvent *event )
424 {
425  bool done = false;
426  // Crashes in customization (especially on Mac), if we're not in the main/UI thread, see #5597
427  if ( thread() == receiver->thread() )
428  emit preNotify( receiver, event, &done );
429 
430  if ( done )
431  return true;
432 
433  // Send event to receiver and catch unhandled exceptions
434  done = true;
435  try
436  {
437  done = QApplication::notify( receiver, event );
438  }
439  catch ( QgsException &e )
440  {
441  QgsDebugMsg( "Caught unhandled QgsException: " + e.what() );
442  if ( qApp->thread() == QThread::currentThread() )
443  QMessageBox::critical( activeWindow(), tr( "Exception" ), e.what() );
444  }
445  catch ( std::exception &e )
446  {
447  QgsDebugMsg( "Caught unhandled std::exception: " + QString::fromLatin1( e.what() ) );
448  if ( qApp->thread() == QThread::currentThread() )
449  QMessageBox::critical( activeWindow(), tr( "Exception" ), e.what() );
450  }
451  catch ( ... )
452  {
453  QgsDebugMsg( QStringLiteral( "Caught unhandled unknown exception" ) );
454  if ( qApp->thread() == QThread::currentThread() )
455  QMessageBox::critical( activeWindow(), tr( "Exception" ), tr( "unknown exception" ) );
456  }
457 
458  return done;
459 }
460 
462 {
463  return members()->mProfiler;
464 }
465 
467 {
468  // Set receiver for FileOpen events
469  ABISYM( mFileOpenEventReceiver ) = receiver;
470  // Propagate any events collected before the receiver has registered.
471  if ( sFileOpenEventList()->count() > 0 )
472  {
473  const QStringList fileOpenEventList = *sFileOpenEventList();
474  for ( const QString &file : fileOpenEventList )
475  {
476  QFileOpenEvent foe( file );
477  QgsApplication::sendEvent( ABISYM( mFileOpenEventReceiver ), &foe );
478  }
479  sFileOpenEventList()->clear();
480  }
481 }
482 
483 void QgsApplication::setPrefixPath( const QString &prefixPath, bool useDefaultPaths )
484 {
485  *sPrefixPath() = prefixPath;
486 #if defined(Q_OS_WIN)
487  if ( sPrefixPath()->endsWith( "/bin" ) )
488  {
489  sPrefixPath()->chop( 4 );
490  }
491 #endif
492  if ( useDefaultPaths && !ABISYM( mRunningFromBuildDir ) )
493  {
494  setPluginPath( *sPrefixPath() + '/' + QStringLiteral( QGIS_PLUGIN_SUBDIR ) );
495  setPkgDataPath( *sPrefixPath() + '/' + QStringLiteral( QGIS_DATA_SUBDIR ) );
496  }
497  *sLibraryPath() = *sPrefixPath() + '/' + QGIS_LIB_SUBDIR + '/';
498  *sLibexecPath() = *sPrefixPath() + '/' + QGIS_LIBEXEC_SUBDIR + '/';
499 #if defined( HAVE_QUICK )
500  *sQmlImportPath() = *sPrefixPath() + '/' + QGIS_QML_SUBDIR + '/';
501 #endif
502 }
503 
505 {
506  *sPluginPath() = pluginPath;
507 }
508 
510 {
511  *sPkgDataPath() = pkgDataPath;
512 
513  QString mySvgPath = pkgDataPath + QStringLiteral( "/svg/" );
514 
515  // avoid duplicate entries
516  if ( !sDefaultSvgPaths()->contains( mySvgPath ) )
517  *sDefaultSvgPaths() << mySvgPath;
518 }
519 
520 void QgsApplication::setDefaultSvgPaths( const QStringList &pathList )
521 {
522  *sDefaultSvgPaths() = pathList;
523 }
524 
525 void QgsApplication::setAuthDatabaseDirPath( const QString &authDbDirPath )
526 {
527  QFileInfo fi( authDbDirPath );
528  if ( fi.exists() && fi.isDir() && fi.isWritable() )
529  {
530  *sAuthDbDirPath() = fi.canonicalFilePath() + QDir::separator();
531  }
532 }
533 
535 {
536 #if 0
537  if ( ABISYM( mRunningFromBuildDir ) )
538  {
539  static bool sOnce = true;
540  if ( sOnce )
541  {
542  QgsMessageLogNotifyBlocker blockNotifications;
543  ( void ) blockNotifications;
544  qWarning( "!!! prefix path was requested, but it is not valid - we do not run from installed path !!!" );
545  }
546  sOnce = false;
547  }
548 #endif
549 
550  return *sPrefixPath();
551 }
553 {
554  return *sPluginPath();
555 }
556 
558 {
559  if ( sPkgDataPath()->isNull() )
560  return resolvePkgPath();
561  else
562  return *sPkgDataPath();
563 }
564 
566 {
567  return QStringLiteral( ":/images/themes/default/" );
568 }
570 {
571  QString usersThemes = userThemesFolder() + QDir::separator() + themeName() + QDir::separator() + "icons/";
572  QDir dir( usersThemes );
573  if ( dir.exists() )
574  {
575  return usersThemes;
576  }
577  else
578  {
579  QString defaultThemes = defaultThemesFolder() + QDir::separator() + themeName() + QDir::separator() + "icons/";
580  return defaultThemes;
581  }
582 }
583 
585 {
586  return iconsPath() + QStringLiteral( "qgis-icon-60x60.png" );
587 }
588 
590 {
591  return ABISYM( sMaxThreads );
592 }
593 
594 QString QgsApplication::iconPath( const QString &iconFile )
595 {
596  // try active theme
597  QString path = activeThemePath();
598  if ( QFile::exists( path + iconFile ) )
599  return path + iconFile;
600 
601  // use default theme
602  return defaultThemePath() + iconFile;
603 }
604 
605 QIcon QgsApplication::getThemeIcon( const QString &name )
606 {
607  QgsApplication *app = instance();
608  if ( app && app->mIconCache.contains( name ) )
609  return app->mIconCache.value( name );
610 
611  QIcon icon;
612 
613  QString myPreferredPath = activeThemePath() + QDir::separator() + name;
614  QString myDefaultPath = defaultThemePath() + QDir::separator() + name;
615  if ( QFile::exists( myPreferredPath ) )
616  {
617  icon = QIcon( myPreferredPath );
618  }
619  else if ( QFile::exists( myDefaultPath ) )
620  {
621  //could still return an empty icon if it
622  //doesn't exist in the default theme either!
623  icon = QIcon( myDefaultPath );
624  }
625  else
626  {
627  icon = QIcon();
628  }
629 
630  if ( app )
631  app->mIconCache.insert( name, icon );
632  return icon;
633 }
634 
636 {
637  QgsApplication *app = instance();
638  if ( app && app->mCursorCache.contains( cursor ) )
639  return app->mCursorCache.value( cursor );
640 
641  // All calculations are done on 32x32 icons
642  // Defaults to center, individual cursors may override
643  int activeX = 16;
644  int activeY = 16;
645 
646  QString name;
647  switch ( cursor )
648  {
649  case ZoomIn:
650  name = QStringLiteral( "mZoomIn.svg" );
651  activeX = 13;
652  activeY = 13;
653  break;
654  case ZoomOut:
655  name = QStringLiteral( "mZoomOut.svg" );
656  activeX = 13;
657  activeY = 13;
658  break;
659  case Identify:
660  activeX = 3;
661  activeY = 6;
662  name = QStringLiteral( "mIdentify.svg" );
663  break;
664  case CrossHair:
665  name = QStringLiteral( "mCrossHair.svg" );
666  break;
667  case CapturePoint:
668  name = QStringLiteral( "mCapturePoint.svg" );
669  break;
670  case Select:
671  name = QStringLiteral( "mSelect.svg" );
672  activeX = 6;
673  activeY = 6;
674  break;
675  case Sampler:
676  activeX = 5;
677  activeY = 5;
678  name = QStringLiteral( "mSampler.svg" );
679  break;
680  // No default
681  }
682  // It should never get here!
683  Q_ASSERT( ! name.isEmpty( ) );
684 
685  QIcon icon = getThemeIcon( QStringLiteral( "cursors" ) + QDir::separator() + name );
686  QCursor cursorIcon;
687  // Check if an icon exists for this cursor (the O.S. default cursor will be used if it does not)
688  if ( ! icon.isNull( ) )
689  {
690  // Apply scaling
691  float scale = Qgis::UI_SCALE_FACTOR * app->fontMetrics().height() / 32.0;
692  cursorIcon = QCursor( icon.pixmap( std::ceil( scale * 32 ), std::ceil( scale * 32 ) ), std::ceil( scale * activeX ), std::ceil( scale * activeY ) );
693  }
694  if ( app )
695  app->mCursorCache.insert( cursor, cursorIcon );
696  return cursorIcon;
697 }
698 
699 // TODO: add some caching mechanism ?
700 QPixmap QgsApplication::getThemePixmap( const QString &name )
701 {
702  QString myPreferredPath = activeThemePath() + QDir::separator() + name;
703  QString myDefaultPath = defaultThemePath() + QDir::separator() + name;
704  if ( QFile::exists( myPreferredPath ) )
705  {
706  return QPixmap( myPreferredPath );
707  }
708  else
709  {
710  //could still return an empty icon if it
711  //doesn't exist in the default theme either!
712  return QPixmap( myDefaultPath );
713  }
714 }
715 
717 {
718  *sThemeName() = themeName;
719 }
720 
722 {
723  static QString appPath;
724  if ( appPath.isNull() )
725  {
726  if ( QCoreApplication::instance() )
727  {
728  appPath = applicationDirPath();
729  }
730  else
731  {
732  qWarning( "Application path not initialized" );
733  }
734  }
735 
736  if ( !appPath.isNull() || getenv( "QGIS_PREFIX_PATH" ) )
737  {
738  QString prefix = getenv( "QGIS_PREFIX_PATH" ) ? getenv( "QGIS_PREFIX_PATH" ) : appPath;
739 
740  // check if QGIS is run from build directory (not the install directory)
741  QFile f;
742  // "/../../.." is for Mac bundled app in build directory
743  static const QStringList paths { QStringList() << QString() << QStringLiteral( "/.." ) << QStringLiteral( "/bin" ) << QStringLiteral( "/../../.." ) };
744  for ( const QString &path : paths )
745  {
746  f.setFileName( prefix + path + "/qgisbuildpath.txt" );
747  if ( f.exists() )
748  break;
749  }
750  if ( f.exists() && f.open( QIODevice::ReadOnly ) )
751  {
752  ABISYM( mRunningFromBuildDir ) = true;
753  *sBuildSourcePath() = f.readLine().trimmed();
754  *sBuildOutputPath() = f.readLine().trimmed();
755  QgsDebugMsgLevel( QStringLiteral( "Running from build directory!" ), 4 );
756  QgsDebugMsgLevel( QStringLiteral( "- source directory: %1" ).arg( sBuildSourcePath()->toUtf8().constData() ), 4 );
757  QgsDebugMsgLevel( QStringLiteral( "- output directory of the build: %1" ).arg( sBuildOutputPath()->toUtf8().constData() ), 4 );
758 #if defined(_MSC_VER) && !defined(USING_NMAKE) && !defined(USING_NINJA)
759  *sCfgIntDir() = appPath.split( '/', QString::SkipEmptyParts ).last();
760  qDebug( "- cfg: %s", sCfgIntDir()->toUtf8().constData() );
761 #endif
762  }
763  }
764 
765  QString prefixPath;
766  if ( getenv( "QGIS_PREFIX_PATH" ) )
767  prefixPath = getenv( "QGIS_PREFIX_PATH" );
768  else
769  {
770 #if defined(ANDROID)
771  // this is "/data/data/org.qgis.qgis" in android
772  QDir dir( QDir::homePath() );
773  dir.cdUp();
774  prefixPath = dir.absolutePath();
775 #else
776 
777 #if defined(Q_OS_MACX)
778  prefixPath = appPath;
779 #elif defined(Q_OS_WIN)
780  prefixPath = appPath;
781  if ( prefixPath.endsWith( "/bin" ) )
782  prefixPath.chop( 4 );
783 #else
784  QDir dir( appPath );
785  // Fix for server which is one level deeper in /usr/lib/cgi-bin
786  if ( appPath.contains( QStringLiteral( "cgi-bin" ) ) )
787  {
788  dir.cdUp();
789  }
790  dir.cdUp(); // Go from /usr/bin or /usr/lib (for server) to /usr
791  prefixPath = dir.absolutePath();
792 #endif
793 #endif
794  }
795 
796  if ( ABISYM( mRunningFromBuildDir ) )
797  return *sBuildOutputPath() + QStringLiteral( "/data" );
798  else
799  return prefixPath + '/' + QStringLiteral( QGIS_DATA_SUBDIR );
800 }
801 
803 {
804  return *sThemeName();
805 }
806 
807 void QgsApplication::setUITheme( const QString &themeName )
808 {
809  // Loop all style sheets, find matching name, load it.
810  QHash<QString, QString> themes = QgsApplication::uiThemes();
811  if ( themeName == QStringLiteral( "default" ) || !themes.contains( themeName ) )
812  {
813  setThemeName( QStringLiteral( "default" ) );
814  qApp->setStyleSheet( QString() );
815  return;
816  }
817 
818  QString path = themes.value( themeName );
819  QString stylesheetname = path + "/style.qss";
820 
821  QFile file( stylesheetname );
822  QFile variablesfile( path + "/variables.qss" );
823 
824  QFileInfo variableInfo( variablesfile );
825 
826  if ( !file.open( QIODevice::ReadOnly ) || ( variableInfo.exists() && !variablesfile.open( QIODevice::ReadOnly ) ) )
827  {
828  return;
829  }
830 
831  QString styledata = file.readAll();
832  styledata.replace( QStringLiteral( "@theme_path" ), path );
833 
834  if ( variableInfo.exists() )
835  {
836  QTextStream in( &variablesfile );
837  while ( !in.atEnd() )
838  {
839  QString line = in.readLine();
840  // This is a variable
841  if ( line.startsWith( '@' ) )
842  {
843  int index = line.indexOf( ':' );
844  QString name = line.mid( 0, index );
845  QString value = line.mid( index + 1, line.length() );
846  styledata.replace( name, value );
847  }
848  }
849  variablesfile.close();
850  }
851  file.close();
852 
853  if ( Qgis::UI_SCALE_FACTOR != 1.0 )
854  {
855  // apply OS-specific UI scale factor to stylesheet's em values
856  int index = 0;
857  QRegularExpression regex( QStringLiteral( "(?<=[\\s:])([0-9\\.]+)(?=em)" ) );
858  QRegularExpressionMatch match = regex.match( styledata, index );
859  while ( match.hasMatch() )
860  {
861  index = match.capturedStart();
862  styledata.remove( index, match.captured( 0 ).length() );
863  QString number = QString::number( match.captured( 0 ).toDouble() * Qgis::UI_SCALE_FACTOR );
864  styledata.insert( index, number );
865  index += number.length();
866  match = regex.match( styledata, index );
867  }
868  }
869 
870  qApp->setStyleSheet( styledata );
871 
872  QFile palettefile( path + "/palette.txt" );
873  QFileInfo paletteInfo( palettefile );
874  if ( paletteInfo.exists() && palettefile.open( QIODevice::ReadOnly ) )
875  {
876  QPalette pal = qApp->palette();
877  QTextStream in( &palettefile );
878  while ( !in.atEnd() )
879  {
880  QString line = in.readLine();
881  QStringList parts = line.split( ':' );
882  if ( parts.count() == 2 )
883  {
884  int role = parts.at( 0 ).trimmed().toInt();
885  QColor color = QgsSymbolLayerUtils::decodeColor( parts.at( 1 ).trimmed() );
886  pal.setColor( static_cast< QPalette::ColorRole >( role ), color );
887  }
888  }
889  palettefile.close();
890  qApp->setPalette( pal );
891  }
892 
893  setThemeName( themeName );
894 }
895 
896 QHash<QString, QString> QgsApplication::uiThemes()
897 {
898  QStringList paths = QStringList() << userThemesFolder() << defaultThemesFolder();
899  QHash<QString, QString> mapping;
900  mapping.insert( QStringLiteral( "default" ), QString() );
901  const auto constPaths = paths;
902  for ( const QString &path : constPaths )
903  {
904  QDir folder( path );
905  QFileInfoList styleFiles = folder.entryInfoList( QDir::Dirs | QDir::NoDotAndDotDot );
906  const auto constStyleFiles = styleFiles;
907  for ( const QFileInfo &info : constStyleFiles )
908  {
909  QFileInfo styleFile( info.absoluteFilePath() + "/style.qss" );
910  if ( !styleFile.exists() )
911  continue;
912 
913  QString name = info.baseName();
914  QString path = info.absoluteFilePath();
915  mapping.insert( name, path );
916  }
917  }
918  return mapping;
919 }
920 
922 {
923  return pkgDataPath() + QStringLiteral( "/doc/AUTHORS" );
924 }
925 
927 {
928  return pkgDataPath() + QStringLiteral( "/doc/CONTRIBUTORS" );
929 }
931 {
932  return pkgDataPath() + QStringLiteral( "/doc/developersmap.html" );
933 }
934 
936 {
937  return pkgDataPath() + QStringLiteral( "/doc/SPONSORS" );
938 }
939 
941 {
942  return pkgDataPath() + QStringLiteral( "/doc/DONORS" );
943 }
944 
946 {
947  return pkgDataPath() + QStringLiteral( "/doc/TRANSLATORS" );
948 }
949 
951 {
952  return pkgDataPath() + QStringLiteral( "/doc/LICENSE" );
953 }
954 
956 {
957  if ( ABISYM( mRunningFromBuildDir ) )
958  return *sBuildOutputPath() + QStringLiteral( "/i18n/" );
959  else
960  return pkgDataPath() + QStringLiteral( "/i18n/" );
961 }
962 
964 {
965  return pkgDataPath() + QStringLiteral( "/resources/metadata-ISO/" );
966 }
967 
969 {
970  return pkgDataPath() + QStringLiteral( "/resources/qgis.db" );
971 }
972 
974 {
975  return *sConfigPath();
976 }
977 
979 {
980  return qgisSettingsDirPath() + QStringLiteral( "qgis.db" );
981 }
982 
984 {
985  return *sAuthDbDirPath() + QStringLiteral( "qgis-auth.db" );
986 }
987 
989 {
990  return QStringLiteral( ":/images/splash/" );
991 }
992 
994 {
995  return pkgDataPath() + QStringLiteral( "/images/icons/" );
996 }
997 
999 {
1000  if ( ABISYM( mRunningFromBuildDir ) )
1001  {
1002 #if PROJ_VERSION_MAJOR>=6
1003  QString tempCopy = QDir::tempPath() + "/srs6.db";
1004 #else
1005  QString tempCopy = QDir::tempPath() + "/srs.db";
1006 #endif
1007 
1008  if ( !QFile( tempCopy ).exists() )
1009  {
1010 #if PROJ_VERSION_MAJOR>=6
1011  QFile f( buildSourcePath() + "/resources/srs6.db" );
1012 #else
1013  QFile f( buildSourcePath() + "/resources/srs.db" );
1014 #endif
1015  if ( !f.copy( tempCopy ) )
1016  {
1017  qFatal( "Could not create temporary copy" );
1018  }
1019  }
1020 
1021  return tempCopy;
1022  }
1023  else
1024  {
1025  return pkgDataPath() + QStringLiteral( "/resources/srs.db" );
1026  }
1027 }
1028 
1030 {
1031  //local directories to search when looking for an SVG with a given basename
1032  //defined by user in options dialog
1033  QgsSettings settings;
1034  const QStringList pathList = settings.value( QStringLiteral( "svg/searchPathsForSVG" ) ).toStringList();
1035 
1036  // maintain user set order while stripping duplicates
1037  QStringList paths;
1038  for ( const QString &path : pathList )
1039  {
1040  if ( !paths.contains( path ) )
1041  paths.append( path );
1042  }
1043  for ( const QString &path : qgis::as_const( *sDefaultSvgPaths() ) )
1044  {
1045  if ( !paths.contains( path ) )
1046  paths.append( path );
1047  }
1048 
1049  return paths;
1050 }
1051 
1053 {
1054  //local directories to search when looking for an template with a given basename
1055  //defined by user in options dialog
1056  QgsSettings settings;
1057  QStringList pathList = settings.value( QStringLiteral( "Layout/searchPathsForTemplates" ), QVariant(), QgsSettings::Core ).toStringList();
1058 
1059  return pathList;
1060 }
1061 
1062 QMap<QString, QString> QgsApplication::systemEnvVars()
1063 {
1064  return *sSystemEnvVars();
1065 }
1066 
1068 {
1069  return qgisSettingsDirPath() + QStringLiteral( "symbology-style.db" );
1070 }
1071 
1073 {
1074  return QRegExp( "^[A-Za-z][A-Za-z0-9\\._-]*" );
1075 }
1076 
1078 {
1079  if ( !sUserName()->isEmpty() )
1080  return *sUserName();
1081 
1082 #ifdef _MSC_VER
1083  TCHAR name [ UNLEN + 1 ];
1084  DWORD size = UNLEN + 1;
1085 
1086  if ( GetUserName( ( TCHAR * )name, &size ) )
1087  {
1088  *sUserName() = QString::fromLocal8Bit( name );
1089  }
1090 
1091 #elif QT_CONFIG(process)
1092  QProcess process;
1093 
1094  process.start( QStringLiteral( "whoami" ) );
1095  process.waitForFinished();
1096  *sUserName() = process.readAllStandardOutput().trimmed();
1097 #endif
1098 
1099  if ( !sUserName()->isEmpty() )
1100  return *sUserName();
1101 
1102  //backup plan - use environment variables
1103  *sUserName() = qgetenv( "USER" );
1104  if ( !sUserName()->isEmpty() )
1105  return *sUserName();
1106 
1107  //last resort
1108  *sUserName() = qgetenv( "USERNAME" );
1109  return *sUserName();
1110 }
1111 
1113 {
1114  if ( !sUserFullName()->isEmpty() )
1115  return *sUserFullName();
1116 
1117 #ifdef _MSC_VER
1118  TCHAR name [ UNLEN + 1 ];
1119  DWORD size = UNLEN + 1;
1120 
1121  //note - this only works for accounts connected to domain
1122  if ( GetUserNameEx( NameDisplay, ( TCHAR * )name, &size ) )
1123  {
1124  *sUserFullName() = QString::fromLocal8Bit( name );
1125  }
1126 
1127  //fall back to login name
1128  if ( sUserFullName()->isEmpty() )
1129  *sUserFullName() = userLoginName();
1130 #elif defined(Q_OS_ANDROID) || defined(__MINGW32__)
1131  *sUserFullName() = QStringLiteral( "Not available" );
1132 #else
1133  struct passwd *p = getpwuid( getuid() );
1134 
1135  if ( p )
1136  {
1137  QString gecosName = QString( p->pw_gecos );
1138  *sUserFullName() = gecosName.left( gecosName.indexOf( ',', 0 ) );
1139  }
1140 
1141 #endif
1142 
1143  return *sUserFullName();
1144 }
1145 
1147 {
1148 #if defined(Q_OS_ANDROID)
1149  return QLatin1String( "android" );
1150 #elif defined(Q_OS_MAC)
1151  return QLatin1String( "osx" );
1152 #elif defined(Q_OS_WIN)
1153  return QLatin1String( "windows" );
1154 #elif defined(Q_OS_LINUX)
1155  return QStringLiteral( "linux" );
1156 #elif defined(Q_OS_FREEBSD)
1157  return QStringLiteral( "freebsd" );
1158 #elif defined(Q_OS_OPENBSD)
1159  return QStringLiteral( "openbsd" );
1160 #elif defined(Q_OS_NETBSD)
1161  return QStringLiteral( "netbsd" );
1162 #elif defined(Q_OS_UNIX)
1163  return QLatin1String( "unix" );
1164 #else
1165  return QLatin1String( "unknown" );
1166 #endif
1167 }
1168 
1170 {
1171  return *sPlatformName();
1172 }
1173 
1175 {
1176  QgsSettings settings;
1177  bool overrideLocale = settings.value( QStringLiteral( "locale/overrideFlag" ), false ).toBool();
1178  if ( overrideLocale )
1179  {
1180  QString locale = settings.value( QStringLiteral( "locale/userLocale" ), QString() ).toString();
1181  // don't differentiate en_US and en_GB
1182  if ( locale.startsWith( QLatin1String( "en" ), Qt::CaseInsensitive ) )
1183  {
1184  return locale.left( 2 );
1185  }
1186 
1187  return locale;
1188  }
1189  else
1190  {
1191  return QLocale().name().left( 2 );
1192  }
1193 }
1194 
1196 {
1197  return qgisSettingsDirPath() + QStringLiteral( "/themes" );
1198 }
1199 
1201 {
1202  return pkgDataPath() + QStringLiteral( "/resources/symbology-style.xml" );
1203 }
1204 
1206 {
1207  return pkgDataPath() + QStringLiteral( "/resources/themes" );
1208 }
1209 
1211 {
1212  return pkgDataPath() + QStringLiteral( "/resources/server/" );
1213 }
1214 
1216 {
1217  return *sLibraryPath();
1218 }
1219 
1221 {
1222  return *sLibexecPath();
1223 }
1224 
1226 {
1227  return *sQmlImportPath();
1228 }
1229 
1231 {
1232  return ( htonl( 1 ) == 1 ) ? XDR : NDR;
1233 }
1234 
1236 {
1237  if ( !ABISYM( mInitialized ) && QgsApplication::instance() )
1238  {
1239  init( *sProfilePath() );
1240  }
1241 
1242  // set the provider plugin path (this creates provider registry)
1244 
1245  // create data item provider registry
1247 
1248  // create project instance if doesn't exist
1250 
1251  // Initialize authentication manager and connect to database
1253 
1254  // Make sure we have a NAM created on the main thread.
1255  // Note that this might call QgsApplication::authManager to
1256  // setup the proxy configuration that's why it needs to be
1257  // called after the QgsAuthManager instance has been created
1259 
1260 }
1261 
1262 
1264 {
1265  if ( instance() )
1266  {
1267  if ( !instance()->mAuthManager )
1268  {
1269  instance()->mAuthManager = QgsAuthManager::instance();
1270  }
1271  return instance()->mAuthManager;
1272  }
1273  else
1274  {
1275  // no QgsApplication instance
1276  if ( !sAuthManager )
1277  sAuthManager = QgsAuthManager::instance();
1278  return sAuthManager;
1279  }
1280 }
1281 
1282 
1284 {
1285  // make sure all threads are done before exiting
1286  QThreadPool::globalInstance()->waitForDone();
1287 
1288  // don't create to delete
1289  if ( instance() )
1290  delete instance()->mAuthManager;
1291  else
1292  delete sAuthManager;
1293 
1294  //Ensure that all remaining deleteLater QObjects are actually deleted before we exit.
1295  //This isn't strictly necessary (since we're exiting anyway) but doing so prevents a lot of
1296  //LeakSanitiser noise which hides real issues
1297  QgsApplication::sendPostedEvents( nullptr, QEvent::DeferredDelete );
1298 
1299  //delete all registered functions from expression engine (see above comment)
1301 
1302  delete QgsProject::instance();
1303 
1304  // avoid creating instance just to delete it!
1305  if ( QgsProviderRegistry::exists() )
1307 
1308  invalidateCaches();
1309 
1311 
1312  // tear-down GDAL/OGR
1313  OGRCleanupAll();
1314  GDALDestroyDriverManager();
1315 }
1316 
1318 {
1319  QString myEnvironmentVar( getenv( "QGIS_PREFIX_PATH" ) );
1320  QString myState = tr( "Application state:\n"
1321  "QGIS_PREFIX_PATH env var:\t\t%1\n"
1322  "Prefix:\t\t%2\n"
1323  "Plugin Path:\t\t%3\n"
1324  "Package Data Path:\t%4\n"
1325  "Active Theme Name:\t%5\n"
1326  "Active Theme Path:\t%6\n"
1327  "Default Theme Path:\t%7\n"
1328  "SVG Search Paths:\t%8\n"
1329  "User DB Path:\t%9\n"
1330  "Auth DB Path:\t%10\n" )
1331  .arg( myEnvironmentVar,
1332  prefixPath(),
1333  pluginPath(),
1334  pkgDataPath(),
1335  themeName(),
1336  activeThemePath(),
1337  defaultThemePath(),
1338  svgPaths().join( tr( "\n\t\t", "match indentation of application state" ) ),
1340  .arg( qgisAuthDatabaseFilePath() );
1341  return myState;
1342 }
1343 
1345 {
1346  //
1347  // Make the style sheet desktop preferences aware by using qapplication
1348  // palette as a basis for colors where appropriate
1349  //
1350  // QColor myColor1 = palette().highlight().color();
1351  QColor myColor1( Qt::lightGray );
1352  QColor myColor2 = myColor1;
1353  myColor2 = myColor2.lighter( 110 ); //10% lighter
1354  QString myStyle;
1355  myStyle = QStringLiteral( ".overview{"
1356  " font: 1.82em;"
1357  " font-weight: bold;"
1358  "}"
1359  "body{"
1360  " background: white;"
1361  " color: black;"
1362  " font-family: 'Lato', 'Ubuntu', 'Lucida Grande', 'Segoe UI', 'Arial', sans-serif;"
1363  " width: 100%;"
1364  "}"
1365  "h1{ background-color: #F6F6F6;"
1366  " color: #589632; " // from http://qgis.org/en/site/getinvolved/styleguide.html
1367  " font-size: x-large; "
1368  " font-weight: normal;"
1369  " background: none;"
1370  " padding: 0.75em 0 0;"
1371  " margin: 0;"
1372  " line-height: 3em;"
1373  "}"
1374  "h2{ background-color: #F6F6F6;"
1375  " color: #589632; " // from http://qgis.org/en/site/getinvolved/styleguide.html
1376  " font-size: medium; "
1377  " font-weight: normal;"
1378  " background: none;"
1379  " padding: 0.75em 0 0;"
1380  " margin: 0;"
1381  " line-height: 1.1em;"
1382  "}"
1383  "h3{ background-color: #F6F6F6;"
1384  " color: #93b023;" // from http://qgis.org/en/site/getinvolved/styleguide.html
1385  " font-weight: bold;"
1386  " font-size: large;"
1387  " text-align: left;"
1388  " border-bottom: 5px solid #DCEB5C;"
1389  "}"
1390  "h4{ background-color: #F6F6F6;"
1391  " color: #93b023;" // from http://qgis.org/en/site/getinvolved/styleguide.html
1392  " font-weight: bold;"
1393  " font-size: medium;"
1394  " text-align: left;"
1395  "}"
1396  "h5{ background-color: #F6F6F6;"
1397  " color: #93b023;" // from http://qgis.org/en/site/getinvolved/styleguide.html
1398  " font-weight: bold;"
1399  " font-size: small;"
1400  " text-align: left;"
1401  "}"
1402  "a{ color: #729FCF;"
1403  " font-family: arial,sans-serif;"
1404  "}"
1405  "label{ background-color: #FFFFCC;"
1406  " border: 1px solid black;"
1407  " margin: 1px;"
1408  " padding: 0px 3px; "
1409  " font-size: small;"
1410  "}"
1411  "th .strong {"
1412  " font-weight: bold;"
1413  "}"
1414  "hr {"
1415  " border: 0;"
1416  " height: 0;"
1417  " border-top: 1px solid black;"
1418  "}"
1419  ".list-view .highlight {"
1420  " text-align: left;"
1421  " border: 0px;"
1422  " width: 20%;"
1423  " padding-right: 15px;"
1424  " padding-left: 20px;"
1425  " font-weight: bold;"
1426  "}"
1427  ".tabular-view .odd-row {"
1428  " background-color: #f9f9f9;"
1429  "}"
1430  ".section {"
1431  " font-weight: bold;"
1432  " padding-top:25px;"
1433  "}" );
1434 
1435  // We have some subtle differences between Qt based style and QWebKit style
1436  switch ( styleSheetType )
1437  {
1438  case StyleSheetType::Qt:
1439  myStyle += QStringLiteral(
1440  ".tabular-view{ "
1441  " border-collapse: collapse;"
1442  " width: 95%;"
1443  "}"
1444  ".tabular-view th, .tabular-view td { "
1445  " border:10px solid black;"
1446  "}" );
1447  break;
1448 
1449  case StyleSheetType::WebBrowser:
1450  myStyle += QStringLiteral(
1451  "body { "
1452  " margin: auto;"
1453  " width: 97%;"
1454  "}"
1455  "table.tabular-view, table.list-view { "
1456  " border-collapse: collapse;"
1457  " table-layout:fixed;"
1458  " width: 100% !important;"
1459  " font-size: 90%;"
1460  "}"
1461  // Override
1462  "h1 { "
1463  " line-height: inherit;"
1464  "}"
1465  "td, th {"
1466  " word-wrap: break-word; "
1467  " vertical-align: top;"
1468  "}"
1469  // Set first column width
1470  ".list-view th:first-child, .list-view td:first-child {"
1471  " width: 20%;"
1472  "}"
1473  ".list-view.highlight { "
1474  " padding-left: inherit; "
1475  "}"
1476  // Set first column width for inner tables
1477  ".tabular-view th:first-child, .tabular-view td:first-child { "
1478  " width: 20%; "
1479  "}"
1480  // Makes titles bg stand up
1481  ".tabular-view th.strong { "
1482  " background-color: #eee; "
1483  "}"
1484  // Give some visual appearance to those ugly nested tables
1485  ".tabular-view th, .tabular-view td { "
1486  " border: solid 1px #eee;"
1487  "}"
1488  );
1489  break;
1490  }
1491 
1492  return myStyle;
1493 }
1494 
1496 {
1497  if ( 0 >= OGRGetDriverCount() )
1498  {
1499  OGRRegisterAll();
1500  }
1501 }
1502 
1503 QString QgsApplication::absolutePathToRelativePath( const QString &aPath, const QString &targetPath )
1504 {
1505  QString aPathUrl = aPath;
1506  QString tPathUrl = targetPath;
1507 #if defined( Q_OS_WIN )
1508  const Qt::CaseSensitivity cs = Qt::CaseInsensitive;
1509 
1510  aPathUrl.replace( '\\', '/' );
1511  if ( aPathUrl.startsWith( "//" ) )
1512  {
1513  // keep UNC prefix
1514  aPathUrl = "\\\\" + aPathUrl.mid( 2 );
1515  }
1516 
1517  tPathUrl.replace( '\\', '/' );
1518  if ( tPathUrl.startsWith( "//" ) )
1519  {
1520  // keep UNC prefix
1521  tPathUrl = "\\\\" + tPathUrl.mid( 2 );
1522  }
1523 #else
1524  const Qt::CaseSensitivity cs = Qt::CaseSensitive;
1525 #endif
1526 
1527  QStringList targetElems = tPathUrl.split( '/', QString::SkipEmptyParts );
1528  QStringList aPathElems = aPathUrl.split( '/', QString::SkipEmptyParts );
1529 
1530  targetElems.removeAll( QStringLiteral( "." ) );
1531  aPathElems.removeAll( QStringLiteral( "." ) );
1532 
1533  // remove common part
1534  int n = 0;
1535  while ( !aPathElems.isEmpty() &&
1536  !targetElems.isEmpty() &&
1537  aPathElems[0].compare( targetElems[0], cs ) == 0 )
1538  {
1539  aPathElems.removeFirst();
1540  targetElems.removeFirst();
1541  n++;
1542  }
1543 
1544  if ( n == 0 )
1545  {
1546  // no common parts; might not even be a file
1547  return aPathUrl;
1548  }
1549 
1550  if ( !targetElems.isEmpty() )
1551  {
1552  // go up to the common directory
1553  for ( int i = 0; i < targetElems.size(); i++ )
1554  {
1555  aPathElems.insert( 0, QStringLiteral( ".." ) );
1556  }
1557  }
1558  else
1559  {
1560  // let it start with . nevertheless,
1561  // so relative path always start with either ./ or ../
1562  aPathElems.insert( 0, QStringLiteral( "." ) );
1563  }
1564 
1565  return aPathElems.join( QStringLiteral( "/" ) );
1566 }
1567 
1568 QString QgsApplication::relativePathToAbsolutePath( const QString &rpath, const QString &targetPath )
1569 {
1570  // relative path should always start with ./ or ../
1571  if ( !rpath.startsWith( QLatin1String( "./" ) ) && !rpath.startsWith( QLatin1String( "../" ) ) )
1572  {
1573  return rpath;
1574  }
1575 
1576  QString rPathUrl = rpath;
1577  QString targetPathUrl = targetPath;
1578 
1579 #if defined(Q_OS_WIN)
1580  rPathUrl.replace( '\\', '/' );
1581  targetPathUrl.replace( '\\', '/' );
1582 
1583  bool uncPath = targetPathUrl.startsWith( "//" );
1584 #endif
1585 
1586  QStringList srcElems = rPathUrl.split( '/', QString::SkipEmptyParts );
1587  QStringList targetElems = targetPathUrl.split( '/', QString::SkipEmptyParts );
1588 
1589 #if defined(Q_OS_WIN)
1590  if ( uncPath )
1591  {
1592  targetElems.insert( 0, "" );
1593  targetElems.insert( 0, "" );
1594  }
1595 #endif
1596 
1597  // append source path elements
1598  targetElems << srcElems;
1599  targetElems.removeAll( QStringLiteral( "." ) );
1600 
1601  // resolve ..
1602  int pos;
1603  while ( ( pos = targetElems.indexOf( QStringLiteral( ".." ) ) ) > 0 )
1604  {
1605  // remove preceding element and ..
1606  targetElems.removeAt( pos - 1 );
1607  targetElems.removeAt( pos - 1 );
1608  }
1609 
1610 #if !defined(Q_OS_WIN)
1611  // make path absolute
1612  targetElems.prepend( QString() );
1613 #endif
1614 
1615  return targetElems.join( QStringLiteral( "/" ) );
1616 }
1617 
1619 {
1620  return *sBuildSourcePath();
1621 }
1622 
1624 {
1625  return *sBuildOutputPath();
1626 }
1627 
1628 #if defined(_MSC_VER) && !defined(USING_NMAKE) && !defined(USING_NINJA)
1629 QString QgsApplication::cfgIntDir()
1630 {
1631  return *sCfgIntDir();
1632 }
1633 #endif
1634 
1635 void QgsApplication::skipGdalDriver( const QString &driver )
1636 {
1637  if ( sGdalSkipList()->contains( driver ) || driver.isEmpty() )
1638  {
1639  return;
1640  }
1641  *sGdalSkipList() << driver;
1643 }
1644 
1645 void QgsApplication::restoreGdalDriver( const QString &driver )
1646 {
1647  if ( !sGdalSkipList()->contains( driver ) )
1648  {
1649  return;
1650  }
1651  int myPos = sGdalSkipList()->indexOf( driver );
1652  if ( myPos >= 0 )
1653  {
1654  sGdalSkipList()->removeAt( myPos );
1655  }
1657 }
1658 
1660 {
1661  return *sGdalSkipList();
1662 }
1663 
1665  const QStringList &deferredSkippedGdalDrivers )
1666 {
1667  *sGdalSkipList() = skippedGdalDrivers;
1668  *sDeferredSkippedGdalDrivers() = deferredSkippedGdalDrivers;
1669 
1670  QgsSettings settings;
1671  settings.setValue( QStringLiteral( "gdal/skipList" ), skippedGdalDrivers.join( QStringLiteral( " " ) ) );
1672 
1674 }
1675 
1677 {
1678  QgsSettings settings;
1679  QString joinedList = settings.value( QStringLiteral( "gdal/skipList" ), QString() ).toString();
1680  QStringList myList;
1681  if ( !joinedList.isEmpty() )
1682  {
1683  myList = joinedList.split( ' ' );
1684  }
1685  *sGdalSkipList() = myList;
1687 }
1688 
1690 {
1691  return *sDeferredSkippedGdalDrivers();
1692 }
1693 
1695 {
1696  sGdalSkipList()->removeDuplicates();
1697  QStringList realDisabledDriverList;
1698  for ( const auto &driverName : *sGdalSkipList() )
1699  {
1700  if ( !sDeferredSkippedGdalDrivers()->contains( driverName ) )
1701  realDisabledDriverList << driverName;
1702  }
1703  QString myDriverList = realDisabledDriverList.join( ' ' );
1704  QgsDebugMsgLevel( QStringLiteral( "Gdal Skipped driver list set to:" ), 2 );
1705  QgsDebugMsgLevel( myDriverList, 2 );
1706  CPLSetConfigOption( "GDAL_SKIP", myDriverList.toUtf8() );
1707  GDALAllRegister(); //to update driver list and skip missing ones
1708 }
1709 
1711 {
1712  QString folder = userThemesFolder();
1713  QDir myDir( folder );
1714  if ( !myDir.exists() )
1715  {
1716  myDir.mkpath( folder );
1717  }
1718 
1719  return true;
1720 }
1721 
1722 void QgsApplication::copyPath( const QString &src, const QString &dst )
1723 {
1724  QDir dir( src );
1725  if ( ! dir.exists() )
1726  return;
1727 
1728  const auto subDirectories = dir.entryList( QDir::Dirs | QDir::NoDotAndDotDot );
1729  for ( const QString &d : subDirectories )
1730  {
1731  QString dst_path = dst + QDir::separator() + d;
1732  dir.mkpath( dst_path );
1733  copyPath( src + QDir::separator() + d, dst_path );
1734  }
1735 
1736  const auto files = dir.entryList( QDir::Files );
1737  for ( const QString &f : files )
1738  {
1739  QFile::copy( src + QDir::separator() + f, dst + QDir::separator() + f );
1740  }
1741 }
1742 
1744 {
1745  //read values from QgsSettings
1746  QgsSettings settings;
1747 
1748  QVariantMap variables;
1749 
1750  //check if settings contains any variables
1751  settings.beginGroup( "variables" );
1752  QStringList childKeys = settings.childKeys();
1753  for ( QStringList::const_iterator it = childKeys.constBegin(); it != childKeys.constEnd(); ++it )
1754  {
1755  QString name = *it;
1756  variables.insert( name, settings.value( name ) );
1757  }
1758 
1759  return variables;
1760 }
1761 
1762 void QgsApplication::setCustomVariables( const QVariantMap &variables )
1763 {
1764  QgsSettings settings;
1765 
1766  QVariantMap::const_iterator it = variables.constBegin();
1767  settings.beginGroup( "variables" );
1768  settings.remove( "" );
1769  for ( ; it != variables.constEnd(); ++it )
1770  {
1771  settings.setValue( it.key(), it.value() );
1772  }
1773 
1774  emit instance()->customVariablesChanged();
1775 }
1776 
1777 void QgsApplication::setCustomVariable( const QString &name, const QVariant &value )
1778 {
1779  // save variable to settings
1780  QgsSettings settings;
1781 
1782  settings.setValue( QStringLiteral( "variables/" ) + name, value );
1783 
1784  emit instance()->customVariablesChanged();
1785 }
1786 
1788 {
1790 }
1791 
1792 void QgsApplication::setTranslation( const QString &translation )
1793 {
1794  *sTranslation() = translation;
1795 }
1796 
1798 {
1799  emit requestForTranslatableObjects( translationContext );
1800 }
1801 
1803 {
1804  ApplicationMembers *appMembers = members();
1805  if ( appMembers->mNullRepresentation.isNull() )
1806  {
1807  appMembers->mNullRepresentation = QgsSettings().value( QStringLiteral( "qgis/nullValue" ), QStringLiteral( "NULL" ) ).toString();
1808  }
1809  return appMembers->mNullRepresentation;
1810 }
1811 
1813 {
1814  ApplicationMembers *appMembers = members();
1815  if ( !appMembers || appMembers->mNullRepresentation == nullRepresentation )
1816  return;
1817 
1818  appMembers->mNullRepresentation = nullRepresentation;
1819  QgsSettings().setValue( QStringLiteral( "qgis/nullValue" ), nullRepresentation );
1820 
1821  QgsApplication *app = instance();
1822  if ( app )
1823  emit app->nullRepresentationChanged();
1824 }
1825 
1827 {
1828  return members()->mActionScopeRegistry;
1829 }
1830 
1831 bool QgsApplication::createDatabase( QString *errorMessage )
1832 {
1833  // set a working directory up for gdal to write .aux.xml files into
1834  // for cases where the raster dir is read only to the user
1835  // if the env var is already set it will be used preferentially
1836  QString myPamPath = qgisSettingsDirPath() + QStringLiteral( "gdal_pam/" );
1837  QDir myDir( myPamPath );
1838  if ( !myDir.exists() )
1839  {
1840  myDir.mkpath( myPamPath ); //fail silently
1841  }
1842 
1843 #if defined(Q_OS_WIN)
1844  CPLSetConfigOption( "GDAL_PAM_PROXY_DIR", myPamPath.toUtf8() );
1845 #else
1846  //under other OS's we use an environment var so the user can
1847  //override the path if he likes
1848  int myChangeFlag = 0; //whether we want to force the env var to change
1849  setenv( "GDAL_PAM_PROXY_DIR", myPamPath.toUtf8(), myChangeFlag );
1850 #endif
1851 
1852  // Check qgis.db and make private copy if necessary
1853  QFile qgisPrivateDbFile( QgsApplication::qgisUserDatabaseFilePath() );
1854 
1855  // first we look for ~/.qgis/qgis.db
1856  if ( !qgisPrivateDbFile.exists() )
1857  {
1858  // if it doesn't exist we copy it in from the global resources dir
1859  QString qgisMasterDbFileName = QgsApplication::qgisMasterDatabaseFilePath();
1860  QFile masterFile( qgisMasterDbFileName );
1861 
1862  // Must be sure there is destination directory ~/.qgis
1863  QDir().mkpath( QgsApplication::qgisSettingsDirPath() );
1864 
1865  //now copy the master file into the users .qgis dir
1866  bool isDbFileCopied = masterFile.copy( qgisPrivateDbFile.fileName() );
1867 
1868  if ( !isDbFileCopied )
1869  {
1870  if ( errorMessage )
1871  {
1872  *errorMessage = tr( "[ERROR] Can not make qgis.db private copy" );
1873  }
1874  return false;
1875  }
1876 
1877  QFile::Permissions perms = QFile( qgisPrivateDbFile.fileName() ).permissions();
1878  if ( !( perms & QFile::WriteOwner ) )
1879  {
1880  if ( !qgisPrivateDbFile.setPermissions( perms | QFile::WriteOwner ) )
1881  {
1882  if ( errorMessage )
1883  {
1884  *errorMessage = tr( "Can not make '%1' user writable" ).arg( qgisPrivateDbFile.fileName() );
1885  }
1886  return false;
1887  }
1888  }
1889  }
1890  else
1891  {
1892  // migrate if necessary
1893  sqlite3_database_unique_ptr database;
1894  if ( database.open( QgsApplication::qgisUserDatabaseFilePath() ) != SQLITE_OK )
1895  {
1896  if ( errorMessage )
1897  {
1898  *errorMessage = tr( "Could not open qgis.db" );
1899  }
1900  return false;
1901  }
1902 
1903  char *errmsg = nullptr;
1904  int res = sqlite3_exec( database.get(), "SELECT srs_id FROM tbl_srs LIMIT 0", nullptr, nullptr, &errmsg );
1905  if ( res != SQLITE_OK )
1906  {
1907  sqlite3_free( errmsg );
1908 
1909  // qgis.db is missing tbl_srs, create it
1910  if ( sqlite3_exec( database.get(),
1911  "DROP INDEX IF EXISTS idx_srsauthid;"
1912  "CREATE TABLE tbl_srs ("
1913  "srs_id INTEGER PRIMARY KEY,"
1914  "description text NOT NULL,"
1915  "projection_acronym text NOT NULL,"
1916  "ellipsoid_acronym NOT NULL,"
1917  "parameters text NOT NULL,"
1918  "srid integer,"
1919  "auth_name varchar,"
1920  "auth_id varchar,"
1921  "is_geo integer NOT NULL,"
1922  "deprecated boolean,"
1923  "wkt text);"
1924  "CREATE INDEX idx_srsauthid on tbl_srs(auth_name,auth_id);", nullptr, nullptr, &errmsg ) != SQLITE_OK )
1925  {
1926  if ( errorMessage )
1927  {
1928  *errorMessage = tr( "Creation of missing tbl_srs in the private qgis.db failed.\n%1" ).arg( QString::fromUtf8( errmsg ) );
1929  }
1930  sqlite3_free( errmsg );
1931  return false;
1932  }
1933  }
1934  else
1935  {
1936  // test if wkt column exists in database
1937  res = sqlite3_exec( database.get(), "SELECT wkt FROM tbl_srs LIMIT 0", nullptr, nullptr, &errmsg );
1938  if ( res != SQLITE_OK )
1939  {
1940  // need to add wkt column
1941  sqlite3_free( errmsg );
1942  if ( sqlite3_exec( database.get(),
1943  "DROP INDEX IF EXISTS idx_srsauthid;"
1944  "DROP TABLE IF EXISTS tbl_srs_bak;"
1945  "ALTER TABLE tbl_srs RENAME TO tbl_srs_bak;"
1946  "CREATE TABLE tbl_srs ("
1947  "srs_id INTEGER PRIMARY KEY,"
1948  "description text NOT NULL,"
1949  "projection_acronym text NOT NULL,"
1950  "ellipsoid_acronym NOT NULL,"
1951  "parameters text NOT NULL,"
1952  "srid integer,"
1953  "auth_name varchar,"
1954  "auth_id varchar,"
1955  "is_geo integer NOT NULL,"
1956  "deprecated boolean,"
1957  "wkt text);"
1958  "CREATE INDEX idx_srsauthid on tbl_srs(auth_name,auth_id);"
1959  "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;"
1960  "DROP TABLE tbl_srs_bak", nullptr, nullptr, &errmsg ) != SQLITE_OK )
1961  {
1962  if ( errorMessage )
1963  {
1964  *errorMessage = tr( "Migration of private qgis.db failed.\n%1" ).arg( QString::fromUtf8( errmsg ) );
1965  }
1966  sqlite3_free( errmsg );
1967  return false;
1968  }
1969  }
1970  }
1971 
1972  res = sqlite3_exec( database.get(), "SELECT acronym FROM tbl_projection LIMIT 0", nullptr, nullptr, &errmsg );
1973  if ( res != SQLITE_OK )
1974  {
1975  sqlite3_free( errmsg );
1976 
1977  // qgis.db is missing tbl_projection, create it
1978  if ( sqlite3_exec( database.get(),
1979  "CREATE TABLE tbl_projection ("
1980  "acronym varchar(20) NOT NULL PRIMARY KEY,"
1981  "name varchar(255) NOT NULL default '',"
1982  "notes varchar(255) NOT NULL default '',"
1983  "parameters varchar(255) NOT NULL default ''"
1984  ")", nullptr, nullptr, &errmsg ) != SQLITE_OK )
1985  {
1986  if ( errorMessage )
1987  {
1988  *errorMessage = tr( "Creation of missing tbl_projection in the private qgis.db failed.\n%1" ).arg( QString::fromUtf8( errmsg ) );
1989  }
1990  sqlite3_free( errmsg );
1991  return false;
1992  }
1993  }
1994 
1995  res = sqlite3_exec( database.get(), "SELECT epsg FROM tbl_srs LIMIT 0", nullptr, nullptr, &errmsg );
1996  if ( res == SQLITE_OK )
1997  {
1998  // epsg column exists => need migration
1999  if ( sqlite3_exec( database.get(),
2000  "DROP INDEX IF EXISTS idx_srsauthid;"
2001  "DROP TABLE IF EXISTS tbl_srs_bak;"
2002  "ALTER TABLE tbl_srs RENAME TO tbl_srs_bak;"
2003  "CREATE TABLE tbl_srs ("
2004  "srs_id INTEGER PRIMARY KEY,"
2005  "description text NOT NULL,"
2006  "projection_acronym text NOT NULL,"
2007  "ellipsoid_acronym NOT NULL,"
2008  "parameters text NOT NULL,"
2009  "srid integer,"
2010  "auth_name varchar,"
2011  "auth_id varchar,"
2012  "is_geo integer NOT NULL,"
2013  "deprecated boolean,"
2014  "wkt text);"
2015  "CREATE INDEX idx_srsauthid on tbl_srs(auth_name,auth_id);"
2016  "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;"
2017  "DROP TABLE tbl_srs_bak", nullptr, nullptr, &errmsg ) != SQLITE_OK )
2018  {
2019  if ( errorMessage )
2020  {
2021  *errorMessage = tr( "Migration of private qgis.db failed.\n%1" ).arg( QString::fromUtf8( errmsg ) );
2022  }
2023  sqlite3_free( errmsg );
2024  return false;
2025  }
2026  }
2027  else
2028  {
2029  sqlite3_free( errmsg );
2030  }
2031 
2032  if ( sqlite3_exec( database.get(), "DROP VIEW vw_srs", nullptr, nullptr, &errmsg ) != SQLITE_OK )
2033  {
2034  QgsDebugMsg( QStringLiteral( "vw_srs didn't exists in private qgis.db: %1" ).arg( errmsg ) );
2035  }
2036 
2037  if ( sqlite3_exec( database.get(),
2038  "CREATE VIEW vw_srs AS"
2039  " SELECT"
2040  " a.description AS description"
2041  ",a.srs_id AS srs_id"
2042  ",a.is_geo AS is_geo"
2043  ",coalesce(b.name,a.projection_acronym) AS name"
2044  ",a.parameters AS parameters"
2045  ",a.auth_name AS auth_name"
2046  ",a.auth_id AS auth_id"
2047  ",a.deprecated AS deprecated"
2048  " FROM tbl_srs a"
2049  " LEFT OUTER JOIN tbl_projection b ON a.projection_acronym=b.acronym"
2050  " ORDER BY coalesce(b.name,a.projection_acronym),a.description", nullptr, nullptr, &errmsg ) != SQLITE_OK )
2051  {
2052  if ( errorMessage )
2053  {
2054  *errorMessage = tr( "Update of view in private qgis.db failed.\n%1" ).arg( QString::fromUtf8( errmsg ) );
2055  }
2056  sqlite3_free( errmsg );
2057  return false;
2058  }
2059  }
2060  return true;
2061 }
2062 
2064 {
2065  QgsDebugMsgLevel( QStringLiteral( "maxThreads: %1" ).arg( maxThreads ), 2 );
2066 
2067  // make sure value is between 1 and #cores, if not set to -1 (use #cores)
2068  // 0 could be used to disable any parallel processing
2069  if ( maxThreads < 1 || maxThreads > QThread::idealThreadCount() )
2070  maxThreads = -1;
2071 
2072  // save value
2073  ABISYM( sMaxThreads ) = maxThreads;
2074 
2075  // if -1 use #cores
2076  if ( maxThreads == -1 )
2077  maxThreads = QThread::idealThreadCount();
2078 
2079  // set max thread count in QThreadPool
2080  QThreadPool::globalInstance()->setMaxThreadCount( maxThreads );
2081  QgsDebugMsgLevel( QStringLiteral( "set QThreadPool max thread count to %1" ).arg( QThreadPool::globalInstance()->maxThreadCount() ), 2 );
2082 }
2083 
2085 {
2086  return members()->mTaskManager;
2087 }
2088 
2090 {
2091  return members()->mColorSchemeRegistry;
2092 }
2093 
2095 {
2096  return members()->mPaintEffectRegistry;
2097 }
2098 
2100 {
2101  return members()->mRendererRegistry;
2102 }
2103 
2105 {
2106  return members()->mRasterRendererRegistry;
2107 }
2108 
2110 {
2111  if ( instance() )
2112  {
2113  if ( !instance()->mDataItemProviderRegistry )
2114  {
2115  instance()->mDataItemProviderRegistry = new QgsDataItemProviderRegistry();
2116  }
2117  return instance()->mDataItemProviderRegistry;
2118  }
2119  else
2120  {
2121  // no QgsApplication instance
2122  static QgsDataItemProviderRegistry *sDataItemProviderRegistry = nullptr;
2123  if ( !sDataItemProviderRegistry )
2124  sDataItemProviderRegistry = new QgsDataItemProviderRegistry();
2125  return sDataItemProviderRegistry;
2126  }
2127 }
2128 
2130 {
2131  return members()->mSvgCache;
2132 }
2133 
2135 {
2136  return members()->mImageCache;
2137 }
2138 
2140 {
2141  return members()->mNetworkContentFetcherRegistry;
2142 }
2143 
2145 {
2146  return members()->mValidityCheckRegistry;
2147 }
2148 
2150 {
2151  return members()->mSymbolLayerRegistry;
2152 }
2153 
2155 {
2156  return members()->mCalloutRegistry;
2157 }
2158 
2160 {
2161  return members()->mLayoutItemRegistry;
2162 }
2163 
2165 {
2166  return members()->mGpsConnectionRegistry;
2167 }
2168 
2170 {
2171  return members()->mPluginLayerRegistry;
2172 }
2173 
2175 {
2176  return members()->mClassificationMethodRegistry;
2177 }
2178 
2180 {
2181  return members()->mBookmarkManager;
2182 }
2183 
2185 {
2186  return members()->mStyleModel;
2187 }
2188 
2190 {
2191  return members()->mMessageLog;
2192 }
2193 
2195 {
2196  return members()->mProcessingRegistry;
2197 }
2198 
2200 {
2201  return members()->mConnectionRegistry;
2202 }
2203 
2205 {
2206  return members()->mPageSizeRegistry;
2207 }
2208 
2209 QgsAnnotationRegistry *QgsApplication::annotationRegistry()
2210 {
2211  return members()->mAnnotationRegistry;
2212 }
2213 
2215 {
2216  return members()->mNumericFormatRegistry;
2217 }
2218 
2220 {
2221  return members()->mFieldFormatterRegistry;
2222 }
2223 
2225 {
2226  return members()->m3DRendererRegistry;
2227 }
2228 
2230 {
2231  return members()->mScaleBarRendererRegistry;
2232 }
2233 
2235 {
2236  return members()->mProjectStorageRegistry;
2237 }
2238 
2240 {
2241  return members()->mLocalizedDataPathRegistry;
2242 }
2243 
2244 QgsApplication::ApplicationMembers::ApplicationMembers()
2245 {
2246  // don't use initializer lists or scoped pointers - as more objects are added here we
2247  // will need to be careful with the order of creation/destruction
2248  mLocalizedDataPathRegistry = new QgsLocalizedDataPathRegistry();
2249  mMessageLog = new QgsMessageLog();
2250  mProfiler = new QgsRuntimeProfiler();
2251 
2252  {
2253  mProfiler->start( tr( "Create connection registry" ) );
2254  mConnectionRegistry = new QgsConnectionRegistry();
2255  mProfiler->end();
2256  }
2257  {
2258  mProfiler->start( tr( "Setup task manager" ) );
2259  mTaskManager = new QgsTaskManager();
2260  mProfiler->end();
2261  }
2262  {
2263  mProfiler->start( tr( "Setup action scope registry" ) );
2264  mActionScopeRegistry = new QgsActionScopeRegistry();
2265  mProfiler->end();
2266  }
2267  {
2268  mProfiler->start( tr( "Setup numeric formats" ) );
2269  mNumericFormatRegistry = new QgsNumericFormatRegistry();
2270  mProfiler->end();
2271  }
2272  {
2273  mProfiler->start( tr( "Setup field formats" ) );
2274  mFieldFormatterRegistry = new QgsFieldFormatterRegistry();
2275  mProfiler->end();
2276  }
2277  {
2278  mProfiler->start( tr( "Setup SVG cache" ) );
2279  mSvgCache = new QgsSvgCache();
2280  mProfiler->end();
2281  }
2282  {
2283  mProfiler->start( tr( "Setup image cache" ) );
2284  mImageCache = new QgsImageCache();
2285  mProfiler->end();
2286  }
2287  {
2288  mProfiler->start( tr( "Setup color scheme registry" ) );
2289  mColorSchemeRegistry = new QgsColorSchemeRegistry();
2290  mProfiler->end();
2291  }
2292  {
2293  mProfiler->start( tr( "Setup paint effect" ) );
2294  mPaintEffectRegistry = new QgsPaintEffectRegistry();
2295  mProfiler->end();
2296  }
2297  {
2298  mProfiler->start( tr( "Setup symbol layer registry" ) );
2299  mSymbolLayerRegistry = new QgsSymbolLayerRegistry();
2300  mProfiler->end();
2301  }
2302  {
2303  mProfiler->start( tr( "Setup callout registry" ) );
2304  mCalloutRegistry = new QgsCalloutRegistry();
2305  mProfiler->end();
2306  }
2307  {
2308  mProfiler->start( tr( "Setup renderer registry" ) );
2309  mRendererRegistry = new QgsRendererRegistry();
2310  mProfiler->end();
2311  }
2312  {
2313  mProfiler->start( tr( "Setup raster renderer registry" ) );
2314  mRasterRendererRegistry = new QgsRasterRendererRegistry();
2315  mProfiler->end();
2316  }
2317  {
2318  mProfiler->start( tr( "Setup GPS registry" ) );
2319  mGpsConnectionRegistry = new QgsGpsConnectionRegistry();
2320  mProfiler->end();
2321  }
2322  {
2323  mProfiler->start( tr( "Setup plugin layer registry" ) );
2324  mPluginLayerRegistry = new QgsPluginLayerRegistry();
2325  mProfiler->end();
2326  }
2327  {
2328  mProfiler->start( tr( "Setup Processing registry" ) );
2329  mProcessingRegistry = new QgsProcessingRegistry();
2330  mProfiler->end();
2331  }
2332  mPageSizeRegistry = new QgsPageSizeRegistry();
2333  {
2334  mProfiler->start( tr( "Setup layout item registry" ) );
2335  mLayoutItemRegistry = new QgsLayoutItemRegistry();
2336  mLayoutItemRegistry->populate();
2337  mProfiler->end();
2338  }
2339  {
2340  mProfiler->start( tr( "Setup annotation registry" ) );
2341  mAnnotationRegistry = new QgsAnnotationRegistry();
2342  mProfiler->end();
2343  }
2344  {
2345  mProfiler->start( tr( "Setup 3D renderer registry" ) );
2346  m3DRendererRegistry = new Qgs3DRendererRegistry();
2347  mProfiler->end();
2348  }
2349  {
2350  mProfiler->start( tr( "Setup project storage registry" ) );
2351  mProjectStorageRegistry = new QgsProjectStorageRegistry();
2352  mProfiler->end();
2353  }
2354  {
2355  mProfiler->start( tr( "Setup network content cache" ) );
2356  mNetworkContentFetcherRegistry = new QgsNetworkContentFetcherRegistry();
2357  mProfiler->end();
2358  }
2359  {
2360  mProfiler->start( tr( "Setup layout check registry" ) );
2361  mValidityCheckRegistry = new QgsValidityCheckRegistry();
2362  mProfiler->end();
2363  }
2364  {
2365  mProfiler->start( tr( "Setup classification registry" ) );
2366  mClassificationMethodRegistry = new QgsClassificationMethodRegistry();
2367  mProfiler->end();
2368  }
2369  {
2370  mProfiler->start( tr( "Setup bookmark manager" ) );
2371  mBookmarkManager = new QgsBookmarkManager( nullptr );
2372  mProfiler->end();
2373  }
2374  {
2375  mProfiler->start( tr( "Setup scalebar registry" ) );
2376  mScaleBarRendererRegistry = new QgsScaleBarRendererRegistry();
2377  mProfiler->end();
2378  }
2379 }
2380 
2381 QgsApplication::ApplicationMembers::~ApplicationMembers()
2382 {
2383  delete mStyleModel;
2384  delete mScaleBarRendererRegistry;
2385  delete mValidityCheckRegistry;
2386  delete mActionScopeRegistry;
2387  delete m3DRendererRegistry;
2388  delete mAnnotationRegistry;
2389  delete mColorSchemeRegistry;
2390  delete mFieldFormatterRegistry;
2391  delete mGpsConnectionRegistry;
2392  delete mMessageLog;
2393  delete mPaintEffectRegistry;
2394  delete mPluginLayerRegistry;
2395  delete mProcessingRegistry;
2396  delete mProjectStorageRegistry;
2397  delete mPageSizeRegistry;
2398  delete mLayoutItemRegistry;
2399  delete mProfiler;
2400  delete mRasterRendererRegistry;
2401  delete mRendererRegistry;
2402  delete mSvgCache;
2403  delete mImageCache;
2404  delete mCalloutRegistry;
2405  delete mSymbolLayerRegistry;
2406  delete mTaskManager;
2407  delete mNetworkContentFetcherRegistry;
2408  delete mClassificationMethodRegistry;
2409  delete mNumericFormatRegistry;
2410  delete mBookmarkManager;
2411  delete mConnectionRegistry;
2412  delete mLocalizedDataPathRegistry;
2413 }
2414 
2415 QgsApplication::ApplicationMembers *QgsApplication::members()
2416 {
2417  if ( instance() )
2418  {
2419  return instance()->mApplicationMembers;
2420  }
2421  else
2422  {
2423  static QMutex sMemberMutex( QMutex::Recursive );
2424  QMutexLocker lock( &sMemberMutex );
2425  if ( !sApplicationMembers )
2426  sApplicationMembers = new ApplicationMembers();
2427  return sApplicationMembers;
2428  }
2429 }
static QStringList layoutTemplatePaths()
Returns the paths to layout template directories.
A QAbstractItemModel subclass for showing symbol and color ramp entities contained within a QgsStyle ...
Definition: qgsstylemodel.h:45
Singleton offering an interface to manage the authentication configuration database and to utilize co...
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 QString buildSourcePath()
Returns path to the source directory. Valid only when running from build directory.
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.
Q_GLOBAL_STATIC_WITH_ARGS(PalPropertyList, palHiddenProperties,({ QgsPalLayerSettings::PositionX, QgsPalLayerSettings::PositionY, QgsPalLayerSettings::Show, QgsPalLayerSettings::LabelRotation, QgsPalLayerSettings::Family, QgsPalLayerSettings::FontStyle, QgsPalLayerSettings::Size, QgsPalLayerSettings::Bold, QgsPalLayerSettings::Italic, QgsPalLayerSettings::Underline, QgsPalLayerSettings::Color, QgsPalLayerSettings::Strikeout, QgsPalLayerSettings::MultiLineAlignment, QgsPalLayerSettings::BufferSize, QgsPalLayerSettings::BufferDraw, QgsPalLayerSettings::BufferColor, QgsPalLayerSettings::LabelDistance, QgsPalLayerSettings::Hali, QgsPalLayerSettings::Vali, QgsPalLayerSettings::ScaleVisibility, QgsPalLayerSettings::MinScale, QgsPalLayerSettings::MaxScale, QgsPalLayerSettings::AlwaysShow, QgsPalLayerSettings::CalloutDraw, QgsPalLayerSettings::LabelAllParts })) QgsAuxiliaryLayer
static QgsCalloutRegistry * calloutRegistry()
Returns the application&#39;s callout registry, used for managing callout types.
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.
static void invalidateCache(bool disableCache=false)
Clears the internal cache used.
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.
Scoped object for logging of the runtime for a single operation or group of operations.
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 invalidateCache(bool disableCache=false)
Clears the internal cache used to initialize QgsCoordinateReferenceSystem objects.
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:182
A registry class to hold localized data paths which can be used for basemaps, logos, etc.
This class is a composition of two QSettings instances:
Definition: qgssettings.h:61
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 QgsImageCache * imageCache()
Returns the application&#39;s image cache, used for caching resampled versions of raster images...
static QgsValidityCheckRegistry * validityCheckRegistry()
Returns the application&#39;s validity check registry, used for managing validity checks.
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:107
static void invalidateCache(bool disableCache=false)
Clears the internal cache used to initialize QgsCoordinateTransform objects.
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 reportStyleSheet(QgsApplication::StyleSheetType styleSheetType=QgsApplication::StyleSheetType::Qt)
Returns a css style sheet for reports, the styleSheetType argument determines what type of stylesheet...
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 QgsNumericFormatRegistry * numericFormatRegistry()
Gets the registry of available numeric formats.
static QVariantMap customVariables()
Custom expression variables for this application.
Manages storage of a set of bookmarks.
The QgsFieldFormatterRegistry manages registered classes of QgsFieldFormatter.
This class keeps a list of QgsAbstractValidityCheck checks which can be used when performing validity...
Color/Value picker.
static void setFileOpenEventReceiver(QObject *receiver)
Sets the FileOpen event receiver.
static endian_t endian()
Returns whether this machine uses big or little endian.
QMap< QString, QString > QgsStringMap
Definition: qgis.h:704
static QStringList deferredSkippedGdalDrivers()
Returns the list of gdal drivers that have been disabled in the current session, and thus...
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 QgsStyle * defaultStyle()
Returns default application-wide style.
Definition: qgsstyle.cpp:111
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.
Q_GLOBAL_STATIC(QReadWriteLock, sDefinitionCacheLock)
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 setTranslation(const QString &translation)
Set translation.
static void cleanRegisteredFunctions()
Deletes all registered functions whose ownership have been transferred to the expression engine...
static QgsLocalizedDataPathRegistry * localizedDataPathRegistry()
Returns the registry of data repositories These are used as paths for basemaps, logos, etc.
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:140
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 int maxThreads()
Gets maximum concurrent thread count.
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
This class manages all known classification methods.
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 void setSkippedGdalDrivers(const QStringList &skippedGdalDrivers, const QStringList &deferredSkippedGdalDrivers)
Sets the list of gdal drivers that should be disabled (skippedGdalDrivers), but excludes for now the ...
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.
StyleSheetType
The StyleSheetType enum represents the stylesheet type that a widget supports.
static QStringList searchPaths()
Returns the current list of Proj file search paths.
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...
static QgsStyleModel * defaultStyleModel()
Returns a shared QgsStyleModel containing the default style library (see QgsStyle::defaultStyle()).
void beginGroup(const QString &prefix, QgsSettings::Section section=QgsSettings::NoSection)
Appends prefix to the current group.
Definition: qgssettings.cpp:87
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 QStringList skippedGdalDrivers()
Returns the list of gdal drivers that should be skipped (based on GDAL_SKIP environment variable) ...
static QString contributorsFilePath()
Returns the path to the contributors file.
static QString activeThemePath()
Returns the path to the currently active theme directory.
static QString buildOutputPath()
Returns path to the build output directory. Valid only when running from build directory.
The QgsScaleBarRendererRegistry manages registered scalebar renderers.
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.
The QgsNumericFormatRegistry manages registered classes of QgsNumericFormat.
static void setPluginPath(const QString &pluginPath)
Alters plugin path - used by 3rd party apps.
QgsUserProfile * getProfile(const QString &defaultProfile="default", bool createNew=true, bool initSettings=true)
Returns the profile from the given root profile location.
static QgsClassificationMethodRegistry * classificationMethodRegistry()
Returns the application&#39;s classification methods registry, used in graduated renderer.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:458
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...
Registry of available callout classes.
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 QgsBookmarkManager * bookmarkManager()
Returns the application&#39;s bookmark manager, used for storing installation-wide bookmarks.
static void exitQgis()
deletes provider registry and map layer registry
Temporarily blocks the application QgsMessageLog (see QgsApplication::messageLog()) from emitting the...
A cache for images derived from raster files.
Definition: qgsimagecache.h:96
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.
A registry for saved data provider connections, allowing retrieval of saved connections by name and p...
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 QgsConnectionRegistry * connectionRegistry()
Returns the application&#39;s connection registry, used for managing saved data provider connections...
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 void registerGdalDriversFromSettings()
Register gdal drivers, excluding the ones mentioned in "gdal/skipList" setting.
static QgsRendererRegistry * rendererRegistry()
Returns the application&#39;s renderer registry, used for managing vector layer renderers.
static QgsScaleBarRendererRegistry * scaleBarRendererRegistry()
Gets the registry of available scalebar 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.
void initialize(const QString &filePath)
initialize
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 QColor decodeColor(const QString &str)
static QString licenceFilePath()
Returns the path to the licence file.
static QMap< QString, QString > systemEnvVars()
Returns the system environment variables passed to application.
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.