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