69 #include "processing/models/qgsprocessingmodelchildparametersource.h"
70 #include "processing/models/qgsprocessingmodelchilddependency.h"
77 #include <QFileOpenEvent>
78 #include <QMessageBox>
81 #include <QProcessEnvironment>
84 #include <QThreadPool>
89 #include <netinet/in.h>
95 #define SECURITY_WIN32
97 #pragma comment( lib, "Secur32.lib" )
100 #include "qgsconfig.h"
104 #include <cpl_conv.h>
107 #if PROJ_VERSION_MAJOR>=6
112 #define CONN_POOL_MAX_CONCURRENT_CONNS 4
114 QObject *
ABISYM( QgsApplication::mFileOpenEventReceiver ) =
nullptr;
115 bool ABISYM( QgsApplication::mInitialized ) =
false;
116 bool ABISYM( QgsApplication::mRunningFromBuildDir ) =
false;
120 QgsApplication::ApplicationMembers *QgsApplication::sApplicationMembers =
nullptr;
122 int ABISYM( QgsApplication::sMaxThreads ) = -1;
139 #if defined(_MSC_VER) && !defined(USING_NMAKE) && !defined(USING_NINJA)
153 : QApplication( argc, argv, GUIenabled )
155 *sPlatformName() = platformName;
157 if ( *sTranslation() != QLatin1String(
"C" ) )
159 mQgisTranslator =
new QTranslator();
160 if ( mQgisTranslator->load( QStringLiteral(
"qgis_" ) + *sTranslation(), i18nPath() ) )
162 installTranslator( mQgisTranslator );
166 QgsDebugMsgLevel( QStringLiteral(
"loading of qgis translation failed %1/qgis_%2" ).arg( i18nPath(), *sTranslation() ), 2 );
174 mQtTranslator =
new QTranslator();
175 if ( mQtTranslator->load( QStringLiteral(
"qt_" ) + *sTranslation(), QLibraryInfo::location( QLibraryInfo::TranslationsPath ) ) )
177 installTranslator( mQtTranslator );
181 QgsDebugMsgLevel( QStringLiteral(
"loading of qt translation failed %1/qt_%2" ).arg( QLibraryInfo::location( QLibraryInfo::TranslationsPath ), *sTranslation() ), 2 );
185 mApplicationMembers =
new ApplicationMembers();
187 *sProfilePath() = profileFolder;
192 if ( profileFolder.isEmpty() )
194 if ( getenv(
"QGIS_CUSTOM_CONFIG_PATH" ) )
196 profileFolder = getenv(
"QGIS_CUSTOM_CONFIG_PATH" );
200 profileFolder = QStandardPaths::standardLocations( QStandardPaths::AppDataLocation ).value( 0 );
207 profileFolder = profile->
folder();
211 *sProfilePath() = profileFolder;
213 qRegisterMetaType<QgsGeometry::Error>(
"QgsGeometry::Error" );
214 qRegisterMetaType<QgsProcessingFeatureSourceDefinition>(
"QgsProcessingFeatureSourceDefinition" );
215 qRegisterMetaType<QgsProcessingOutputLayerDefinition>(
"QgsProcessingOutputLayerDefinition" );
216 qRegisterMetaType<QgsUnitTypes::LayoutUnit>(
"QgsUnitTypes::LayoutUnit" );
217 qRegisterMetaType<QgsFeatureId>(
"QgsFeatureId" );
218 qRegisterMetaType<QgsFeatureIds>(
"QgsFeatureIds" );
219 qRegisterMetaType<QgsProperty>(
"QgsProperty" );
220 qRegisterMetaType<Qgis::MessageLevel>(
"Qgis::MessageLevel" );
221 qRegisterMetaType<QgsReferencedRectangle>(
"QgsReferencedRectangle" );
222 qRegisterMetaType<QgsReferencedPointXY>(
"QgsReferencedPointXY" );
223 qRegisterMetaType<QgsLayoutRenderContext::Flags>(
"QgsLayoutRenderContext::Flags" );
224 qRegisterMetaType<QgsStyle::StyleEntity>(
"QgsStyle::StyleEntity" );
225 qRegisterMetaType<QgsCoordinateReferenceSystem>(
"QgsCoordinateReferenceSystem" );
226 qRegisterMetaType<QgsAuthManager::MessageLevel>(
"QgsAuthManager::MessageLevel" );
227 qRegisterMetaType<QgsNetworkRequestParameters>(
"QgsNetworkRequestParameters" );
228 qRegisterMetaType<QgsNetworkReplyContent>(
"QgsNetworkReplyContent" );
229 qRegisterMetaType<QgsGeometry>(
"QgsGeometry" );
230 qRegisterMetaType<QgsDatumTransform::GridDetails>(
"QgsDatumTransform::GridDetails" );
231 qRegisterMetaType<QgsDatumTransform::TransformDetails>(
"QgsDatumTransform::TransformDetails" );
232 qRegisterMetaType<QgsNewsFeedParser::Entry>(
"QgsNewsFeedParser::Entry" );
233 qRegisterMetaType<QgsRectangle>(
"QgsRectangle" );
234 qRegisterMetaType<QgsProcessingModelChildParameterSource>(
"QgsProcessingModelChildParameterSource" );
235 qRegisterMetaTypeStreamOperators<QgsProcessingModelChildParameterSource>(
"QgsProcessingModelChildParameterSource" );
236 qRegisterMetaType<QgsRemappingSinkDefinition>(
"QgsRemappingSinkDefinition" );
237 qRegisterMetaType<QgsProcessingModelChildDependency>(
"QgsProcessingModelChildDependency" );
238 QMetaType::registerComparators<QgsProcessingModelChildDependency>();
242 if ( ABISYM( mRunningFromBuildDir ) )
245 *sPrefixPath() = QString();
246 #if defined(_MSC_VER) && !defined(USING_NMAKE) && !defined(USING_NINJA)
247 setPluginPath( *sBuildOutputPath() +
'/' + QString( QGIS_PLUGIN_SUBDIR ) +
'/' + *sCfgIntDir() );
249 setPluginPath( *sBuildOutputPath() +
'/' + QStringLiteral( QGIS_PLUGIN_SUBDIR ) );
251 setPkgDataPath( *sBuildOutputPath() + QStringLiteral(
"/data" ) );
252 *sLibraryPath() = *sBuildOutputPath() +
'/' + QGIS_LIB_SUBDIR +
'/';
253 #if defined(_MSC_VER) && !defined(USING_NMAKE) && !defined(USING_NINJA)
254 *sLibexecPath() = *sBuildOutputPath() +
'/' + QGIS_LIBEXEC_SUBDIR +
'/' + *sCfgIntDir() +
'/';
256 *sLibexecPath() = *sBuildOutputPath() +
'/' + QGIS_LIBEXEC_SUBDIR +
'/';
258 #if defined( HAVE_QUICK )
259 *sQmlImportPath() = *sBuildOutputPath() +
'/' + QGIS_QML_SUBDIR +
'/';
264 char *
prefixPath = getenv(
"QGIS_PREFIX_PATH" );
267 if ( sPrefixPath()->isNull() )
269 #if defined(Q_OS_MACX) || defined(Q_OS_WIN)
271 #elif defined(ANDROID)
273 QDir myDir( QDir::homePath() );
275 QString myPrefix = myDir.absolutePath();
278 QDir myDir( applicationDirPath() );
280 if ( applicationDirPath().contains( QStringLiteral(
"cgi-bin" ) ) )
285 QString myPrefix = myDir.absolutePath();
296 *sConfigPath() = profileFolder +
'/';
300 if ( getenv(
"QGIS_AUTH_DB_DIR_PATH" ) )
306 QMap<QString, QString> systemEnvVarMap;
307 QString passfile( QStringLiteral(
"QGIS_AUTH_PASSWORD_FILE" ) );
309 const auto systemEnvironment = QProcessEnvironment::systemEnvironment().toStringList();
310 for (
const QString &varStr : systemEnvironment )
312 int pos = varStr.indexOf( QLatin1Char(
'=' ) );
315 QString varStrName = varStr.left( pos );
316 QString varStrValue = varStr.mid( pos + 1 );
317 if ( varStrName != passfile )
319 systemEnvVarMap.insert( varStrName, varStrValue );
322 *sSystemEnvVars() = systemEnvVarMap;
324 #if PROJ_VERSION_MAJOR>=6
328 char **newPaths =
new char *[currentProjSearchPaths.length()];
329 for (
int i = 0; i < currentProjSearchPaths.count(); ++i )
331 newPaths[i] = CPLStrdup( currentProjSearchPaths.at( i ).toUtf8().constData() );
333 proj_context_set_search_paths(
nullptr, currentProjSearchPaths.count(), newPaths );
334 for (
int i = 0; i < currentProjSearchPaths.count(); ++i )
336 CPLFree( newPaths[i] );
343 QCoreApplication::addLibraryPath(
pluginPath() );
348 ABISYM( sMaxThreads ) = -1;
361 if ( !members()->mStyleModel )
364 ABISYM( mInitialized ) =
true;
369 delete mDataItemProviderRegistry;
370 delete mApplicationMembers;
371 delete mQgisTranslator;
372 delete mQtTranslator;
380 void QgsApplication::invalidateCaches()
392 return qobject_cast<QgsApplication *>( QCoreApplication::instance() );
398 if (
event->type() == QEvent::FileOpen )
401 if ( ABISYM( mFileOpenEventReceiver ) )
404 done =
notify( ABISYM( mFileOpenEventReceiver ),
event );
411 sFileOpenEventList()->append(
static_cast<QFileOpenEvent *
>(
event )->file() );
418 done = QApplication::event(
event );
427 if ( thread() == receiver->thread() )
437 done = QApplication::notify( receiver,
event );
442 if ( qApp->thread() == QThread::currentThread() )
443 QMessageBox::critical( activeWindow(), tr(
"Exception" ), e.
what() );
445 catch ( std::exception &e )
447 QgsDebugMsg(
"Caught unhandled std::exception: " + QString::fromLatin1( e.what() ) );
448 if ( qApp->thread() == QThread::currentThread() )
449 QMessageBox::critical( activeWindow(), tr(
"Exception" ), e.what() );
453 QgsDebugMsg( QStringLiteral(
"Caught unhandled unknown exception" ) );
454 if ( qApp->thread() == QThread::currentThread() )
455 QMessageBox::critical( activeWindow(), tr(
"Exception" ), tr(
"unknown exception" ) );
463 return members()->mProfiler;
469 ABISYM( mFileOpenEventReceiver ) = receiver;
471 if ( sFileOpenEventList()->count() > 0 )
473 const QStringList fileOpenEventList = *sFileOpenEventList();
474 for (
const QString &file : fileOpenEventList )
476 QFileOpenEvent foe( file );
477 QgsApplication::sendEvent( ABISYM( mFileOpenEventReceiver ), &foe );
479 sFileOpenEventList()->clear();
486 #if defined(Q_OS_WIN)
487 if ( sPrefixPath()->endsWith(
"/bin" ) )
489 sPrefixPath()->chop( 4 );
492 if ( useDefaultPaths && !ABISYM( mRunningFromBuildDir ) )
494 setPluginPath( *sPrefixPath() +
'/' + QStringLiteral( QGIS_PLUGIN_SUBDIR ) );
495 setPkgDataPath( *sPrefixPath() +
'/' + QStringLiteral( QGIS_DATA_SUBDIR ) );
497 *sLibraryPath() = *sPrefixPath() +
'/' + QGIS_LIB_SUBDIR +
'/';
498 *sLibexecPath() = *sPrefixPath() +
'/' + QGIS_LIBEXEC_SUBDIR +
'/';
499 #if defined( HAVE_QUICK )
500 *sQmlImportPath() = *sPrefixPath() +
'/' + QGIS_QML_SUBDIR +
'/';
513 QString mySvgPath =
pkgDataPath + QStringLiteral(
"/svg/" );
516 if ( !sDefaultSvgPaths()->contains( mySvgPath ) )
517 *sDefaultSvgPaths() << mySvgPath;
522 *sDefaultSvgPaths() = pathList;
527 QFileInfo fi( authDbDirPath );
528 if ( fi.exists() && fi.isDir() && fi.isWritable() )
530 *sAuthDbDirPath() = fi.canonicalFilePath() + QDir::separator();
537 if ( ABISYM( mRunningFromBuildDir ) )
539 static bool sOnce =
true;
543 ( void ) blockNotifications;
544 qWarning(
"!!! prefix path was requested, but it is not valid - we do not run from installed path !!!" );
550 return *sPrefixPath();
554 return *sPluginPath();
559 if ( sPkgDataPath()->isNull() )
562 return *sPkgDataPath();
567 return QStringLiteral(
":/images/themes/default/" );
572 QDir dir( usersThemes );
580 return defaultThemes;
586 return iconsPath() + QStringLiteral(
"qgis-icon-60x60.png" );
591 return ABISYM( sMaxThreads );
598 if ( QFile::exists( path + iconFile ) )
599 return path + iconFile;
608 if ( app && app->mIconCache.contains( name ) )
609 return app->mIconCache.value( name );
613 QString myPreferredPath =
activeThemePath() + QDir::separator() + name;
615 if ( QFile::exists( myPreferredPath ) )
617 icon = QIcon( myPreferredPath );
619 else if ( QFile::exists( myDefaultPath ) )
623 icon = QIcon( myDefaultPath );
631 app->mIconCache.insert( name, icon );
638 if ( app && app->mCursorCache.contains( cursor ) )
639 return app->mCursorCache.value( cursor );
650 name = QStringLiteral(
"mZoomIn.svg" );
655 name = QStringLiteral(
"mZoomOut.svg" );
662 name = QStringLiteral(
"mIdentify.svg" );
665 name = QStringLiteral(
"mCrossHair.svg" );
668 name = QStringLiteral(
"mCapturePoint.svg" );
671 name = QStringLiteral(
"mSelect.svg" );
678 name = QStringLiteral(
"mSampler.svg" );
683 Q_ASSERT( ! name.isEmpty( ) );
685 QIcon icon =
getThemeIcon( QStringLiteral(
"cursors" ) + QDir::separator() + name );
688 if ( ! icon.isNull( ) )
692 cursorIcon = QCursor( icon.pixmap( std::ceil( scale * 32 ), std::ceil( scale * 32 ) ), std::ceil( scale * activeX ), std::ceil( scale * activeY ) );
695 app->mCursorCache.insert( cursor, cursorIcon );
702 QString myPreferredPath =
activeThemePath() + QDir::separator() + name;
704 if ( QFile::exists( myPreferredPath ) )
706 return QPixmap( myPreferredPath );
712 return QPixmap( myDefaultPath );
723 static QString appPath;
724 if ( appPath.isNull() )
726 if ( QCoreApplication::instance() )
728 appPath = applicationDirPath();
732 qWarning(
"Application path not initialized" );
736 if ( !appPath.isNull() || getenv(
"QGIS_PREFIX_PATH" ) )
738 QString prefix = getenv(
"QGIS_PREFIX_PATH" ) ? getenv(
"QGIS_PREFIX_PATH" ) : appPath;
743 static const QStringList paths { QStringList() << QString() << QStringLiteral(
"/.." ) << QStringLiteral(
"/bin" ) << QStringLiteral(
"/../../.." ) };
744 for (
const QString &path : paths )
746 f.setFileName( prefix + path +
"/qgisbuildpath.txt" );
750 if ( f.exists() && f.open( QIODevice::ReadOnly ) )
752 ABISYM( mRunningFromBuildDir ) =
true;
753 *sBuildSourcePath() = f.readLine().trimmed();
754 *sBuildOutputPath() = f.readLine().trimmed();
756 QgsDebugMsgLevel( QStringLiteral(
"- source directory: %1" ).arg( sBuildSourcePath()->toUtf8().constData() ), 4 );
757 QgsDebugMsgLevel( QStringLiteral(
"- output directory of the build: %1" ).arg( sBuildOutputPath()->toUtf8().constData() ), 4 );
758 #if defined(_MSC_VER) && !defined(USING_NMAKE) && !defined(USING_NINJA)
759 *sCfgIntDir() = appPath.split(
'/', QString::SkipEmptyParts ).last();
760 qDebug(
"- cfg: %s", sCfgIntDir()->toUtf8().constData() );
766 if ( getenv(
"QGIS_PREFIX_PATH" ) )
772 QDir dir( QDir::homePath() );
777 #if defined(Q_OS_MACX)
779 #elif defined(Q_OS_WIN)
786 if ( appPath.contains( QStringLiteral(
"cgi-bin" ) ) )
796 if ( ABISYM( mRunningFromBuildDir ) )
797 return *sBuildOutputPath() + QStringLiteral(
"/data" );
799 return prefixPath +
'/' + QStringLiteral( QGIS_DATA_SUBDIR );
804 return *sThemeName();
814 qApp->setStyleSheet( QString() );
818 QString path = themes.value(
themeName );
819 QString stylesheetname = path +
"/style.qss";
821 QFile file( stylesheetname );
822 QFile variablesfile( path +
"/variables.qss" );
824 QFileInfo variableInfo( variablesfile );
826 if ( !file.open( QIODevice::ReadOnly ) || ( variableInfo.exists() && !variablesfile.open( QIODevice::ReadOnly ) ) )
831 QString styledata = file.readAll();
832 styledata.replace( QStringLiteral(
"@theme_path" ), path );
834 if ( variableInfo.exists() )
836 QTextStream in( &variablesfile );
837 while ( !in.atEnd() )
839 QString line = in.readLine();
841 if ( line.startsWith(
'@' ) )
843 int index = line.indexOf(
':' );
844 QString name = line.mid( 0, index );
845 QString value = line.mid( index + 1, line.length() );
846 styledata.replace( name, value );
849 variablesfile.close();
857 QRegularExpression regex( QStringLiteral(
"(?<=[\\s:])([0-9\\.]+)(?=em)" ) );
858 QRegularExpressionMatch match = regex.match( styledata, index );
859 while ( match.hasMatch() )
861 index = match.capturedStart();
862 styledata.remove( index, match.captured( 0 ).length() );
864 styledata.insert( index, number );
865 index += number.length();
866 match = regex.match( styledata, index );
870 qApp->setStyleSheet( styledata );
872 QFile palettefile( path +
"/palette.txt" );
873 QFileInfo paletteInfo( palettefile );
874 if ( paletteInfo.exists() && palettefile.open( QIODevice::ReadOnly ) )
876 QPalette
pal = qApp->palette();
877 QTextStream in( &palettefile );
878 while ( !in.atEnd() )
880 QString line = in.readLine();
881 QStringList parts = line.split(
':' );
882 if ( parts.count() == 2 )
884 int role = parts.at( 0 ).trimmed().toInt();
886 pal.setColor(
static_cast< QPalette::ColorRole
>( role ), color );
890 qApp->setPalette(
pal );
899 QHash<QString, QString> mapping;
900 mapping.insert( QStringLiteral(
"default" ), QString() );
901 const auto constPaths = paths;
902 for (
const QString &path : constPaths )
905 QFileInfoList styleFiles = folder.entryInfoList( QDir::Dirs | QDir::NoDotAndDotDot );
906 const auto constStyleFiles = styleFiles;
907 for (
const QFileInfo &info : constStyleFiles )
909 QFileInfo styleFile( info.absoluteFilePath() +
"/style.qss" );
910 if ( !styleFile.exists() )
913 QString name = info.baseName();
914 QString path = info.absoluteFilePath();
915 mapping.insert( name, path );
923 return pkgDataPath() + QStringLiteral(
"/doc/AUTHORS" );
928 return pkgDataPath() + QStringLiteral(
"/doc/CONTRIBUTORS" );
932 return pkgDataPath() + QStringLiteral(
"/doc/developersmap.html" );
937 return pkgDataPath() + QStringLiteral(
"/doc/SPONSORS" );
942 return pkgDataPath() + QStringLiteral(
"/doc/DONORS" );
947 return pkgDataPath() + QStringLiteral(
"/doc/TRANSLATORS" );
952 return pkgDataPath() + QStringLiteral(
"/doc/LICENSE" );
957 if ( ABISYM( mRunningFromBuildDir ) )
958 return *sBuildOutputPath() + QStringLiteral(
"/i18n/" );
965 return pkgDataPath() + QStringLiteral(
"/resources/metadata-ISO/" );
970 return pkgDataPath() + QStringLiteral(
"/resources/qgis.db" );
975 return *sConfigPath();
985 return *sAuthDbDirPath() + QStringLiteral(
"qgis-auth.db" );
990 return QStringLiteral(
":/images/splash/" );
995 return pkgDataPath() + QStringLiteral(
"/images/icons/" );
1000 if ( ABISYM( mRunningFromBuildDir ) )
1002 #if PROJ_VERSION_MAJOR>=6
1003 QString tempCopy = QDir::tempPath() +
"/srs6.db";
1005 QString tempCopy = QDir::tempPath() +
"/srs.db";
1008 if ( !QFile( tempCopy ).exists() )
1010 #if PROJ_VERSION_MAJOR>=6
1015 if ( !f.copy( tempCopy ) )
1017 qFatal(
"Could not create temporary copy" );
1025 return pkgDataPath() + QStringLiteral(
"/resources/srs.db" );
1034 const QStringList pathList = settings.
value( QStringLiteral(
"svg/searchPathsForSVG" ) ).toStringList();
1038 for (
const QString &path : pathList )
1040 if ( !paths.contains( path ) )
1041 paths.append( path );
1043 for (
const QString &path : qgis::as_const( *sDefaultSvgPaths() ) )
1045 if ( !paths.contains( path ) )
1046 paths.append( path );
1057 QStringList pathList = settings.
value( QStringLiteral(
"Layout/searchPathsForTemplates" ), QVariant(),
QgsSettings::Core ).toStringList();
1064 return *sSystemEnvVars();
1074 return QRegExp(
"^[A-Za-z][A-Za-z0-9\\._-]*" );
1079 if ( !sUserName()->isEmpty() )
1080 return *sUserName();
1083 TCHAR name [ UNLEN + 1 ];
1084 DWORD size = UNLEN + 1;
1086 if ( GetUserName( ( TCHAR * )name, &size ) )
1088 *sUserName() = QString::fromLocal8Bit( name );
1091 #elif QT_CONFIG(process)
1094 process.start( QStringLiteral(
"whoami" ) );
1095 process.waitForFinished();
1096 *sUserName() = process.readAllStandardOutput().trimmed();
1099 if ( !sUserName()->isEmpty() )
1100 return *sUserName();
1103 *sUserName() = qgetenv(
"USER" );
1104 if ( !sUserName()->isEmpty() )
1105 return *sUserName();
1108 *sUserName() = qgetenv(
"USERNAME" );
1109 return *sUserName();
1114 if ( !sUserFullName()->isEmpty() )
1115 return *sUserFullName();
1118 TCHAR name [ UNLEN + 1 ];
1119 DWORD size = UNLEN + 1;
1122 if ( GetUserNameEx( NameDisplay, ( TCHAR * )name, &size ) )
1124 *sUserFullName() = QString::fromLocal8Bit( name );
1128 if ( sUserFullName()->isEmpty() )
1130 #elif defined(Q_OS_ANDROID) || defined(__MINGW32__)
1131 *sUserFullName() = QStringLiteral(
"Not available" );
1133 struct passwd *p = getpwuid( getuid() );
1137 QString gecosName = QString( p->pw_gecos );
1138 *sUserFullName() = gecosName.left( gecosName.indexOf(
',', 0 ) );
1143 return *sUserFullName();
1148 #if defined(Q_OS_ANDROID)
1149 return QLatin1String(
"android" );
1150 #elif defined(Q_OS_MAC)
1151 return QLatin1String(
"osx" );
1152 #elif defined(Q_OS_WIN)
1153 return QLatin1String(
"windows" );
1154 #elif defined(Q_OS_LINUX)
1155 return QStringLiteral(
"linux" );
1156 #elif defined(Q_OS_FREEBSD)
1157 return QStringLiteral(
"freebsd" );
1158 #elif defined(Q_OS_OPENBSD)
1159 return QStringLiteral(
"openbsd" );
1160 #elif defined(Q_OS_NETBSD)
1161 return QStringLiteral(
"netbsd" );
1162 #elif defined(Q_OS_UNIX)
1163 return QLatin1String(
"unix" );
1165 return QLatin1String(
"unknown" );
1171 return *sPlatformName();
1177 bool overrideLocale = settings.
value( QStringLiteral(
"locale/overrideFlag" ),
false ).toBool();
1178 if ( overrideLocale )
1180 QString
locale = settings.
value( QStringLiteral(
"locale/userLocale" ), QString() ).toString();
1182 if (
locale.startsWith( QLatin1String(
"en" ), Qt::CaseInsensitive ) )
1191 return QLocale().name().left( 2 );
1202 return pkgDataPath() + QStringLiteral(
"/resources/symbology-style.xml" );
1207 return pkgDataPath() + QStringLiteral(
"/resources/themes" );
1212 return pkgDataPath() + QStringLiteral(
"/resources/server/" );
1217 return *sLibraryPath();
1222 return *sLibexecPath();
1227 return *sQmlImportPath();
1232 return ( htonl( 1 ) == 1 ) ?
XDR :
NDR;
1239 init( *sProfilePath() );
1276 if ( !sAuthManager )
1278 return sAuthManager;
1286 QThreadPool::globalInstance()->waitForDone();
1292 delete sAuthManager;
1297 QgsApplication::sendPostedEvents(
nullptr, QEvent::DeferredDelete );
1305 if ( QgsProviderRegistry::exists() )
1314 GDALDestroyDriverManager();
1319 QString myEnvironmentVar( getenv(
"QGIS_PREFIX_PATH" ) );
1320 QString myState = tr(
"Application state:\n"
1321 "QGIS_PREFIX_PATH env var:\t\t%1\n"
1323 "Plugin Path:\t\t%3\n"
1324 "Package Data Path:\t%4\n"
1325 "Active Theme Name:\t%5\n"
1326 "Active Theme Path:\t%6\n"
1327 "Default Theme Path:\t%7\n"
1328 "SVG Search Paths:\t%8\n"
1329 "User DB Path:\t%9\n"
1330 "Auth DB Path:\t%10\n" )
1331 .arg( myEnvironmentVar,
1338 svgPaths().join( tr(
"\n\t\t",
"match indentation of application state" ) ),
1351 QColor myColor1( Qt::lightGray );
1352 QColor myColor2 = myColor1;
1353 myColor2 = myColor2.lighter( 110 );
1355 myStyle = QStringLiteral(
".overview{"
1357 " font-weight: bold;"
1360 " background: white;"
1362 " font-family: 'Lato', 'Ubuntu', 'Lucida Grande', 'Segoe UI', 'Arial', sans-serif;"
1365 "h1{ background-color: #F6F6F6;"
1367 " font-size: x-large; "
1368 " font-weight: normal;"
1369 " background: none;"
1370 " padding: 0.75em 0 0;"
1372 " line-height: 3em;"
1374 "h2{ background-color: #F6F6F6;"
1376 " font-size: medium; "
1377 " font-weight: normal;"
1378 " background: none;"
1379 " padding: 0.75em 0 0;"
1381 " line-height: 1.1em;"
1383 "h3{ background-color: #F6F6F6;"
1385 " font-weight: bold;"
1386 " font-size: large;"
1387 " text-align: left;"
1388 " border-bottom: 5px solid #DCEB5C;"
1390 "h4{ background-color: #F6F6F6;"
1392 " font-weight: bold;"
1393 " font-size: medium;"
1394 " text-align: left;"
1396 "h5{ background-color: #F6F6F6;"
1398 " font-weight: bold;"
1399 " font-size: small;"
1400 " text-align: left;"
1402 "a{ color: #729FCF;"
1403 " font-family: arial,sans-serif;"
1405 "label{ background-color: #FFFFCC;"
1406 " border: 1px solid black;"
1408 " padding: 0px 3px; "
1409 " font-size: small;"
1412 " font-weight: bold;"
1417 " border-top: 1px solid black;"
1419 ".list-view .highlight {"
1420 " text-align: left;"
1423 " padding-right: 15px;"
1424 " padding-left: 20px;"
1425 " font-weight: bold;"
1427 ".tabular-view .odd-row {"
1428 " background-color: #f9f9f9;"
1431 " font-weight: bold;"
1432 " padding-top:25px;"
1436 switch ( styleSheetType )
1438 case StyleSheetType::Qt:
1439 myStyle += QStringLiteral(
1441 " border-collapse: collapse;"
1444 ".tabular-view th, .tabular-view td { "
1445 " border:10px solid black;"
1449 case StyleSheetType::WebBrowser:
1450 myStyle += QStringLiteral(
1455 "table.tabular-view, table.list-view { "
1456 " border-collapse: collapse;"
1457 " table-layout:fixed;"
1458 " width: 100% !important;"
1463 " line-height: inherit;"
1466 " word-wrap: break-word; "
1467 " vertical-align: top;"
1470 ".list-view th:first-child, .list-view td:first-child {"
1473 ".list-view.highlight { "
1474 " padding-left: inherit; "
1477 ".tabular-view th:first-child, .tabular-view td:first-child { "
1481 ".tabular-view th.strong { "
1482 " background-color: #eee; "
1485 ".tabular-view th, .tabular-view td { "
1486 " border: solid 1px #eee;"
1497 if ( 0 >= OGRGetDriverCount() )
1505 QString aPathUrl = aPath;
1506 QString tPathUrl = targetPath;
1507 #if defined( Q_OS_WIN )
1508 const Qt::CaseSensitivity cs = Qt::CaseInsensitive;
1510 aPathUrl.replace(
'\\',
'/' );
1511 if ( aPathUrl.startsWith(
"//" ) )
1514 aPathUrl =
"\\\\" + aPathUrl.mid( 2 );
1517 tPathUrl.replace(
'\\',
'/' );
1518 if ( tPathUrl.startsWith(
"//" ) )
1521 tPathUrl =
"\\\\" + tPathUrl.mid( 2 );
1524 const Qt::CaseSensitivity cs = Qt::CaseSensitive;
1527 QStringList targetElems = tPathUrl.split(
'/', QString::SkipEmptyParts );
1528 QStringList aPathElems = aPathUrl.split(
'/', QString::SkipEmptyParts );
1530 targetElems.removeAll( QStringLiteral(
"." ) );
1531 aPathElems.removeAll( QStringLiteral(
"." ) );
1535 while ( !aPathElems.isEmpty() &&
1536 !targetElems.isEmpty() &&
1537 aPathElems[0].compare( targetElems[0], cs ) == 0 )
1539 aPathElems.removeFirst();
1540 targetElems.removeFirst();
1550 if ( !targetElems.isEmpty() )
1553 for (
int i = 0; i < targetElems.size(); i++ )
1555 aPathElems.insert( 0, QStringLiteral(
".." ) );
1562 aPathElems.insert( 0, QStringLiteral(
"." ) );
1565 return aPathElems.join( QStringLiteral(
"/" ) );
1571 if ( !rpath.startsWith( QLatin1String(
"./" ) ) && !rpath.startsWith( QLatin1String(
"../" ) ) )
1576 QString rPathUrl = rpath;
1577 QString targetPathUrl = targetPath;
1579 #if defined(Q_OS_WIN)
1580 rPathUrl.replace(
'\\',
'/' );
1581 targetPathUrl.replace(
'\\',
'/' );
1583 bool uncPath = targetPathUrl.startsWith(
"//" );
1586 QStringList srcElems = rPathUrl.split(
'/', QString::SkipEmptyParts );
1587 QStringList targetElems = targetPathUrl.split(
'/', QString::SkipEmptyParts );
1589 #if defined(Q_OS_WIN)
1592 targetElems.insert( 0,
"" );
1593 targetElems.insert( 0,
"" );
1598 targetElems << srcElems;
1599 targetElems.removeAll( QStringLiteral(
"." ) );
1603 while ( ( pos = targetElems.indexOf( QStringLiteral(
".." ) ) ) > 0 )
1606 targetElems.removeAt( pos - 1 );
1607 targetElems.removeAt( pos - 1 );
1610 #if !defined(Q_OS_WIN)
1612 targetElems.prepend( QString() );
1615 return targetElems.join( QStringLiteral(
"/" ) );
1620 return *sBuildSourcePath();
1625 return *sBuildOutputPath();
1628 #if defined(_MSC_VER) && !defined(USING_NMAKE) && !defined(USING_NINJA)
1629 QString QgsApplication::cfgIntDir()
1631 return *sCfgIntDir();
1637 if ( sGdalSkipList()->contains( driver ) || driver.isEmpty() )
1641 *sGdalSkipList() << driver;
1647 if ( !sGdalSkipList()->contains( driver ) )
1651 int myPos = sGdalSkipList()->indexOf( driver );
1654 sGdalSkipList()->removeAt( myPos );
1661 return *sGdalSkipList();
1665 const QStringList &deferredSkippedGdalDrivers )
1679 QString joinedList = settings.
value( QStringLiteral(
"gdal/skipList" ), QString() ).toString();
1681 if ( !joinedList.isEmpty() )
1683 myList = joinedList.split(
' ' );
1685 *sGdalSkipList() = myList;
1691 return *sDeferredSkippedGdalDrivers();
1696 sGdalSkipList()->removeDuplicates();
1697 QStringList realDisabledDriverList;
1698 for (
const auto &driverName : *sGdalSkipList() )
1700 if ( !sDeferredSkippedGdalDrivers()->contains( driverName ) )
1701 realDisabledDriverList << driverName;
1703 QString myDriverList = realDisabledDriverList.join(
' ' );
1704 QgsDebugMsgLevel( QStringLiteral(
"Gdal Skipped driver list set to:" ), 2 );
1706 CPLSetConfigOption(
"GDAL_SKIP", myDriverList.toUtf8() );
1713 QDir myDir( folder );
1714 if ( !myDir.exists() )
1716 myDir.mkpath( folder );
1722 void QgsApplication::copyPath(
const QString &src,
const QString &dst )
1725 if ( ! dir.exists() )
1728 const auto subDirectories = dir.entryList( QDir::Dirs | QDir::NoDotAndDotDot );
1729 for (
const QString &d : subDirectories )
1731 QString dst_path = dst + QDir::separator() + d;
1732 dir.mkpath( dst_path );
1733 copyPath( src + QDir::separator() + d, dst_path );
1736 const auto files = dir.entryList( QDir::Files );
1737 for (
const QString &f : files )
1739 QFile::copy( src + QDir::separator() + f, dst + QDir::separator() + f );
1748 QVariantMap variables;
1752 QStringList childKeys = settings.
childKeys();
1753 for ( QStringList::const_iterator it = childKeys.constBegin(); it != childKeys.constEnd(); ++it )
1756 variables.insert( name, settings.
value( name ) );
1766 QVariantMap::const_iterator it = variables.constBegin();
1769 for ( ; it != variables.constEnd(); ++it )
1771 settings.
setValue( it.key(), it.value() );
1782 settings.
setValue( QStringLiteral(
"variables/" ) + name, value );
1794 *sTranslation() = translation;
1804 ApplicationMembers *appMembers = members();
1805 if ( appMembers->mNullRepresentation.isNull() )
1807 appMembers->mNullRepresentation =
QgsSettings().
value( QStringLiteral(
"qgis/nullValue" ), QStringLiteral(
"NULL" ) ).toString();
1809 return appMembers->mNullRepresentation;
1814 ApplicationMembers *appMembers = members();
1828 return members()->mActionScopeRegistry;
1837 QDir myDir( myPamPath );
1838 if ( !myDir.exists() )
1840 myDir.mkpath( myPamPath );
1843 #if defined(Q_OS_WIN)
1844 CPLSetConfigOption(
"GDAL_PAM_PROXY_DIR", myPamPath.toUtf8() );
1848 int myChangeFlag = 0;
1849 setenv(
"GDAL_PAM_PROXY_DIR", myPamPath.toUtf8(), myChangeFlag );
1856 if ( !qgisPrivateDbFile.exists() )
1860 QFile masterFile( qgisMasterDbFileName );
1866 bool isDbFileCopied = masterFile.copy( qgisPrivateDbFile.fileName() );
1868 if ( !isDbFileCopied )
1872 *errorMessage = tr(
"[ERROR] Can not make qgis.db private copy" );
1877 QFile::Permissions perms = QFile( qgisPrivateDbFile.fileName() ).permissions();
1878 if ( !( perms & QFile::WriteOwner ) )
1880 if ( !qgisPrivateDbFile.setPermissions( perms | QFile::WriteOwner ) )
1884 *errorMessage = tr(
"Can not make '%1' user writable" ).arg( qgisPrivateDbFile.fileName() );
1898 *errorMessage = tr(
"Could not open qgis.db" );
1903 char *errmsg =
nullptr;
1904 int res = sqlite3_exec( database.get(),
"SELECT srs_id FROM tbl_srs LIMIT 0",
nullptr,
nullptr, &errmsg );
1905 if ( res != SQLITE_OK )
1907 sqlite3_free( errmsg );
1910 if ( sqlite3_exec( database.get(),
1911 "DROP INDEX IF EXISTS idx_srsauthid;"
1912 "CREATE TABLE tbl_srs ("
1913 "srs_id INTEGER PRIMARY KEY,"
1914 "description text NOT NULL,"
1915 "projection_acronym text NOT NULL,"
1916 "ellipsoid_acronym NOT NULL,"
1917 "parameters text NOT NULL,"
1919 "auth_name varchar,"
1921 "is_geo integer NOT NULL,"
1922 "deprecated boolean,"
1924 "CREATE INDEX idx_srsauthid on tbl_srs(auth_name,auth_id);",
nullptr,
nullptr, &errmsg ) != SQLITE_OK )
1928 *errorMessage = tr(
"Creation of missing tbl_srs in the private qgis.db failed.\n%1" ).arg( QString::fromUtf8( errmsg ) );
1930 sqlite3_free( errmsg );
1937 res = sqlite3_exec( database.get(),
"SELECT wkt FROM tbl_srs LIMIT 0",
nullptr,
nullptr, &errmsg );
1938 if ( res != SQLITE_OK )
1941 sqlite3_free( errmsg );
1942 if ( sqlite3_exec( database.get(),
1943 "DROP INDEX IF EXISTS idx_srsauthid;"
1944 "DROP TABLE IF EXISTS tbl_srs_bak;"
1945 "ALTER TABLE tbl_srs RENAME TO tbl_srs_bak;"
1946 "CREATE TABLE tbl_srs ("
1947 "srs_id INTEGER PRIMARY KEY,"
1948 "description text NOT NULL,"
1949 "projection_acronym text NOT NULL,"
1950 "ellipsoid_acronym NOT NULL,"
1951 "parameters text NOT NULL,"
1953 "auth_name varchar,"
1955 "is_geo integer NOT NULL,"
1956 "deprecated boolean,"
1958 "CREATE INDEX idx_srsauthid on tbl_srs(auth_name,auth_id);"
1959 "INSERT INTO tbl_srs(srs_id,description,projection_acronym,ellipsoid_acronym,parameters,srid,auth_name,auth_id,is_geo,deprecated) SELECT srs_id,description,projection_acronym,ellipsoid_acronym,parameters,srid,'','',is_geo,0 FROM tbl_srs_bak;"
1960 "DROP TABLE tbl_srs_bak",
nullptr,
nullptr, &errmsg ) != SQLITE_OK )
1964 *errorMessage = tr(
"Migration of private qgis.db failed.\n%1" ).arg( QString::fromUtf8( errmsg ) );
1966 sqlite3_free( errmsg );
1972 res = sqlite3_exec( database.get(),
"SELECT acronym FROM tbl_projection LIMIT 0",
nullptr,
nullptr, &errmsg );
1973 if ( res != SQLITE_OK )
1975 sqlite3_free( errmsg );
1978 if ( sqlite3_exec( database.get(),
1979 "CREATE TABLE tbl_projection ("
1980 "acronym varchar(20) NOT NULL PRIMARY KEY,"
1981 "name varchar(255) NOT NULL default '',"
1982 "notes varchar(255) NOT NULL default '',"
1983 "parameters varchar(255) NOT NULL default ''"
1984 ")",
nullptr,
nullptr, &errmsg ) != SQLITE_OK )
1988 *errorMessage = tr(
"Creation of missing tbl_projection in the private qgis.db failed.\n%1" ).arg( QString::fromUtf8( errmsg ) );
1990 sqlite3_free( errmsg );
1995 res = sqlite3_exec( database.get(),
"SELECT epsg FROM tbl_srs LIMIT 0",
nullptr,
nullptr, &errmsg );
1996 if ( res == SQLITE_OK )
1999 if ( sqlite3_exec( database.get(),
2000 "DROP INDEX IF EXISTS idx_srsauthid;"
2001 "DROP TABLE IF EXISTS tbl_srs_bak;"
2002 "ALTER TABLE tbl_srs RENAME TO tbl_srs_bak;"
2003 "CREATE TABLE tbl_srs ("
2004 "srs_id INTEGER PRIMARY KEY,"
2005 "description text NOT NULL,"
2006 "projection_acronym text NOT NULL,"
2007 "ellipsoid_acronym NOT NULL,"
2008 "parameters text NOT NULL,"
2010 "auth_name varchar,"
2012 "is_geo integer NOT NULL,"
2013 "deprecated boolean,"
2015 "CREATE INDEX idx_srsauthid on tbl_srs(auth_name,auth_id);"
2016 "INSERT INTO tbl_srs(srs_id,description,projection_acronym,ellipsoid_acronym,parameters,srid,auth_name,auth_id,is_geo,deprecated) SELECT srs_id,description,projection_acronym,ellipsoid_acronym,parameters,srid,'','',is_geo,0 FROM tbl_srs_bak;"
2017 "DROP TABLE tbl_srs_bak",
nullptr,
nullptr, &errmsg ) != SQLITE_OK )
2021 *errorMessage = tr(
"Migration of private qgis.db failed.\n%1" ).arg( QString::fromUtf8( errmsg ) );
2023 sqlite3_free( errmsg );
2029 sqlite3_free( errmsg );
2032 if ( sqlite3_exec( database.get(),
"DROP VIEW vw_srs",
nullptr,
nullptr, &errmsg ) != SQLITE_OK )
2034 QgsDebugMsg( QStringLiteral(
"vw_srs didn't exists in private qgis.db: %1" ).arg( errmsg ) );
2037 if ( sqlite3_exec( database.get(),
2038 "CREATE VIEW vw_srs AS"
2040 " a.description AS description"
2041 ",a.srs_id AS srs_id"
2042 ",a.is_geo AS is_geo"
2043 ",coalesce(b.name,a.projection_acronym) AS name"
2044 ",a.parameters AS parameters"
2045 ",a.auth_name AS auth_name"
2046 ",a.auth_id AS auth_id"
2047 ",a.deprecated AS deprecated"
2049 " LEFT OUTER JOIN tbl_projection b ON a.projection_acronym=b.acronym"
2050 " ORDER BY coalesce(b.name,a.projection_acronym),a.description",
nullptr,
nullptr, &errmsg ) != SQLITE_OK )
2054 *errorMessage = tr(
"Update of view in private qgis.db failed.\n%1" ).arg( QString::fromUtf8( errmsg ) );
2056 sqlite3_free( errmsg );
2069 if ( maxThreads < 1 || maxThreads > QThread::idealThreadCount() )
2080 QThreadPool::globalInstance()->setMaxThreadCount(
maxThreads );
2081 QgsDebugMsgLevel( QStringLiteral(
"set QThreadPool max thread count to %1" ).arg( QThreadPool::globalInstance()->maxThreadCount() ), 2 );
2086 return members()->mTaskManager;
2091 return members()->mColorSchemeRegistry;
2096 return members()->mPaintEffectRegistry;
2101 return members()->mRendererRegistry;
2106 return members()->mRasterRendererRegistry;
2113 if ( !
instance()->mDataItemProviderRegistry )
2117 return instance()->mDataItemProviderRegistry;
2123 if ( !sDataItemProviderRegistry )
2125 return sDataItemProviderRegistry;
2131 return members()->mSvgCache;
2136 return members()->mImageCache;
2141 return members()->mNetworkContentFetcherRegistry;
2146 return members()->mValidityCheckRegistry;
2151 return members()->mSymbolLayerRegistry;
2156 return members()->mCalloutRegistry;
2161 return members()->mLayoutItemRegistry;
2166 return members()->mGpsConnectionRegistry;
2171 return members()->mPluginLayerRegistry;
2176 return members()->mClassificationMethodRegistry;
2181 return members()->mBookmarkManager;
2186 return members()->mStyleModel;
2191 return members()->mMessageLog;
2196 return members()->mProcessingRegistry;
2201 return members()->mConnectionRegistry;
2206 return members()->mPageSizeRegistry;
2211 return members()->mAnnotationRegistry;
2216 return members()->mNumericFormatRegistry;
2221 return members()->mFieldFormatterRegistry;
2226 return members()->m3DRendererRegistry;
2231 return members()->mScaleBarRendererRegistry;
2236 return members()->mProjectStorageRegistry;
2241 return members()->mLocalizedDataPathRegistry;
2244 QgsApplication::ApplicationMembers::ApplicationMembers()
2253 mProfiler->start( tr(
"Create connection registry" ) );
2258 mProfiler->start( tr(
"Setup task manager" ) );
2263 mProfiler->start( tr(
"Setup action scope registry" ) );
2268 mProfiler->start( tr(
"Setup numeric formats" ) );
2273 mProfiler->start( tr(
"Setup field formats" ) );
2278 mProfiler->start( tr(
"Setup SVG cache" ) );
2283 mProfiler->start( tr(
"Setup image cache" ) );
2288 mProfiler->start( tr(
"Setup color scheme registry" ) );
2293 mProfiler->start( tr(
"Setup paint effect" ) );
2298 mProfiler->start( tr(
"Setup symbol layer registry" ) );
2303 mProfiler->start( tr(
"Setup callout registry" ) );
2308 mProfiler->start( tr(
"Setup renderer registry" ) );
2313 mProfiler->start( tr(
"Setup raster renderer registry" ) );
2318 mProfiler->start( tr(
"Setup GPS registry" ) );
2323 mProfiler->start( tr(
"Setup plugin layer registry" ) );
2328 mProfiler->start( tr(
"Setup Processing registry" ) );
2334 mProfiler->start( tr(
"Setup layout item registry" ) );
2336 mLayoutItemRegistry->populate();
2340 mProfiler->start( tr(
"Setup annotation registry" ) );
2341 mAnnotationRegistry =
new QgsAnnotationRegistry();
2345 mProfiler->start( tr(
"Setup 3D renderer registry" ) );
2350 mProfiler->start( tr(
"Setup project storage registry" ) );
2355 mProfiler->start( tr(
"Setup network content cache" ) );
2360 mProfiler->start( tr(
"Setup layout check registry" ) );
2365 mProfiler->start( tr(
"Setup classification registry" ) );
2370 mProfiler->start( tr(
"Setup bookmark manager" ) );
2375 mProfiler->start( tr(
"Setup scalebar registry" ) );
2381 QgsApplication::ApplicationMembers::~ApplicationMembers()
2384 delete mScaleBarRendererRegistry;
2385 delete mValidityCheckRegistry;
2386 delete mActionScopeRegistry;
2387 delete m3DRendererRegistry;
2388 delete mAnnotationRegistry;
2389 delete mColorSchemeRegistry;
2390 delete mFieldFormatterRegistry;
2391 delete mGpsConnectionRegistry;
2393 delete mPaintEffectRegistry;
2394 delete mPluginLayerRegistry;
2395 delete mProcessingRegistry;
2396 delete mProjectStorageRegistry;
2397 delete mPageSizeRegistry;
2398 delete mLayoutItemRegistry;
2400 delete mRasterRendererRegistry;
2401 delete mRendererRegistry;
2404 delete mCalloutRegistry;
2405 delete mSymbolLayerRegistry;
2406 delete mTaskManager;
2407 delete mNetworkContentFetcherRegistry;
2408 delete mClassificationMethodRegistry;
2409 delete mNumericFormatRegistry;
2410 delete mBookmarkManager;
2411 delete mConnectionRegistry;
2412 delete mLocalizedDataPathRegistry;
2415 QgsApplication::ApplicationMembers *QgsApplication::members()
2419 return instance()->mApplicationMembers;
2423 static QMutex sMemberMutex( QMutex::Recursive );
2424 QMutexLocker lock( &sMemberMutex );
2425 if ( !sApplicationMembers )
2426 sApplicationMembers =
new ApplicationMembers();
2427 return sApplicationMembers;