QGIS API Documentation 3.99.0-Master (d270888f95f)
Loading...
Searching...
No Matches
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
24#include "qgs3dsymbolregistry.h"
30#include "qgsauthmanager.h"
32#include "qgsbookmarkmanager.h"
33#include "qgscalloutsregistry.h"
35#include "qgscolorrampimpl.h"
41#include "qgsdbquerylog.h"
42#include "qgsexception.h"
43#include "qgsexpression.h"
45#include "qgsfeaturestore.h"
47#include "qgsfontmanager.h"
48#include "qgsgeometry.h"
49#include "qgsgpsconnection.h"
50#include "qgsimagecache.h"
51#include "qgsinterval.h"
54#include "qgslayout.h"
58#include "qgslocator.h"
59#include "qgslogger.h"
60#include "qgsmeshlayer.h"
61#include "qgsmessagelog.h"
64#include "qgsnetworkreply.h"
65#include "qgsnewsfeedparser.h"
68#include "qgsplotregistry.h"
72#include "qgsproject.h"
74#include "qgsprojutils.h"
75#include "qgsproviderregistry.h"
77#include "qgsreadwritelocker.h"
81#include "qgsrendererregistry.h"
82#include "qgsruntimeprofiler.h"
84#include "qgssensorregistry.h"
86#include "qgssettings.h"
88#include "qgssourcecache.h"
89#include "qgssqliteutils.h"
90#include "qgsstyle.h"
91#include "qgsstylemodel.h"
92#include "qgssvgcache.h"
94#include "qgssymbollayerutils.h"
95#include "qgstaskmanager.h"
98#include "qgsunittypes.h"
100#include "qgsuserprofile.h"
103
104#include <QAuthenticator>
105#include <QDir>
106#include <QFile>
107#include <QFileInfo>
108#include <QFileOpenEvent>
109#include <QIcon>
110#include <QImageReader>
111#include <QLibraryInfo>
112#include <QLocale>
113#include <QMessageBox>
114#include <QPalette>
115#include <QPixmap>
116#include <QProcess>
117#include <QProcessEnvironment>
118#include <QRecursiveMutex>
119#include <QRegularExpression>
120#include <QScreen>
121#include <QStandardPaths>
122#include <QString>
123#include <QStyle>
124#include <QTextStream>
125#include <QThreadPool>
126
127#include "moc_qgsapplication.cpp"
128
129using namespace Qt::StringLiterals;
130
132
134
136
138
140
141const QgsSettingsEntryInteger *QgsApplication::settingsConnectionPoolMaximumConcurrentConnections = new QgsSettingsEntryInteger( u"connection-pool-maximum-concurrent-connections"_s, QgsSettingsTree::sTreeCore, 4, QObject::tr( "Maximum number of concurrent connections per connection pool" ), Qgis::SettingsOptions(), 4, 999 );
142
143#ifndef Q_OS_WIN
144#include <netinet/in.h>
145#include <pwd.h>
146#else
147#include <winsock.h>
148#include <windows.h>
149#include <lmcons.h>
150#define SECURITY_WIN32
151#include <security.h>
152#ifdef _MSC_VER
153#pragma comment( lib, "Secur32.lib" )
154#endif
155#endif
156
157#include "qgsconfig.h"
158
159#include <gdal.h>
160#include <ogr_api.h>
161#include <cpl_conv.h> // for setting gdal options
162#include <sqlite3.h>
163#include <mutex>
164
165#include <proj.h>
166
167#if defined(Q_OS_LINUX)
168#include <sys/sysinfo.h>
169#endif
170
171#define CONN_POOL_MAX_CONCURRENT_CONNS 4
172
174{
175 std::unique_ptr<QgsSettingsRegistryCore > mSettingsRegistryCore;
176 std::unique_ptr<QgsCoordinateReferenceSystemRegistry > mCrsRegistry;
177 std::unique_ptr<Qgs3DRendererRegistry > m3DRendererRegistry;
178 std::unique_ptr<Qgs3DSymbolRegistry > m3DSymbolRegistry;
179 std::unique_ptr<QgsActionScopeRegistry > mActionScopeRegistry;
180 std::unique_ptr<QgsAnnotationRegistry > mAnnotationRegistry;
181 std::unique_ptr<QgsApplicationThemeRegistry > mApplicationThemeRegistry;
182 std::unique_ptr<QgsColorSchemeRegistry > mColorSchemeRegistry;
183 std::unique_ptr<QgsLocalizedDataPathRegistry > mLocalizedDataPathRegistry;
184 std::unique_ptr<QgsNumericFormatRegistry > mNumericFormatRegistry;
185 std::unique_ptr<QgsFieldFormatterRegistry > mFieldFormatterRegistry;
186 std::unique_ptr<QgsGpsConnectionRegistry > mGpsConnectionRegistry;
187 std::unique_ptr<QgsBabelFormatRegistry > mGpsBabelFormatRegistry;
188 std::unique_ptr<QgsNetworkContentFetcherRegistry > mNetworkContentFetcherRegistry;
189 std::unique_ptr<QgsScaleBarRendererRegistry > mScaleBarRendererRegistry;
190 std::unique_ptr<QgsLabelingEngineRuleRegistry > mLabelingEngineRuleRegistry;
191 std::unique_ptr<QgsValidityCheckRegistry > mValidityCheckRegistry;
192 std::unique_ptr<QgsMessageLog > mMessageLog;
193 std::unique_ptr<QgsPaintEffectRegistry > mPaintEffectRegistry;
194 std::unique_ptr<QgsPluginLayerRegistry > mPluginLayerRegistry;
195 std::unique_ptr<QgsClassificationMethodRegistry > mClassificationMethodRegistry;
196 std::unique_ptr<QgsProcessingRegistry > mProcessingRegistry;
197 std::unique_ptr<QgsConnectionRegistry > mConnectionRegistry;
198 std::unique_ptr<QgsProjectStorageRegistry > mProjectStorageRegistry;
199 std::unique_ptr<QgsLayerMetadataProviderRegistry > mLayerMetadataProviderRegistry;
200 std::unique_ptr<QgsExternalStorageRegistry > mExternalStorageRegistry;
201 std::unique_ptr<QgsProfileSourceRegistry > mProfileSourceRegistry;
202 std::unique_ptr<QgsPageSizeRegistry > mPageSizeRegistry;
203 std::unique_ptr<QgsRasterRendererRegistry > mRasterRendererRegistry;
204 std::unique_ptr<QgsRendererRegistry > mRendererRegistry;
205 std::unique_ptr<QgsPointCloudRendererRegistry > mPointCloudRendererRegistry;
206 std::unique_ptr<QgsTiledSceneRendererRegistry > mTiledSceneRendererRegistry;
207 std::unique_ptr<QgsSvgCache > mSvgCache;
208 std::unique_ptr<QgsImageCache > mImageCache;
209 std::unique_ptr<QgsSourceCache > mSourceCache;
210 std::unique_ptr<QgsSymbolLayerRegistry > mSymbolLayerRegistry;
211 std::unique_ptr<QgsCalloutRegistry > mCalloutRegistry;
212 std::unique_ptr<QgsTaskManager > mTaskManager;
213 std::unique_ptr<QgsLayoutItemRegistry > mLayoutItemRegistry;
214 std::unique_ptr<QgsAnnotationItemRegistry > mAnnotationItemRegistry;
215 std::unique_ptr<QgsSensorRegistry > mSensorRegistry;
216 std::unique_ptr<QgsPlotRegistry > mPlotRegistry;
217 std::unique_ptr<QgsBookmarkManager > mBookmarkManager;
218 std::unique_ptr<QgsTileDownloadManager > mTileDownloadManager;
219 std::unique_ptr<QgsStyleModel > mStyleModel;
220 std::unique_ptr<QgsRecentStyleHandler > mRecentStyleHandler;
221 std::unique_ptr<QgsDatabaseQueryLog > mQueryLogger;
222 std::unique_ptr<QgsFontManager > mFontManager;
224 QStringList mSvgPathCache;
225 bool mSvgPathCacheValid = false;
226
229};
230
231
232QObject *ABISYM( QgsApplication::mFileOpenEventReceiver ) = nullptr;
233bool ABISYM( QgsApplication::mInitialized ) = false;
234bool ABISYM( QgsApplication::mRunningFromBuildDir ) = false;
235const char *QgsApplication::QGIS_ORGANIZATION_NAME = "QGIS";
236const char *QgsApplication::QGIS_ORGANIZATION_DOMAIN = "qgis.org";
237const char *QgsApplication::QGIS_APPLICATION_NAME = "QGIS3";
238QgsApplication::ApplicationMembers *QgsApplication::sApplicationMembers = nullptr;
239QgsAuthManager *QgsApplication::sAuthManager = nullptr;
240int ABISYM( QgsApplication::sMaxThreads ) = -1;
241
242Q_GLOBAL_STATIC( QStringList, sFileOpenEventList )
243Q_GLOBAL_STATIC( QString, sPrefixPath )
244Q_GLOBAL_STATIC( QString, sPluginPath )
245Q_GLOBAL_STATIC( QString, sPkgDataPath )
246Q_GLOBAL_STATIC( QString, sLibraryPath )
247Q_GLOBAL_STATIC( QString, sLibexecPath )
248Q_GLOBAL_STATIC( QString, sQmlImportPath )
249Q_GLOBAL_STATIC( QString, sThemeName )
250Q_GLOBAL_STATIC( QString, sProfilePath )
251
252Q_GLOBAL_STATIC( QStringList, sDefaultSvgPaths )
253Q_GLOBAL_STATIC( QgsStringMap, sSystemEnvVars )
254Q_GLOBAL_STATIC( QString, sConfigPath )
255
256Q_GLOBAL_STATIC( QString, sBuildSourcePath )
257#if defined(_MSC_VER) && !defined(USING_NMAKE) && !defined(USING_NINJA)
258Q_GLOBAL_STATIC( QString, sCfgIntDir )
259#endif
260Q_GLOBAL_STATIC( QString, sBuildOutputPath )
261Q_GLOBAL_STATIC( QStringList, sGdalSkipList )
262Q_GLOBAL_STATIC( QStringList, sDeferredSkippedGdalDrivers )
263Q_GLOBAL_STATIC( QString, sAuthDbDirPath )
264Q_GLOBAL_STATIC( QString, sAuthDbUri )
265
266Q_GLOBAL_STATIC( QString, sUserName )
267Q_GLOBAL_STATIC( QString, sUserFullName )
268Q_GLOBAL_STATIC_WITH_ARGS( QString, sPlatformName, ( "external" ) )
269Q_GLOBAL_STATIC( QString, sApplicationFullName )
270Q_GLOBAL_STATIC( QString, sTranslation )
271
272Q_GLOBAL_STATIC( QTemporaryDir, sIconCacheDir )
273
274QgsApplication::QgsApplication( int &argc, char **argv, bool GUIenabled, const QString &profileFolder, const QString &platformName )
275 : QApplication( argc, argv, GUIenabled )
276{
277 *sPlatformName() = platformName;
278
280
281 // Delay application members initialization in desktop app (In desktop app, profile folder is not known at this point)
282 if ( platformName != "desktop"_L1 )
283 {
284 mApplicationMembers = std::make_unique<ApplicationMembers>();
285 try
286 {
287 mApplicationMembers->mSettingsRegistryCore->migrateOldSettings();
288 }
289 catch ( QgsSettingsException &e )
290 {
291 QgsDebugError( u"Error migrating old settings: %1"_s.arg( e.what() ) );
292 }
293 }
294 else
295 {
296 *sProfilePath() = profileFolder;
297 }
298
299}
300
302{
303 qRegisterMetaType<QgsGeometry::Error>( "QgsGeometry::Error" );
304 qRegisterMetaType<QgsDatabaseQueryLogEntry>( "QgsDatabaseQueryLogEntry" );
305 qRegisterMetaType<QgsProcessingFeatureSourceDefinition>( "QgsProcessingFeatureSourceDefinition" );
306 qRegisterMetaType<QgsProcessingOutputLayerDefinition>( "QgsProcessingOutputLayerDefinition" );
307 qRegisterMetaType<Qgis::LayoutUnit>( "Qgis::LayoutUnit" );
308 qRegisterMetaType<QgsUnsetAttributeValue>( "QgsUnsetAttributeValue" );
309 qRegisterMetaType<QgsFeatureId>( "QgsFeatureId" );
310 qRegisterMetaType<QgsFields>( "QgsFields" );
311 qRegisterMetaType<QgsFeatureIds>( "QgsFeatureIds" );
312 qRegisterMetaType<QgsProperty>( "QgsProperty" );
313 qRegisterMetaType<QgsFeatureStoreList>( "QgsFeatureStoreList" );
314 qRegisterMetaType<Qgis::MessageLevel>( "Qgis::MessageLevel" );
315 qRegisterMetaType<Qgis::BrowserItemState>( "Qgis::BrowserItemState" );
316 qRegisterMetaType<Qgis::GpsFixStatus>( "Qgis::GpsFixStatus" );
317 qRegisterMetaType<QgsReferencedRectangle>( "QgsReferencedRectangle" );
318 qRegisterMetaType<QgsReferencedPointXY>( "QgsReferencedPointXY" );
319 qRegisterMetaType<QgsReferencedGeometry>( "QgsReferencedGeometry" );
320 qRegisterMetaType<Qgis::LayoutRenderFlags>( "Qgis::LayoutRenderFlags" );
321 qRegisterMetaType<QgsStyle::StyleEntity>( "QgsStyle::StyleEntity" );
322 qRegisterMetaType<QgsCoordinateReferenceSystem>( "QgsCoordinateReferenceSystem" );
323 qRegisterMetaType<QgsAuthManager::MessageLevel>( "QgsAuthManager::MessageLevel" );
324 qRegisterMetaType<QgsNetworkRequestParameters>( "QgsNetworkRequestParameters" );
325 qRegisterMetaType<QgsNetworkReplyContent>( "QgsNetworkReplyContent" );
326 qRegisterMetaType<QgsFeature>( "QgsFeature" );
327 qRegisterMetaType<QgsGeometry>( "QgsGeometry" );
328 qRegisterMetaType<QgsInterval>( "QgsInterval" );
329 qRegisterMetaType<QgsRectangle>( "QgsRectangle" );
330 qRegisterMetaType<QgsPointXY>( "QgsPointXY" );
331 qRegisterMetaType<QgsPoint>( "QgsPoint" );
332 qRegisterMetaType<QgsDatumTransform::GridDetails>( "QgsDatumTransform::GridDetails" );
333 qRegisterMetaType<QgsDatumTransform::TransformDetails>( "QgsDatumTransform::TransformDetails" );
334 qRegisterMetaType<QgsNewsFeedParser::Entry>( "QgsNewsFeedParser::Entry" );
335 qRegisterMetaType<QgsRectangle>( "QgsRectangle" );
336 qRegisterMetaType<QgsLocatorResult>( "QgsLocatorResult" );
337 qRegisterMetaType<QgsGradientColorRamp>( "QgsGradientColorRamp" );
338 qRegisterMetaType<QgsProcessingModelChildParameterSource>( "QgsProcessingModelChildParameterSource" );
339 qRegisterMetaType<QgsRemappingSinkDefinition>( "QgsRemappingSinkDefinition" );
340 qRegisterMetaType<QgsProcessingModelChildDependency>( "QgsProcessingModelChildDependency" );
341 qRegisterMetaType<QgsTextFormat>( "QgsTextFormat" );
342 qRegisterMetaType<QPainter::CompositionMode>( "QPainter::CompositionMode" );
343 qRegisterMetaType<QgsDateTimeRange>( "QgsDateTimeRange" );
344 qRegisterMetaType<QgsDoubleRange>( "QgsDoubleRange" );
345 qRegisterMetaType<QgsIntRange>( "QgsIntRange" );
346 qRegisterMetaType<QList<QgsMapLayer *>>( "QList<QgsMapLayer*>" );
347 qRegisterMetaType<QMap<QNetworkRequest::Attribute, QVariant>>( "QMap<QNetworkRequest::Attribute,QVariant>" );
348 qRegisterMetaType<QMap<QNetworkRequest::KnownHeaders, QVariant>>( "QMap<QNetworkRequest::KnownHeaders,QVariant>" );
349 qRegisterMetaType<QList<QNetworkReply::RawHeaderPair>>( "QList<QNetworkReply::RawHeaderPair>" );
350 qRegisterMetaType<QNetworkReply::NetworkError>( "QNetworkReply::NetworkError" );
351 qRegisterMetaType< QAuthenticator * >( "QAuthenticator*" );
352 qRegisterMetaType< QgsGpsInformation >( "QgsGpsInformation" );
353 qRegisterMetaType< QgsSensorThingsExpansionDefinition >( "QgsSensorThingsExpansionDefinition" );
354 qRegisterMetaType< QTimeZone >( "QTimeZone" );
355};
356
357void QgsApplication::init( QString profileFolder )
358{
359 // Initialize application members in desktop app (at this point, profile folder is known)
360 if ( platform() == "desktop"_L1 )
361 {
362 instance()->mApplicationMembers = std::make_unique<ApplicationMembers>();
363 try
364 {
365 instance()->mApplicationMembers->mSettingsRegistryCore->migrateOldSettings();
366 }
367 catch ( QgsSettingsException &e )
368 {
369 QgsDebugError( u"Error migrating old settings: %1"_s.arg( e.what() ) );
370 }
371 }
372
373 if ( profileFolder.isEmpty() )
374 {
375 if ( getenv( "QGIS_CUSTOM_CONFIG_PATH" ) )
376 {
377 profileFolder = getenv( "QGIS_CUSTOM_CONFIG_PATH" );
378 }
379 else
380 {
381 profileFolder = QStandardPaths::standardLocations( QStandardPaths::AppDataLocation ).value( 0 );
382 }
383 // This will normally get here for custom scripts that use QgsApplication.
384 // This doesn't get this hit for QGIS Desktop because we setup the profile via main
385 QString rootProfileFolder = QgsUserProfileManager::resolveProfilesFolder( profileFolder );
386 QgsUserProfileManager manager( rootProfileFolder );
387 std::unique_ptr< QgsUserProfile > profile = manager.getProfile();
388 profileFolder = profile->folder();
389 }
390
391 *sProfilePath() = profileFolder;
392
393 static std::once_flag sMetaTypesRegistered;
394 std::call_once( sMetaTypesRegistered, registerMetaTypes );
395
396 ( void ) resolvePkgPath();
397
398 if ( ABISYM( mRunningFromBuildDir ) )
399 {
400 // we run from source directory - not installed to destination (specified prefix)
401 *sPrefixPath() = QString(); // set invalid path
402#if defined(_MSC_VER) && !defined(USING_NMAKE) && !defined(USING_NINJA)
403 setPluginPath( *sBuildOutputPath() + '/' + QString( QGIS_PLUGIN_SUBDIR ) + '/' + *sCfgIntDir() );
404#else
405 setPluginPath( *sBuildOutputPath() + '/' + QStringLiteral( QGIS_PLUGIN_SUBDIR ) );
406#endif
407 setPkgDataPath( *sBuildOutputPath() + u"/data"_s ); // in buildDir/data - used for: doc, resources, svg
408 *sLibraryPath() = *sBuildOutputPath() + '/' + QGIS_LIB_SUBDIR + '/';
409#if defined(_MSC_VER) && !defined(USING_NMAKE) && !defined(USING_NINJA)
410 *sLibexecPath() = *sBuildOutputPath() + '/' + QGIS_LIBEXEC_SUBDIR + '/' + *sCfgIntDir() + '/';
411#else
412 *sLibexecPath() = *sBuildOutputPath() + '/' + QGIS_LIBEXEC_SUBDIR + '/';
413#endif
414#if defined( HAVE_QUICK )
415 *sQmlImportPath() = *sBuildOutputPath() + '/' + QGIS_QML_SUBDIR + '/';
416#endif
417 }
418 else
419 {
420 char *prefixPath = getenv( "QGIS_PREFIX_PATH" );
421 if ( !prefixPath )
422 {
423 if ( sPrefixPath()->isNull() )
424 {
425#if defined(Q_OS_WIN) || defined(Q_OS_MACOS) && !defined(QGIS_MAC_BUNDLE)
426 setPrefixPath( applicationDirPath(), true );
427#elif defined(QGIS_MAC_BUNDLE)
428 QDir myDir( applicationDirPath() + "/../.."_L1 );
429 setPrefixPath( myDir.absolutePath(), true );
430#elif defined(ANDROID)
431 // this is "/data/data/org.qgis.qgis" in android
432 QDir myDir( QDir::homePath() );
433 myDir.cdUp();
434 QString myPrefix = myDir.absolutePath();
435 setPrefixPath( myPrefix, true );
436#else
437 QDir myDir( applicationDirPath() );
438 // Fix for server which is one level deeper in /usr/lib/cgi-bin
439 if ( applicationDirPath().contains( u"cgi-bin"_s ) )
440 {
441 myDir.cdUp();
442 }
443 myDir.cdUp(); // Go from /usr/bin or /usr/lib (for server) to /usr
444 QString myPrefix = myDir.absolutePath();
445 setPrefixPath( myPrefix, true );
446#endif
447 }
448 }
449 else
450 {
451 setPrefixPath( prefixPath, true );
452 }
453 }
454
455 *sConfigPath() = profileFolder + '/'; // make sure trailing slash is included
456 *sDefaultSvgPaths() << qgisSettingsDirPath() + u"svg/"_s;
457
458 // Determine the auth DB URI, the first match wins:
459 // 1 - get it from QGIS_AUTH_DB_URI environment variable
460 // 2 - get it from QGIS_AUTH_DB_DIR_PATH environment variable, assume QSQLITE driver and add "qgis-auth.db"
461 // 3 - use the default path from settings dir path, assume QSQLITE and add "qgis-auth.db"
462 *sAuthDbDirPath() = qgisSettingsDirPath();
463
464 if ( getenv( "QGIS_AUTH_DB_DIR_PATH" ) )
465 {
466 setAuthDatabaseDirPath( getenv( "QGIS_AUTH_DB_DIR_PATH" ) );
467 sAuthDbUri()->clear();
468 }
469
470 if ( getenv( "QGIS_AUTH_DB_URI" ) )
471 {
472 *sAuthDbUri() = getenv( "QGIS_AUTH_DB_URI" );
473 }
474
475 // Default to sAuthDbDirPath
476 if ( sAuthDbUri->isEmpty() )
477 {
478 *sAuthDbUri() = u"QSQLITE://"_s + *sAuthDbDirPath() + u"qgis-auth.db"_s;
479 }
480
481 // force use of OpenGL renderer for Qt3d.
482 qputenv( "QT3D_RENDERER", "opengl" );
483
484 // store system environment variables passed to application, before they are adjusted
485 QMap<QString, QString> systemEnvVarMap;
486 QString passfile( u"QGIS_AUTH_PASSWORD_FILE"_s ); // QString, for comparison
487
488 const auto systemEnvironment = QProcessEnvironment::systemEnvironment().toStringList();
489 for ( const QString &varStr : systemEnvironment )
490 {
491 int pos = varStr.indexOf( '='_L1 );
492 if ( pos == -1 )
493 continue;
494 QString varStrName = varStr.left( pos );
495 QString varStrValue = varStr.mid( pos + 1 );
496 if ( varStrName != passfile )
497 {
498 systemEnvVarMap.insert( varStrName, varStrValue );
499 }
500 }
501 *sSystemEnvVars() = systemEnvVarMap;
502
503 // append local user-writable folder as a proj search path
504 QStringList currentProjSearchPaths = QgsProjUtils::searchPaths();
505 currentProjSearchPaths.append( qgisSettingsDirPath() + u"proj"_s );
506#ifdef Q_OS_MACOS
507 // append bundled proj lib for MacOS
508 QString projLib( QDir::cleanPath( pkgDataPath().append( "/proj" ) ) );
509 if ( QFile::exists( projLib ) )
510 {
511 currentProjSearchPaths.append( projLib );
512 }
513#endif // Q_OS_MACOS
514
515 char **newPaths = new char *[currentProjSearchPaths.length()];
516 for ( int i = 0; i < currentProjSearchPaths.count(); ++i )
517 {
518 newPaths[i] = CPLStrdup( currentProjSearchPaths.at( i ).toUtf8().constData() );
519 }
520 proj_context_set_search_paths( nullptr, currentProjSearchPaths.count(), newPaths );
521 for ( int i = 0; i < currentProjSearchPaths.count(); ++i )
522 {
523 CPLFree( newPaths[i] );
524 }
525 delete [] newPaths;
526
527 // allow Qt to search for Qt plugins (e.g. sqldrivers) in our plugin directory
528 QCoreApplication::addLibraryPath( pluginPath() );
529
530 // the default of 256 is not enough for QGIS
531 QImageReader::setAllocationLimit( 512 );
532
533 {
534 QgsScopedRuntimeProfile profile( tr( "Load user fonts" ) );
536 }
537
538 // set max. thread count to -1
539 // this should be read from QgsSettings but we don't know where they are at this point
540 // so we read actual value in main.cpp
541 ABISYM( sMaxThreads ) = -1;
542
543 {
544 QgsScopedRuntimeProfile profile( tr( "Load color schemes" ) );
547 }
548
549 {
550 QgsScopedRuntimeProfile profile( tr( "Load bookmarks" ) );
552 }
553
554 // trigger creation of default style, but defer initialization until
555 // it's actually required
556 QgsStyle *defaultStyle = QgsStyle::defaultStyle( false );
557 if ( !members()->mStyleModel )
558 members()->mStyleModel = std::make_unique<QgsStyleModel>( defaultStyle );
559
560 ABISYM( mInitialized ) = true;
561}
562
563
564void QgsApplication::installTranslators()
565{
566 // Remove translators if any are already installed
567 if ( mQgisTranslator )
568 {
569 removeTranslator( mQgisTranslator.get() );
570 mQgisTranslator.reset( );
571
572 }
573 if ( mQtTranslator )
574 {
575 removeTranslator( mQtTranslator.get() );
576 mQtTranslator.reset( );
577
578 }
579 if ( mQtBaseTranslator )
580 {
581 removeTranslator( mQtBaseTranslator.get() );
582 mQtBaseTranslator.reset( );
583
584 }
585
586 if ( *sTranslation() != "C"_L1 )
587 {
588 mQgisTranslator = std::make_unique<QTranslator>( this );
589 if ( mQgisTranslator->load( u"qgis_"_s + *sTranslation(), i18nPath() ) )
590 {
591 installTranslator( mQgisTranslator.get() );
592 }
593 else
594 {
595 QgsDebugMsgLevel( u"loading of qgis translation failed %1/qgis_%2"_s.arg( i18nPath(), *sTranslation() ), 2 );
596 }
597
598 /* Translation file for Qt.
599 * The strings from the QMenuBar context section are used by Qt/Mac to shift
600 * the About, Preferences and Quit items to the Mac Application menu.
601 * These items must be translated identically in both qt_ and qgis_ files.
602 */
603 QString qtTranslationsPath = QLibraryInfo::location( QLibraryInfo::TranslationsPath );
604#ifdef __MINGW32__
605 QString prefix = QDir( QString( "%1/../" ).arg( QApplication::applicationDirPath() ) ).absolutePath();
606 qtTranslationsPath = prefix + qtTranslationsPath.mid( QLibraryInfo::location( QLibraryInfo::PrefixPath ).length() );
607#endif
608
609 mQtTranslator = std::make_unique<QTranslator>( this );
610 if ( mQtTranslator->load( u"qt_"_s + *sTranslation(), qtTranslationsPath ) )
611 {
612 installTranslator( mQtTranslator.get() );
613 }
614 else
615 {
616 QgsDebugMsgLevel( u"loading of qt translation failed %1/qt_%2"_s.arg( qtTranslationsPath, *sTranslation() ), 2 );
617 }
618
619 mQtBaseTranslator = std::make_unique<QTranslator>( this );
620 if ( mQtBaseTranslator->load( u"qtbase_"_s + *sTranslation(), qtTranslationsPath ) )
621 {
622 installTranslator( mQtBaseTranslator.get() );
623 }
624 else
625 {
626 QgsDebugMsgLevel( u"loading of qtbase translation failed %1/qt_%2"_s.arg( qtTranslationsPath, *sTranslation() ), 2 );
627 }
628 }
629}
630
632{
633 if ( mApplicationMembers )
634 {
635 try
636 {
637 mApplicationMembers->mSettingsRegistryCore->backwardCompatibility();
638 }
639 catch ( QgsSettingsException &e )
640 {
641 QgsDebugError( u"An error occurred while performing backwards compatibility for settings: %1"_s.arg( e.what() ) );
642 }
643 }
644
645 // we do this here as well as in exitQgis() -- it's safe to call as often as we want,
646 // and there's just a *chance* that someone hasn't properly called exitQgis prior to
647 // this destructor...
648 invalidateCaches();
649}
650
651void QgsApplication::invalidateCaches()
652{
653 // invalidate coordinate cache while the PROJ context held by the thread-locale
654 // QgsProjContextStore object is still alive. Otherwise if this later object
655 // is destroyed before the static variables of the cache, we might use freed memory.
659}
660
662{
663 return qobject_cast<QgsApplication *>( QCoreApplication::instance() );
664}
665
667{
668 bool done = false;
669 if ( event->type() == QEvent::FileOpen )
670 {
671 // handle FileOpen event (double clicking a file icon in Mac OS X Finder)
672 if ( ABISYM( mFileOpenEventReceiver ) )
673 {
674 // Forward event to main window.
675 done = notify( ABISYM( mFileOpenEventReceiver ), event );
676 }
677 else
678 {
679 // Store filename because receiver has not registered yet.
680 // If QGIS has been launched by double clicking a file icon, FileOpen will be
681 // the first event; the main window is not yet ready to handle the event.
682 sFileOpenEventList()->append( static_cast<QFileOpenEvent *>( event )->file() );
683 done = true;
684 }
685 }
686 else
687 {
688 // pass other events to base class
689 done = QApplication::event( event );
690 }
691 return done;
692}
693
694bool QgsApplication::notify( QObject *receiver, QEvent *event )
695{
696 bool done = false;
697 // Crashes in customization (especially on Mac), if we're not in the main/UI thread, see #5597
698 if ( thread() == receiver->thread() )
699 emit preNotify( receiver, event, &done );
700
701 if ( done )
702 return true;
703
704 // Send event to receiver and catch unhandled exceptions
705 done = true;
706 try
707 {
708 done = QApplication::notify( receiver, event );
709 }
710 catch ( QgsException &e )
711 {
712 qCritical() << "Caught unhandled QgsException: " << e.what();
713 if ( qApp->thread() == QThread::currentThread() )
714 QMessageBox::critical( activeWindow(), tr( "Exception" ), e.what() );
715 }
716 catch ( std::exception &e )
717 {
718 qCritical() << "Caught unhandled std::exception: " << e.what();
719 if ( qApp->thread() == QThread::currentThread() )
720 QMessageBox::critical( activeWindow(), tr( "Exception" ), e.what() );
721 }
722 catch ( ... )
723 {
724 qCritical() << "Caught unhandled unknown exception";
725 if ( qApp->thread() == QThread::currentThread() )
726 QMessageBox::critical( activeWindow(), tr( "Exception" ), tr( "unknown exception" ) );
727 }
728
729 return done;
730}
731
733{
734 return QgsRuntimeProfiler::threadLocalInstance();
735}
736
738{
739 // Set receiver for FileOpen events
740 ABISYM( mFileOpenEventReceiver ) = receiver;
741 // Propagate any events collected before the receiver has registered.
742 if ( sFileOpenEventList()->count() > 0 )
743 {
744 const QStringList fileOpenEventList = *sFileOpenEventList();
745 for ( const QString &file : fileOpenEventList )
746 {
747 QFileOpenEvent foe( file );
748 QgsApplication::sendEvent( ABISYM( mFileOpenEventReceiver ), &foe );
749 }
750 sFileOpenEventList()->clear();
751 }
752}
753
754void QgsApplication::setPrefixPath( const QString &prefixPath, bool useDefaultPaths )
755{
756 *sPrefixPath() = prefixPath;
757#if defined(Q_OS_WIN)
758 if ( sPrefixPath()->endsWith( "/bin" ) )
759 {
760 sPrefixPath()->chop( 4 );
761 }
762#endif
763 if ( useDefaultPaths && !ABISYM( mRunningFromBuildDir ) )
764 {
765 setPluginPath( *sPrefixPath() + '/' + QStringLiteral( QGIS_PLUGIN_SUBDIR ) );
766 setPkgDataPath( *sPrefixPath() + '/' + QStringLiteral( QGIS_DATA_SUBDIR ) );
767 }
768 *sLibraryPath() = *sPrefixPath() + '/' + QGIS_LIB_SUBDIR + '/';
769 *sLibexecPath() = *sPrefixPath() + '/' + QGIS_LIBEXEC_SUBDIR + '/';
770#if defined( HAVE_QUICK )
771 *sQmlImportPath() = *sPrefixPath() + '/' + QGIS_QML_SUBDIR + '/';
772#endif
773}
774
776{
777 *sPluginPath() = pluginPath;
778}
779
781{
782 *sPkgDataPath() = pkgDataPath;
783
784 QString mySvgPath = pkgDataPath + u"/svg/"_s;
785
786 // avoid duplicate entries
787 if ( !sDefaultSvgPaths()->contains( mySvgPath ) )
788 *sDefaultSvgPaths() << mySvgPath;
789}
790
791void QgsApplication::setDefaultSvgPaths( const QStringList &pathList )
792{
793 *sDefaultSvgPaths() = pathList;
794}
795
796void QgsApplication::setAuthDatabaseDirPath( const QString &authDbDirPath )
797{
798 QFileInfo fi( authDbDirPath );
799 if ( fi.exists() && fi.isDir() && fi.isWritable() )
800 {
801 *sAuthDbDirPath() = fi.canonicalFilePath() + QDir::separator();
802 }
803}
804
806{
807#if 0
808 if ( ABISYM( mRunningFromBuildDir ) )
809 {
810 static bool sOnce = true;
811 if ( sOnce )
812 {
813 QgsMessageLogNotifyBlocker blockNotifications;
814 ( void ) blockNotifications;
815 qWarning( "!!! prefix path was requested, but it is not valid - we do not run from installed path !!!" );
816 }
817 sOnce = false;
818 }
819#endif
820
821 return *sPrefixPath();
822}
824{
825 return *sPluginPath();
826}
827
829{
830 if ( sPkgDataPath()->isNull() )
831 return resolvePkgPath();
832 else
833 return *sPkgDataPath();
834}
835
837{
838 return u":/images/themes/default/"_s;
839}
841{
842 QString usersThemes = userThemesFolder() + QDir::separator() + themeName() + QDir::separator() + "icons/";
843 QDir dir( usersThemes );
844 if ( dir.exists() )
845 {
846 return usersThemes;
847 }
848 else
849 {
850 QString defaultThemes = defaultThemesFolder() + QDir::separator() + themeName() + QDir::separator() + "icons/";
851 return defaultThemes;
852 }
853}
854
856{
857 return iconsPath() + u"qgis-icon-60x60.png"_s;
858}
859
861{
862 return ABISYM( sMaxThreads );
863}
864
865QString QgsApplication::iconPath( const QString &iconFile )
866{
867 // try active theme
868 QString path = activeThemePath();
869 if ( QFile::exists( path + iconFile ) )
870 return path + iconFile;
871
872 // use default theme
873 return defaultThemePath() + iconFile;
874}
875
876QIcon QgsApplication::getThemeIcon( const QString &name, const QColor &fillColor, const QColor &strokeColor )
877{
878 const QString cacheKey = ( name.startsWith( '/' ) ? name.mid( 1 ) : name )
879 + ( fillColor.isValid() ? u"_%1"_s.arg( fillColor.name( QColor::HexArgb ).mid( 1 ) ) : QString() )
880 + ( strokeColor.isValid() ? u"_%1"_s.arg( strokeColor.name( QColor::HexArgb ).mid( 1 ) ) : QString() );
881 QgsApplication *app = instance();
882 if ( app && app->mIconCache.contains( cacheKey ) )
883 return app->mIconCache.value( cacheKey );
884
885 QIcon icon;
886 const bool colorBased = fillColor.isValid() || strokeColor.isValid();
887
888 auto iconFromColoredSvg = [fillColor, strokeColor, cacheKey]( const QString & path ) -> QIcon
889 {
890 // sizes are unused here!
891 const QByteArray svgContent = QgsApplication::svgCache()->svgContent( path, 16, fillColor, strokeColor, 1, 1 );
892
893 const QString iconPath = sIconCacheDir()->filePath( cacheKey + u".svg"_s );
894 if ( const QDir dir = QFileInfo( iconPath ).dir(); !dir.exists() )
895 {
896 dir.mkpath( "." );
897 }
898
899 QFile f( iconPath );
900 if ( f.open( QFile::WriteOnly | QFile::Truncate ) )
901 {
902 f.write( svgContent );
903 f.close();
904 }
905 else
906 {
907 QgsDebugError( u"Could not create colorized icon svg at %1"_s.arg( iconPath ) );
908 return QIcon();
909 }
910
911 return QIcon( f.fileName() );
912 };
913
914 QString preferredPath = activeThemePath() + QDir::separator() + name;
915 QString defaultPath = defaultThemePath() + QDir::separator() + name;
916 if ( QFile::exists( preferredPath ) )
917 {
918 if ( colorBased )
919 {
920 icon = iconFromColoredSvg( preferredPath );
921 }
922 else
923 {
924 icon = QIcon( preferredPath );
925 }
926 }
927 else if ( QFile::exists( defaultPath ) )
928 {
929 //could still return an empty icon if it
930 //doesn't exist in the default theme either!
931 if ( colorBased )
932 {
933 icon = iconFromColoredSvg( defaultPath );
934 }
935 else
936 {
937 icon = QIcon( defaultPath );
938 }
939 }
940 else
941 {
942 icon = QIcon();
943 }
944
945 if ( app )
946 app->mIconCache.insert( cacheKey, icon );
947 return icon;
948}
949
951{
952 QgsApplication *app = instance();
953 if ( app && app->mCursorCache.contains( cursor ) )
954 return app->mCursorCache.value( cursor );
955
956 // All calculations are done on 32x32 icons
957 // Defaults to center, individual cursors may override
958 int activeX = 16;
959 int activeY = 16;
960
961 QString name;
962 switch ( cursor )
963 {
964 case ZoomIn:
965 name = u"mZoomIn.svg"_s;
966 activeX = 13;
967 activeY = 13;
968 break;
969 case ZoomOut:
970 name = u"mZoomOut.svg"_s;
971 activeX = 13;
972 activeY = 13;
973 break;
974 case Identify:
975 activeX = 3;
976 activeY = 6;
977 name = u"mIdentify.svg"_s;
978 break;
979 case CrossHair:
980 name = u"mCrossHair.svg"_s;
981 break;
982 case CapturePoint:
983 name = u"mCapturePoint.svg"_s;
984 break;
985 case Select:
986 name = u"mSelect.svg"_s;
987 activeX = 6;
988 activeY = 6;
989 break;
990 case Sampler:
991 activeX = 5;
992 activeY = 5;
993 name = u"mSampler.svg"_s;
994 break;
995 // No default
996 }
997 // It should never get here!
998 Q_ASSERT( ! name.isEmpty( ) );
999
1000 QIcon icon = getThemeIcon( u"cursors"_s + QDir::separator() + name );
1001 QCursor cursorIcon;
1002 // Check if an icon exists for this cursor (the O.S. default cursor will be used if it does not)
1003 if ( ! icon.isNull( ) )
1004 {
1005 // Apply scaling
1006 float scale = Qgis::UI_SCALE_FACTOR * QgsApplication::fontMetrics().height() / 32.0;
1007 cursorIcon = QCursor( icon.pixmap( std::ceil( scale * 32 ), std::ceil( scale * 32 ) ), std::ceil( scale * activeX ), std::ceil( scale * activeY ) );
1008 }
1009 if ( app )
1010 app->mCursorCache.insert( cursor, cursorIcon );
1011 return cursorIcon;
1012}
1013
1014// TODO: add some caching mechanism ?
1015QPixmap QgsApplication::getThemePixmap( const QString &name, const QColor &foreColor, const QColor &backColor, const int size )
1016{
1017 const QString preferredPath = activeThemePath() + QDir::separator() + name;
1018 const QString defaultPath = defaultThemePath() + QDir::separator() + name;
1019 const QString path = QFile::exists( preferredPath ) ? preferredPath : defaultPath;
1020 if ( foreColor.isValid() || backColor.isValid() )
1021 {
1022 bool fitsInCache = false;
1023 const QImage image = svgCache()->svgAsImage( path, size, backColor, foreColor, 1, 1, fitsInCache );
1024 return QPixmap::fromImage( image );
1025 }
1026
1027 return QPixmap( path );
1028}
1029
1031{
1032 *sThemeName() = themeName;
1033}
1034
1036{
1037 static QString appPath;
1038 if ( appPath.isNull() )
1039 {
1040 if ( QCoreApplication::instance() )
1041 {
1042 appPath = applicationDirPath();
1043 }
1044 else
1045 {
1046 qWarning( "Application path not initialized" );
1047 }
1048 }
1049
1050 if ( !appPath.isNull() || getenv( "QGIS_PREFIX_PATH" ) )
1051 {
1052 QString prefix = getenv( "QGIS_PREFIX_PATH" ) ? getenv( "QGIS_PREFIX_PATH" ) : appPath;
1053
1054 // check if QGIS is run from build directory (not the install directory)
1055 QFile f;
1056 // "/../../.." is for Mac bundled app in build directory
1057 static const QStringList paths { QStringList() << QString() << u"/.."_s << u"/bin"_s << u"/../../.."_s };
1058 for ( const QString &path : paths )
1059 {
1060 f.setFileName( prefix + path + "/qgisbuildpath.txt" );
1061 if ( f.exists() )
1062 break;
1063 }
1064 if ( f.exists() && f.open( QIODevice::ReadOnly ) )
1065 {
1066 ABISYM( mRunningFromBuildDir ) = true;
1067 *sBuildSourcePath() = f.readLine().trimmed();
1068 *sBuildOutputPath() = f.readLine().trimmed();
1069 QgsDebugMsgLevel( u"Running from build directory!"_s, 4 );
1070 QgsDebugMsgLevel( u"- source directory: %1"_s.arg( sBuildSourcePath()->toUtf8().constData() ), 4 );
1071 QgsDebugMsgLevel( u"- output directory of the build: %1"_s.arg( sBuildOutputPath()->toUtf8().constData() ), 4 );
1072#if defined(_MSC_VER) && !defined(USING_NMAKE) && !defined(USING_NINJA)
1073 *sCfgIntDir() = prefix.split( '/', Qt::SkipEmptyParts ).last();
1074 qDebug( "- cfg: %s", sCfgIntDir()->toUtf8().constData() );
1075#endif
1076 }
1077 }
1078
1079 QString prefixPath;
1080 if ( getenv( "QGIS_PREFIX_PATH" ) )
1081 prefixPath = getenv( "QGIS_PREFIX_PATH" );
1082 else
1083 {
1084#if defined(ANDROID)
1085 // this is "/data/data/org.qgis.qgis" in android
1086 QDir dir( QDir::homePath() );
1087 dir.cdUp();
1088 prefixPath = dir.absolutePath();
1089#else
1090
1091#if defined(Q_OS_MACOS)
1092 prefixPath = appPath;
1093#elif defined(Q_OS_WIN)
1094 prefixPath = appPath;
1095 if ( prefixPath.endsWith( "/bin" ) )
1096 prefixPath.chop( 4 );
1097#else
1098 QDir dir( appPath );
1099 // Fix for server which is one level deeper in /usr/lib/cgi-bin
1100 if ( appPath.contains( u"cgi-bin"_s ) )
1101 {
1102 dir.cdUp();
1103 }
1104 dir.cdUp(); // Go from /usr/bin or /usr/lib (for server) to /usr
1105 prefixPath = dir.absolutePath();
1106#endif
1107#endif
1108 }
1109
1110 if ( ABISYM( mRunningFromBuildDir ) )
1111 return *sBuildOutputPath() + u"/data"_s;
1112 else
1113 return prefixPath + '/' + QStringLiteral( QGIS_DATA_SUBDIR );
1114}
1115
1117{
1118 return *sThemeName();
1119}
1120
1122{
1123 // Loop all style sheets, find matching name, load it.
1124 const QString path = applicationThemeRegistry()->themeFolder( themeName );
1125 if ( themeName == "default"_L1 || path.isEmpty() )
1126 {
1127 setThemeName( u"default"_s );
1128 qApp->setStyleSheet( QString() );
1130 return;
1131 }
1132
1133 QFile file( path + "/style.qss" );
1134 QFile variablesfile( path + "/variables.qss" );
1135 QFileInfo variableInfo( variablesfile );
1136
1137 if ( !file.open( QIODevice::ReadOnly ) || ( variableInfo.exists() && !variablesfile.open( QIODevice::ReadOnly ) ) )
1138 {
1139 qApp->setStyleSheet( QString() );
1141 return;
1142 }
1143
1144 QFile palettefile( path + "/palette.txt" );
1145 QFileInfo paletteInfo( palettefile );
1146 if ( paletteInfo.exists() && palettefile.open( QIODevice::ReadOnly ) )
1147 {
1148 QPalette pal = qApp->palette();
1149 QTextStream in( &palettefile );
1150 while ( !in.atEnd() )
1151 {
1152 QString line = in.readLine();
1153 QStringList parts = line.split( ':' );
1154 if ( parts.count() == 2 )
1155 {
1156 int role = parts.at( 0 ).trimmed().toInt();
1157 QColor color = QgsSymbolLayerUtils::decodeColor( parts.at( 1 ).trimmed() );
1158 pal.setColor( static_cast< QPalette::ColorRole >( role ), color );
1159 }
1160 }
1161 palettefile.close();
1162 qApp->setPalette( pal );
1163 }
1164
1165 QString styledata = file.readAll();
1166 styledata.replace( "@theme_path"_L1, path );
1167
1168 if ( variableInfo.exists() )
1169 {
1170 QTextStream in( &variablesfile );
1171 while ( !in.atEnd() )
1172 {
1173 QString line = in.readLine();
1174 // This is a variable
1175 if ( line.startsWith( '@' ) )
1176 {
1177 int index = line.indexOf( ':' );
1178 QString name = line.mid( 0, index );
1179 QString value = line.mid( index + 1, line.length() );
1180 styledata.replace( name, value );
1181 }
1182 }
1183 variablesfile.close();
1184 }
1185 file.close();
1186
1187 if ( Qgis::UI_SCALE_FACTOR != 1.0 )
1188 {
1189 // apply OS-specific UI scale factor to stylesheet's em values
1190 int index = 0;
1191 const static QRegularExpression regex( u"(?<=[\\s:])([0-9\\.]+)(?=em)"_s );
1192 QRegularExpressionMatch match = regex.match( styledata, index );
1193 while ( match.hasMatch() )
1194 {
1195 index = match.capturedStart();
1196 styledata.remove( index, match.captured( 0 ).length() );
1197 QString number = QString::number( match.captured( 0 ).toDouble() * Qgis::UI_SCALE_FACTOR );
1198 styledata.insert( index, number );
1199 index += number.length();
1200 match = regex.match( styledata, index );
1201 }
1202 }
1203
1204 qApp->setStyleSheet( styledata );
1205
1208}
1209
1210QHash<QString, QString> QgsApplication::uiThemes()
1211{
1212 QHash<QString, QString> mapping = applicationThemeRegistry()->themeFolders();
1213 mapping.insert( u"default"_s, QString() );
1214 return mapping;
1215}
1216
1218{
1219 return pkgDataPath() + u"/doc/AUTHORS"_s;
1220}
1221
1223{
1224 return pkgDataPath() + u"/doc/CONTRIBUTORS"_s;
1225}
1226
1228{
1229 return pkgDataPath() + u"/doc/SPONSORS"_s;
1230}
1231
1233{
1234 return pkgDataPath() + u"/doc/DONORS"_s;
1235}
1236
1238{
1239 return pkgDataPath() + u"/doc/TRANSLATORS"_s;
1240}
1241
1243{
1244 return pkgDataPath() + u"/doc/LICENSE"_s;
1245}
1246
1248{
1249 if ( ABISYM( mRunningFromBuildDir ) )
1250 return *sBuildOutputPath() + u"/i18n/"_s;
1251 else
1252 return pkgDataPath() + u"/i18n/"_s;
1253}
1254
1256{
1257 return pkgDataPath() + u"/resources/metadata-ISO/"_s;
1258}
1259
1261{
1262 return pkgDataPath() + u"/resources/qgis.db"_s;
1263}
1264
1266{
1267 return *sConfigPath();
1268}
1269
1271{
1272 return qgisSettingsDirPath() + u"qgis.db"_s;
1273}
1274
1276{
1277 return *sAuthDbDirPath() + u"qgis-auth.db"_s;
1278}
1279
1281{
1282 return *sAuthDbUri();
1283}
1284
1286{
1287 return u":/images/splash/"_s;
1288}
1289
1291{
1292 return pkgDataPath() + u"/images/icons/"_s;
1293}
1294
1296{
1297 if ( ABISYM( mRunningFromBuildDir ) )
1298 {
1299 QString tempCopy = QDir::tempPath() + "/srs6.db";
1300
1301 if ( !QFile( tempCopy ).exists() )
1302 {
1303 QFile f( buildSourcePath() + "/resources/srs6.db" );
1304 if ( !f.copy( tempCopy ) )
1305 {
1306 qFatal( "Could not create temporary copy" );
1307 }
1308 }
1309
1310 return tempCopy;
1311 }
1312 else
1313 {
1314 return pkgDataPath() + u"/resources/srs.db"_s;
1315 }
1316}
1317
1318void QgsApplication::setSvgPaths( const QStringList &svgPaths )
1319{
1321 members()->mSvgPathCacheValid = false;
1322}
1323
1325{
1326 static QReadWriteLock lock;
1327
1329
1330 if ( members()->mSvgPathCacheValid )
1331 {
1332 return members()->mSvgPathCache;
1333 }
1334 else
1335 {
1337 //local directories to search when looking for an SVG with a given basename
1338 //defined by user in options dialog
1339 const QStringList pathList = settingsSearchPathsForSVG->value();
1340
1341 // maintain user set order while stripping duplicates
1342 QStringList paths;
1343 for ( const QString &path : pathList )
1344 {
1345 if ( !paths.contains( path ) )
1346 paths.append( path );
1347 }
1348 for ( const QString &path : std::as_const( *sDefaultSvgPaths() ) )
1349 {
1350 if ( !paths.contains( path ) )
1351 paths.append( path );
1352 }
1353 members()->mSvgPathCache = paths;
1354
1355 return paths;
1356 }
1357}
1358
1360{
1361 //local directories to search when looking for an template with a given basename
1362 //defined by user in options dialog
1364}
1365
1366QMap<QString, QString> QgsApplication::systemEnvVars()
1367{
1368 return *sSystemEnvVars();
1369}
1370
1372{
1373 return qgisSettingsDirPath() + u"symbology-style.db"_s;
1374}
1375
1377{
1378 const thread_local QRegularExpression regexp( QRegularExpression::anchoredPattern( u"^[A-Za-z][A-Za-z0-9\\._-]*"_s ) );
1379 return regexp;
1380}
1381
1383{
1384 if ( !sUserName()->isEmpty() )
1385 return *sUserName();
1386
1387#ifdef _MSC_VER
1388 TCHAR name [ UNLEN + 1 ];
1389 DWORD size = UNLEN + 1;
1390
1391 if ( GetUserName( ( TCHAR * )name, &size ) )
1392 {
1393 *sUserName() = QString::fromWCharArray( name );
1394 }
1395
1396
1397#elif QT_CONFIG(process)
1398 QProcess process;
1399
1400 process.start( u"whoami"_s, QStringList() );
1401 process.waitForFinished();
1402 *sUserName() = process.readAllStandardOutput().trimmed();
1403#endif
1404
1405 if ( !sUserName()->isEmpty() )
1406 return *sUserName();
1407
1408 //backup plan - use environment variables
1409 *sUserName() = qgetenv( "USER" );
1410 if ( !sUserName()->isEmpty() )
1411 return *sUserName();
1412
1413 //last resort
1414 *sUserName() = qgetenv( "USERNAME" );
1415 return *sUserName();
1416}
1417
1419{
1420 if ( !sUserFullName()->isEmpty() )
1421 return *sUserFullName();
1422
1423#ifdef _MSC_VER
1424 TCHAR name [ UNLEN + 1 ];
1425 DWORD size = UNLEN + 1;
1426
1427 //note - this only works for accounts connected to domain
1428 if ( GetUserNameEx( NameDisplay, ( TCHAR * )name, &size ) )
1429 {
1430 *sUserFullName() = QString::fromWCharArray( name );
1431 }
1432
1433 //fall back to login name
1434 if ( sUserFullName()->isEmpty() )
1435 *sUserFullName() = userLoginName();
1436#elif defined(Q_OS_ANDROID) || defined(__MINGW32__)
1437 *sUserFullName() = u"Not available"_s;
1438#else
1439 struct passwd *p = getpwuid( getuid() );
1440
1441 if ( p )
1442 {
1443 QString gecosName = QString( p->pw_gecos );
1444 *sUserFullName() = gecosName.left( gecosName.indexOf( ',', 0 ) );
1445 }
1446
1447#endif
1448
1449 return *sUserFullName();
1450}
1451
1453{
1454#if defined(Q_OS_ANDROID)
1455 return "android"_L1;
1456#elif defined(Q_OS_MAC)
1457 return "osx"_L1;
1458#elif defined(Q_OS_WIN)
1459 return "windows"_L1;
1460#elif defined(Q_OS_LINUX)
1461 return u"linux"_s;
1462#elif defined(Q_OS_FREEBSD)
1463 return u"freebsd"_s;
1464#elif defined(Q_OS_OPENBSD)
1465 return u"openbsd"_s;
1466#elif defined(Q_OS_NETBSD)
1467 return u"netbsd"_s;
1468#elif defined(Q_OS_UNIX)
1469 return "unix"_L1;
1470#else
1471 return "unknown"_L1;
1472#endif
1473}
1474
1476{
1477 // Bytes to Mb (using 1024 * 1024)
1478 return static_cast<int>( CPLGetUsablePhysicalRAM() / 1048576 );
1479}
1480
1482{
1483 return *sPlatformName();
1484}
1485
1487{
1488 if ( !sApplicationFullName()->isEmpty() )
1489 return *sApplicationFullName();
1490
1491 //use environment variables
1492 *sApplicationFullName() = qgetenv( "QGIS_APPLICATION_FULL_NAME" );
1493 if ( !sApplicationFullName()->isEmpty() )
1494 return *sApplicationFullName();
1495
1496 //last resort
1497 QgsSettings settings;
1498 *sApplicationFullName() = settings.value(
1499 u"/qgis/application_full_name"_s,
1500 u"%1 %2"_s.arg( applicationName(), platform() )
1501 ).toString();
1502 return *sApplicationFullName();
1503}
1504
1506{
1507 if ( settingsLocaleOverrideFlag->value() )
1508 {
1509 QString locale = settingsLocaleUserLocale->value();
1510 // don't differentiate en_US and en_GB
1511 if ( locale.startsWith( "en"_L1, Qt::CaseInsensitive ) )
1512 {
1513 return locale.left( 2 );
1514 }
1515
1516 return locale;
1517 }
1518 else
1519 {
1520 return QLocale().name().left( 2 );
1521 }
1522}
1523
1524void QgsApplication::setLocale( const QLocale &locale )
1525{
1526 QLocale::setDefault( locale );
1527 emit instance()->localeChanged();
1528}
1529
1531{
1532 return qgisSettingsDirPath() + u"/themes"_s;
1533}
1534
1536{
1537 return pkgDataPath() + u"/resources/symbology-style.xml"_s;
1538}
1539
1541{
1542 return pkgDataPath() + u"/resources/themes"_s;
1543}
1544
1546{
1547 return pkgDataPath() + u"/resources/server/"_s;
1548}
1549
1551{
1552 return *sLibraryPath();
1553}
1554
1556{
1557 return *sLibexecPath();
1558}
1559
1561{
1562 return *sQmlImportPath();
1563}
1564
1566{
1567 return ( htonl( 1 ) == 1 ) ? XDR : NDR;
1568}
1569
1571{
1572 if ( !ABISYM( mInitialized ) && QgsApplication::instance() )
1573 {
1574 init( *sProfilePath() );
1575 }
1576
1577 // set the provider plugin path (this creates provider registry)
1579
1580 // create data item provider registry
1582
1583 // create project instance if doesn't exist
1584 QgsProject::instance(); // skip-keyword-check
1585
1586 // Setup authentication manager for lazy initialization
1588
1589 // Make sure we have a NAM created on the main thread.
1590 // Note that this might call QgsApplication::authManager to
1591 // setup the proxy configuration that's why it needs to be
1592 // called after the QgsAuthManager instance has been created
1594
1595}
1596
1598{
1599 if ( auto *lInstance = instance() )
1600 {
1601 if ( !lInstance->mAuthManager )
1602 {
1603 lInstance->mAuthManager = QgsAuthManager::instance();
1604 }
1605 return lInstance->mAuthManager;
1606 }
1607 else
1608 {
1609 // no QgsApplication instance
1610 if ( !sAuthManager )
1611 sAuthManager = QgsAuthManager::instance();
1612 return sAuthManager;
1613 }
1614}
1615
1620
1621
1623{
1624 // make sure all threads are done before exiting
1625 QThreadPool::globalInstance()->waitForDone();
1626
1627 // don't create to delete
1628 if ( auto *lInstance = instance() )
1629 delete lInstance->mAuthManager;
1630 else
1631 delete sAuthManager;
1632
1633 //Ensure that all remaining deleteLater QObjects are actually deleted before we exit.
1634 QgsApplication::sendPostedEvents( nullptr, QEvent::DeferredDelete );
1635
1636 //delete all registered functions from expression engine (see above comment)
1638
1639 // avoid creating instance just to delete it!
1640 if ( QgsProject::sProject )
1641 delete QgsProject::instance(); // skip-keyword-check
1642
1643 //Ensure that providers/layers which called deleteLater on objects as part of their cleanup
1644 //result in fully deleted objects before we do the provider registry cleanup.
1645 //E.g. the QgsOgrConnPool instance has deleteLater calls when unrefing layers, so clearing
1646 //the project above has not yet fully cleaned up OGR objects, which we MUST do before
1647 //cleaning up the provider
1648 QgsApplication::sendPostedEvents( nullptr, QEvent::DeferredDelete );
1649
1650 // avoid creating instance just to delete it!
1651 if ( QgsProviderRegistry::exists() )
1653
1654 invalidateCaches();
1655
1657
1658 // tear-down GDAL/OGR
1659 OGRCleanupAll();
1660 GDALDestroyDriverManager();
1661}
1662
1664{
1665 QString myEnvironmentVar( getenv( "QGIS_PREFIX_PATH" ) );
1666 QString myState = tr( "QgsApplication state:\n"
1667 " - QGIS_PREFIX_PATH env var: %1\n"
1668 " - Prefix: %2\n"
1669 " - Plugin Path: %3\n"
1670 " - Package Data Path: %4\n"
1671 " - Active Theme Name: %5\n"
1672 " - Active Theme Path: %6\n"
1673 " - Default Theme Path: %7\n"
1674 " - SVG Search Paths: %8\n"
1675 " - User DB Path: %9\n"
1676 " - Auth DB Path: %10\n" )
1677 .arg( myEnvironmentVar,
1678 prefixPath(),
1679 pluginPath(),
1680 pkgDataPath(),
1681 themeName(),
1684 svgPaths().join( tr( "\n ", "match indentation of application state" ) ),
1686 .arg( QgsAuthManager::instance()->authenticationDatabaseUriStripped() );
1687 return myState;
1688}
1689
1691{
1692 //
1693 // Make the style sheet desktop preferences aware by using qapplication
1694 // palette as a basis for colors where appropriate
1695 //
1696 // QColor myColor1 = palette().highlight().color();
1697 QColor myColor1( Qt::lightGray );
1698 QColor myColor2 = myColor1;
1699 myColor2 = myColor2.lighter( 110 ); //10% lighter
1700 QString myStyle;
1701 myStyle = QStringLiteral( ".overview{"
1702 " font: 1.82em;"
1703 " font-weight: bold;"
1704 "}"
1705 "body{"
1706 " background: white;"
1707 " color: black;"
1708 " font-family: 'Lato', 'Open Sans', 'Lucida Grande', 'Segoe UI', 'Arial', sans-serif;"
1709 " width: 100%;"
1710 "}"
1711 "h1{ background-color: #F6F6F6;"
1712 " color: #589632; " // from https://qgis.org/styleguide/
1713 " font-size: x-large; "
1714 " font-weight: normal;"
1715 " background: none;"
1716 " padding: 0.75em 0 0;"
1717 " margin: 0;"
1718 " line-height: 3em;"
1719 "}"
1720 "h2{ background-color: #F6F6F6;"
1721 " color: #589632; " // from https://qgis.org/styleguide/
1722 " font-size: medium; "
1723 " font-weight: normal;"
1724 " background: none;"
1725 " padding: 0.75em 0 0;"
1726 " margin: 0;"
1727 " line-height: 1.1em;"
1728 "}"
1729 "h3{ background-color: #F6F6F6;"
1730 " color: #93b023;" // from https://qgis.org/styleguide/
1731 " font-weight: bold;"
1732 " font-size: large;"
1733 " text-align: left;"
1734 " border-bottom: 5px solid #DCEB5C;"
1735 "}"
1736 "h4{ background-color: #F6F6F6;"
1737 " color: #93b023;" // from https://qgis.org/styleguide/
1738 " font-weight: bold;"
1739 " font-size: medium;"
1740 " text-align: left;"
1741 "}"
1742 "h5{ background-color: #F6F6F6;"
1743 " color: #93b023;" // from https://qgis.org/styleguide/
1744 " font-weight: bold;"
1745 " font-size: small;"
1746 " text-align: left;"
1747 "}"
1748 "a{ color: #729FCF;"
1749 " font-family: arial,sans-serif;"
1750 "}"
1751 "label{ background-color: #FFFFCC;"
1752 " border: 1px solid black;"
1753 " margin: 1px;"
1754 " padding: 0px 3px; "
1755 " font-size: small;"
1756 "}"
1757 "th .strong {"
1758 " font-weight: bold;"
1759 "}"
1760 "hr {"
1761 " border: 0;"
1762 " height: 0;"
1763 " border-top: 1px solid black;"
1764 "}"
1765 ".list-view .highlight {"
1766 " text-align: left;"
1767 " border: 0px;"
1768 " width: 20%;"
1769 " padding-right: 15px;"
1770 " padding-left: 20px;"
1771 " font-weight: bold;"
1772 "}"
1773 ".tabular-view .odd-row {"
1774 " background-color: #f9f9f9;"
1775 "}"
1776 ".section {"
1777 " font-weight: bold;"
1778 " padding-top:25px;"
1779 "}" );
1780
1781 // We have some subtle differences between Qt based style and QWebKit style
1782 switch ( styleSheetType )
1783 {
1784 case StyleSheetType::Qt:
1785 myStyle += QStringLiteral(
1786 ".tabular-view{ "
1787 " border-collapse: collapse;"
1788 " width: 95%;"
1789 "}"
1790 ".tabular-view th, .tabular-view td { "
1791 " border:1px solid black;"
1792 "}" );
1793 break;
1794
1796 myStyle += QStringLiteral(
1797 "body { "
1798 " margin: auto;"
1799 " width: 97%;"
1800 "}"
1801 "table.tabular-view, table.list-view { "
1802 " border-collapse: collapse;"
1803 " table-layout:fixed;"
1804 " width: 100% !important;"
1805 " font-size: 90%;"
1806 "}"
1807 // Override
1808 "h1 { "
1809 " line-height: inherit;"
1810 "}"
1811 "td, th {"
1812 " word-wrap: break-word; "
1813 " vertical-align: top;"
1814 "}"
1815 // Set first column width
1816 ".list-view th:first-child, .list-view td:first-child {"
1817 " width: 20%;"
1818 "}"
1819 ".list-view.highlight { "
1820 " padding-left: inherit; "
1821 "}"
1822 // Set first column width for inner tables
1823 ".tabular-view th:first-child, .tabular-view td:first-child { "
1824 " width: 20%; "
1825 "}"
1826 // Makes titles bg stand up
1827 ".tabular-view th.strong { "
1828 " background-color: #eee; "
1829 "}"
1830 // Give some visual appearance to those ugly nested tables
1831 ".tabular-view th, .tabular-view td { "
1832 " border: 1px solid #eee;"
1833 "}"
1834 );
1835 break;
1836 }
1837
1838 return myStyle;
1839}
1840
1842{
1843 if ( 0 >= OGRGetDriverCount() )
1844 {
1845 OGRRegisterAll();
1846 }
1847}
1848
1849QString QgsApplication::absolutePathToRelativePath( const QString &aPath, const QString &targetPath )
1850{
1851 QString aPathUrl = aPath;
1852 QString tPathUrl = targetPath;
1853#if defined( Q_OS_WIN )
1854 const Qt::CaseSensitivity cs = Qt::CaseInsensitive;
1855
1856 aPathUrl.replace( '\\', '/' );
1857 if ( aPathUrl.startsWith( "//" ) )
1858 {
1859 // keep UNC prefix
1860 aPathUrl = "\\\\" + aPathUrl.mid( 2 );
1861 }
1862
1863 tPathUrl.replace( '\\', '/' );
1864 if ( tPathUrl.startsWith( "//" ) )
1865 {
1866 // keep UNC prefix
1867 tPathUrl = "\\\\" + tPathUrl.mid( 2 );
1868 }
1869#else
1870 const Qt::CaseSensitivity cs = Qt::CaseSensitive;
1871#endif
1872
1873 QStringList targetElems = tPathUrl.split( '/', Qt::SkipEmptyParts );
1874 QStringList aPathElems = aPathUrl.split( '/', Qt::SkipEmptyParts );
1875
1876 targetElems.removeAll( u"."_s );
1877 aPathElems.removeAll( u"."_s );
1878
1879 // remove common part
1880 int n = 0;
1881 while ( !aPathElems.isEmpty() &&
1882 !targetElems.isEmpty() &&
1883 aPathElems[0].compare( targetElems[0], cs ) == 0 )
1884 {
1885 aPathElems.removeFirst();
1886 targetElems.removeFirst();
1887 n++;
1888 }
1889
1890 if ( n == 0 )
1891 {
1892 // no common parts; might not even be a file
1893 return aPathUrl;
1894 }
1895
1896 if ( !targetElems.isEmpty() )
1897 {
1898 // go up to the common directory
1899 for ( int i = 0; i < targetElems.size(); i++ )
1900 {
1901 aPathElems.insert( 0, u".."_s );
1902 }
1903 }
1904 else
1905 {
1906 // let it start with . nevertheless,
1907 // so relative path always start with either ./ or ../
1908 aPathElems.insert( 0, u"."_s );
1909 }
1910
1911 return aPathElems.join( '/'_L1 );
1912}
1913
1914QString QgsApplication::relativePathToAbsolutePath( const QString &rpath, const QString &targetPath )
1915{
1916 // relative path should always start with ./ or ../
1917 if ( !rpath.startsWith( "./"_L1 ) && !rpath.startsWith( "../"_L1 ) )
1918 {
1919 return rpath;
1920 }
1921
1922 QString rPathUrl = rpath;
1923 QString targetPathUrl = targetPath;
1924
1925#if defined(Q_OS_WIN)
1926 rPathUrl.replace( '\\', '/' );
1927 targetPathUrl.replace( '\\', '/' );
1928
1929 bool uncPath = targetPathUrl.startsWith( "//" );
1930#endif
1931
1932 QStringList srcElems = rPathUrl.split( '/', Qt::SkipEmptyParts );
1933 QStringList targetElems = targetPathUrl.split( '/', Qt::SkipEmptyParts );
1934
1935#if defined(Q_OS_WIN)
1936 if ( uncPath )
1937 {
1938 targetElems.insert( 0, "" );
1939 targetElems.insert( 0, "" );
1940 }
1941#endif
1942
1943 // append source path elements
1944 targetElems << srcElems;
1945 targetElems.removeAll( u"."_s );
1946
1947 // resolve ..
1948 int pos;
1949 while ( ( pos = targetElems.indexOf( ".."_L1 ) ) > 0 )
1950 {
1951 // remove preceding element and ..
1952 targetElems.removeAt( pos - 1 );
1953 targetElems.removeAt( pos - 1 );
1954 }
1955
1956#if !defined(Q_OS_WIN)
1957 // make path absolute
1958 targetElems.prepend( QString() );
1959#endif
1960
1961 return targetElems.join( '/'_L1 );
1962}
1963
1965{
1966 return *sBuildSourcePath();
1967}
1968
1970{
1971 return *sBuildOutputPath();
1972}
1973
1974#if defined(_MSC_VER) && !defined(USING_NMAKE) && !defined(USING_NINJA)
1975QString QgsApplication::cfgIntDir()
1976{
1977 return *sCfgIntDir();
1978}
1979#endif
1980
1981void QgsApplication::skipGdalDriver( const QString &driver )
1982{
1983 if ( sGdalSkipList()->contains( driver ) || driver.isEmpty() )
1984 {
1985 return;
1986 }
1987 *sGdalSkipList() << driver;
1989}
1990
1991void QgsApplication::restoreGdalDriver( const QString &driver )
1992{
1993 if ( !sGdalSkipList()->contains( driver ) )
1994 {
1995 return;
1996 }
1997 int myPos = sGdalSkipList()->indexOf( driver );
1998 if ( myPos >= 0 )
1999 {
2000 sGdalSkipList()->removeAt( myPos );
2001 }
2003}
2004
2006{
2007 return *sGdalSkipList();
2008}
2009
2011 const QStringList &deferredSkippedGdalDrivers )
2012{
2013 *sGdalSkipList() = skippedGdalDrivers;
2014 *sDeferredSkippedGdalDrivers() = deferredSkippedGdalDrivers;
2015
2016 QgsSettings settings;
2017 settings.setValue( u"gdal/skipDrivers"_s, skippedGdalDrivers.join( ','_L1 ) );
2018
2020}
2021
2023{
2024 QgsSettings settings;
2025 QString joinedList, delimiter;
2026 if ( settings.contains( u"gdal/skipDrivers"_s ) )
2027 {
2028 joinedList = settings.value( u"gdal/skipDrivers"_s, QString() ).toString();
2029 delimiter = u","_s;
2030 }
2031 else
2032 {
2033 joinedList = settings.value( u"gdal/skipList"_s, QString() ).toString();
2034 delimiter = u" "_s;
2035 }
2036 QStringList myList;
2037 if ( !joinedList.isEmpty() )
2038 {
2039 myList = joinedList.split( delimiter );
2040 }
2041 *sGdalSkipList() = myList;
2043}
2044
2046{
2047 return *sDeferredSkippedGdalDrivers();
2048}
2049
2051{
2052 sGdalSkipList()->removeDuplicates();
2053 QStringList realDisabledDriverList;
2054 for ( const auto &driverName : *sGdalSkipList() )
2055 {
2056 if ( !sDeferredSkippedGdalDrivers()->contains( driverName ) )
2057 realDisabledDriverList << driverName;
2058 }
2059 QString myDriverList = realDisabledDriverList.join( ',' );
2060 QgsDebugMsgLevel( u"Gdal Skipped driver list set to:"_s, 2 );
2061 QgsDebugMsgLevel( myDriverList, 2 );
2062 CPLSetConfigOption( "GDAL_SKIP", myDriverList.toUtf8() );
2063 GDALAllRegister(); //to update driver list and skip missing ones
2064}
2065
2067{
2068 QString folder = userThemesFolder();
2069 QDir myDir( folder );
2070 if ( !myDir.exists() )
2071 {
2072 myDir.mkpath( folder );
2073 }
2074
2075 return true;
2076}
2077
2078void QgsApplication::copyPath( const QString &src, const QString &dst )
2079{
2080 QDir dir( src );
2081 if ( ! dir.exists() )
2082 return;
2083
2084 const auto subDirectories = dir.entryList( QDir::Dirs | QDir::NoDotAndDotDot );
2085 for ( const QString &d : subDirectories )
2086 {
2087 QString dst_path = dst + QDir::separator() + d;
2088 dir.mkpath( dst_path );
2089 copyPath( src + QDir::separator() + d, dst_path );
2090 }
2091
2092 const auto files = dir.entryList( QDir::Files );
2093 for ( const QString &f : files )
2094 {
2095 QFile::copy( src + QDir::separator() + f, dst + QDir::separator() + f );
2096 }
2097}
2098
2100{
2101 //read values from QgsSettings
2102 QgsSettings settings;
2103
2104 QVariantMap variables;
2105
2106 //check if settings contains any variables
2107 settings.beginGroup( "variables" );
2108 QStringList childKeys = settings.childKeys();
2109 for ( QStringList::const_iterator it = childKeys.constBegin(); it != childKeys.constEnd(); ++it )
2110 {
2111 QString name = *it;
2112 variables.insert( name, settings.value( name ) );
2113 }
2114
2115 return variables;
2116}
2117
2118void QgsApplication::setCustomVariables( const QVariantMap &variables )
2119{
2120 QgsSettings settings;
2121
2122 QVariantMap::const_iterator it = variables.constBegin();
2123 settings.beginGroup( "variables" );
2124 settings.remove( "" );
2125 for ( ; it != variables.constEnd(); ++it )
2126 {
2127 settings.setValue( it.key(), it.value() );
2128 }
2129
2131}
2132
2133void QgsApplication::setCustomVariable( const QString &name, const QVariant &value )
2134{
2135 // save variable to settings
2136 QgsSettings settings;
2137
2138 settings.setValue( u"variables/"_s + name, value );
2139
2141}
2142
2144{
2145 return instance()->mTemporarilyTrustedProjectFolders;
2146}
2147
2148void QgsApplication::setTemporarilyTrustedProjectsFolders( const QStringList &trustedProjectsFolders )
2149{
2150 instance()->mTemporarilyTrustedProjectFolders = trustedProjectsFolders;
2151}
2152
2154{
2155 return instance()->mTemporarilyUntrustedProjectFolders;
2156}
2157
2158void QgsApplication::setTemporarilyUntrustedProjectsFolders( const QStringList &untrustedProjectsFolders )
2159{
2160 instance()->mTemporarilyUntrustedProjectFolders = untrustedProjectsFolders;
2161}
2162
2163int QgsApplication::scaleIconSize( int standardSize, bool applyDevicePixelRatio )
2164{
2165 QFontMetrics fm( ( QFont() ) );
2166 const double scale = 1.1 * standardSize / 24;
2167 int scaledIconSize = static_cast< int >( std::floor( std::max( Qgis::UI_SCALE_FACTOR * fm.height() * scale, static_cast< double >( standardSize ) ) ) );
2168 if ( applyDevicePixelRatio )
2169 {
2170 if ( QWidget *activeWindow = QApplication::activeWindow() )
2171 scaledIconSize *= ( activeWindow->screen() ? QApplication::activeWindow()->screen()->devicePixelRatio() : 1 );
2172 }
2173 return scaledIconSize;
2174}
2175
2180
2182{
2183 *sTranslation() = translation;
2184 if ( auto app = QgsApplication::instance() )
2185 {
2186 app->installTranslators();
2187 }
2188}
2189
2191{
2192 return *sTranslation();
2193}
2194
2196{
2197 emit requestForTranslatableObjects( translationContext );
2198}
2199
2201{
2202 ApplicationMembers *appMembers = members();
2203 if ( appMembers->mNullRepresentation.isNull() )
2204 {
2205 appMembers->mNullRepresentation = QgsSettings().value( u"qgis/nullValue"_s, u"NULL"_s ).toString();
2206 }
2207 return appMembers->mNullRepresentation;
2208}
2209
2211{
2212 ApplicationMembers *appMembers = members();
2213 if ( !appMembers || appMembers->mNullRepresentation == nullRepresentation )
2214 return;
2215
2217 QgsSettings().setValue( u"qgis/nullValue"_s, nullRepresentation );
2218
2219 QgsApplication *app = instance();
2220 if ( app )
2221 emit app->nullRepresentationChanged();
2222}
2223
2225{
2226 return members()->mActionScopeRegistry.get();
2227}
2228
2229bool QgsApplication::createDatabase( QString *errorMessage )
2230{
2231 // set a working directory up for gdal to write .aux.xml files into
2232 // for cases where the raster dir is read only to the user
2233 // if the env var is already set it will be used preferentially
2234 QString myPamPath = qgisSettingsDirPath() + u"gdal_pam/"_s;
2235 QDir myDir( myPamPath );
2236 if ( !myDir.exists() )
2237 {
2238 myDir.mkpath( myPamPath ); //fail silently
2239 }
2240
2241#if defined(Q_OS_WIN)
2242 CPLSetConfigOption( "GDAL_PAM_PROXY_DIR", myPamPath.toUtf8() );
2243#else
2244 //under other OS's we use an environment var so the user can
2245 //override the path if he likes
2246 int myChangeFlag = 0; //whether we want to force the env var to change
2247 setenv( "GDAL_PAM_PROXY_DIR", myPamPath.toUtf8(), myChangeFlag );
2248#endif
2249
2250 // Check qgis.db and make private copy if necessary
2251 QFile qgisPrivateDbFile( QgsApplication::qgisUserDatabaseFilePath() );
2252
2253 // first we look for ~/.qgis/qgis.db
2254 if ( !qgisPrivateDbFile.exists() )
2255 {
2256 // if it doesn't exist we copy it in from the global resources dir
2257 QString qgisMasterDbFileName = QgsApplication::qgisMasterDatabaseFilePath();
2258 QFile masterFile( qgisMasterDbFileName );
2259
2260 // Must be sure there is destination directory ~/.qgis
2261 QDir().mkpath( QgsApplication::qgisSettingsDirPath() );
2262
2263 //now copy the master file into the users .qgis dir
2264 bool isDbFileCopied = masterFile.copy( qgisPrivateDbFile.fileName() );
2265
2266 if ( !isDbFileCopied )
2267 {
2268 if ( errorMessage )
2269 {
2270 *errorMessage = tr( "[ERROR] Can not make qgis.db private copy" );
2271 }
2272 return false;
2273 }
2274
2275 QFile::Permissions perms = QFile( qgisPrivateDbFile.fileName() ).permissions();
2276 if ( !( perms & QFile::WriteOwner ) )
2277 {
2278 if ( !qgisPrivateDbFile.setPermissions( perms | QFile::WriteOwner ) )
2279 {
2280 if ( errorMessage )
2281 {
2282 *errorMessage = tr( "Can not make '%1' user writable" ).arg( qgisPrivateDbFile.fileName() );
2283 }
2284 return false;
2285 }
2286 }
2287 }
2288 else
2289 {
2290 // migrate if necessary
2292 if ( database.open( QgsApplication::qgisUserDatabaseFilePath() ) != SQLITE_OK )
2293 {
2294 if ( errorMessage )
2295 {
2296 *errorMessage = tr( "Could not open qgis.db" );
2297 }
2298 return false;
2299 }
2300
2301 char *errmsg = nullptr;
2302 int res = sqlite3_exec( database.get(), "SELECT srs_id FROM tbl_srs LIMIT 0", nullptr, nullptr, &errmsg );
2303 if ( res != SQLITE_OK )
2304 {
2305 sqlite3_free( errmsg );
2306
2307 // qgis.db is missing tbl_srs, create it
2308 if ( sqlite3_exec( database.get(),
2309 "DROP INDEX IF EXISTS idx_srsauthid;"
2310 "CREATE TABLE tbl_srs ("
2311 "srs_id INTEGER PRIMARY KEY,"
2312 "description text NOT NULL,"
2313 "projection_acronym text NOT NULL,"
2314 "ellipsoid_acronym NOT NULL,"
2315 "parameters text NOT NULL,"
2316 "srid integer,"
2317 "auth_name varchar,"
2318 "auth_id varchar,"
2319 "is_geo integer NOT NULL,"
2320 "deprecated boolean,"
2321 "wkt text);"
2322 "CREATE INDEX idx_srsauthid on tbl_srs(auth_name,auth_id);", nullptr, nullptr, &errmsg ) != SQLITE_OK )
2323 {
2324 if ( errorMessage )
2325 {
2326 *errorMessage = tr( "Creation of missing tbl_srs in the private qgis.db failed.\n%1" ).arg( QString::fromUtf8( errmsg ) );
2327 }
2328 sqlite3_free( errmsg );
2329 return false;
2330 }
2331 }
2332 else
2333 {
2334 // test if wkt column exists in database
2335 res = sqlite3_exec( database.get(), "SELECT wkt FROM tbl_srs LIMIT 0", nullptr, nullptr, &errmsg );
2336 if ( res != SQLITE_OK )
2337 {
2338 // need to add wkt column
2339 sqlite3_free( errmsg );
2340 if ( sqlite3_exec( database.get(),
2341 "DROP INDEX IF EXISTS idx_srsauthid;"
2342 "DROP TABLE IF EXISTS tbl_srs_bak;"
2343 "ALTER TABLE tbl_srs RENAME TO tbl_srs_bak;"
2344 "CREATE TABLE tbl_srs ("
2345 "srs_id INTEGER PRIMARY KEY,"
2346 "description text NOT NULL,"
2347 "projection_acronym text NOT NULL,"
2348 "ellipsoid_acronym NOT NULL,"
2349 "parameters text NOT NULL,"
2350 "srid integer,"
2351 "auth_name varchar,"
2352 "auth_id varchar,"
2353 "is_geo integer NOT NULL,"
2354 "deprecated boolean,"
2355 "wkt text);"
2356 "CREATE INDEX idx_srsauthid on tbl_srs(auth_name,auth_id);"
2357 "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;"
2358 "DROP TABLE tbl_srs_bak", nullptr, nullptr, &errmsg ) != SQLITE_OK )
2359 {
2360 if ( errorMessage )
2361 {
2362 *errorMessage = tr( "Migration of private qgis.db failed.\n%1" ).arg( QString::fromUtf8( errmsg ) );
2363 }
2364 sqlite3_free( errmsg );
2365 return false;
2366 }
2367 }
2368 }
2369
2370 res = sqlite3_exec( database.get(), "SELECT acronym FROM tbl_projection LIMIT 0", nullptr, nullptr, &errmsg );
2371 if ( res != SQLITE_OK )
2372 {
2373 sqlite3_free( errmsg );
2374
2375 // qgis.db is missing tbl_projection, create it
2376 if ( sqlite3_exec( database.get(),
2377 "CREATE TABLE tbl_projection ("
2378 "acronym varchar(20) NOT NULL PRIMARY KEY,"
2379 "name varchar(255) NOT NULL default '',"
2380 "notes varchar(255) NOT NULL default '',"
2381 "parameters varchar(255) NOT NULL default ''"
2382 ")", nullptr, nullptr, &errmsg ) != SQLITE_OK )
2383 {
2384 if ( errorMessage )
2385 {
2386 *errorMessage = tr( "Creation of missing tbl_projection in the private qgis.db failed.\n%1" ).arg( QString::fromUtf8( errmsg ) );
2387 }
2388 sqlite3_free( errmsg );
2389 return false;
2390 }
2391 }
2392
2393 res = sqlite3_exec( database.get(), "SELECT epsg FROM tbl_srs LIMIT 0", nullptr, nullptr, &errmsg );
2394 if ( res == SQLITE_OK )
2395 {
2396 // epsg column exists => need migration
2397 if ( sqlite3_exec( database.get(),
2398 "DROP INDEX IF EXISTS idx_srsauthid;"
2399 "DROP TABLE IF EXISTS tbl_srs_bak;"
2400 "ALTER TABLE tbl_srs RENAME TO tbl_srs_bak;"
2401 "CREATE TABLE tbl_srs ("
2402 "srs_id INTEGER PRIMARY KEY,"
2403 "description text NOT NULL,"
2404 "projection_acronym text NOT NULL,"
2405 "ellipsoid_acronym NOT NULL,"
2406 "parameters text NOT NULL,"
2407 "srid integer,"
2408 "auth_name varchar,"
2409 "auth_id varchar,"
2410 "is_geo integer NOT NULL,"
2411 "deprecated boolean,"
2412 "wkt text);"
2413 "CREATE INDEX idx_srsauthid on tbl_srs(auth_name,auth_id);"
2414 "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;"
2415 "DROP TABLE tbl_srs_bak", nullptr, nullptr, &errmsg ) != SQLITE_OK )
2416 {
2417 if ( errorMessage )
2418 {
2419 *errorMessage = tr( "Migration of private qgis.db failed.\n%1" ).arg( QString::fromUtf8( errmsg ) );
2420 }
2421 sqlite3_free( errmsg );
2422 return false;
2423 }
2424 }
2425 else
2426 {
2427 sqlite3_free( errmsg );
2428 }
2429
2430 if ( sqlite3_exec( database.get(), "DROP VIEW vw_srs", nullptr, nullptr, &errmsg ) != SQLITE_OK )
2431 {
2432 QgsDebugError( u"vw_srs didn't exists in private qgis.db: %1"_s.arg( errmsg ) );
2433 }
2434
2435 if ( sqlite3_exec( database.get(),
2436 "CREATE VIEW vw_srs AS"
2437 " SELECT"
2438 " a.description AS description"
2439 ",a.srs_id AS srs_id"
2440 ",a.is_geo AS is_geo"
2441 ",coalesce(b.name,a.projection_acronym) AS name"
2442 ",a.parameters AS parameters"
2443 ",a.auth_name AS auth_name"
2444 ",a.auth_id AS auth_id"
2445 ",a.deprecated AS deprecated"
2446 " FROM tbl_srs a"
2447 " LEFT OUTER JOIN tbl_projection b ON a.projection_acronym=b.acronym"
2448 " ORDER BY coalesce(b.name,a.projection_acronym),a.description", nullptr, nullptr, &errmsg ) != SQLITE_OK )
2449 {
2450 if ( errorMessage )
2451 {
2452 *errorMessage = tr( "Update of view in private qgis.db failed.\n%1" ).arg( QString::fromUtf8( errmsg ) );
2453 }
2454 sqlite3_free( errmsg );
2455 return false;
2456 }
2457 }
2458 return true;
2459}
2460
2462{
2463 QgsDebugMsgLevel( u"maxThreads: %1"_s.arg( maxThreads ), 2 );
2464
2465 // make sure value is between 1 and #cores, if not set to -1 (use #cores)
2466 if ( maxThreads < 1 || maxThreads > QThread::idealThreadCount() )
2467 maxThreads = -1;
2468
2469 // force at least 2 threads -- anything less risks deadlocks within Qt itself (e.g in QImage internal mutexes)
2470 if ( maxThreads > 0 && maxThreads < 2 )
2471 maxThreads = 2;
2472
2473 // save value
2474 ABISYM( sMaxThreads ) = maxThreads;
2475
2476 // if -1 use #cores
2477 if ( maxThreads == -1 )
2478 maxThreads = QThread::idealThreadCount();
2479
2480 // set max thread count in QThreadPool
2481 QThreadPool::globalInstance()->setMaxThreadCount( maxThreads );
2482 QgsDebugMsgLevel( u"set QThreadPool max thread count to %1"_s.arg( QThreadPool::globalInstance()->maxThreadCount() ), 2 );
2483}
2484
2486{
2487 return members()->mTaskManager.get();
2488}
2489
2491{
2492 return members()->mSettingsRegistryCore.get();
2493}
2494
2496{
2497 return members()->mColorSchemeRegistry.get();
2498}
2499
2501{
2502 return members()->mPaintEffectRegistry.get();
2503}
2504
2506{
2507 return members()->mRendererRegistry.get();
2508}
2509
2511{
2512 return members()->mRasterRendererRegistry.get();
2513}
2514
2516{
2517 return members()->mPointCloudRendererRegistry.get();
2518}
2519
2521{
2522 return members()->mTiledSceneRendererRegistry.get();
2523}
2524
2526{
2527 if ( auto *lInstance = instance() )
2528 {
2529 if ( !instance()->mDataItemProviderRegistry )
2530 {
2531 lInstance->mDataItemProviderRegistry = std::make_unique<QgsDataItemProviderRegistry>();
2532 }
2533 return lInstance->mDataItemProviderRegistry.get();
2534 }
2535 else
2536 {
2537 // no QgsApplication instance
2538 static QgsDataItemProviderRegistry *sDataItemProviderRegistry = nullptr;
2539 if ( !sDataItemProviderRegistry )
2540 sDataItemProviderRegistry = new QgsDataItemProviderRegistry();
2541 return sDataItemProviderRegistry;
2542 }
2543}
2544
2546{
2547 return members()->mCrsRegistry.get();
2548}
2549
2551{
2552 return members()->mSvgCache.get();
2553}
2554
2556{
2557 return members()->mImageCache.get();
2558}
2559
2561{
2562 return members()->mSourceCache.get();
2563}
2564
2566{
2567 return members()->mNetworkContentFetcherRegistry.get();
2568}
2569
2571{
2572 return members()->mValidityCheckRegistry.get();
2573}
2574
2576{
2577 return members()->mSymbolLayerRegistry.get();
2578}
2579
2581{
2582 return members()->mCalloutRegistry.get();
2583}
2584
2586{
2587 return members()->mLayoutItemRegistry.get();
2588}
2589
2591{
2592 return members()->mAnnotationItemRegistry.get();
2593}
2594
2596{
2597 return members()->mSensorRegistry.get();
2598}
2599
2601{
2602 return members()->mPlotRegistry.get();
2603}
2604
2606{
2607 return members()->mGpsConnectionRegistry.get();
2608}
2609
2611{
2612 return members()->mGpsBabelFormatRegistry.get();
2613}
2614
2616{
2617 return members()->mPluginLayerRegistry.get();
2618}
2619
2621{
2622 return members()->mClassificationMethodRegistry.get();
2623}
2624
2626{
2627 return members()->mBookmarkManager.get();
2628}
2629
2631{
2632 return members()->mTileDownloadManager.get();
2633}
2634
2636{
2637 return members()->mRecentStyleHandler.get();
2638}
2639
2641{
2642 return members()->mQueryLogger.get();
2643}
2644
2646{
2647 return members()->mStyleModel.get();
2648}
2649
2651{
2652 return members()->mFontManager.get();
2653}
2654
2656{
2657 return members()->mMessageLog.get();
2658}
2659
2661{
2662 return members()->mProcessingRegistry.get();
2663}
2664
2666{
2667 return members()->mConnectionRegistry.get();
2668}
2669
2671{
2672 return members()->mLayerMetadataProviderRegistry.get();
2673}
2674
2676{
2677 return members()->mPageSizeRegistry.get();
2678}
2679
2681{
2682 return members()->mAnnotationRegistry.get();
2683}
2684
2686{
2687 return members()->mApplicationThemeRegistry.get();
2688}
2689
2691{
2692 return members()->mNumericFormatRegistry.get();
2693}
2694
2696{
2697 return members()->mFieldFormatterRegistry.get();
2698}
2699
2701{
2702 return members()->m3DRendererRegistry.get();
2703}
2704
2706{
2707 return members()->m3DSymbolRegistry.get();
2708}
2709
2711{
2712 return members()->mScaleBarRendererRegistry.get();
2713}
2714
2716{
2717 return members()->mLabelingEngineRuleRegistry.get();
2718}
2719
2721{
2722 return members()->mProjectStorageRegistry.get();
2723}
2724
2726{
2727 return members()->mExternalStorageRegistry.get();
2728}
2729
2731{
2732 return members()->mProfileSourceRegistry.get();
2733}
2734
2736{
2737 return members()->mLocalizedDataPathRegistry.get();
2738}
2739
2741{
2742 // don't use initializer lists or scoped pointers - as more objects are added here we
2743 // will need to be careful with the order of creation/destruction
2744 mSettingsRegistryCore = std::make_unique<QgsSettingsRegistryCore>();
2745 mLocalizedDataPathRegistry = std::make_unique<QgsLocalizedDataPathRegistry>();
2746 mMessageLog = std::make_unique<QgsMessageLog>();
2747 QgsRuntimeProfiler *profiler = QgsRuntimeProfiler::threadLocalInstance();
2748
2749 {
2750 profiler->start( tr( "Create query logger" ) );
2751 mQueryLogger = std::make_unique<QgsDatabaseQueryLog>();
2752 profiler->end();
2753 }
2754 {
2755 profiler->start( tr( "Setup coordinate reference system registry" ) );
2756 mCrsRegistry = std::make_unique<QgsCoordinateReferenceSystemRegistry>();
2757 profiler->end();
2758 }
2759 {
2760 profiler->start( tr( "Create connection registry" ) );
2761 mConnectionRegistry = std::make_unique<QgsConnectionRegistry>();
2762 profiler->end();
2763 }
2764 {
2765 profiler->start( tr( "Create project storage registry" ) );
2766 mProjectStorageRegistry = std::make_unique<QgsProjectStorageRegistry>();
2767 profiler->end();
2768 }
2769 {
2770 profiler->start( tr( "Create layer metadata provider registry" ) );
2771 mLayerMetadataProviderRegistry = std::make_unique<QgsLayerMetadataProviderRegistry>();
2772 profiler->end();
2773 }
2774 {
2775 profiler->start( tr( "Create font manager" ) );
2776 mFontManager = std::make_unique<QgsFontManager>();
2777 profiler->end();
2778 }
2779 {
2780 profiler->start( tr( "Setup task manager" ) );
2781 mTaskManager = std::make_unique<QgsTaskManager>();
2782 profiler->end();
2783 }
2784 {
2785 profiler->start( tr( "Setup action scope registry" ) );
2786 mActionScopeRegistry = std::make_unique<QgsActionScopeRegistry>();
2787 profiler->end();
2788 }
2789 {
2790 profiler->start( tr( "Setup numeric formats" ) );
2791 mNumericFormatRegistry = std::make_unique<QgsNumericFormatRegistry>();
2792 profiler->end();
2793 }
2794 {
2795 profiler->start( tr( "Setup field formats" ) );
2796 mFieldFormatterRegistry = std::make_unique<QgsFieldFormatterRegistry>();
2797 profiler->end();
2798 }
2799 {
2800 profiler->start( tr( "Setup SVG cache" ) );
2801 mSvgCache = std::make_unique<QgsSvgCache>();
2802 profiler->end();
2803 }
2804 {
2805 profiler->start( tr( "Setup image cache" ) );
2806 mImageCache = std::make_unique<QgsImageCache>();
2807 profiler->end();
2808 }
2809 {
2810 profiler->start( tr( "Setup source cache" ) );
2811 mSourceCache = std::make_unique<QgsSourceCache>();
2812 profiler->end();
2813 }
2814 {
2815 profiler->start( tr( "Setup color scheme registry" ) );
2816 mColorSchemeRegistry = std::make_unique<QgsColorSchemeRegistry>();
2817 profiler->end();
2818 }
2819 {
2820 profiler->start( tr( "Setup paint effect" ) );
2821 mPaintEffectRegistry = std::make_unique<QgsPaintEffectRegistry>();
2822 profiler->end();
2823 }
2824 {
2825 profiler->start( tr( "Setup symbol layer registry" ) );
2826 mSymbolLayerRegistry = std::make_unique<QgsSymbolLayerRegistry>();
2827 profiler->end();
2828 }
2829 {
2830 profiler->start( tr( "Recent style handler" ) );
2831 mRecentStyleHandler = std::make_unique<QgsRecentStyleHandler>();
2832 profiler->end();
2833 }
2834 {
2835 profiler->start( tr( "Setup callout registry" ) );
2836 mCalloutRegistry = std::make_unique<QgsCalloutRegistry>();
2837 profiler->end();
2838 }
2839 {
2840 profiler->start( tr( "Setup renderer registry" ) );
2841 mRendererRegistry = std::make_unique<QgsRendererRegistry>();
2842 profiler->end();
2843 }
2844 {
2845 profiler->start( tr( "Setup raster renderer registry" ) );
2846 mRasterRendererRegistry = std::make_unique<QgsRasterRendererRegistry>();
2847 profiler->end();
2848 }
2849 {
2850 profiler->start( tr( "Setup point cloud renderer registry" ) );
2851 mPointCloudRendererRegistry = std::make_unique<QgsPointCloudRendererRegistry>();
2852 profiler->end();
2853 }
2854 {
2855 profiler->start( tr( "Setup tiled scene renderer registry" ) );
2856 mTiledSceneRendererRegistry = std::make_unique<QgsTiledSceneRendererRegistry>();
2857 profiler->end();
2858 }
2859 {
2860 profiler->start( tr( "Setup GPS registry" ) );
2861 mGpsConnectionRegistry = std::make_unique<QgsGpsConnectionRegistry>();
2862 profiler->end();
2863 }
2864 {
2865 profiler->start( tr( "Setup GPSBabel format registry" ) );
2866 mGpsBabelFormatRegistry = std::make_unique<QgsBabelFormatRegistry>();
2867 profiler->end();
2868 }
2869 {
2870 profiler->start( tr( "Setup plugin layer registry" ) );
2871 mPluginLayerRegistry = std::make_unique<QgsPluginLayerRegistry>();
2872 profiler->end();
2873 }
2874 {
2875 profiler->start( tr( "Setup Processing registry" ) );
2876 mProcessingRegistry = std::make_unique<QgsProcessingRegistry>();
2877 profiler->end();
2878 }
2879 mPageSizeRegistry = std::make_unique<QgsPageSizeRegistry>();
2880 {
2881 profiler->start( tr( "Setup layout item registry" ) );
2882 mLayoutItemRegistry = std::make_unique<QgsLayoutItemRegistry>();
2883 mLayoutItemRegistry->populate();
2884 profiler->end();
2885 }
2886 {
2887 profiler->start( tr( "Setup annotation registry" ) );
2888 mAnnotationRegistry = std::make_unique<QgsAnnotationRegistry>();
2889 profiler->end();
2890 }
2891 {
2892 profiler->start( tr( "Setup application theme registry" ) );
2893 mApplicationThemeRegistry = std::make_unique<QgsApplicationThemeRegistry>();
2894 profiler->end();
2895 }
2896 {
2897 profiler->start( tr( "Setup annotation item registry" ) );
2898 mAnnotationItemRegistry = std::make_unique<QgsAnnotationItemRegistry>();
2899 mAnnotationItemRegistry->populate();
2900 profiler->end();
2901 }
2902 {
2903 profiler->start( tr( "Setup labeling engine rule registry" ) );
2904 mLabelingEngineRuleRegistry = std::make_unique<QgsLabelingEngineRuleRegistry>();
2905 profiler->end();
2906 }
2907 {
2908 profiler->start( tr( "Setup sensor registry" ) );
2909 mSensorRegistry = std::make_unique<QgsSensorRegistry>();
2910 mSensorRegistry->populate();
2911 profiler->end();
2912 }
2913 {
2914 profiler->start( tr( "Setup plot registry" ) );
2915 mPlotRegistry = std::make_unique<QgsPlotRegistry>();
2916 mPlotRegistry->populate();
2917 profiler->end();
2918 }
2919 {
2920 profiler->start( tr( "Setup 3D symbol registry" ) );
2921 m3DSymbolRegistry = std::make_unique<Qgs3DSymbolRegistry>();
2922 profiler->end();
2923 }
2924 {
2925 profiler->start( tr( "Setup 3D renderer registry" ) );
2926 m3DRendererRegistry = std::make_unique<Qgs3DRendererRegistry>();
2927 profiler->end();
2928 }
2929 {
2930 profiler->start( tr( "Setup external storage registry" ) );
2931 mExternalStorageRegistry = std::make_unique<QgsExternalStorageRegistry>();
2932 profiler->end();
2933 }
2934 {
2935 profiler->start( tr( "Setup profile source registry" ) );
2936 mProfileSourceRegistry = std::make_unique<QgsProfileSourceRegistry>();
2937 profiler->end();
2938 }
2939 {
2940 profiler->start( tr( "Setup network content cache" ) );
2941 mNetworkContentFetcherRegistry = std::make_unique<QgsNetworkContentFetcherRegistry>();
2942 profiler->end();
2943 }
2944 {
2945 profiler->start( tr( "Setup layout check registry" ) );
2946 mValidityCheckRegistry = std::make_unique<QgsValidityCheckRegistry>();
2947 profiler->end();
2948 }
2949 {
2950 profiler->start( tr( "Setup classification registry" ) );
2951 mClassificationMethodRegistry = std::make_unique<QgsClassificationMethodRegistry>();
2952 profiler->end();
2953 }
2954 {
2955 profiler->start( tr( "Setup bookmark manager" ) );
2956 mBookmarkManager = std::make_unique<QgsBookmarkManager>( nullptr );
2957 profiler->end();
2958 }
2959 {
2960 profiler->start( tr( "Setup tile download manager" ) );
2961 mTileDownloadManager = std::make_unique<QgsTileDownloadManager>();
2962 profiler->end();
2963 }
2964 {
2965 profiler->start( tr( "Setup scalebar registry" ) );
2966 mScaleBarRendererRegistry = std::make_unique<QgsScaleBarRendererRegistry>();
2967 profiler->end();
2968 }
2969}
2970
2972{
2973 // we reset unique_ptr manually because we care about destruction order
2974 mStyleModel.reset();
2975 mTileDownloadManager.reset();
2977 mValidityCheckRegistry.reset();
2978 mActionScopeRegistry.reset();
2979 m3DRendererRegistry.reset();
2980 m3DSymbolRegistry.reset();
2981 mAnnotationRegistry.reset();
2983 mColorSchemeRegistry.reset();
2985 mGpsConnectionRegistry.reset();
2987 mPaintEffectRegistry.reset();
2988 mPluginLayerRegistry.reset();
2989 mProcessingRegistry.reset();
2990 mPageSizeRegistry.reset();
2992 mSensorRegistry.reset();
2993 mPlotRegistry.reset();
2994 mLayoutItemRegistry.reset();
2998 mRendererRegistry.reset();
2999 mSvgCache.reset();
3000 mImageCache.reset();
3001 mSourceCache.reset();
3002 mCalloutRegistry.reset();
3003 mRecentStyleHandler.reset();
3005 mSymbolLayerRegistry.reset();
3007 mProfileSourceRegistry.reset();
3008 mTaskManager.reset();
3011 mNumericFormatRegistry.reset();
3012 mBookmarkManager.reset();
3013 mConnectionRegistry.reset();
3016 mFontManager.reset();
3018 mCrsRegistry.reset();
3019 mQueryLogger.reset();
3020 mMessageLog.reset();
3021}
3022
3023QgsApplication::ApplicationMembers *QgsApplication::members()
3024{
3025 if ( auto *lInstance = instance() )
3026 {
3027 return lInstance->mApplicationMembers.get();
3028 }
3029 else
3030 {
3031 static QRecursiveMutex sMemberMutex;
3032 QMutexLocker lock( &sMemberMutex );
3033 if ( !sApplicationMembers )
3034 sApplicationMembers = new ApplicationMembers();
3035 return sApplicationMembers;
3036 }
3037}
QFlags< SettingsOption > SettingsOptions
Definition qgis.h:748
static const double UI_SCALE_FACTOR
UI scaling factor.
Definition qgis.h:6499
A registry for available 3D renderers.
Registry of available 3D symbol classes.
The action scope registry is an application wide registry that contains a list of available action sc...
Registry of available annotation item types.
Registry of user interface themes.
QHash< QString, QString > themeFolders() const
Returns a map of user interface theme names and folders.
QString themeFolder(const QString &name) const
Returns the user interface theme folder for a matching name.
static QString resolvePkgPath()
Calculate the application pkg path.
static int scaleIconSize(int standardSize, bool applyDevicePixelRatio=false)
Scales an icon size to compensate for display pixel density, making the icon size hi-dpi friendly,...
static void restoreGdalDriver(const QString &driver)
Sets the GDAL_SKIP environment variable to exclude the specified driver and then calls GDALDriverMana...
static QgsLabelingEngineRuleRegistry * labelingEngineRuleRegistry()
Gets the registry of available labeling engine rules.
static void setCustomVariables(const QVariantMap &customVariables)
Custom expression variables for this application.
QString translation() const
Returns the current application translation locale code.
static QString i18nPath()
Returns the path to the translation directory.
static QgsAnnotationItemRegistry * annotationItemRegistry()
Returns the application's annotation item registry, used for annotation item types.
static QString osName()
Returns a string name of the operating system QGIS is running on.
static void registerOgrDrivers()
Register OGR drivers ensuring this only happens once.
static QString sponsorsFilePath()
Returns the path to the sponsors file.
static QgsRecentStyleHandler * recentStyleHandler()
Returns the handler for recently used style items.
endian_t
Constants for endian-ness.
static QString qgisMasterDatabaseFilePath()
Returns the path to the master qgis.db file.
static void skipGdalDriver(const QString &driver)
Sets the GDAL_SKIP environment variable to include the specified driver and then calls GDALDriverMana...
static QString defaultThemePath()
Returns the path to the default theme directory.
static QgsPageSizeRegistry * pageSizeRegistry()
Returns the application's page size registry, used for managing layout page sizes.
static QgsValidityCheckRegistry * validityCheckRegistry()
Returns the application's validity check registry, used for managing validity checks.
static QgsDataItemProviderRegistry * dataItemProviderRegistry()
Returns the application's data item provider registry, which keeps a list of data item providers that...
static QString userStylePath()
Returns the path to user's style.
static QString platform()
Returns the QGIS platform name, e.g., "desktop", "server", "qgis_process" or "external" (for external...
static QgsProcessingRegistry * processingRegistry()
Returns the application's processing registry, used for managing processing providers,...
static QgsLayerMetadataProviderRegistry * layerMetadataProviderRegistry()
Returns registry of available layer metadata provider implementations.
static QgsConnectionRegistry * connectionRegistry()
Returns the application's connection registry, used for managing saved data provider connections.
static void exitQgis()
deletes provider registry and map layer registry
static void setPluginPath(const QString &pluginPath)
Alters plugin path - used by 3rd party apps.
static const QgsSettingsEntryStringList * settingsSearchPathsForSVG
Settings entry search path for SVG.
void themeChanged()
Emitted when the application theme has changed.
static QPixmap getThemePixmap(const QString &name, const QColor &foreColor=QColor(), const QColor &backColor=QColor(), int size=16)
Helper to get a theme icon as a pixmap.
static QString nullRepresentation()
Returns the string used to represent the value NULL throughout QGIS.
static QVariantMap customVariables()
Custom expression variables for this application.
static QgsPointCloudRendererRegistry * pointCloudRendererRegistry()
Returns the application's point cloud renderer registry, used for managing point cloud layer 2D rende...
static QgsPaintEffectRegistry * paintEffectRegistry()
Returns the application's paint effect registry, used for managing paint effects.
static QgsSensorRegistry * sensorRegistry()
Returns the application's sensor registry, used for sensor types.
static QString pluginPath()
Returns the path to the application plugin directory.
static void setUITheme(const QString &themeName)
Set the current UI theme used to style the interface.
static bool createDatabase(QString *errorMessage=nullptr)
initialize qgis.db
static const QgsSettingsEntryBool * settingsLocaleOverrideFlag
Settings entry locale override flag.
static void setTemporarilyUntrustedProjectsFolders(const QStringList &untrustedProjectsFolders)
Sets the list of projects and folders that have been temporarily determined as untrusted by the user.
static QCursor getThemeCursor(Cursor cursor)
Helper to get a theme cursor.
static int systemMemorySizeMb()
Returns the size of the system memory (RAM) in megabytes.
static void setLocale(const QLocale &locale)
Sets the QGIS locale - used mainly by 3rd party apps and tests.
static void init(QString profileFolder=QString())
This method initializes paths etc for QGIS.
static void setThemeName(const QString &themeName)
Set the active theme to the specified theme.
void customVariablesChanged()
Emitted whenever a custom global variable changes.
static QString buildSourcePath()
Returns path to the source directory. Valid only when running from build directory.
static QString buildOutputPath()
Returns path to the build output directory. Valid only when running from build directory.
bool notify(QObject *receiver, QEvent *event) override
Catch exceptions when sending event to receiver.
static int maxThreads()
Gets maximum concurrent thread count.
static QgsColorSchemeRegistry * colorSchemeRegistry()
Returns the application's color scheme registry, used for managing color schemes.
static QgsApplication * instance()
Returns the singleton instance of the QgsApplication.
static QString reportStyleSheet(QgsApplication::StyleSheetType styleSheetType=QgsApplication::StyleSheetType::Qt)
Returns a css style sheet for reports, the styleSheetType argument determines what type of stylesheet...
static QString pkgDataPath()
Returns the common root path of all application data directories.
static QgsScaleBarRendererRegistry * scaleBarRendererRegistry()
Gets the registry of available scalebar renderers.
static QgsLayoutItemRegistry * layoutItemRegistry()
Returns the application's layout item registry, used for layout item types.
static void setFileOpenEventReceiver(QObject *receiver)
Sets the FileOpen event receiver.
static QgsSymbolLayerRegistry * symbolLayerRegistry()
Returns the application's symbol layer registry, used for managing symbol layers.
static QgsRasterRendererRegistry * rasterRendererRegistry()
Returns the application's raster renderer registry, used for managing raster layer renderers.
static void applyGdalSkippedDrivers()
Apply the skipped drivers list to gdal.
static void setMaxThreads(int maxThreads)
Set maximum concurrent thread count.
static QgsNumericFormatRegistry * numericFormatRegistry()
Gets the registry of available numeric formats.
static QgsNetworkContentFetcherRegistry * networkContentFetcherRegistry()
Returns the application's network content registry used for fetching temporary files during QGIS sess...
static QgsProjectStorageRegistry * projectStorageRegistry()
Returns registry of available project storage implementations.
static QString licenceFilePath()
Returns the path to the licence file.
static QString libexecPath()
Returns the path with utility executables (help viewer, crssync, ...).
static QStringList skippedGdalDrivers()
Returns the list of gdal drivers that should be skipped (based on GDAL_SKIP environment variable).
StyleSheetType
The StyleSheetType enum represents the stylesheet type that a widget supports.
@ Qt
StyleSheet for Qt GUI widgets (based on QLabel or QTextBrowser), supports basic CSS and Qt extensions...
@ WebBrowser
StyleSheet for embedded browsers (QtWebKit), supports full standard CSS.
static QString translatorsFilePath()
Returns the path to the sponsors file.
static const QgsSettingsEntryString * settingsLocaleGlobalLocale
Settings entry locale global locale.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static void setNullRepresentation(const QString &nullRepresentation)
Sets the string used to represent the value NULL throughout QGIS.
static QStringList temporarilyTrustedProjectsFolders()
Returns the list of projects and folders that have been temporarily determined as trusted by the user...
static QString applicationFullName()
Returns the QGIS application full name.
static QgsGpsConnectionRegistry * gpsConnectionRegistry()
Returns the application's GPS connection registry, used for managing GPS connections.
static QString locale()
Returns the QGIS locale.
static QgsImageCache * imageCache()
Returns the application's image cache, used for caching resampled versions of raster images.
static QStringList svgPaths()
Returns the paths to svg directories.
static void initQgis()
loads providers
static QString showSettings()
Convenience function to get a summary of the paths used in this application instance useful for debug...
bool event(QEvent *event) override
Watch for QFileOpenEvent.
static void setPkgDataPath(const QString &pkgDataPath)
Alters pkg data path - used by 3rd party apps.
static QString absolutePathToRelativePath(const QString &apath, const QString &targetPath)
Converts absolute path to path relative to target.
static const QgsSettingsEntryString * settingsLocaleUserLocale
Settings entry locale user locale.
static QgsRuntimeProfiler * profiler()
Returns the application runtime profiler.
~QgsApplication() override
static QgsLocalizedDataPathRegistry * localizedDataPathRegistry()
Returns the registry of data repositories These are used as paths for basemaps, logos,...
static const char * QGIS_APPLICATION_NAME
static QgsTileDownloadManager * tileDownloadManager()
Returns the application's tile download manager, used for download of map tiles when rendering.
static const char * QGIS_ORGANIZATION_DOMAIN
static QMap< QString, QString > systemEnvVars()
Returns the system environment variables passed to application.
static void setAuthDatabaseDirPath(const QString &authDbDirPath)
Alters authentication data base directory path - used by 3rd party apps.
static QgsAuthConfigurationStorageRegistry * authConfigurationStorageRegistry()
Returns the application's authentication configuration storage registry.
static QString prefixPath()
Returns the path to the application prefix directory.
static QgsSvgCache * svgCache()
Returns the application's SVG cache, used for caching SVG images and handling parameter replacement w...
static QgsFontManager * fontManager()
Returns the application font manager, which manages available fonts and font installation for the QGI...
static QString qgisSettingsDirPath()
Returns the path to the settings directory in user's home dir.
static QgsDatabaseQueryLog * databaseQueryLog()
Returns the database query log.
static QgsMessageLog * messageLog()
Returns the application's message log.
void preNotify(QObject *receiver, QEvent *event, bool *done)
static bool createThemeFolder()
Create the users theme folder.
static QString metadataPath()
Returns the path to the metadata directory.
void localeChanged()
Emitted when project locale has been changed.
static QgsActionScopeRegistry * actionScopeRegistry()
Returns the action scope registry.
static QgsCoordinateReferenceSystemRegistry * coordinateReferenceSystemRegistry()
Returns the application's coordinate reference system (CRS) registry, which handles known CRS definit...
static const char * QGIS_ORGANIZATION_NAME
static QString contributorsFilePath()
Returns the path to the contributors file.
void collectTranslatableObjects(QgsTranslationContext *translationContext)
Emits the signal to collect all the strings of .qgs to be included in ts file.
static QgsSourceCache * sourceCache()
Returns the application's source cache, used for caching embedded and remote source strings as local ...
static QStringList temporarilyUntrustedProjectsFolders()
Returns the list of projects and folders that have been temporarily determined as untrusted by the us...
static QRegularExpression shortNameRegularExpression()
Returns the short name regular expression for line edit validator.
static QgsTaskManager * taskManager()
Returns the application's task manager, used for managing application wide background task handling.
static QgsProfileSourceRegistry * profileSourceRegistry()
Returns registry of available profile source implementations.
static QgsAnnotationRegistry * annotationRegistry()
Returns the application's annotation registry, used for managing annotation types.
static QgsPluginLayerRegistry * pluginLayerRegistry()
Returns the application's plugin layer registry, used for managing plugin layer types.
static QgsClassificationMethodRegistry * classificationMethodRegistry()
Returns the application's classification methods registry, used in graduated renderer.
static QStringList deferredSkippedGdalDrivers()
Returns the list of gdal drivers that have been disabled in the current session, and thus,...
static QString qgisAuthDatabaseUri()
Returns the URI to the user authentication database.
static QString defaultStylePath()
Returns the path to default style (works as a starting point).
static QgsAuthManager * authManager()
Returns the application's authentication manager instance.
static QString qmlImportPath()
Returns the path where QML components are installed for QGIS Quick library.
static QgsApplicationThemeRegistry * applicationThemeRegistry()
Returns the application's theme registry, used for styling the user interface.
QgsApplication(int &argc, char **argv, bool GUIenabled, const QString &profileFolder=QString(), const QString &platformName="external")
Constructor for QgsApplication.
Cursor
The Cursor enum defines constants for QGIS custom cursors.
@ ZoomOut
Zoom out.
@ CrossHair
Precisely identify a point on the canvas.
@ Identify
Identify: obtain information about the object.
@ Select
Select a rectangle.
@ CapturePoint
Select and capture a point or a feature.
@ Sampler
Color/Value picker.
static const QgsSettingsEntryInteger * settingsConnectionPoolMaximumConcurrentConnections
Settings entry to configure the maximum number of concurrent connections within connection pools.
static Q_DECL_DEPRECATED QString qgisAuthDatabaseFilePath()
Returns the path to the user authentication database file: qgis-auth.db.
static QString authorsFilePath()
Returns the path to the authors file.
static QgsBookmarkManager * bookmarkManager()
Returns the application's bookmark manager, used for storing installation-wide bookmarks.
static QString qgisUserDatabaseFilePath()
Returns the path to the user qgis.db file.
static QgsFieldFormatterRegistry * fieldFormatterRegistry()
Gets the registry of available field formatters.
static QString activeThemePath()
Returns the path to the currently active theme directory.
static QString defaultThemesFolder()
Returns the path to default themes folder from install (works as a starting point).
static void setTemporarilyTrustedProjectsFolders(const QStringList &trustedProjectsFolders)
Sets the list of projects and folders that have been temporarily determined as trusted by the user.
static void setSkippedGdalDrivers(const QStringList &skippedGdalDrivers, const QStringList &deferredSkippedGdalDrivers)
Sets the list of gdal drivers that should be disabled (skippedGdalDrivers), but excludes for now the ...
static QgsRendererRegistry * rendererRegistry()
Returns the application's renderer registry, used for managing vector layer renderers.
static void setTranslation(const QString &translation)
Set translation locale code.
static QgsCalloutRegistry * calloutRegistry()
Returns the application's callout registry, used for managing callout types.
static void setPrefixPath(const QString &prefixPath, bool useDefaultPaths=false)
Alters prefix path - used by 3rd party apps.
static QgsStyleModel * defaultStyleModel()
Returns a shared QgsStyleModel containing the default style library (see QgsStyle::defaultStyle()).
static QString relativePathToAbsolutePath(const QString &rpath, const QString &targetPath)
Converts path relative to target to an absolute path.
static void setSvgPaths(const QStringList &svgPaths)
Sets the paths to svg directories and invalidates the svg path list cache.
static QgsBabelFormatRegistry * gpsBabelFormatRegistry()
Returns the application's GPSBabel format registry, used for managing GPSBabel formats.
static endian_t endian()
Returns whether this machine uses big or little endian.
int maxConcurrentConnectionsPerPool() const
The maximum number of concurrent connections per connections pool.
static void setCustomVariable(const QString &name, const QVariant &value)
Set a single custom expression variable.
void requestForTranslatableObjects(QgsTranslationContext *translationContext)
Emitted when project strings which require translation are being collected for inclusion in a ....
static QString iconsPath()
Returns the path to the icons image directory.
static Qgs3DSymbolRegistry * symbol3DRegistry()
Returns registry of available 3D symbols.
static QgsExternalStorageRegistry * externalStorageRegistry()
Returns registry of available external storage implementations.
static QHash< QString, QString > uiThemes()
All themes found in ~/.qgis3/themes folder.
static QString splashPath()
Returns the path to the splash screen image directory.
static QString donorsFilePath()
Returns the path to the donors file.
static QString themeName()
Set the active theme to the specified theme.
void nullRepresentationChanged()
Emitted when the string representing the NULL value is changed.
static QString srsDatabaseFilePath()
Returns the path to the srs.db file.
static QString userThemesFolder()
Returns the path to user's themes folder.
static void registerGdalDriversFromSettings()
Register gdal drivers, excluding the ones mentioned in "gdal/skipList" setting.
static QgsPlotRegistry * plotRegistry()
Returns the application's plot registry, used for plot types.
static Qgs3DRendererRegistry * renderer3DRegistry()
Returns registry of available 3D renderers.
static QString iconPath(const QString &iconFile)
Returns path to the desired icon file.
static QgsTiledSceneRendererRegistry * tiledSceneRendererRegistry()
Returns the application's tiled scene renderer registry, used for managing tiled scene layer 2D rende...
static void setDefaultSvgPaths(const QStringList &pathList)
Alters default svg paths - used by 3rd party apps.
static QString libraryPath()
Returns the path containing qgis_core, qgis_gui, qgispython (and other) libraries.
static QStringList layoutTemplatePaths()
Returns the paths to layout template directories.
static const QgsSettingsEntryBool * settingsLocaleShowGroupSeparator
Settings entry locale show group separator.
static QString userFullName()
Returns the user's operating system login account full display name.
static Q_DECL_DEPRECATED QgsSettingsRegistryCore * settingsRegistryCore()
Returns the application's settings registry, used for managing application settings.
static QString serverResourcesPath()
Returns the path to the server resources directory.
static QString appIconPath()
Gets application icon.
static QString userLoginName()
Returns the user's operating system login account name.
Registry for authentication configuration storages.
Singleton which offers an interface to manage the authentication configuration database and to utiliz...
QgsAuthConfigurationStorageRegistry * authConfigurationStorageRegistry() const
Returns the authentication configuration storage registry.
void setup(const QString &pluginPath=QString(), const QString &authDatabasePath=QString())
Sets up the authentication manager configuration.
static QgsAuthManager * instance()
Enforce singleton pattern.
A registry for QgsAbstractBabelFormat GPSBabel formats.
Manages storage of a set of bookmarks.
void initialize(const QString &filePath)
Initializes the bookmark manager.
Registry of available callout classes.
Manages all known classification methods.
Registry of color schemes.
void addDefaultSchemes()
Adds all default color schemes to this color scheme.
void initStyleScheme()
Initializes the default random style color scheme for the user.
A registry for saved data provider connections, allowing retrieval of saved connections by name and p...
A registry for known coordinate reference system (CRS) definitions, including any user-defined CRSes.
static void invalidateCache(bool disableCache=false)
Clears the internal cache used to initialize QgsCoordinateReferenceSystem objects.
static void invalidateCache(bool disableCache=false)
Clears the internal cache used to initialize QgsCoordinateTransform objects.
A registry for data item providers that may add items to the browser tree.
Handles logging of database queries.
static void applyLocaleChange()
Adjusts the date time display formats according to locale.
static void invalidateCache(bool disableCache=false)
Clears the internal cache used.
Defines a QGIS exception class.
QString what() const
static void cleanRegisteredFunctions()
Deletes all registered functions whose ownership have been transferred to the expression engine.
Registry of external storage backends used by QgsExternalResourceWidget.
A registry which manages classes of QgsFieldFormatter.
Manages available fonts and font installation for a QGIS instance.
void installUserFonts()
Installs user fonts from the profile/fonts directory as application fonts.
Registers existing GPS connections such that the information is available to all classes and plugins.
A cache for images derived from raster files.
A registry for labeling engine rules.
Registry of layer metadata provider backends.
Registry of available layout item types.
static const QgsSettingsEntryStringList * settingsSearchPathForTemplates
Settings entry search path for templates.
Definition qgslayout.h:664
A registry class to hold localized data paths which can be used for basemaps, logos,...
Temporarily blocks the application QgsMessageLog (see QgsApplication::messageLog()) from emitting the...
Interface for logging messages from QGIS in GUI independent way.
static QgsNetworkAccessManager * instance(Qt::ConnectionType connectionType=Qt::BlockingQueuedConnection)
Returns a pointer to the active QgsNetworkAccessManager for the current thread.
Registry for temporary fetched files.
A registry which manages classes of QgsNumericFormat.
A registry for known page sizes.
Registry of available paint effects.
Registry of available plot types.
A registry of plugin layers types.
Registry of 2D renderers for point clouds.
Registry for various processing components, including providers, algorithms and various parameters an...
Registry of profile sources used by QgsProfilePlotRenderer.
static QStringList searchPaths()
Returns the current list of Proj file search paths.
Registry of storage backends that QgsProject may use.
static QgsProject * instance()
Returns the QgsProject singleton instance.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
Registry for raster renderers.
A convenience class that simplifies locking and unlocking QReadWriteLocks.
@ Write
Lock for write.
void changeMode(Mode mode)
Change the mode of the lock to mode.
Handles and tracks style items recently used in the QGIS GUI.
Registry of renderers.
Provides a method of recording run time profiles of operations, allowing easy recording of their over...
A registry which manages registered scalebar renderers.
Scoped object for logging of the runtime for a single operation or group of operations.
Registry of available sensor types.
A boolean settings entry.
An integer settings entry.
A string list settings entry.
A string settings entry.
Custom exception class for settings related exceptions.
Used for settings introspection and collects all QgsSettingsEntry instances of core.
static QgsSettingsTreeNode * sTreeLocale
static QgsSettingsTreeNode * sTreeSvg
static QgsSettingsTreeNode * sTreeCore
Stores settings for use within QGIS.
Definition qgssettings.h:68
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
bool contains(const QString &key, QgsSettings::Section section=QgsSettings::NoSection) const
Returns true if there exists a setting called key; returns false otherwise.
void beginGroup(const QString &prefix, QgsSettings::Section section=QgsSettings::NoSection)
Appends prefix to the current group.
QStringList childKeys() const
Returns a list of all top-level keys that can be read using the QSettings object.
void remove(const QString &key, QgsSettings::Section section=QgsSettings::NoSection)
Removes the setting key and any sub-settings of key in a section.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
A cache for source strings that returns a local file path containing the source content.
A QAbstractItemModel subclass for showing symbol and color ramp entities contained within a QgsStyle ...
A database of saved style entities, including symbols, color ramps, text formats and others.
Definition qgsstyle.h:89
static void cleanDefaultStyle()
Deletes the default style. Only to be used by QgsApplication::exitQgis().
Definition qgsstyle.cpp:207
static QgsStyle * defaultStyle(bool initialize=true)
Returns the default application-wide style.
Definition qgsstyle.cpp:150
A cache for images / pictures derived from SVG files.
QImage svgAsImage(const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, bool &fitsInCache, double fixedAspectRatio=0, bool blocking=false, const QMap< QString, QString > &parameters=QMap< QString, QString >())
Returns an SVG drawing as a QImage.
QByteArray svgContent(const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, double fixedAspectRatio=0, bool blocking=false, const QMap< QString, QString > &parameters=QMap< QString, QString >(), bool *isMissingImage=nullptr)
Gets the SVG content corresponding to the given path.
Registry of available symbol layer classes.
static QColor decodeColor(const QString &str)
Task manager for managing a set of long-running QgsTask tasks.
Tile download manager handles downloads of map tiles for the purpose of map rendering.
QgsTileDownloadManagerReply * get(const QNetworkRequest &request)
Starts a request.
Registry of 2D renderers for tiled scenes.
Used for the collecting of strings from projects for translation and creation of ts files.
A manager for QGIS user profiles.
std::unique_ptr< QgsUserProfile > getProfile(const QString &defaultProfile="default", bool createNew=true, bool initSettings=true)
Returns the profile from the given root profile location.
static QString resolveProfilesFolder(const QString &basePath=QString())
Resolves the profiles folder for the given path.
A registry that keeps a list of QgsAbstractValidityCheck checks which can be used when performing val...
Unique pointer for sqlite3 databases, which automatically closes the database when the pointer goes o...
int open(const QString &path)
Opens the database at the specified file path.
QMap< QString, QString > QgsStringMap
Definition qgis.h:7413
void registerMetaTypes()
QObject * ABISYM(QgsApplication::mFileOpenEventReceiver)
Q_GLOBAL_STATIC_WITH_ARGS(PalPropertyList, palHiddenProperties,({ static_cast< int >(QgsPalLayerSettings::Property::PositionX), static_cast< int >(QgsPalLayerSettings::Property::PositionY), static_cast< int >(QgsPalLayerSettings::Property::Show), static_cast< int >(QgsPalLayerSettings::Property::LabelRotation), static_cast< int >(QgsPalLayerSettings::Property::Family), static_cast< int >(QgsPalLayerSettings::Property::FontStyle), static_cast< int >(QgsPalLayerSettings::Property::Size), static_cast< int >(QgsPalLayerSettings::Property::Bold), static_cast< int >(QgsPalLayerSettings::Property::Italic), static_cast< int >(QgsPalLayerSettings::Property::Underline), static_cast< int >(QgsPalLayerSettings::Property::Color), static_cast< int >(QgsPalLayerSettings::Property::Strikeout), static_cast< int >(QgsPalLayerSettings::Property::MultiLineAlignment), static_cast< int >(QgsPalLayerSettings::Property::BufferSize), static_cast< int >(QgsPalLayerSettings::Property::BufferDraw), static_cast< int >(QgsPalLayerSettings::Property::BufferColor), static_cast< int >(QgsPalLayerSettings::Property::LabelDistance), static_cast< int >(QgsPalLayerSettings::Property::Hali), static_cast< int >(QgsPalLayerSettings::Property::Vali), static_cast< int >(QgsPalLayerSettings::Property::ScaleVisibility), static_cast< int >(QgsPalLayerSettings::Property::MinScale), static_cast< int >(QgsPalLayerSettings::Property::MaxScale), static_cast< int >(QgsPalLayerSettings::Property::AlwaysShow), static_cast< int >(QgsPalLayerSettings::Property::CalloutDraw), static_cast< int >(QgsPalLayerSettings::Property::LabelAllParts) })) Q_GLOBAL_STATIC_WITH_ARGS(SymbolPropertyList
const QString cacheKey(const QString &pathIn)
Q_GLOBAL_STATIC(QReadWriteLock, sDefinitionCacheLock)
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:63
#define QgsDebugError(str)
Definition qgslogger.h:59
std::unique_ptr< QgsBookmarkManager > mBookmarkManager
std::unique_ptr< QgsRasterRendererRegistry > mRasterRendererRegistry
std::unique_ptr< QgsProcessingRegistry > mProcessingRegistry
std::unique_ptr< QgsTaskManager > mTaskManager
std::unique_ptr< QgsAnnotationRegistry > mAnnotationRegistry
std::unique_ptr< QgsCoordinateReferenceSystemRegistry > mCrsRegistry
std::unique_ptr< QgsGpsConnectionRegistry > mGpsConnectionRegistry
std::unique_ptr< QgsLabelingEngineRuleRegistry > mLabelingEngineRuleRegistry
std::unique_ptr< QgsPointCloudRendererRegistry > mPointCloudRendererRegistry
std::unique_ptr< QgsRendererRegistry > mRendererRegistry
std::unique_ptr< Qgs3DSymbolRegistry > m3DSymbolRegistry
std::unique_ptr< QgsPlotRegistry > mPlotRegistry
std::unique_ptr< QgsApplicationThemeRegistry > mApplicationThemeRegistry
std::unique_ptr< QgsRecentStyleHandler > mRecentStyleHandler
std::unique_ptr< QgsClassificationMethodRegistry > mClassificationMethodRegistry
std::unique_ptr< QgsSensorRegistry > mSensorRegistry
std::unique_ptr< QgsPluginLayerRegistry > mPluginLayerRegistry
std::unique_ptr< QgsDatabaseQueryLog > mQueryLogger
std::unique_ptr< QgsScaleBarRendererRegistry > mScaleBarRendererRegistry
std::unique_ptr< QgsNumericFormatRegistry > mNumericFormatRegistry
std::unique_ptr< QgsLayoutItemRegistry > mLayoutItemRegistry
std::unique_ptr< QgsTiledSceneRendererRegistry > mTiledSceneRendererRegistry
std::unique_ptr< QgsStyleModel > mStyleModel
std::unique_ptr< QgsAnnotationItemRegistry > mAnnotationItemRegistry
std::unique_ptr< QgsImageCache > mImageCache
std::unique_ptr< Qgs3DRendererRegistry > m3DRendererRegistry
std::unique_ptr< QgsCalloutRegistry > mCalloutRegistry
std::unique_ptr< QgsSourceCache > mSourceCache
std::unique_ptr< QgsFontManager > mFontManager
std::unique_ptr< QgsSettingsRegistryCore > mSettingsRegistryCore
std::unique_ptr< QgsPageSizeRegistry > mPageSizeRegistry
std::unique_ptr< QgsExternalStorageRegistry > mExternalStorageRegistry
std::unique_ptr< QgsProfileSourceRegistry > mProfileSourceRegistry
std::unique_ptr< QgsSvgCache > mSvgCache
std::unique_ptr< QgsPaintEffectRegistry > mPaintEffectRegistry
std::unique_ptr< QgsColorSchemeRegistry > mColorSchemeRegistry
std::unique_ptr< QgsActionScopeRegistry > mActionScopeRegistry
std::unique_ptr< QgsBabelFormatRegistry > mGpsBabelFormatRegistry
std::unique_ptr< QgsTileDownloadManager > mTileDownloadManager
std::unique_ptr< QgsValidityCheckRegistry > mValidityCheckRegistry
std::unique_ptr< QgsNetworkContentFetcherRegistry > mNetworkContentFetcherRegistry
std::unique_ptr< QgsConnectionRegistry > mConnectionRegistry
std::unique_ptr< QgsFieldFormatterRegistry > mFieldFormatterRegistry
std::unique_ptr< QgsProjectStorageRegistry > mProjectStorageRegistry
std::unique_ptr< QgsMessageLog > mMessageLog
std::unique_ptr< QgsLocalizedDataPathRegistry > mLocalizedDataPathRegistry
std::unique_ptr< QgsLayerMetadataProviderRegistry > mLayerMetadataProviderRegistry
std::unique_ptr< QgsSymbolLayerRegistry > mSymbolLayerRegistry