QGIS API Documentation  2.99.0-Master (0a63d1f)
qgsapplication.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsapplication.cpp - Accessors for application-wide data
3  --------------------------------------
4  Date : 02-Jan-2006
5  Copyright : (C) 2006 by Tom Elwertowski
6  Email : telwertowski at users dot sourceforge dot net
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "qgsapplication.h"
17 #include "qgsauthmanager.h"
19 #include "qgsexception.h"
20 #include "qgsgeometry.h"
21 #include "qgslogger.h"
22 #include "qgsproject.h"
24 #include "qgsproviderregistry.h"
25 #include "qgsexpression.h"
26 #include "qgsactionscoperegistry.h"
27 #include "qgsruntimeprofiler.h"
28 #include "qgstaskmanager.h"
30 #include "qgssvgcache.h"
31 #include "qgscolorschemeregistry.h"
32 #include "qgspainteffectregistry.h"
34 #include "qgsrendererregistry.h"
35 #include "qgssymbollayerregistry.h"
37 #include "qgspluginlayerregistry.h"
38 #include "qgsmessagelog.h"
40 
41 #include <QDir>
42 #include <QFile>
43 #include <QFileInfo>
44 #include <QFileOpenEvent>
45 #include <QMessageBox>
46 #include <QPalette>
47 #include <QProcess>
48 #include <QSettings>
49 #include <QIcon>
50 #include <QPixmap>
51 #include <QThreadPool>
52 #include <QLocale>
53 
54 #ifndef Q_OS_WIN
55 #include <netinet/in.h>
56 #include <pwd.h>
57 #else
58 #include <winsock.h>
59 #include <windows.h>
60 #include <Lmcons.h>
61 #define SECURITY_WIN32
62 #include <Security.h>
63 #pragma comment( lib, "Secur32.lib" )
64 #endif
65 
66 #include "qgsconfig.h"
67 
68 #include <gdal.h>
69 #include <ogr_api.h>
70 #include <cpl_conv.h> // for setting gdal options
71 #include <sqlite3.h>
72 
73 QObject * ABISYM( QgsApplication::mFileOpenEventReceiver );
74 QStringList ABISYM( QgsApplication::mFileOpenEventList );
75 QString ABISYM( QgsApplication::mPrefixPath );
76 QString ABISYM( QgsApplication::mPluginPath );
77 QString ABISYM( QgsApplication::mPkgDataPath );
78 QString ABISYM( QgsApplication::mLibraryPath );
79 QString ABISYM( QgsApplication::mLibexecPath );
80 QString ABISYM( QgsApplication::mThemeName );
81 QString ABISYM( QgsApplication::mUIThemeName );
82 QStringList ABISYM( QgsApplication::mDefaultSvgPaths );
83 QMap<QString, QString> ABISYM( QgsApplication::mSystemEnvVars );
84 QString ABISYM( QgsApplication::mConfigPath );
85 bool ABISYM( QgsApplication::mRunningFromBuildDir ) = false;
86 QString ABISYM( QgsApplication::mBuildSourcePath );
87 #ifdef _MSC_VER
88 QString ABISYM( QgsApplication::mCfgIntDir );
89 #endif
90 QString ABISYM( QgsApplication::mBuildOutputPath );
91 QStringList ABISYM( QgsApplication::mGdalSkipList );
92 int ABISYM( QgsApplication::mMaxThreads );
93 QString ABISYM( QgsApplication::mAuthDbDirPath );
94 
95 QString QgsApplication::sUserName;
96 QString QgsApplication::sUserFullName;
97 QString QgsApplication::sPlatformName = QStringLiteral( "desktop" );
98 
99 const char* QgsApplication::QGIS_ORGANIZATION_NAME = "QGIS";
100 const char* QgsApplication::QGIS_ORGANIZATION_DOMAIN = "qgis.org";
101 const char* QgsApplication::QGIS_APPLICATION_NAME = "QGIS3";
102 
116 QgsApplication::QgsApplication( int & argc, char ** argv, bool GUIenabled, const QString& customConfigPath, const QString& platformName )
117  : QApplication( argc, argv, GUIenabled )
118 {
119  sPlatformName = platformName;
120 
121  // don't use initializer lists or scoped pointers - as more objects are added here we
122  // will need to be careful with the order of creation/destruction
123  mMessageLog = new QgsMessageLog();
124  mProfiler = new QgsRuntimeProfiler();
125  mTaskManager = new QgsTaskManager();
126  mActionScopeRegistry = new QgsActionScopeRegistry();
127  mFieldFormatterRegistry = new QgsFieldFormatterRegistry();
128  mSvgCache = new QgsSvgCache();
129  mColorSchemeRegistry = new QgsColorSchemeRegistry();
130  mColorSchemeRegistry->addDefaultSchemes();
131  mPaintEffectRegistry = new QgsPaintEffectRegistry();
132  mSymbolLayerRegistry = new QgsSymbolLayerRegistry();
133  mRendererRegistry = new QgsRendererRegistry();
134  mRasterRendererRegistry = new QgsRasterRendererRegistry();
135  mGpsConnectionRegistry = new QgsGPSConnectionRegistry();
136  mPluginLayerRegistry = new QgsPluginLayerRegistry();
137  mProcessingRegistry = new QgsProcessingRegistry();
138 
139  init( customConfigPath ); // init can also be called directly by e.g. unit tests that don't inherit QApplication.
140 }
141 
142 void QgsApplication::init( QString customConfigPath )
143 {
144  if ( customConfigPath.isEmpty() )
145  {
146  if ( getenv( "QGIS_CUSTOM_CONFIG_PATH" ) )
147  {
148  customConfigPath = getenv( "QGIS_CUSTOM_CONFIG_PATH" );
149  }
150  else
151  {
152  customConfigPath = QStringLiteral( "%1/.qgis3/" ).arg( QDir::homePath() );
153  }
154  }
155 
156  qRegisterMetaType<QgsGeometry::Error>( "QgsGeometry::Error" );
157 
158  QString prefixPath( getenv( "QGIS_PREFIX_PATH" ) ? getenv( "QGIS_PREFIX_PATH" ) : applicationDirPath() );
159  // QgsDebugMsg( QString( "prefixPath(): %1" ).arg( prefixPath ) );
160 
161  // check if QGIS is run from build directory (not the install directory)
162  QFile f;
163  // "/../../.." is for Mac bundled app in build directory
164  Q_FOREACH ( const QString& path, QStringList() << "" << "/.." << "/bin" << "/../../.." )
165  {
166  f.setFileName( prefixPath + path + "/qgisbuildpath.txt" );
167  if ( f.exists() )
168  break;
169  }
170  if ( f.exists() && f.open( QIODevice::ReadOnly ) )
171  {
172  ABISYM( mRunningFromBuildDir ) = true;
173  ABISYM( mBuildSourcePath ) = f.readLine().trimmed();
174  ABISYM( mBuildOutputPath ) = f.readLine().trimmed();
175  qDebug( "Running from build directory!" );
176  qDebug( "- source directory: %s", ABISYM( mBuildSourcePath ).toUtf8().data() );
177  qDebug( "- output directory of the build: %s", ABISYM( mBuildOutputPath ).toUtf8().data() );
178 #ifdef _MSC_VER
179  ABISYM( mCfgIntDir ) = prefixPath.split( '/', QString::SkipEmptyParts ).last();
180  qDebug( "- cfg: %s", ABISYM( mCfgIntDir ).toUtf8().data() );
181 #endif
182  }
183 
184  if ( ABISYM( mRunningFromBuildDir ) )
185  {
186  // we run from source directory - not installed to destination (specified prefix)
187  ABISYM( mPrefixPath ) = QString(); // set invalid path
188 #if defined(_MSC_VER) && !defined(USING_NMAKE) && !defined(USING_NINJA)
189  setPluginPath( ABISYM( mBuildOutputPath ) + '/' + QString( QGIS_PLUGIN_SUBDIR ) + '/' + ABISYM( mCfgIntDir ) );
190 #else
191  setPluginPath( ABISYM( mBuildOutputPath ) + '/' + QStringLiteral( QGIS_PLUGIN_SUBDIR ) );
192 #endif
193  setPkgDataPath( ABISYM( mBuildSourcePath ) ); // directly source path - used for: doc, resources, svg
194  ABISYM( mLibraryPath ) = ABISYM( mBuildOutputPath ) + '/' + QGIS_LIB_SUBDIR + '/';
195 #if defined(_MSC_VER) && !defined(USING_NMAKE) && !defined(USING_NINJA)
196  ABISYM( mLibexecPath ) = ABISYM( mBuildOutputPath ) + '/' + QGIS_LIBEXEC_SUBDIR + '/' + ABISYM( mCfgIntDir ) + '/';
197 #else
198  ABISYM( mLibexecPath ) = ABISYM( mBuildOutputPath ) + '/' + QGIS_LIBEXEC_SUBDIR + '/';
199 #endif
200  }
201  else
202  {
203  char *prefixPath = getenv( "QGIS_PREFIX_PATH" );
204  if ( !prefixPath )
205  {
206 #if defined(Q_OS_MACX) || defined(Q_OS_WIN)
207  setPrefixPath( applicationDirPath(), true );
208 #elif defined(ANDROID)
209  // this is "/data/data/org.qgis.qgis" in android
210  QDir myDir( QDir::homePath() );
211  myDir.cdUp();
212  QString myPrefix = myDir.absolutePath();
213  setPrefixPath( myPrefix, true );
214 #else
215  QDir myDir( applicationDirPath() );
216  myDir.cdUp();
217  QString myPrefix = myDir.absolutePath();
218  setPrefixPath( myPrefix, true );
219 #endif
220  }
221  else
222  {
223  setPrefixPath( prefixPath, true );
224  }
225  }
226 
227  if ( !customConfigPath.isEmpty() )
228  {
229  ABISYM( mConfigPath ) = customConfigPath + '/'; // make sure trailing slash is included
230  }
231 
232  ABISYM( mDefaultSvgPaths ) << qgisSettingsDirPath() + QStringLiteral( "svg/" );
233 
234  ABISYM( mAuthDbDirPath ) = qgisSettingsDirPath();
235  if ( getenv( "QGIS_AUTH_DB_DIR_PATH" ) )
236  {
237  setAuthDbDirPath( getenv( "QGIS_AUTH_DB_DIR_PATH" ) );
238  }
239 
240 
241  // store system environment variables passed to application, before they are adjusted
242  QMap<QString, QString> systemEnvVarMap;
243  QString passfile( QStringLiteral( "QGIS_AUTH_PASSWORD_FILE" ) ); // QString, for comparison
244  Q_FOREACH ( const QString &varStr, QProcess::systemEnvironment() )
245  {
246  int pos = varStr.indexOf( QLatin1Char( '=' ) );
247  if ( pos == -1 )
248  continue;
249  QString varStrName = varStr.left( pos );
250  QString varStrValue = varStr.mid( pos + 1 );
251  if ( varStrName != passfile )
252  {
253  systemEnvVarMap.insert( varStrName, varStrValue );
254  }
255  }
256  ABISYM( mSystemEnvVars ) = systemEnvVarMap;
257 
258  // allow Qt to search for Qt plugins (e.g. sqldrivers) in our plugin directory
259  QCoreApplication::addLibraryPath( pluginPath() );
260 
261  // set max. thread count to -1
262  // this should be read from QSettings but we don't know where they are at this point
263  // so we read actual value in main.cpp
264  ABISYM( mMaxThreads ) = -1;
265 }
266 
268 {
269  delete mProcessingRegistry;
270  delete mActionScopeRegistry;
271  delete mTaskManager;
272  delete mFieldFormatterRegistry;
273  delete mRasterRendererRegistry;
274  delete mRendererRegistry;
275  delete mSymbolLayerRegistry;
276  delete mPaintEffectRegistry;
277  delete mColorSchemeRegistry;
278  delete mSvgCache;
279  delete mGpsConnectionRegistry;
280  delete mPluginLayerRegistry;
281  delete mDataItemProviderRegistry;
282  delete mProfiler;
283  delete mMessageLog;
284 }
285 
287 {
288  return qobject_cast<QgsApplication*>( QCoreApplication::instance() );
289 }
290 
291 bool QgsApplication::event( QEvent * event )
292 {
293  bool done = false;
294  if ( event->type() == QEvent::FileOpen )
295  {
296  // handle FileOpen event (double clicking a file icon in Mac OS X Finder)
297  if ( ABISYM( mFileOpenEventReceiver ) )
298  {
299  // Forward event to main window.
300  done = notify( ABISYM( mFileOpenEventReceiver ), event );
301  }
302  else
303  {
304  // Store filename because receiver has not registered yet.
305  // If QGIS has been launched by double clicking a file icon, FileOpen will be
306  // the first event; the main window is not yet ready to handle the event.
307  ABISYM( mFileOpenEventList ).append( static_cast<QFileOpenEvent *>( event )->file() );
308  done = true;
309  }
310  }
311  else
312  {
313  // pass other events to base class
314  done = QApplication::event( event );
315  }
316  return done;
317 }
318 
319 bool QgsApplication::notify( QObject * receiver, QEvent * event )
320 {
321  bool done = false;
322  // Crashes in customization (especially on Mac), if we're not in the main/UI thread, see #5597
323  if ( thread() == receiver->thread() )
324  emit preNotify( receiver, event, &done );
325 
326  if ( done )
327  return true;
328 
329  // Send event to receiver and catch unhandled exceptions
330  done = true;
331  try
332  {
333  done = QApplication::notify( receiver, event );
334  }
335  catch ( QgsException & e )
336  {
337  QgsDebugMsg( "Caught unhandled QgsException: " + e.what() );
338  if ( qApp->thread() == QThread::currentThread() )
339  QMessageBox::critical( activeWindow(), tr( "Exception" ), e.what() );
340  }
341  catch ( std::exception & e )
342  {
343  QgsDebugMsg( "Caught unhandled std::exception: " + QString::fromAscii( e.what() ) );
344  if ( qApp->thread() == QThread::currentThread() )
345  QMessageBox::critical( activeWindow(), tr( "Exception" ), e.what() );
346  }
347  catch ( ... )
348  {
349  QgsDebugMsg( "Caught unhandled unknown exception" );
350  if ( qApp->thread() == QThread::currentThread() )
351  QMessageBox::critical( activeWindow(), tr( "Exception" ), tr( "unknown exception" ) );
352  }
353 
354  return done;
355 }
356 
358 {
359  return instance()->mProfiler;
360 }
361 
363 {
364  // Set receiver for FileOpen events
365  ABISYM( mFileOpenEventReceiver ) = receiver;
366  // Propagate any events collected before the receiver has registered.
367  if ( ABISYM( mFileOpenEventList ).count() > 0 )
368  {
369  QStringListIterator i( ABISYM( mFileOpenEventList ) );
370  while ( i.hasNext() )
371  {
372  QFileOpenEvent foe( i.next() );
373  QgsApplication::sendEvent( ABISYM( mFileOpenEventReceiver ), &foe );
374  }
375  ABISYM( mFileOpenEventList ).clear();
376  }
377 }
378 
379 void QgsApplication::setPrefixPath( const QString &thePrefixPath, bool useDefaultPaths )
380 {
381  ABISYM( mPrefixPath ) = thePrefixPath;
382 #if defined(_MSC_VER)
383  if ( ABISYM( mPrefixPath ).endsWith( "/bin" ) )
384  {
385  ABISYM( mPrefixPath ).chop( 4 );
386  }
387 #endif
388  if ( useDefaultPaths && !ABISYM( mRunningFromBuildDir ) )
389  {
390  setPluginPath( ABISYM( mPrefixPath ) + '/' + QStringLiteral( QGIS_PLUGIN_SUBDIR ) );
391  setPkgDataPath( ABISYM( mPrefixPath ) + '/' + QStringLiteral( QGIS_DATA_SUBDIR ) );
392  }
393  ABISYM( mLibraryPath ) = ABISYM( mPrefixPath ) + '/' + QGIS_LIB_SUBDIR + '/';
394  ABISYM( mLibexecPath ) = ABISYM( mPrefixPath ) + '/' + QGIS_LIBEXEC_SUBDIR + '/';
395 }
396 
397 void QgsApplication::setPluginPath( const QString &thePluginPath )
398 {
399  ABISYM( mPluginPath ) = thePluginPath;
400 }
401 
402 void QgsApplication::setPkgDataPath( const QString &thePkgDataPath )
403 {
404  ABISYM( mPkgDataPath ) = thePkgDataPath;
405  QString mySvgPath = thePkgDataPath + ( ABISYM( mRunningFromBuildDir ) ? "/images/svg/" : "/svg/" );
406  // avoid duplicate entries
407  if ( !ABISYM( mDefaultSvgPaths ).contains( mySvgPath ) )
408  ABISYM( mDefaultSvgPaths ) << mySvgPath;
409 }
410 
411 void QgsApplication::setDefaultSvgPaths( const QStringList& pathList )
412 {
413  ABISYM( mDefaultSvgPaths ) = pathList;
414 }
415 
416 void QgsApplication::setAuthDbDirPath( const QString& theAuthDbDirPath )
417 {
418  QFileInfo fi( theAuthDbDirPath );
419  if ( fi.exists() && fi.isDir() && fi.isWritable() )
420  {
421  ABISYM( mAuthDbDirPath ) = fi.canonicalFilePath() + QDir::separator();
422  }
423 }
424 
426 {
427  if ( ABISYM( mRunningFromBuildDir ) )
428  {
429  static bool sOnce = true;
430  if ( sOnce )
431  qWarning( "!!! prefix path was requested, but it is not valid - we do not run from installed path !!!" );
432  sOnce = false;
433  }
434 
435  return ABISYM( mPrefixPath );
436 }
438 {
439  return ABISYM( mPluginPath );
440 }
442 {
443  return ABISYM( mPkgDataPath );
444 }
446 {
447  return QStringLiteral( ":/images/themes/default/" );
448 }
450 {
451  return userThemesFolder() + QDir::separator() + themeName() + QDir::separator() + "icons/";
452 }
453 
455 {
456  return iconsPath() + QStringLiteral( "qgis-icon-60x60.png" );
457 }
458 
459 QString QgsApplication::iconPath( const QString& iconFile )
460 {
461  // try active theme
462  QString path = activeThemePath();
463  if ( QFile::exists( path + iconFile ) )
464  return path + iconFile;
465 
466  // use default theme
467  return defaultThemePath() + iconFile;
468 }
469 
470 QIcon QgsApplication::getThemeIcon( const QString &theName )
471 {
472  QgsApplication* app = instance();
473  if ( app && app->mIconCache.contains( theName ) )
474  return app->mIconCache.value( theName );
475 
476  QIcon icon;
477 
478  QString myPreferredPath = activeThemePath() + QDir::separator() + theName;
479  QString myDefaultPath = defaultThemePath() + QDir::separator() + theName;
480  if ( QFile::exists( myPreferredPath ) )
481  {
482  icon = QIcon( myPreferredPath );
483  }
484  else if ( QFile::exists( myDefaultPath ) )
485  {
486  //could still return an empty icon if it
487  //doesn't exist in the default theme either!
488  icon = QIcon( myDefaultPath );
489  }
490  else
491  {
492  icon = QIcon();
493  }
494 
495  if ( app )
496  app->mIconCache.insert( theName, icon );
497  return icon;
498 }
499 
500 // TODO: add some caching mechanism ?
501 QPixmap QgsApplication::getThemePixmap( const QString &theName )
502 {
503  QString myPreferredPath = activeThemePath() + QDir::separator() + theName;
504  QString myDefaultPath = defaultThemePath() + QDir::separator() + theName;
505  if ( QFile::exists( myPreferredPath ) )
506  {
507  return QPixmap( myPreferredPath );
508  }
509  else
510  {
511  //could still return an empty icon if it
512  //doesn't exist in the default theme either!
513  return QPixmap( myDefaultPath );
514  }
515 }
516 
520 void QgsApplication::setThemeName( const QString &theThemeName )
521 {
522  ABISYM( mThemeName ) = theThemeName;
523 }
528 {
529  return ABISYM( mThemeName );
530 }
531 
532 void QgsApplication::setUITheme( const QString &themeName )
533 {
534  // Loop all style sheets, find matching name, load it.
535  QHash<QString, QString> themes = QgsApplication::uiThemes();
536  QString themename = themeName;
537  if ( !themes.contains( themename ) )
538  themename = QStringLiteral( "default" );
539 
540  QString path = themes[themename];
541  QString stylesheetname = path + "/style.qss";
542  QString autostylesheet = stylesheetname + ".auto";
543 
544  QFile file( stylesheetname );
545  QFile variablesfile( path + "/variables.qss" );
546  QFile fileout( autostylesheet );
547 
548  QFileInfo variableInfo( variablesfile );
549 
550  if ( variableInfo.exists() && variablesfile.open( QIODevice::ReadOnly ) )
551  {
552  if ( !file.open( QIODevice::ReadOnly ) || !fileout.open( QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate ) )
553  {
554  return;
555  }
556 
557  QHash<QString, QString> variables;
558  QString styledata = file.readAll();
559  QTextStream in( &variablesfile );
560  while ( !in.atEnd() )
561  {
562  QString line = in.readLine();
563  // This is is a variable
564  if ( line.startsWith( '@' ) )
565  {
566  int index = line.indexOf( ':' );
567  QString name = line.mid( 0, index );
568  QString value = line.mid( index + 1, line.length() );
569  styledata.replace( name, value );
570  }
571  }
572  variablesfile.close();
573  QTextStream out( &fileout );
574  out << styledata;
575  fileout.close();
576  file.close();
577  stylesheetname = autostylesheet;
578  }
579 
580  QString styleSheet = QStringLiteral( "file:///" );
581  styleSheet.append( stylesheetname );
582  qApp->setStyleSheet( styleSheet );
583  setThemeName( themename );
584 }
585 
586 QHash<QString, QString> QgsApplication::uiThemes()
587 {
588  QStringList paths = QStringList() << userThemesFolder();
589  QHash<QString, QString> mapping;
590  mapping.insert( QStringLiteral( "default" ), QLatin1String( "" ) );
591  Q_FOREACH ( const QString& path, paths )
592  {
593  QDir folder( path );
594  QFileInfoList styleFiles = folder.entryInfoList( QDir::Dirs | QDir::NoDotAndDotDot );
595  Q_FOREACH ( const QFileInfo& info, styleFiles )
596  {
597  QFileInfo styleFile( info.absoluteFilePath() + "/style.qss" );
598  if ( !styleFile.exists() )
599  continue;
600 
601  QString name = info.baseName();
602  QString path = info.absoluteFilePath();
603  mapping.insert( name, path );
604  }
605  }
606  return mapping;
607 }
608 
613 {
614  return ABISYM( mPkgDataPath ) + QStringLiteral( "/doc/AUTHORS" );
615 }
620 {
621  return ABISYM( mPkgDataPath ) + QStringLiteral( "/doc/CONTRIBUTORS" );
622 }
624 {
625  return ABISYM( mPkgDataPath ) + QStringLiteral( "/doc/developersmap.html" );
626 }
627 
632 {
633  return ABISYM( mPkgDataPath ) + QStringLiteral( "/doc/SPONSORS" );
634 }
635 
640 {
641  return ABISYM( mPkgDataPath ) + QStringLiteral( "/doc/DONORS" );
642 }
643 
646 {
647  return ABISYM( mPkgDataPath ) + QStringLiteral( "/doc/TRANSLATORS" );
648 }
649 
652 {
653  return ABISYM( mPkgDataPath ) + QStringLiteral( "/doc/LICENSE" );
654 }
655 
660 {
661  QString helpAppPath;
662 #ifdef Q_OS_MACX
663  helpAppPath = applicationDirPath() + "/bin/qgis_help.app/Contents/MacOS";
664 #else
665  helpAppPath = libexecPath();
666 #endif
667  helpAppPath += QLatin1String( "/qgis_help" );
668 #ifdef Q_OS_WIN
669  helpAppPath += ".exe";
670 #endif
671  return helpAppPath;
672 }
677 {
678  if ( ABISYM( mRunningFromBuildDir ) )
679  return ABISYM( mBuildOutputPath ) + QStringLiteral( "/i18n" );
680  else
681  return ABISYM( mPkgDataPath ) + QStringLiteral( "/i18n/" );
682 }
683 
688 {
689  return ABISYM( mPkgDataPath ) + QStringLiteral( "/resources/qgis.db" );
690 }
691 
696 {
697  return ABISYM( mConfigPath );
698 }
699 
704 {
705  return qgisSettingsDirPath() + QStringLiteral( "qgis.db" );
706 }
707 
712 {
713  return ABISYM( mAuthDbDirPath ) + QStringLiteral( "qgis-auth.db" );
714 }
715 
720 {
721  return QStringLiteral( ":/images/splash/" );
722 }
723 
728 {
729  return ABISYM( mPkgDataPath ) + QStringLiteral( "/images/icons/" );
730 }
735 {
736  if ( ABISYM( mRunningFromBuildDir ) )
737  {
738  QString tempCopy = QDir::tempPath() + "/srs.db";
739 
740  if ( !QFile( tempCopy ).exists() )
741  {
742  QFile f( ABISYM( mPkgDataPath ) + "/resources/srs.db" );
743  if ( !f.copy( tempCopy ) )
744  {
745  qFatal( "Could not create temporary copy" );
746  }
747  }
748 
749  return tempCopy;
750  }
751  else
752  {
753  return ABISYM( mPkgDataPath ) + QStringLiteral( "/resources/srs.db" );
754  }
755 }
756 
761 {
762  //local directories to search when looking for an SVG with a given basename
763  //defined by user in options dialog
764  QSettings settings;
765  QStringList pathList = settings.value( QStringLiteral( "svg/searchPathsForSVG" ) ).toStringList();
766 
767  // maintain user set order while stripping duplicates
768  QStringList paths;
769  Q_FOREACH ( const QString& path, pathList )
770  {
771  if ( !paths.contains( path ) )
772  paths.append( path );
773  }
774  Q_FOREACH ( const QString& path, ABISYM( mDefaultSvgPaths ) )
775  {
776  if ( !paths.contains( path ) )
777  paths.append( path );
778  }
779 
780  return paths;
781 }
782 
787 {
788  //local directories to search when looking for an SVG with a given basename
789  //defined by user in options dialog
790  QSettings settings;
791  QStringList pathList = settings.value( QStringLiteral( "composer/searchPathsForTemplates" ) ).toStringList();
792 
793  return pathList;
794 }
795 
797 {
798  return qgisSettingsDirPath() + QStringLiteral( "symbology-ng-style.db" );
799 }
800 
802 {
803  return QRegExp( "^[A-Za-z][A-Za-z0-9\\._-]*" );
804 }
805 
807 {
808  if ( !sUserName.isEmpty() )
809  return sUserName;
810 
811 #ifdef Q_OS_WIN
812  TCHAR name [ UNLEN + 1 ];
813  DWORD size = UNLEN + 1;
814 
815  if ( GetUserName(( TCHAR* )name, &size ) )
816  {
817  sUserName = QString( name );
818  }
819 
820 #else
821  QProcess process;
822 
823  process.start( QStringLiteral( "whoami" ) );
824  process.waitForFinished();
825  sUserName = process.readAllStandardOutput().trimmed();
826 #endif
827 
828  if ( !sUserName.isEmpty() )
829  return sUserName;
830 
831  //backup plan - use environment variables
832  sUserName = qgetenv( "USER" );
833  if ( !sUserName.isEmpty() )
834  return sUserName;
835 
836  //last resort
837  sUserName = qgetenv( "USERNAME" );
838  return sUserName;
839 }
840 
842 {
843  if ( !sUserFullName.isEmpty() )
844  return sUserFullName;
845 
846 #ifdef Q_OS_WIN
847  TCHAR name [ UNLEN + 1 ];
848  DWORD size = UNLEN + 1;
849 
850  //note - this only works for accounts connected to domain
851  if ( GetUserNameEx( NameDisplay, ( TCHAR* )name, &size ) )
852  {
853  sUserFullName = QString( name );
854  }
855 
856  //fall back to login name
857  if ( sUserFullName.isEmpty() )
858  sUserFullName = userLoginName();
859 #elif defined(Q_OS_ANDROID)
860  sUserFullName = "Not available";
861 #else
862  struct passwd *p = getpwuid( getuid() );
863 
864  if ( p )
865  {
866  QString gecosName = QString( p->pw_gecos );
867  sUserFullName = gecosName.left( gecosName.indexOf( ',', 0 ) );
868  }
869 
870 #endif
871 
872  return sUserFullName;
873 }
874 
876 {
877 #if defined(Q_OS_ANDROID)
878  return QLatin1String( "android" );
879 #elif defined(Q_OS_MAC)
880  return QLatin1String( "osx" );
881 #elif defined(Q_OS_WIN)
882  return QLatin1String( "windows" );
883 #elif defined(Q_OS_LINUX)
884  return QStringLiteral( "linux" );
885 #else
886  return QLatin1String( "unknown" );
887 #endif
888 }
889 
891 {
892  return sPlatformName;
893 }
894 
896 {
897  QSettings settings;
898  bool overrideLocale = settings.value( QStringLiteral( "locale/overrideFlag" ), false ).toBool();
899  if ( overrideLocale )
900  {
901  return settings.value( QStringLiteral( "locale/userLocale" ), QString() ).toString();
902  }
903  else
904  {
905  return QLocale::system().name().left( 2 );
906  }
907 }
908 
910 {
911  return qgisSettingsDirPath() + QStringLiteral( "/themes" );
912 }
913 
915 {
916  return ABISYM( mPkgDataPath ) + QStringLiteral( "/resources/symbology-ng-style.xml" );
917 }
918 
920 {
921  return ABISYM( mPkgDataPath ) + QStringLiteral( "/resources/themes" );
922 }
923 
925 {
926  return ABISYM( mLibraryPath );
927 }
928 
930 {
931  return ABISYM( mLibexecPath );
932 }
933 
935 {
936  return ( htonl( 1 ) == 1 ) ? XDR : NDR;
937 }
938 
940 {
941  // set the provider plugin path (this creates provider registry)
943 
944  instance()->mDataItemProviderRegistry = new QgsDataItemProviderRegistry();
945 
946  // create project instance if doesn't exist
948 
949  // Make sure we have a NAM created on the main thread.
951 
952  // initialize authentication manager and connect to database
954 }
955 
957 {
958  delete QgsAuthManager::instance();
959 
960  //Ensure that all remaining deleteLater QObjects are actually deleted before we exit.
961  //This isn't strictly necessary (since we're exiting anyway) but doing so prevents a lot of
962  //LeakSanitiser noise which hides real issues
963  QgsApplication::sendPostedEvents( nullptr, QEvent::DeferredDelete );
964 
966 
967  //delete all registered functions from expression engine (see above comment)
969 
970  // tear-down GDAL/OGR
971  OGRCleanupAll();
972  GDALDestroyDriverManager();
973 }
974 
976 {
977  QString myEnvironmentVar( getenv( "QGIS_PREFIX_PATH" ) );
978  QString myState = tr( "Application state:\n"
979  "QGIS_PREFIX_PATH env var:\t\t%1\n"
980  "Prefix:\t\t%2\n"
981  "Plugin Path:\t\t%3\n"
982  "Package Data Path:\t%4\n"
983  "Active Theme Name:\t%5\n"
984  "Active Theme Path:\t%6\n"
985  "Default Theme Path:\t%7\n"
986  "SVG Search Paths:\t%8\n"
987  "User DB Path:\t%9\n"
988  "Auth DB Path:\t%10\n" )
989  .arg( myEnvironmentVar,
990  prefixPath(),
991  pluginPath(),
992  pkgDataPath(),
993  themeName(),
994  activeThemePath(),
996  svgPaths().join( tr( "\n\t\t", "match indentation of application state" ) ),
998  .arg( qgisAuthDbFilePath() );
999  return myState;
1000 }
1001 
1003 {
1004  //
1005  // Make the style sheet desktop preferences aware by using qappliation
1006  // palette as a basis for colors where appropriate
1007  //
1008 // QColor myColor1 = palette().highlight().color();
1009  QColor myColor1( Qt::lightGray );
1010  QColor myColor2 = myColor1;
1011  myColor2 = myColor2.lighter( 110 ); //10% lighter
1012  QString myStyle;
1013  myStyle = "p.glossy{ background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, "
1014  " stop: 0 " + myColor1.name() + ","
1015  " stop: 0.1 " + myColor2.name() + ","
1016  " stop: 0.5 " + myColor1.name() + ","
1017  " stop: 0.9 " + myColor2.name() + ","
1018  " stop: 1 " + myColor1.name() + ");"
1019  " color: black;"
1020  " padding-left: 4px;"
1021  " padding-top: 20px;"
1022  " padding-bottom: 8px;"
1023  " border: 1px solid #6c6c6c;"
1024  "}"
1025  "p.subheaderglossy{ background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, "
1026  " stop: 0 " + myColor1.name() + ","
1027  " stop: 0.1 " + myColor2.name() + ","
1028  " stop: 0.5 " + myColor1.name() + ","
1029  " stop: 0.9 " + myColor2.name() + ","
1030  " stop: 1 " + myColor1.name() + ");"
1031  " font-weight: bold;"
1032  " font-size: medium;"
1033  " line-height: 1.1em;"
1034  " width: 100%;"
1035  " color: black;"
1036  " padding-left: 4px;"
1037  " padding-right: 4px;"
1038  " padding-top: 20px;"
1039  " padding-bottom: 8px;"
1040  " border: 1px solid #6c6c6c;"
1041  "}"
1042  "th.glossy{ background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, "
1043  " stop: 0 " + myColor1.name() + ","
1044  " stop: 0.1 " + myColor2.name() + ","
1045  " stop: 0.5 " + myColor1.name() + ","
1046  " stop: 0.9 " + myColor2.name() + ","
1047  " stop: 1 " + myColor1.name() + ");"
1048  " color: black;"
1049  " border: 1px solid #6c6c6c;"
1050  "}"
1051  ".overview{ font: 1.82em; font-weight: bold;}"
1052  "body{ background: white;"
1053  " color: black;"
1054  " font-family: arial,sans-serif;"
1055  "}"
1056  "h1{ background-color: #F6F6F6;"
1057  " color: #8FB171; "
1058  " font-size: x-large; "
1059  " font-weight: normal;"
1060  " font-family: luxi serif, georgia, times new roman, times, serif;"
1061  " background: none;"
1062  " padding: 0.75em 0 0;"
1063  " margin: 0;"
1064  " line-height: 3em;"
1065  "}"
1066  "h2{ background-color: #F6F6F6;"
1067  " color: #8FB171; "
1068  " font-size: medium; "
1069  " font-weight: normal;"
1070  " font-family: luxi serif, georgia, times new roman, times, serif;"
1071  " background: none;"
1072  " padding: 0.75em 0 0;"
1073  " margin: 0;"
1074  " line-height: 1.1em;"
1075  "}"
1076  "h3{ background-color: #F6F6F6;"
1077  " color: #729FCF;"
1078  " font-family: luxi serif, georgia, times new roman, times, serif;"
1079  " font-weight: bold;"
1080  " font-size: large;"
1081  " text-align: right;"
1082  " border-bottom: 5px solid #DCEB5C;"
1083  "}"
1084  "h4{ background-color: #F6F6F6;"
1085  " color: #729FCF;"
1086  " font-family: luxi serif, georgia, times new roman, times, serif;"
1087  " font-weight: bold;"
1088  " font-size: medium;"
1089  " text-align: right;"
1090  "}"
1091  "h5{ background-color: #F6F6F6;"
1092  " color: #729FCF;"
1093  " font-family: luxi serif, georgia, times new roman, times, serif;"
1094  " font-weight: bold;"
1095  " font-size: small;"
1096  " text-align: right;"
1097  "}"
1098  "a{ color: #729FCF;"
1099  " font-family: arial,sans-serif;"
1100  " font-size: small;"
1101  "}"
1102  "label{ background-color: #FFFFCC;"
1103  " border: 1px solid black;"
1104  " margin: 1px;"
1105  " padding: 0px 3px; "
1106  " font-size: small;"
1107  "}";
1108  return myStyle;
1109 }
1110 
1112 {
1113  if ( 0 >= OGRGetDriverCount() )
1114  {
1115  OGRRegisterAll();
1116  }
1117 }
1118 
1119 QString QgsApplication::absolutePathToRelativePath( const QString& aPath, const QString& targetPath )
1120 {
1121  QString aPathUrl = aPath;
1122  QString tPathUrl = targetPath;
1123 #if defined( Q_OS_WIN )
1124  const Qt::CaseSensitivity cs = Qt::CaseInsensitive;
1125 
1126  aPathUrl.replace( '\\', '/' );
1127  if ( aPathUrl.startsWith( "//" ) )
1128  {
1129  // keep UNC prefix
1130  aPathUrl = "\\\\" + aPathUrl.mid( 2 );
1131  }
1132 
1133  tPathUrl.replace( '\\', '/' );
1134  if ( tPathUrl.startsWith( "//" ) )
1135  {
1136  // keep UNC prefix
1137  tPathUrl = "\\\\" + tPathUrl.mid( 2 );
1138  }
1139 #else
1140  const Qt::CaseSensitivity cs = Qt::CaseSensitive;
1141 #endif
1142 
1143  QStringList targetElems = tPathUrl.split( '/', QString::SkipEmptyParts );
1144  QStringList aPathElems = aPathUrl.split( '/', QString::SkipEmptyParts );
1145 
1146  targetElems.removeAll( QStringLiteral( "." ) );
1147  aPathElems.removeAll( QStringLiteral( "." ) );
1148 
1149  // remove common part
1150  int n = 0;
1151  while ( !aPathElems.isEmpty() &&
1152  !targetElems.isEmpty() &&
1153  aPathElems[0].compare( targetElems[0], cs ) == 0 )
1154  {
1155  aPathElems.removeFirst();
1156  targetElems.removeFirst();
1157  n++;
1158  }
1159 
1160  if ( n == 0 )
1161  {
1162  // no common parts; might not even be a file
1163  return aPathUrl;
1164  }
1165 
1166  if ( !targetElems.isEmpty() )
1167  {
1168  // go up to the common directory
1169  for ( int i = 0; i < targetElems.size(); i++ )
1170  {
1171  aPathElems.insert( 0, QStringLiteral( ".." ) );
1172  }
1173  }
1174  else
1175  {
1176  // let it start with . nevertheless,
1177  // so relative path always start with either ./ or ../
1178  aPathElems.insert( 0, QStringLiteral( "." ) );
1179  }
1180 
1181  return aPathElems.join( QStringLiteral( "/" ) );
1182 }
1183 
1184 QString QgsApplication::relativePathToAbsolutePath( const QString& rpath, const QString& targetPath )
1185 {
1186  // relative path should always start with ./ or ../
1187  if ( !rpath.startsWith( QLatin1String( "./" ) ) && !rpath.startsWith( QLatin1String( "../" ) ) )
1188  {
1189  return rpath;
1190  }
1191 
1192  QString rPathUrl = rpath;
1193  QString targetPathUrl = targetPath;
1194 
1195 #if defined(Q_OS_WIN)
1196  rPathUrl.replace( '\\', '/' );
1197  targetPathUrl.replace( '\\', '/' );
1198 
1199  bool uncPath = targetPathUrl.startsWith( "//" );
1200 #endif
1201 
1202  QStringList srcElems = rPathUrl.split( '/', QString::SkipEmptyParts );
1203  QStringList targetElems = targetPathUrl.split( '/', QString::SkipEmptyParts );
1204 
1205 #if defined(Q_OS_WIN)
1206  if ( uncPath )
1207  {
1208  targetElems.insert( 0, "" );
1209  targetElems.insert( 0, "" );
1210  }
1211 #endif
1212 
1213  // append source path elements
1214  targetElems << srcElems;
1215  targetElems.removeAll( QStringLiteral( "." ) );
1216 
1217  // resolve ..
1218  int pos;
1219  while (( pos = targetElems.indexOf( QStringLiteral( ".." ) ) ) > 0 )
1220  {
1221  // remove preceding element and ..
1222  targetElems.removeAt( pos - 1 );
1223  targetElems.removeAt( pos - 1 );
1224  }
1225 
1226 #if !defined(Q_OS_WIN)
1227  // make path absolute
1228  targetElems.prepend( QLatin1String( "" ) );
1229 #endif
1230 
1231  return targetElems.join( QStringLiteral( "/" ) );
1232 }
1233 
1234 void QgsApplication::skipGdalDriver( const QString& theDriver )
1235 {
1236  if ( ABISYM( mGdalSkipList ).contains( theDriver ) || theDriver.isEmpty() )
1237  {
1238  return;
1239  }
1240  ABISYM( mGdalSkipList ) << theDriver;
1242 }
1243 
1244 void QgsApplication::restoreGdalDriver( const QString& theDriver )
1245 {
1246  if ( !ABISYM( mGdalSkipList ).contains( theDriver ) )
1247  {
1248  return;
1249  }
1250  int myPos = ABISYM( mGdalSkipList ).indexOf( theDriver );
1251  if ( myPos >= 0 )
1252  {
1253  ABISYM( mGdalSkipList ).removeAt( myPos );
1254  }
1256 }
1257 
1259 {
1260  ABISYM( mGdalSkipList ).removeDuplicates();
1261  QString myDriverList = ABISYM( mGdalSkipList ).join( QStringLiteral( " " ) );
1262  QgsDebugMsg( "Gdal Skipped driver list set to:" );
1263  QgsDebugMsg( myDriverList );
1264  CPLSetConfigOption( "GDAL_SKIP", myDriverList.toUtf8() );
1265  GDALAllRegister(); //to update driver list and skip missing ones
1266 }
1267 
1269 {
1270  QString folder = userThemesFolder();
1271  QDir myDir( folder );
1272  if ( !myDir.exists() )
1273  {
1274  myDir.mkpath( folder );
1275  }
1276 
1277  copyPath( defaultThemesFolder(), userThemesFolder() );
1278  return true;
1279 }
1280 
1281 void QgsApplication::copyPath( const QString& src, const QString& dst )
1282 {
1283  QDir dir( src );
1284  if ( ! dir.exists() )
1285  return;
1286 
1287  Q_FOREACH ( const QString& d, dir.entryList( QDir::Dirs | QDir::NoDotAndDotDot ) )
1288  {
1289  QString dst_path = dst + QDir::separator() + d;
1290  dir.mkpath( dst_path );
1291  copyPath( src + QDir::separator() + d, dst_path );
1292  }
1293 
1294  Q_FOREACH ( const QString& f, dir.entryList( QDir::Files ) )
1295  {
1296  QFile::copy( src + QDir::separator() + f, dst + QDir::separator() + f );
1297  }
1298 }
1299 
1301 {
1302  //read values from QSettings
1303  QSettings settings;
1304 
1305  QVariantMap variables;
1306 
1307  //check if settings contains any variables
1308  if ( settings.contains( QStringLiteral( "/variables/values" ) ) )
1309  {
1310  QList< QVariant > customVariableVariants = settings.value( QStringLiteral( "/variables/values" ) ).toList();
1311  QList< QVariant > customVariableNames = settings.value( QStringLiteral( "/variables/names" ) ).toList();
1312  int variableIndex = 0;
1313  for ( QList< QVariant >::const_iterator it = customVariableVariants.constBegin();
1314  it != customVariableVariants.constEnd(); ++it )
1315  {
1316  if ( variableIndex >= customVariableNames.length() )
1317  {
1318  break;
1319  }
1320 
1321  QVariant value = ( *it );
1322  QString name = customVariableNames.at( variableIndex ).toString();
1323 
1324  variables.insert( name, value );
1325  variableIndex++;
1326  }
1327  }
1328 
1329  return variables;
1330 }
1331 
1332 void QgsApplication::setCustomVariables( const QVariantMap& variables )
1333 {
1334  QSettings settings;
1335 
1336  QList< QVariant > customVariableValues;
1337  QList< QVariant > customVariableNames;
1338 
1339  QVariantMap::const_iterator it = variables.constBegin();
1340  for ( ; it != variables.constEnd(); ++it )
1341  {
1342  customVariableNames << it.key();
1343  customVariableValues << it.value();
1344  }
1345 
1346  settings.setValue( QStringLiteral( "/variables/names" ), customVariableNames );
1347  settings.setValue( QStringLiteral( "/variables/values" ), customVariableValues );
1348 
1349  emit instance()->customVariablesChanged();
1350 }
1351 
1352 void QgsApplication::setCustomVariable( const QString& name, const QVariant& value )
1353 {
1354  // save variable to settings
1355  QSettings settings;
1356 
1357  QList< QVariant > customVariableVariants = settings.value( QStringLiteral( "/variables/values" ) ).toList();
1358  QList< QVariant > customVariableNames = settings.value( QStringLiteral( "/variables/names" ) ).toList();
1359 
1360  customVariableVariants << value;
1361  customVariableNames << name;
1362 
1363  settings.setValue( QStringLiteral( "/variables/names" ), customVariableNames );
1364  settings.setValue( QStringLiteral( "/variables/values" ), customVariableVariants );
1365 
1366  emit instance()->customVariablesChanged();
1367 }
1368 
1370 {
1371  QgsApplication* app = instance();
1372  if ( app->mNullRepresentation.isNull() )
1373  app->mNullRepresentation = QSettings().value( QStringLiteral( "qgis/nullValue" ), QStringLiteral( "NULL" ) ).toString();
1374  return app->mNullRepresentation;
1375 }
1376 
1378 {
1379  QgsApplication* app = instance();
1380  if ( app->mNullRepresentation == nullRepresentation )
1381  return;
1382 
1383  app->mNullRepresentation = nullRepresentation;
1384  QSettings().setValue( QStringLiteral( "qgis/nullValue" ), nullRepresentation );
1385  emit app->nullRepresentationChanged();
1386 }
1387 
1389 {
1390  return instance()->mActionScopeRegistry;
1391 }
1392 
1393 bool QgsApplication::createDB( QString *errorMessage )
1394 {
1395  // set a working directory up for gdal to write .aux.xml files into
1396  // for cases where the raster dir is read only to the user
1397  // if the env var is already set it will be used preferentially
1398  QString myPamPath = qgisSettingsDirPath() + QStringLiteral( "gdal_pam/" );
1399  QDir myDir( myPamPath );
1400  if ( !myDir.exists() )
1401  {
1402  myDir.mkpath( myPamPath ); //fail silently
1403  }
1404 
1405 #if defined(Q_OS_WIN)
1406  CPLSetConfigOption( "GDAL_PAM_PROXY_DIR", myPamPath.toUtf8() );
1407 #else
1408  //under other OS's we use an environment var so the user can
1409  //override the path if he likes
1410  int myChangeFlag = 0; //whether we want to force the env var to change
1411  setenv( "GDAL_PAM_PROXY_DIR", myPamPath.toUtf8(), myChangeFlag );
1412 #endif
1413 
1414  // Check qgis.db and make private copy if necessary
1415  QFile qgisPrivateDbFile( QgsApplication::qgisUserDbFilePath() );
1416 
1417  // first we look for ~/.qgis/qgis.db
1418  if ( !qgisPrivateDbFile.exists() )
1419  {
1420  // if it doesn't exist we copy it in from the global resources dir
1421  QString qgisMasterDbFileName = QgsApplication::qgisMasterDbFilePath();
1422  QFile masterFile( qgisMasterDbFileName );
1423 
1424  // Must be sure there is destination directory ~/.qgis
1425  QDir().mkpath( QgsApplication::qgisSettingsDirPath() );
1426 
1427  //now copy the master file into the users .qgis dir
1428  bool isDbFileCopied = masterFile.copy( qgisPrivateDbFile.fileName() );
1429 
1430  if ( !isDbFileCopied )
1431  {
1432  if ( errorMessage )
1433  {
1434  *errorMessage = tr( "[ERROR] Can not make qgis.db private copy" );
1435  }
1436  return false;
1437  }
1438  }
1439  else
1440  {
1441  // migrate if necessary
1442  sqlite3 *db;
1443  if ( sqlite3_open( QgsApplication::qgisUserDbFilePath().toUtf8().constData(), &db ) != SQLITE_OK )
1444  {
1445  if ( errorMessage )
1446  {
1447  *errorMessage = tr( "Could not open qgis.db" );
1448  }
1449  return false;
1450  }
1451 
1452  char *errmsg;
1453  int res = sqlite3_exec( db, "SELECT epsg FROM tbl_srs LIMIT 0", nullptr, nullptr, &errmsg );
1454  if ( res == SQLITE_OK )
1455  {
1456  // epsg column exists => need migration
1457  if ( sqlite3_exec( db,
1458  "ALTER TABLE tbl_srs RENAME TO tbl_srs_bak;"
1459  "CREATE TABLE tbl_srs ("
1460  "srs_id INTEGER PRIMARY KEY,"
1461  "description text NOT NULL,"
1462  "projection_acronym text NOT NULL,"
1463  "ellipsoid_acronym NOT NULL,"
1464  "parameters text NOT NULL,"
1465  "srid integer,"
1466  "auth_name varchar,"
1467  "auth_id varchar,"
1468  "is_geo integer NOT NULL,"
1469  "deprecated boolean);"
1470  "CREATE INDEX idx_srsauthid on tbl_srs(auth_name,auth_id);"
1471  "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;"
1472  "DROP TABLE tbl_srs_bak", nullptr, nullptr, &errmsg ) != SQLITE_OK
1473  )
1474  {
1475  if ( errorMessage )
1476  {
1477  *errorMessage = tr( "Migration of private qgis.db failed.\n%1" ).arg( QString::fromUtf8( errmsg ) );
1478  }
1479  sqlite3_free( errmsg );
1480  sqlite3_close( db );
1481  return false;
1482  }
1483  }
1484  else
1485  {
1486  sqlite3_free( errmsg );
1487  }
1488 
1489  if ( sqlite3_exec( db, "DROP VIEW vw_srs", nullptr, nullptr, &errmsg ) != SQLITE_OK )
1490  {
1491  QgsDebugMsg( QString( "vw_srs didn't exists in private qgis.db: %1" ).arg( errmsg ) );
1492  }
1493 
1494  if ( sqlite3_exec( db,
1495  "CREATE VIEW vw_srs AS"
1496  " SELECT"
1497  " a.description AS description"
1498  ",a.srs_id AS srs_id"
1499  ",a.is_geo AS is_geo"
1500  ",coalesce(b.name,a.projection_acronym) AS name"
1501  ",a.parameters AS parameters"
1502  ",a.auth_name AS auth_name"
1503  ",a.auth_id AS auth_id"
1504  ",a.deprecated AS deprecated"
1505  " FROM tbl_srs a"
1506  " LEFT OUTER JOIN tbl_projection b ON a.projection_acronym=b.acronym"
1507  " ORDER BY coalesce(b.name,a.projection_acronym),a.description", nullptr, nullptr, &errmsg ) != SQLITE_OK
1508  )
1509  {
1510  if ( errorMessage )
1511  {
1512  *errorMessage = tr( "Update of view in private qgis.db failed.\n%1" ).arg( QString::fromUtf8( errmsg ) );
1513  }
1514  sqlite3_free( errmsg );
1515  sqlite3_close( db );
1516  return false;
1517  }
1518 
1519  sqlite3_close( db );
1520  }
1521  return true;
1522 }
1523 
1525 {
1526  QgsDebugMsg( QString( "maxThreads: %1" ).arg( maxThreads ) );
1527 
1528  // make sure value is between 1 and #cores, if not set to -1 (use #cores)
1529  // 0 could be used to disable any parallel processing
1530  if ( maxThreads < 1 || maxThreads > QThread::idealThreadCount() )
1531  maxThreads = -1;
1532 
1533  // save value
1534  ABISYM( mMaxThreads ) = maxThreads;
1535 
1536  // if -1 use #cores
1537  if ( maxThreads == -1 )
1538  maxThreads = QThread::idealThreadCount();
1539 
1540  // set max thread count in QThreadPool
1541  QThreadPool::globalInstance()->setMaxThreadCount( maxThreads );
1542  QgsDebugMsg( QString( "set QThreadPool max thread count to %1" ).arg( QThreadPool::globalInstance()->maxThreadCount() ) );
1543 }
1544 
1546 {
1547  return instance()->mTaskManager;
1548 }
1549 
1551 {
1552  return instance()->mColorSchemeRegistry;
1553 }
1554 
1556 {
1557  return instance()->mPaintEffectRegistry;
1558 }
1559 
1561 {
1562  return instance()->mRendererRegistry;
1563 }
1564 
1566 {
1567  return instance()->mRasterRendererRegistry;
1568 }
1569 
1571 {
1572  return instance()->mDataItemProviderRegistry;
1573 }
1574 
1576 {
1577  return instance()->mSvgCache;
1578 }
1579 
1581 {
1582  return instance()->mSymbolLayerRegistry;
1583 }
1584 
1586 {
1587  return instance()->mGpsConnectionRegistry;
1588 }
1589 
1591 {
1592  return instance()->mPluginLayerRegistry;
1593 }
1594 
1596 {
1597  return instance()->mMessageLog;
1598 }
1599 
1601 {
1602  return instance()->mProcessingRegistry;
1603 }
1604 
1606 {
1607  return instance()->mFieldFormatterRegistry;
1608 }
static bool createDB(QString *errorMessage=nullptr)
initialize qgis.db
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...
static void init(QString customConfigPath=QString())
This method initializes paths etc for QGIS.
This class keeps a list of data item providers that may add items to the browser tree.
static unsigned index
static QgsProviderRegistry * instance(const QString &pluginPath=QString::null)
Means of accessing canonical single instance.
void addDefaultSchemes()
Adds all default color schemes to this color scheme.
Extends QApplication to provide access to QGIS specific resources such as theme paths, database paths etc.
static void skipGdalDriver(const QString &theDriver)
Sets the GDAL_SKIP environment variable to include the specified driver and then calls GDALDriverMana...
static QgsFieldFormatterRegistry * fieldFormatterRegistry()
Get the registry of available field formatters.
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.
A registry of plugin layers types.
static QString qgisSettingsDirPath()
Returns the path to the settings directory in user&#39;s home dir.
static QString qgisUserDbFilePath()
Returns the path to the user qgis.db file.
static 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.
void customVariablesChanged()
Emitted whenever a custom global variable changes.
virtual bool event(QEvent *event) override
Watch for QFileOpenEvent.
static QString qgisAuthDbFilePath()
Returns the path to the user authentication database file: qgis-auth.db.
static QString donorsFilePath()
Returns the path to the donors file.
static QString relativePathToAbsolutePath(const QString &rpath, const QString &targetPath)
Converts path relative to target to an absolute path.
static void setPrefixPath(const QString &thePrefixPath, bool useDefaultPaths=false)
Alters prefix path - used by 3rd party apps.
QgsApplication(int &argc, char **argv, bool GUIenabled, const QString &customConfigPath=QString(), const QString &platformName="desktop")
#define QgsDebugMsg(str)
Definition: qgslogger.h:36
void nullRepresentationChanged()
This string is used to represent the value NULL throughout QGIS.
static QIcon getThemeIcon(const QString &theName)
Helper to get a theme icon.
static QString themeName()
Set the active theme to the specified theme.
static QString defaultThemesFolder()
Returns the path to default themes folder from install (works as a starting point).
static QString iconPath(const QString &iconFile)
Returns path to the desired icon file.
A cache for images / pictures derived from svg files.
Definition: qgssvgcache.h:100
Registry of renderers.
Registry for raster renderers.
static void registerOgrDrivers()
Register OGR drivers ensuring this only happens once.
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.
static void setFileOpenEventReceiver(QObject *receiver)
Set the FileOpen event receiver.
static QString reportStyleSheet()
get a standard css style sheet for reports.
static int maxThreads()
Get maximum concurrent thread count.
static endian_t endian()
Returns whether this machine uses big or little endian.
static QPixmap getThemePixmap(const QString &theName)
Helper to get a theme icon as a pixmap.
static QString userFullName()
Returns the user&#39;s operating system login account full display name.
static 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:38
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 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.
Registry of available symbol layer classes.
static void setThemeName(const QString &theThemeName)
Set the active theme to the specified theme.
bool init(const QString &pluginPath=QString::null)
Initialize QCA, prioritize qca-ossl plugin and optionally set up the authentication database...
static QString helpAppPath()
Returns the path to the help application.
static bool createThemeFolder()
Create the users theme folder.
static void cleanRegisteredFunctions()
Deletes all registered functions whose ownership have been transferred to the expression engine...
virtual ~QgsApplication()
static QString i18nPath()
Returns the path to the translation directory.
static void setPkgDataPath(const QString &thePkgDataPath)
Alters pkg data path - used by 3rd party apps.
static QString 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 const char * QGIS_ORGANIZATION_NAME
static QString qgisMasterDbFilePath()
Returns the path to the master qgis.db file.
static void setPluginPath(const QString &thePluginPath)
Alters plugin path - used by 3rd party apps.
static void restoreGdalDriver(const QString &theDriver)
Sets the GDAL_SKIP environment variable to exclude the specified driver and then calls GDALDriverMana...
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.
struct sqlite3 sqlite3
static QString osName()
Returns a string name of the operating system QGIS is running on.
static void initQgis()
loads providers
static void setDefaultSvgPaths(const QStringList &pathList)
Alters default svg paths - used by 3rd party apps.
static void setAuthDbDirPath(const QString &theAuthDbDirPath)
Alters authentication data base directory path - used by 3rd party apps.
static QRegExp shortNameRegExp()
Returns the short name regular expression for line edit validator.
A class to register / unregister existing GPS connections such that the information is available to a...
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()
get application icon
static QgsColorSchemeRegistry * colorSchemeRegistry()
Returns the application&#39;s color scheme registry, used for managing color schemes. ...
static const char * QGIS_ORGANIZATION_DOMAIN
virtual bool notify(QObject *receiver, QEvent *event) override
Catch exceptions when sending event to receiver.
static QString contributorsFilePath()
Returns the path to the contributors file.
static QString activeThemePath()
Returns the path to the currently active theme directory.
static QgsNetworkAccessManager * instance()
returns a pointer to the single instance
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:350
static QString platform()
Returns the QGIS platform name, e.g., "desktop" or "server".
QObject * ABISYM(QgsApplication::mFileOpenEventReceiver)
static void exitQgis()
deletes provider registry and map layer registry
static QStringList svgPaths()
Returns the paths to svg directories.
static QString sponsorsFilePath()
Returns the path to the sponsors file.
static QStringList composerTemplatePaths()
Returns the paths to composer template directories.
static QString srsDbFilePath()
Returns the path to the srs.db file.
The action scope registry is an application wide registry that contains a list of available action sc...
static QHash< QString, QString > uiThemes()
All themes found in ~/.qgis3/themes folder.
static QString libexecPath()
Returns the path with utility executables (help viewer, crssync, ...)
static QString prefixPath()
Returns the path to the application prefix directory.
static QString iconsPath()
Returns the path to the icons image directory.
static QString translatorsFilePath()
Returns the path to the sponsors file.
static const char * QGIS_APPLICATION_NAME
static QgsActionScopeRegistry * actionScopeRegistry()
Returns the action scope registry.
Defines a qgis exception class.
Definition: qgsexception.h:27
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:36
static void setMaxThreads(int maxThreads)
Set maximum concurrent thread count.
static QgsGPSConnectionRegistry * gpsConnectionRegistry()
Returns the application&#39;s GPS connection registry, used for managing GPS connections.
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)