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