74 #include "processing/models/qgsprocessingmodelchildparametersource.h"
75 #include "processing/models/qgsprocessingmodelchilddependency.h"
79 #include <QDesktopWidget>
83 #include <QFileOpenEvent>
84 #include <QMessageBox>
87 #include <QProcessEnvironment>
90 #include <QThreadPool>
95 #include <netinet/in.h>
101 #define SECURITY_WIN32
102 #include <security.h>
104 #pragma comment( lib, "Secur32.lib" )
108 #include "qgsconfig.h"
112 #include <cpl_conv.h>
115 #if PROJ_VERSION_MAJOR>=6
120 #define CONN_POOL_MAX_CONCURRENT_CONNS 4
122 QObject *
ABISYM( QgsApplication::mFileOpenEventReceiver ) =
nullptr;
123 bool ABISYM( QgsApplication::mInitialized ) =
false;
124 bool ABISYM( QgsApplication::mRunningFromBuildDir ) =
false;
128 QgsApplication::ApplicationMembers *QgsApplication::sApplicationMembers =
nullptr;
130 int ABISYM( QgsApplication::sMaxThreads ) = -1;
147 #if defined(_MSC_VER) && !defined(USING_NMAKE) && !defined(USING_NINJA)
161 : QApplication( argc, argv, GUIenabled )
163 *sPlatformName() = platformName;
165 if ( *sTranslation() != QLatin1String(
"C" ) )
167 mQgisTranslator =
new QTranslator();
168 if ( mQgisTranslator->load( QStringLiteral(
"qgis_" ) + *sTranslation(), i18nPath() ) )
170 installTranslator( mQgisTranslator );
174 QgsDebugMsgLevel( QStringLiteral(
"loading of qgis translation failed %1/qgis_%2" ).arg( i18nPath(), *sTranslation() ), 2 );
182 mQtTranslator =
new QTranslator();
183 if ( mQtTranslator->load( QStringLiteral(
"qt_" ) + *sTranslation(), QLibraryInfo::location( QLibraryInfo::TranslationsPath ) ) )
185 installTranslator( mQtTranslator );
189 QgsDebugMsgLevel( QStringLiteral(
"loading of qt translation failed %1/qt_%2" ).arg( QLibraryInfo::location( QLibraryInfo::TranslationsPath ), *sTranslation() ), 2 );
193 mApplicationMembers =
new ApplicationMembers();
195 *sProfilePath() = profileFolder;
200 if ( profileFolder.isEmpty() )
202 if ( getenv(
"QGIS_CUSTOM_CONFIG_PATH" ) )
204 profileFolder = getenv(
"QGIS_CUSTOM_CONFIG_PATH" );
208 profileFolder = QStandardPaths::standardLocations( QStandardPaths::AppDataLocation ).value( 0 );
215 profileFolder = profile->
folder();
219 *sProfilePath() = profileFolder;
221 qRegisterMetaType<QgsGeometry::Error>(
"QgsGeometry::Error" );
222 qRegisterMetaType<QgsProcessingFeatureSourceDefinition>(
"QgsProcessingFeatureSourceDefinition" );
223 qRegisterMetaType<QgsProcessingOutputLayerDefinition>(
"QgsProcessingOutputLayerDefinition" );
224 qRegisterMetaType<QgsUnitTypes::LayoutUnit>(
"QgsUnitTypes::LayoutUnit" );
225 qRegisterMetaType<QgsFeatureId>(
"QgsFeatureId" );
226 qRegisterMetaType<QgsFeatureIds>(
"QgsFeatureIds" );
227 qRegisterMetaType<QgsProperty>(
"QgsProperty" );
228 qRegisterMetaType<QgsFeatureStoreList>(
"QgsFeatureStoreList" );
229 qRegisterMetaType<Qgis::MessageLevel>(
"Qgis::MessageLevel" );
230 qRegisterMetaType<QgsReferencedRectangle>(
"QgsReferencedRectangle" );
231 qRegisterMetaType<QgsReferencedPointXY>(
"QgsReferencedPointXY" );
232 qRegisterMetaType<QgsReferencedGeometry>(
"QgsReferencedGeometry" );
233 qRegisterMetaType<QgsLayoutRenderContext::Flags>(
"QgsLayoutRenderContext::Flags" );
234 qRegisterMetaType<QgsStyle::StyleEntity>(
"QgsStyle::StyleEntity" );
235 qRegisterMetaType<QgsCoordinateReferenceSystem>(
"QgsCoordinateReferenceSystem" );
236 qRegisterMetaType<QgsAuthManager::MessageLevel>(
"QgsAuthManager::MessageLevel" );
237 qRegisterMetaType<QgsNetworkRequestParameters>(
"QgsNetworkRequestParameters" );
238 qRegisterMetaType<QgsNetworkReplyContent>(
"QgsNetworkReplyContent" );
239 qRegisterMetaType<QgsGeometry>(
"QgsGeometry" );
240 qRegisterMetaType<QgsDatumTransform::GridDetails>(
"QgsDatumTransform::GridDetails" );
241 qRegisterMetaType<QgsDatumTransform::TransformDetails>(
"QgsDatumTransform::TransformDetails" );
242 qRegisterMetaType<QgsNewsFeedParser::Entry>(
"QgsNewsFeedParser::Entry" );
243 qRegisterMetaType<QgsRectangle>(
"QgsRectangle" );
244 qRegisterMetaType<QgsProcessingModelChildParameterSource>(
"QgsProcessingModelChildParameterSource" );
245 qRegisterMetaTypeStreamOperators<QgsProcessingModelChildParameterSource>(
"QgsProcessingModelChildParameterSource" );
246 qRegisterMetaType<QgsRemappingSinkDefinition>(
"QgsRemappingSinkDefinition" );
247 qRegisterMetaType<QgsProcessingModelChildDependency>(
"QgsProcessingModelChildDependency" );
248 qRegisterMetaType<QgsTextFormat>(
"QgsTextFormat" );
249 QMetaType::registerComparators<QgsProcessingModelChildDependency>();
250 QMetaType::registerEqualsComparator<QgsProcessingFeatureSourceDefinition>();
251 QMetaType::registerEqualsComparator<QgsProperty>();
255 if ( ABISYM( mRunningFromBuildDir ) )
258 *sPrefixPath() = QString();
259 #if defined(_MSC_VER) && !defined(USING_NMAKE) && !defined(USING_NINJA)
260 setPluginPath( *sBuildOutputPath() +
'/' + QString( QGIS_PLUGIN_SUBDIR ) +
'/' + *sCfgIntDir() );
262 setPluginPath( *sBuildOutputPath() +
'/' + QStringLiteral( QGIS_PLUGIN_SUBDIR ) );
264 setPkgDataPath( *sBuildOutputPath() + QStringLiteral(
"/data" ) );
265 *sLibraryPath() = *sBuildOutputPath() +
'/' + QGIS_LIB_SUBDIR +
'/';
266 #if defined(_MSC_VER) && !defined(USING_NMAKE) && !defined(USING_NINJA)
267 *sLibexecPath() = *sBuildOutputPath() +
'/' + QGIS_LIBEXEC_SUBDIR +
'/' + *sCfgIntDir() +
'/';
269 *sLibexecPath() = *sBuildOutputPath() +
'/' + QGIS_LIBEXEC_SUBDIR +
'/';
271 #if defined( HAVE_QUICK )
272 *sQmlImportPath() = *sBuildOutputPath() +
'/' + QGIS_QML_SUBDIR +
'/';
277 char *
prefixPath = getenv(
"QGIS_PREFIX_PATH" );
280 if ( sPrefixPath()->isNull() )
282 #if defined(Q_OS_MACX) || defined(Q_OS_WIN)
284 #elif defined(ANDROID)
286 QDir myDir( QDir::homePath() );
288 QString myPrefix = myDir.absolutePath();
291 QDir myDir( applicationDirPath() );
293 if ( applicationDirPath().contains( QStringLiteral(
"cgi-bin" ) ) )
298 QString myPrefix = myDir.absolutePath();
309 *sConfigPath() = profileFolder +
'/';
313 if ( getenv(
"QGIS_AUTH_DB_DIR_PATH" ) )
319 QMap<QString, QString> systemEnvVarMap;
320 QString passfile( QStringLiteral(
"QGIS_AUTH_PASSWORD_FILE" ) );
322 const auto systemEnvironment = QProcessEnvironment::systemEnvironment().toStringList();
323 for (
const QString &varStr : systemEnvironment )
325 int pos = varStr.indexOf( QLatin1Char(
'=' ) );
328 QString varStrName = varStr.left( pos );
329 QString varStrValue = varStr.mid( pos + 1 );
330 if ( varStrName != passfile )
332 systemEnvVarMap.insert( varStrName, varStrValue );
335 *sSystemEnvVars() = systemEnvVarMap;
337 #if PROJ_VERSION_MAJOR>=6
343 QString projLib( QDir::cleanPath(
pkgDataPath().append(
"/proj" ) ) );
344 if ( QFile::exists( projLib ) )
346 currentProjSearchPaths.append( projLib );
350 char **newPaths =
new char *[currentProjSearchPaths.length()];
351 for (
int i = 0; i < currentProjSearchPaths.count(); ++i )
353 newPaths[i] = CPLStrdup( currentProjSearchPaths.at( i ).toUtf8().constData() );
355 proj_context_set_search_paths(
nullptr, currentProjSearchPaths.count(), newPaths );
356 for (
int i = 0; i < currentProjSearchPaths.count(); ++i )
358 CPLFree( newPaths[i] );
361 #endif // PROJ_VERSION_MAJOR>=6
364 QCoreApplication::addLibraryPath(
pluginPath() );
369 ABISYM( sMaxThreads ) = -1;
382 if ( !members()->mStyleModel )
385 ABISYM( mInitialized ) =
true;
390 delete mDataItemProviderRegistry;
391 delete mApplicationMembers;
392 delete mQgisTranslator;
393 delete mQtTranslator;
401 void QgsApplication::invalidateCaches()
413 return qobject_cast<QgsApplication *>( QCoreApplication::instance() );
419 if (
event->type() == QEvent::FileOpen )
422 if ( ABISYM( mFileOpenEventReceiver ) )
425 done =
notify( ABISYM( mFileOpenEventReceiver ),
event );
432 sFileOpenEventList()->append(
static_cast<QFileOpenEvent *
>(
event )->file() );
439 done = QApplication::event(
event );
448 if ( thread() == receiver->thread() )
458 done = QApplication::notify( receiver,
event );
462 qCritical() <<
"Caught unhandled QgsException: " << e.
what();
463 if ( qApp->thread() == QThread::currentThread() )
464 QMessageBox::critical( activeWindow(), tr(
"Exception" ), e.
what() );
466 catch ( std::exception &e )
468 qCritical() <<
"Caught unhandled std::exception: " << e.what();
469 if ( qApp->thread() == QThread::currentThread() )
470 QMessageBox::critical( activeWindow(), tr(
"Exception" ), e.what() );
474 qCritical() <<
"Caught unhandled unknown exception";
475 if ( qApp->thread() == QThread::currentThread() )
476 QMessageBox::critical( activeWindow(), tr(
"Exception" ), tr(
"unknown exception" ) );
484 return QgsRuntimeProfiler::threadLocalInstance();
490 ABISYM( mFileOpenEventReceiver ) = receiver;
492 if ( sFileOpenEventList()->count() > 0 )
494 const QStringList fileOpenEventList = *sFileOpenEventList();
495 for (
const QString &file : fileOpenEventList )
497 QFileOpenEvent foe( file );
498 QgsApplication::sendEvent( ABISYM( mFileOpenEventReceiver ), &foe );
500 sFileOpenEventList()->clear();
507 #if defined(Q_OS_WIN)
508 if ( sPrefixPath()->endsWith(
"/bin" ) )
510 sPrefixPath()->chop( 4 );
513 if ( useDefaultPaths && !ABISYM( mRunningFromBuildDir ) )
515 setPluginPath( *sPrefixPath() +
'/' + QStringLiteral( QGIS_PLUGIN_SUBDIR ) );
516 setPkgDataPath( *sPrefixPath() +
'/' + QStringLiteral( QGIS_DATA_SUBDIR ) );
518 *sLibraryPath() = *sPrefixPath() +
'/' + QGIS_LIB_SUBDIR +
'/';
519 *sLibexecPath() = *sPrefixPath() +
'/' + QGIS_LIBEXEC_SUBDIR +
'/';
520 #if defined( HAVE_QUICK )
521 *sQmlImportPath() = *sPrefixPath() +
'/' + QGIS_QML_SUBDIR +
'/';
534 QString mySvgPath =
pkgDataPath + QStringLiteral(
"/svg/" );
537 if ( !sDefaultSvgPaths()->contains( mySvgPath ) )
538 *sDefaultSvgPaths() << mySvgPath;
543 *sDefaultSvgPaths() = pathList;
548 QFileInfo fi( authDbDirPath );
549 if ( fi.exists() && fi.isDir() && fi.isWritable() )
551 *sAuthDbDirPath() = fi.canonicalFilePath() + QDir::separator();
558 if ( ABISYM( mRunningFromBuildDir ) )
560 static bool sOnce =
true;
564 ( void ) blockNotifications;
565 qWarning(
"!!! prefix path was requested, but it is not valid - we do not run from installed path !!!" );
571 return *sPrefixPath();
575 return *sPluginPath();
580 if ( sPkgDataPath()->isNull() )
583 return *sPkgDataPath();
588 return QStringLiteral(
":/images/themes/default/" );
593 QDir dir( usersThemes );
601 return defaultThemes;
607 return iconsPath() + QStringLiteral(
"qgis-icon-60x60.png" );
612 return ABISYM( sMaxThreads );
619 if ( QFile::exists( path + iconFile ) )
620 return path + iconFile;
629 if ( app && app->mIconCache.contains( name ) )
630 return app->mIconCache.value( name );
634 QString myPreferredPath =
activeThemePath() + QDir::separator() + name;
636 if ( QFile::exists( myPreferredPath ) )
638 icon = QIcon( myPreferredPath );
640 else if ( QFile::exists( myDefaultPath ) )
644 icon = QIcon( myDefaultPath );
652 app->mIconCache.insert( name, icon );
659 if ( app && app->mCursorCache.contains( cursor ) )
660 return app->mCursorCache.value( cursor );
671 name = QStringLiteral(
"mZoomIn.svg" );
676 name = QStringLiteral(
"mZoomOut.svg" );
683 name = QStringLiteral(
"mIdentify.svg" );
686 name = QStringLiteral(
"mCrossHair.svg" );
689 name = QStringLiteral(
"mCapturePoint.svg" );
692 name = QStringLiteral(
"mSelect.svg" );
699 name = QStringLiteral(
"mSampler.svg" );
704 Q_ASSERT( ! name.isEmpty( ) );
706 QIcon icon =
getThemeIcon( QStringLiteral(
"cursors" ) + QDir::separator() + name );
709 if ( ! icon.isNull( ) )
713 cursorIcon = QCursor( icon.pixmap( std::ceil( scale * 32 ), std::ceil( scale * 32 ) ), std::ceil( scale * activeX ), std::ceil( scale * activeY ) );
716 app->mCursorCache.insert( cursor, cursorIcon );
723 const QString preferredPath =
activeThemePath() + QDir::separator() + name;
725 const QString path = QFile::exists( preferredPath ) ? preferredPath : defaultPath;
726 if ( foreColor.isValid() || backColor.isValid() )
728 bool fitsInCache =
false;
729 const QImage image =
svgCache()->
svgAsImage( path, size, backColor, foreColor, 1, 1, fitsInCache );
730 return QPixmap::fromImage( image );
733 return QPixmap( path );
743 static QString appPath;
744 if ( appPath.isNull() )
746 if ( QCoreApplication::instance() )
748 appPath = applicationDirPath();
752 qWarning(
"Application path not initialized" );
756 if ( !appPath.isNull() || getenv(
"QGIS_PREFIX_PATH" ) )
758 QString prefix = getenv(
"QGIS_PREFIX_PATH" ) ? getenv(
"QGIS_PREFIX_PATH" ) : appPath;
763 static const QStringList paths { QStringList() << QString() << QStringLiteral(
"/.." ) << QStringLiteral(
"/bin" ) << QStringLiteral(
"/../../.." ) };
764 for (
const QString &path : paths )
766 f.setFileName( prefix + path +
"/qgisbuildpath.txt" );
770 if ( f.exists() && f.open( QIODevice::ReadOnly ) )
772 ABISYM( mRunningFromBuildDir ) =
true;
773 *sBuildSourcePath() = f.readLine().trimmed();
774 *sBuildOutputPath() = f.readLine().trimmed();
776 QgsDebugMsgLevel( QStringLiteral(
"- source directory: %1" ).arg( sBuildSourcePath()->toUtf8().constData() ), 4 );
777 QgsDebugMsgLevel( QStringLiteral(
"- output directory of the build: %1" ).arg( sBuildOutputPath()->toUtf8().constData() ), 4 );
778 #if defined(_MSC_VER) && !defined(USING_NMAKE) && !defined(USING_NINJA)
779 *sCfgIntDir() = prefix.split(
'/', QString::SkipEmptyParts ).last();
780 qDebug(
"- cfg: %s", sCfgIntDir()->toUtf8().constData() );
786 if ( getenv(
"QGIS_PREFIX_PATH" ) )
792 QDir dir( QDir::homePath() );
797 #if defined(Q_OS_MACX)
799 #elif defined(Q_OS_WIN)
806 if ( appPath.contains( QStringLiteral(
"cgi-bin" ) ) )
816 if ( ABISYM( mRunningFromBuildDir ) )
817 return *sBuildOutputPath() + QStringLiteral(
"/data" );
819 return prefixPath +
'/' + QStringLiteral( QGIS_DATA_SUBDIR );
824 return *sThemeName();
834 qApp->setStyleSheet( QString() );
838 QString path = themes.value(
themeName );
839 QString stylesheetname = path +
"/style.qss";
841 QFile file( stylesheetname );
842 QFile variablesfile( path +
"/variables.qss" );
844 QFileInfo variableInfo( variablesfile );
846 if ( !file.open( QIODevice::ReadOnly ) || ( variableInfo.exists() && !variablesfile.open( QIODevice::ReadOnly ) ) )
851 QString styledata = file.readAll();
852 styledata.replace( QLatin1String(
"@theme_path" ), path );
854 if ( variableInfo.exists() )
856 QTextStream in( &variablesfile );
857 while ( !in.atEnd() )
859 QString line = in.readLine();
861 if ( line.startsWith(
'@' ) )
863 int index = line.indexOf(
':' );
864 QString name = line.mid( 0, index );
865 QString value = line.mid( index + 1, line.length() );
866 styledata.replace( name, value );
869 variablesfile.close();
877 QRegularExpression regex( QStringLiteral(
"(?<=[\\s:])([0-9\\.]+)(?=em)" ) );
878 QRegularExpressionMatch match = regex.match( styledata, index );
879 while ( match.hasMatch() )
881 index = match.capturedStart();
882 styledata.remove( index, match.captured( 0 ).length() );
884 styledata.insert( index, number );
885 index += number.length();
886 match = regex.match( styledata, index );
890 qApp->setStyleSheet( styledata );
892 QFile palettefile( path +
"/palette.txt" );
893 QFileInfo paletteInfo( palettefile );
894 if ( paletteInfo.exists() && palettefile.open( QIODevice::ReadOnly ) )
896 QPalette
pal = qApp->palette();
897 QTextStream in( &palettefile );
898 while ( !in.atEnd() )
900 QString line = in.readLine();
901 QStringList parts = line.split(
':' );
902 if ( parts.count() == 2 )
904 int role = parts.at( 0 ).trimmed().toInt();
906 pal.setColor(
static_cast< QPalette::ColorRole
>( role ), color );
910 qApp->setPalette(
pal );
919 QHash<QString, QString> mapping;
920 mapping.insert( QStringLiteral(
"default" ), QString() );
921 const auto constPaths = paths;
922 for (
const QString &path : constPaths )
925 QFileInfoList styleFiles = folder.entryInfoList( QDir::Dirs | QDir::NoDotAndDotDot );
926 const auto constStyleFiles = styleFiles;
927 for (
const QFileInfo &info : constStyleFiles )
929 QFileInfo styleFile( info.absoluteFilePath() +
"/style.qss" );
930 if ( !styleFile.exists() )
933 QString name = info.baseName();
934 QString path = info.absoluteFilePath();
935 mapping.insert( name, path );
943 return pkgDataPath() + QStringLiteral(
"/doc/AUTHORS" );
948 return pkgDataPath() + QStringLiteral(
"/doc/CONTRIBUTORS" );
952 return pkgDataPath() + QStringLiteral(
"/doc/developersmap.html" );
957 return pkgDataPath() + QStringLiteral(
"/doc/SPONSORS" );
962 return pkgDataPath() + QStringLiteral(
"/doc/DONORS" );
967 return pkgDataPath() + QStringLiteral(
"/doc/TRANSLATORS" );
972 return pkgDataPath() + QStringLiteral(
"/doc/LICENSE" );
977 if ( ABISYM( mRunningFromBuildDir ) )
978 return *sBuildOutputPath() + QStringLiteral(
"/i18n/" );
985 return pkgDataPath() + QStringLiteral(
"/resources/metadata-ISO/" );
990 return pkgDataPath() + QStringLiteral(
"/resources/qgis.db" );
995 return *sConfigPath();
1005 return *sAuthDbDirPath() + QStringLiteral(
"qgis-auth.db" );
1010 return QStringLiteral(
":/images/splash/" );
1015 return pkgDataPath() + QStringLiteral(
"/images/icons/" );
1020 if ( ABISYM( mRunningFromBuildDir ) )
1022 #if PROJ_VERSION_MAJOR>=6
1023 QString tempCopy = QDir::tempPath() +
"/srs6.db";
1025 QString tempCopy = QDir::tempPath() +
"/srs.db";
1028 if ( !QFile( tempCopy ).exists() )
1030 #if PROJ_VERSION_MAJOR>=6
1035 if ( !f.copy( tempCopy ) )
1037 qFatal(
"Could not create temporary copy" );
1045 return pkgDataPath() + QStringLiteral(
"/resources/srs.db" );
1054 const QStringList pathList = settings.
value( QStringLiteral(
"svg/searchPathsForSVG" ) ).toStringList();
1058 for (
const QString &path : pathList )
1060 if ( !paths.contains( path ) )
1061 paths.append( path );
1063 for (
const QString &path : qgis::as_const( *sDefaultSvgPaths() ) )
1065 if ( !paths.contains( path ) )
1066 paths.append( path );
1077 QStringList pathList = settings.
value( QStringLiteral(
"Layout/searchPathsForTemplates" ), QVariant(),
QgsSettings::Core ).toStringList();
1084 return *sSystemEnvVars();
1094 return QRegExp(
"^[A-Za-z][A-Za-z0-9\\._-]*" );
1099 if ( !sUserName()->isEmpty() )
1100 return *sUserName();
1103 TCHAR name [ UNLEN + 1 ];
1104 DWORD size = UNLEN + 1;
1106 if ( GetUserName( ( TCHAR * )name, &size ) )
1108 *sUserName() = QString::fromLocal8Bit( name );
1111 #elif QT_CONFIG(process)
1114 process.start( QStringLiteral(
"whoami" ), QStringList() );
1115 process.waitForFinished();
1116 *sUserName() = process.readAllStandardOutput().trimmed();
1119 if ( !sUserName()->isEmpty() )
1120 return *sUserName();
1123 *sUserName() = qgetenv(
"USER" );
1124 if ( !sUserName()->isEmpty() )
1125 return *sUserName();
1128 *sUserName() = qgetenv(
"USERNAME" );
1129 return *sUserName();
1134 if ( !sUserFullName()->isEmpty() )
1135 return *sUserFullName();
1138 TCHAR name [ UNLEN + 1 ];
1139 DWORD size = UNLEN + 1;
1142 if ( GetUserNameEx( NameDisplay, ( TCHAR * )name, &size ) )
1144 *sUserFullName() = QString::fromLocal8Bit( name );
1148 if ( sUserFullName()->isEmpty() )
1150 #elif defined(Q_OS_ANDROID) || defined(__MINGW32__)
1151 *sUserFullName() = QStringLiteral(
"Not available" );
1153 struct passwd *p = getpwuid( getuid() );
1157 QString gecosName = QString( p->pw_gecos );
1158 *sUserFullName() = gecosName.left( gecosName.indexOf(
',', 0 ) );
1163 return *sUserFullName();
1168 #if defined(Q_OS_ANDROID)
1169 return QLatin1String(
"android" );
1170 #elif defined(Q_OS_MAC)
1171 return QLatin1String(
"osx" );
1172 #elif defined(Q_OS_WIN)
1173 return QLatin1String(
"windows" );
1174 #elif defined(Q_OS_LINUX)
1175 return QStringLiteral(
"linux" );
1176 #elif defined(Q_OS_FREEBSD)
1177 return QStringLiteral(
"freebsd" );
1178 #elif defined(Q_OS_OPENBSD)
1179 return QStringLiteral(
"openbsd" );
1180 #elif defined(Q_OS_NETBSD)
1181 return QStringLiteral(
"netbsd" );
1182 #elif defined(Q_OS_UNIX)
1183 return QLatin1String(
"unix" );
1185 return QLatin1String(
"unknown" );
1191 return *sPlatformName();
1197 bool overrideLocale = settings.
value( QStringLiteral(
"locale/overrideFlag" ),
false ).toBool();
1198 if ( overrideLocale )
1200 QString
locale = settings.
value( QStringLiteral(
"locale/userLocale" ), QString() ).toString();
1202 if (
locale.startsWith( QLatin1String(
"en" ), Qt::CaseInsensitive ) )
1211 return QLocale().name().left( 2 );
1222 return pkgDataPath() + QStringLiteral(
"/resources/symbology-style.xml" );
1227 return pkgDataPath() + QStringLiteral(
"/resources/themes" );
1232 return pkgDataPath() + QStringLiteral(
"/resources/server/" );
1237 return *sLibraryPath();
1242 return *sLibexecPath();
1247 return *sQmlImportPath();
1252 return ( htonl( 1 ) == 1 ) ?
XDR :
NDR;
1259 init( *sProfilePath() );
1284 if (
auto *lInstance =
instance() )
1286 if ( !lInstance->mAuthManager )
1290 return lInstance->mAuthManager;
1295 if ( !sAuthManager )
1297 return sAuthManager;
1305 QThreadPool::globalInstance()->waitForDone();
1308 if (
auto *lInstance =
instance() )
1309 delete lInstance->mAuthManager;
1311 delete sAuthManager;
1316 QgsApplication::sendPostedEvents(
nullptr, QEvent::DeferredDelete );
1324 if ( QgsProviderRegistry::exists() )
1333 GDALDestroyDriverManager();
1338 QString myEnvironmentVar( getenv(
"QGIS_PREFIX_PATH" ) );
1339 QString myState = tr(
"Application state:\n"
1340 "QGIS_PREFIX_PATH env var:\t\t%1\n"
1342 "Plugin Path:\t\t%3\n"
1343 "Package Data Path:\t%4\n"
1344 "Active Theme Name:\t%5\n"
1345 "Active Theme Path:\t%6\n"
1346 "Default Theme Path:\t%7\n"
1347 "SVG Search Paths:\t%8\n"
1348 "User DB Path:\t%9\n"
1349 "Auth DB Path:\t%10\n" )
1350 .arg( myEnvironmentVar,
1357 svgPaths().join( tr(
"\n\t\t",
"match indentation of application state" ) ),
1370 QColor myColor1( Qt::lightGray );
1371 QColor myColor2 = myColor1;
1372 myColor2 = myColor2.lighter( 110 );
1374 myStyle = QStringLiteral(
".overview{"
1376 " font-weight: bold;"
1379 " background: white;"
1381 " font-family: 'Lato', 'Ubuntu', 'Lucida Grande', 'Segoe UI', 'Arial', sans-serif;"
1384 "h1{ background-color: #F6F6F6;"
1386 " font-size: x-large; "
1387 " font-weight: normal;"
1388 " background: none;"
1389 " padding: 0.75em 0 0;"
1391 " line-height: 3em;"
1393 "h2{ background-color: #F6F6F6;"
1395 " font-size: medium; "
1396 " font-weight: normal;"
1397 " background: none;"
1398 " padding: 0.75em 0 0;"
1400 " line-height: 1.1em;"
1402 "h3{ background-color: #F6F6F6;"
1404 " font-weight: bold;"
1405 " font-size: large;"
1406 " text-align: left;"
1407 " border-bottom: 5px solid #DCEB5C;"
1409 "h4{ background-color: #F6F6F6;"
1411 " font-weight: bold;"
1412 " font-size: medium;"
1413 " text-align: left;"
1415 "h5{ background-color: #F6F6F6;"
1417 " font-weight: bold;"
1418 " font-size: small;"
1419 " text-align: left;"
1421 "a{ color: #729FCF;"
1422 " font-family: arial,sans-serif;"
1424 "label{ background-color: #FFFFCC;"
1425 " border: 1px solid black;"
1427 " padding: 0px 3px; "
1428 " font-size: small;"
1431 " font-weight: bold;"
1436 " border-top: 1px solid black;"
1438 ".list-view .highlight {"
1439 " text-align: left;"
1442 " padding-right: 15px;"
1443 " padding-left: 20px;"
1444 " font-weight: bold;"
1446 ".tabular-view .odd-row {"
1447 " background-color: #f9f9f9;"
1450 " font-weight: bold;"
1451 " padding-top:25px;"
1455 switch ( styleSheetType )
1457 case StyleSheetType::Qt:
1458 myStyle += QStringLiteral(
1460 " border-collapse: collapse;"
1463 ".tabular-view th, .tabular-view td { "
1464 " border:1px solid black;"
1468 case StyleSheetType::WebBrowser:
1469 myStyle += QStringLiteral(
1474 "table.tabular-view, table.list-view { "
1475 " border-collapse: collapse;"
1476 " table-layout:fixed;"
1477 " width: 100% !important;"
1482 " line-height: inherit;"
1485 " word-wrap: break-word; "
1486 " vertical-align: top;"
1489 ".list-view th:first-child, .list-view td:first-child {"
1492 ".list-view.highlight { "
1493 " padding-left: inherit; "
1496 ".tabular-view th:first-child, .tabular-view td:first-child { "
1500 ".tabular-view th.strong { "
1501 " background-color: #eee; "
1504 ".tabular-view th, .tabular-view td { "
1505 " border: 1px solid #eee;"
1516 if ( 0 >= OGRGetDriverCount() )
1524 QString aPathUrl = aPath;
1525 QString tPathUrl = targetPath;
1526 #if defined( Q_OS_WIN )
1527 const Qt::CaseSensitivity cs = Qt::CaseInsensitive;
1529 aPathUrl.replace(
'\\',
'/' );
1530 if ( aPathUrl.startsWith(
"//" ) )
1533 aPathUrl =
"\\\\" + aPathUrl.mid( 2 );
1536 tPathUrl.replace(
'\\',
'/' );
1537 if ( tPathUrl.startsWith(
"//" ) )
1540 tPathUrl =
"\\\\" + tPathUrl.mid( 2 );
1543 const Qt::CaseSensitivity cs = Qt::CaseSensitive;
1546 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
1547 QStringList targetElems = tPathUrl.split(
'/', QString::SkipEmptyParts );
1548 QStringList aPathElems = aPathUrl.split(
'/', QString::SkipEmptyParts );
1550 QStringList targetElems = tPathUrl.split(
'/', Qt::SkipEmptyParts );
1551 QStringList aPathElems = aPathUrl.split(
'/', Qt::SkipEmptyParts );
1554 targetElems.removeAll( QStringLiteral(
"." ) );
1555 aPathElems.removeAll( QStringLiteral(
"." ) );
1559 while ( !aPathElems.isEmpty() &&
1560 !targetElems.isEmpty() &&
1561 aPathElems[0].compare( targetElems[0], cs ) == 0 )
1563 aPathElems.removeFirst();
1564 targetElems.removeFirst();
1574 if ( !targetElems.isEmpty() )
1577 for (
int i = 0; i < targetElems.size(); i++ )
1579 aPathElems.insert( 0, QStringLiteral(
".." ) );
1586 aPathElems.insert( 0, QStringLiteral(
"." ) );
1589 return aPathElems.join( QLatin1Char(
'/' ) );
1595 if ( !rpath.startsWith( QLatin1String(
"./" ) ) && !rpath.startsWith( QLatin1String(
"../" ) ) )
1600 QString rPathUrl = rpath;
1601 QString targetPathUrl = targetPath;
1603 #if defined(Q_OS_WIN)
1604 rPathUrl.replace(
'\\',
'/' );
1605 targetPathUrl.replace(
'\\',
'/' );
1607 bool uncPath = targetPathUrl.startsWith(
"//" );
1610 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
1611 QStringList srcElems = rPathUrl.split(
'/', QString::SkipEmptyParts );
1612 QStringList targetElems = targetPathUrl.split(
'/', QString::SkipEmptyParts );
1614 QStringList srcElems = rPathUrl.split(
'/', Qt::SkipEmptyParts );
1615 QStringList targetElems = targetPathUrl.split(
'/', Qt::SkipEmptyParts );
1618 #if defined(Q_OS_WIN)
1621 targetElems.insert( 0,
"" );
1622 targetElems.insert( 0,
"" );
1627 targetElems << srcElems;
1628 targetElems.removeAll( QStringLiteral(
"." ) );
1632 while ( ( pos = targetElems.indexOf( QLatin1String(
".." ) ) ) > 0 )
1635 targetElems.removeAt( pos - 1 );
1636 targetElems.removeAt( pos - 1 );
1639 #if !defined(Q_OS_WIN)
1641 targetElems.prepend( QString() );
1644 return targetElems.join( QLatin1Char(
'/' ) );
1649 return *sBuildSourcePath();
1654 return *sBuildOutputPath();
1657 #if defined(_MSC_VER) && !defined(USING_NMAKE) && !defined(USING_NINJA)
1658 QString QgsApplication::cfgIntDir()
1660 return *sCfgIntDir();
1666 if ( sGdalSkipList()->contains( driver ) || driver.isEmpty() )
1670 *sGdalSkipList() << driver;
1676 if ( !sGdalSkipList()->contains( driver ) )
1680 int myPos = sGdalSkipList()->indexOf( driver );
1683 sGdalSkipList()->removeAt( myPos );
1690 return *sGdalSkipList();
1694 const QStringList &deferredSkippedGdalDrivers )
1708 QString joinedList, delimiter;
1709 if ( settings.
contains( QStringLiteral(
"gdal/skipDrivers" ) ) )
1711 joinedList = settings.
value( QStringLiteral(
"gdal/skipDrivers" ), QString() ).toString();
1712 delimiter = QStringLiteral(
"," );
1716 joinedList = settings.
value( QStringLiteral(
"gdal/skipList" ), QString() ).toString();
1717 delimiter = QStringLiteral(
" " );
1720 if ( !joinedList.isEmpty() )
1722 myList = joinedList.split( delimiter );
1724 *sGdalSkipList() = myList;
1730 return *sDeferredSkippedGdalDrivers();
1735 sGdalSkipList()->removeDuplicates();
1736 QStringList realDisabledDriverList;
1737 for (
const auto &driverName : *sGdalSkipList() )
1739 if ( !sDeferredSkippedGdalDrivers()->contains( driverName ) )
1740 realDisabledDriverList << driverName;
1742 QString myDriverList = realDisabledDriverList.join(
',' );
1743 QgsDebugMsgLevel( QStringLiteral(
"Gdal Skipped driver list set to:" ), 2 );
1745 CPLSetConfigOption(
"GDAL_SKIP", myDriverList.toUtf8() );
1752 QDir myDir( folder );
1753 if ( !myDir.exists() )
1755 myDir.mkpath( folder );
1761 void QgsApplication::copyPath(
const QString &src,
const QString &dst )
1764 if ( ! dir.exists() )
1767 const auto subDirectories = dir.entryList( QDir::Dirs | QDir::NoDotAndDotDot );
1768 for (
const QString &d : subDirectories )
1770 QString dst_path = dst + QDir::separator() + d;
1771 dir.mkpath( dst_path );
1772 copyPath( src + QDir::separator() + d, dst_path );
1775 const auto files = dir.entryList( QDir::Files );
1776 for (
const QString &f : files )
1778 QFile::copy( src + QDir::separator() + f, dst + QDir::separator() + f );
1787 QVariantMap variables;
1791 QStringList childKeys = settings.
childKeys();
1792 for ( QStringList::const_iterator it = childKeys.constBegin(); it != childKeys.constEnd(); ++it )
1795 variables.insert( name, settings.
value( name ) );
1805 QVariantMap::const_iterator it = variables.constBegin();
1808 for ( ; it != variables.constEnd(); ++it )
1810 settings.
setValue( it.key(), it.value() );
1821 settings.
setValue( QStringLiteral(
"variables/" ) + name, value );
1828 QFontMetrics fm( ( QFont() ) );
1829 const double scale = 1.1 * standardSize / 24;
1830 int scaledIconSize =
static_cast< int >( std::floor( std::max(
Qgis::UI_SCALE_FACTOR * fm.height() * scale,
static_cast< double >( standardSize ) ) ) );
1831 if ( applyDevicePixelRatio && QApplication::desktop() )
1832 scaledIconSize *= QApplication::desktop()->devicePixelRatio();
1833 return scaledIconSize;
1843 *sTranslation() = translation;
1853 ApplicationMembers *appMembers = members();
1854 if ( appMembers->mNullRepresentation.isNull() )
1856 appMembers->mNullRepresentation =
QgsSettings().
value( QStringLiteral(
"qgis/nullValue" ), QStringLiteral(
"NULL" ) ).toString();
1858 return appMembers->mNullRepresentation;
1863 ApplicationMembers *appMembers = members();
1877 return members()->mActionScopeRegistry;
1886 QDir myDir( myPamPath );
1887 if ( !myDir.exists() )
1889 myDir.mkpath( myPamPath );
1892 #if defined(Q_OS_WIN)
1893 CPLSetConfigOption(
"GDAL_PAM_PROXY_DIR", myPamPath.toUtf8() );
1897 int myChangeFlag = 0;
1898 setenv(
"GDAL_PAM_PROXY_DIR", myPamPath.toUtf8(), myChangeFlag );
1905 if ( !qgisPrivateDbFile.exists() )
1909 QFile masterFile( qgisMasterDbFileName );
1915 bool isDbFileCopied = masterFile.copy( qgisPrivateDbFile.fileName() );
1917 if ( !isDbFileCopied )
1921 *errorMessage = tr(
"[ERROR] Can not make qgis.db private copy" );
1926 QFile::Permissions perms = QFile( qgisPrivateDbFile.fileName() ).permissions();
1927 if ( !( perms & QFile::WriteOwner ) )
1929 if ( !qgisPrivateDbFile.setPermissions( perms | QFile::WriteOwner ) )
1933 *errorMessage = tr(
"Can not make '%1' user writable" ).arg( qgisPrivateDbFile.fileName() );
1947 *errorMessage = tr(
"Could not open qgis.db" );
1952 char *errmsg =
nullptr;
1953 int res = sqlite3_exec( database.get(),
"SELECT srs_id FROM tbl_srs LIMIT 0",
nullptr,
nullptr, &errmsg );
1954 if ( res != SQLITE_OK )
1956 sqlite3_free( errmsg );
1959 if ( sqlite3_exec( database.get(),
1960 "DROP INDEX IF EXISTS idx_srsauthid;"
1961 "CREATE TABLE tbl_srs ("
1962 "srs_id INTEGER PRIMARY KEY,"
1963 "description text NOT NULL,"
1964 "projection_acronym text NOT NULL,"
1965 "ellipsoid_acronym NOT NULL,"
1966 "parameters text NOT NULL,"
1968 "auth_name varchar,"
1970 "is_geo integer NOT NULL,"
1971 "deprecated boolean,"
1973 "CREATE INDEX idx_srsauthid on tbl_srs(auth_name,auth_id);",
nullptr,
nullptr, &errmsg ) != SQLITE_OK )
1977 *errorMessage = tr(
"Creation of missing tbl_srs in the private qgis.db failed.\n%1" ).arg( QString::fromUtf8( errmsg ) );
1979 sqlite3_free( errmsg );
1986 res = sqlite3_exec( database.get(),
"SELECT wkt FROM tbl_srs LIMIT 0",
nullptr,
nullptr, &errmsg );
1987 if ( res != SQLITE_OK )
1990 sqlite3_free( errmsg );
1991 if ( sqlite3_exec( database.get(),
1992 "DROP INDEX IF EXISTS idx_srsauthid;"
1993 "DROP TABLE IF EXISTS tbl_srs_bak;"
1994 "ALTER TABLE tbl_srs RENAME TO tbl_srs_bak;"
1995 "CREATE TABLE tbl_srs ("
1996 "srs_id INTEGER PRIMARY KEY,"
1997 "description text NOT NULL,"
1998 "projection_acronym text NOT NULL,"
1999 "ellipsoid_acronym NOT NULL,"
2000 "parameters text NOT NULL,"
2002 "auth_name varchar,"
2004 "is_geo integer NOT NULL,"
2005 "deprecated boolean,"
2007 "CREATE INDEX idx_srsauthid on tbl_srs(auth_name,auth_id);"
2008 "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;"
2009 "DROP TABLE tbl_srs_bak",
nullptr,
nullptr, &errmsg ) != SQLITE_OK )
2013 *errorMessage = tr(
"Migration of private qgis.db failed.\n%1" ).arg( QString::fromUtf8( errmsg ) );
2015 sqlite3_free( errmsg );
2021 res = sqlite3_exec( database.get(),
"SELECT acronym FROM tbl_projection LIMIT 0",
nullptr,
nullptr, &errmsg );
2022 if ( res != SQLITE_OK )
2024 sqlite3_free( errmsg );
2027 if ( sqlite3_exec( database.get(),
2028 "CREATE TABLE tbl_projection ("
2029 "acronym varchar(20) NOT NULL PRIMARY KEY,"
2030 "name varchar(255) NOT NULL default '',"
2031 "notes varchar(255) NOT NULL default '',"
2032 "parameters varchar(255) NOT NULL default ''"
2033 ")",
nullptr,
nullptr, &errmsg ) != SQLITE_OK )
2037 *errorMessage = tr(
"Creation of missing tbl_projection in the private qgis.db failed.\n%1" ).arg( QString::fromUtf8( errmsg ) );
2039 sqlite3_free( errmsg );
2044 res = sqlite3_exec( database.get(),
"SELECT epsg FROM tbl_srs LIMIT 0",
nullptr,
nullptr, &errmsg );
2045 if ( res == SQLITE_OK )
2048 if ( sqlite3_exec( database.get(),
2049 "DROP INDEX IF EXISTS idx_srsauthid;"
2050 "DROP TABLE IF EXISTS tbl_srs_bak;"
2051 "ALTER TABLE tbl_srs RENAME TO tbl_srs_bak;"
2052 "CREATE TABLE tbl_srs ("
2053 "srs_id INTEGER PRIMARY KEY,"
2054 "description text NOT NULL,"
2055 "projection_acronym text NOT NULL,"
2056 "ellipsoid_acronym NOT NULL,"
2057 "parameters text NOT NULL,"
2059 "auth_name varchar,"
2061 "is_geo integer NOT NULL,"
2062 "deprecated boolean,"
2064 "CREATE INDEX idx_srsauthid on tbl_srs(auth_name,auth_id);"
2065 "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;"
2066 "DROP TABLE tbl_srs_bak",
nullptr,
nullptr, &errmsg ) != SQLITE_OK )
2070 *errorMessage = tr(
"Migration of private qgis.db failed.\n%1" ).arg( QString::fromUtf8( errmsg ) );
2072 sqlite3_free( errmsg );
2078 sqlite3_free( errmsg );
2081 if ( sqlite3_exec( database.get(),
"DROP VIEW vw_srs",
nullptr,
nullptr, &errmsg ) != SQLITE_OK )
2083 QgsDebugMsg( QStringLiteral(
"vw_srs didn't exists in private qgis.db: %1" ).arg( errmsg ) );
2086 if ( sqlite3_exec( database.get(),
2087 "CREATE VIEW vw_srs AS"
2089 " a.description AS description"
2090 ",a.srs_id AS srs_id"
2091 ",a.is_geo AS is_geo"
2092 ",coalesce(b.name,a.projection_acronym) AS name"
2093 ",a.parameters AS parameters"
2094 ",a.auth_name AS auth_name"
2095 ",a.auth_id AS auth_id"
2096 ",a.deprecated AS deprecated"
2098 " LEFT OUTER JOIN tbl_projection b ON a.projection_acronym=b.acronym"
2099 " ORDER BY coalesce(b.name,a.projection_acronym),a.description",
nullptr,
nullptr, &errmsg ) != SQLITE_OK )
2103 *errorMessage = tr(
"Update of view in private qgis.db failed.\n%1" ).arg( QString::fromUtf8( errmsg ) );
2105 sqlite3_free( errmsg );
2118 if ( maxThreads < 1 || maxThreads > QThread::idealThreadCount() )
2129 QThreadPool::globalInstance()->setMaxThreadCount(
maxThreads );
2130 QgsDebugMsgLevel( QStringLiteral(
"set QThreadPool max thread count to %1" ).arg( QThreadPool::globalInstance()->maxThreadCount() ), 2 );
2135 return members()->mTaskManager;
2140 return members()->mColorSchemeRegistry;
2145 return members()->mPaintEffectRegistry;
2150 return members()->mRendererRegistry;
2155 return members()->mRasterRendererRegistry;
2160 if (
auto *lInstance =
instance() )
2162 if ( !
instance()->mDataItemProviderRegistry )
2166 return lInstance->mDataItemProviderRegistry;
2172 if ( !sDataItemProviderRegistry )
2174 return sDataItemProviderRegistry;
2180 return members()->mSvgCache;
2185 return members()->mImageCache;
2190 return members()->mSourceCache;
2195 return members()->mNetworkContentFetcherRegistry;
2200 return members()->mValidityCheckRegistry;
2205 return members()->mSymbolLayerRegistry;
2210 return members()->mCalloutRegistry;
2215 return members()->mLayoutItemRegistry;
2220 return members()->mAnnotationItemRegistry;
2225 return members()->mGpsConnectionRegistry;
2230 return members()->mPluginLayerRegistry;
2235 return members()->mClassificationMethodRegistry;
2240 return members()->mBookmarkManager;
2245 return members()->mStyleModel;
2250 return members()->mMessageLog;
2255 return members()->mProcessingRegistry;
2260 return members()->mConnectionRegistry;
2265 return members()->mPageSizeRegistry;
2270 return members()->mAnnotationRegistry;
2275 return members()->mNumericFormatRegistry;
2280 return members()->mFieldFormatterRegistry;
2285 return members()->m3DRendererRegistry;
2290 return members()->m3DSymbolRegistry;
2295 return members()->mScaleBarRendererRegistry;
2300 return members()->mProjectStorageRegistry;
2305 return members()->mLocalizedDataPathRegistry;
2308 QgsApplication::ApplicationMembers::ApplicationMembers()
2317 profiler->
start( tr(
"Create connection registry" ) );
2322 profiler->
start( tr(
"Setup task manager" ) );
2327 profiler->
start( tr(
"Setup action scope registry" ) );
2332 profiler->
start( tr(
"Setup numeric formats" ) );
2337 profiler->
start( tr(
"Setup field formats" ) );
2342 profiler->
start( tr(
"Setup SVG cache" ) );
2347 profiler->
start( tr(
"Setup image cache" ) );
2352 profiler->
start( tr(
"Setup source cache" ) );
2357 profiler->
start( tr(
"Setup color scheme registry" ) );
2362 profiler->
start( tr(
"Setup paint effect" ) );
2367 profiler->
start( tr(
"Setup symbol layer registry" ) );
2372 profiler->
start( tr(
"Setup callout registry" ) );
2377 profiler->
start( tr(
"Setup renderer registry" ) );
2382 profiler->
start( tr(
"Setup raster renderer registry" ) );
2387 profiler->
start( tr(
"Setup GPS registry" ) );
2392 profiler->
start( tr(
"Setup plugin layer registry" ) );
2397 profiler->
start( tr(
"Setup Processing registry" ) );
2403 profiler->
start( tr(
"Setup layout item registry" ) );
2405 mLayoutItemRegistry->populate();
2409 profiler->
start( tr(
"Setup annotation registry" ) );
2410 mAnnotationRegistry =
new QgsAnnotationRegistry();
2414 profiler->
start( tr(
"Setup annotation item registry" ) );
2416 mAnnotationItemRegistry->populate();
2420 profiler->
start( tr(
"Setup 3D symbol registry" ) );
2425 profiler->
start( tr(
"Setup 3D renderer registry" ) );
2430 profiler->
start( tr(
"Setup project storage registry" ) );
2435 profiler->
start( tr(
"Setup network content cache" ) );
2440 profiler->
start( tr(
"Setup layout check registry" ) );
2445 profiler->
start( tr(
"Setup classification registry" ) );
2450 profiler->
start( tr(
"Setup bookmark manager" ) );
2455 profiler->
start( tr(
"Setup scalebar registry" ) );
2461 QgsApplication::ApplicationMembers::~ApplicationMembers()
2464 delete mScaleBarRendererRegistry;
2465 delete mValidityCheckRegistry;
2466 delete mActionScopeRegistry;
2467 delete m3DRendererRegistry;
2468 delete m3DSymbolRegistry;
2469 delete mAnnotationRegistry;
2470 delete mColorSchemeRegistry;
2471 delete mFieldFormatterRegistry;
2472 delete mGpsConnectionRegistry;
2474 delete mPaintEffectRegistry;
2475 delete mPluginLayerRegistry;
2476 delete mProcessingRegistry;
2477 delete mProjectStorageRegistry;
2478 delete mPageSizeRegistry;
2479 delete mAnnotationItemRegistry;
2480 delete mLayoutItemRegistry;
2481 delete mRasterRendererRegistry;
2482 delete mRendererRegistry;
2485 delete mSourceCache;
2486 delete mCalloutRegistry;
2487 delete mSymbolLayerRegistry;
2488 delete mTaskManager;
2489 delete mNetworkContentFetcherRegistry;
2490 delete mClassificationMethodRegistry;
2491 delete mNumericFormatRegistry;
2492 delete mBookmarkManager;
2493 delete mConnectionRegistry;
2494 delete mLocalizedDataPathRegistry;
2497 QgsApplication::ApplicationMembers *QgsApplication::members()
2499 if (
auto *lInstance =
instance() )
2501 return lInstance->mApplicationMembers;
2505 static QMutex sMemberMutex( QMutex::Recursive );
2506 QMutexLocker lock( &sMemberMutex );
2507 if ( !sApplicationMembers )
2508 sApplicationMembers =
new ApplicationMembers();
2509 return sApplicationMembers;