QGIS API Documentation 3.41.0-Master (3440c17df1d)
Loading...
Searching...
No Matches
qgsuserprofilemanager.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsuserprofilemanager.cpp
3 --------------------------------------
4 Date : Jul-2017
5 Copyright : (C) 2017 by Nathan Woodrow
6 Email : woodrow.nathan at gmail dot com
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
17#include "moc_qgsuserprofilemanager.cpp"
18#include "qgsuserprofile.h"
19#include "qgsapplication.h"
20#include "qgslogger.h"
21#include "qgssettings.h"
22
23#include <QFile>
24#include <QDir>
25#include <QTextStream>
26#include <QProcess>
27#include <QStandardPaths>
28
29
30QgsUserProfileManager::QgsUserProfileManager( const QString &rootLocation, QObject *parent )
31 : QObject( parent )
32{
34}
35
36QString QgsUserProfileManager::resolveProfilesFolder( const QString &basePath )
37{
38 return basePath + QDir::separator() + "profiles";
39}
40
41QgsUserProfile *QgsUserProfileManager::getProfile( const QString &defaultProfile, bool createNew, bool initSettings )
42{
43 const QString profileName = defaultProfile.isEmpty() ? defaultProfileName() : defaultProfile;
44
45 if ( createNew && !profileExists( defaultProfile ) )
46 {
47 createUserProfile( profileName );
48 }
49
50 QgsUserProfile *profile = profileForName( profileName );
51 if ( initSettings )
52 profile->initSettings();
53
54 return profile;
55}
56
57void QgsUserProfileManager::setRootLocation( const QString &rootProfileLocation )
58{
59 mRootProfilePath = rootProfileLocation;
60
61 //updates (or removes) profile file watcher for new root location
62 setNewProfileNotificationEnabled( mWatchProfiles );
63
64 mSettings.reset( new QSettings( settingsFile(), QSettings::IniFormat ) );
65}
66
68{
69 mWatchProfiles = enabled;
70 if ( mWatchProfiles && !mRootProfilePath.isEmpty() && QDir( mRootProfilePath ).exists() )
71 {
72 mWatcher.reset( new QFileSystemWatcher() );
73 mWatcher->addPath( mRootProfilePath );
74 connect( mWatcher.get(), &QFileSystemWatcher::directoryChanged, this, [this]
75 {
76 emit profilesChanged();
77 } );
78 }
79 else
80 {
81 mWatcher.reset();
82 }
83}
84
86{
87 return static_cast< bool >( mWatcher.get() );
88}
89
91{
92 return !mRootProfilePath.isEmpty();
93}
94
96{
97 const QString defaultName = QStringLiteral( "default" );
98 // If the profiles.ini doesn't have the default profile we grab it from
99 // global settings as it might be set by the admin.
100 // If the overrideProfile flag is set then no matter what the profiles.ini says we always take the
101 // global profile.
102 const QgsSettings globalSettings;
103 if ( !mSettings->contains( QStringLiteral( "/core/defaultProfile" ) ) || globalSettings.value( QStringLiteral( "overrideLocalProfile" ), false, QgsSettings::Core ).toBool() )
104 {
105 return globalSettings.value( QStringLiteral( "defaultProfile" ), defaultName, QgsSettings::Core ).toString();
106 }
107 return mSettings->value( QStringLiteral( "/core/defaultProfile" ), defaultName ).toString();
108}
109
111{
112 mSettings->setValue( QStringLiteral( "/core/defaultProfile" ), name );
113 mSettings->sync();
114}
115
120
122{
123 return mSettings->value( QStringLiteral( "/core/lastProfile" ), QString() ).toString();
124}
125
127{
128 mSettings->setValue( QStringLiteral( "/core/lastProfile" ), userProfile()->name() );
129 mSettings->sync();
130}
131
133{
134 return static_cast< Qgis::UserProfileSelectionPolicy >( mSettings->value( QStringLiteral( "/core/selectionPolicy" ), 0 ).toInt() );
135}
136
138{
139 mSettings->setValue( QStringLiteral( "/core/selectionPolicy" ), static_cast< int >( policy ) );
140 mSettings->sync();
141}
142
144{
145 return QDir( mRootProfilePath ).entryList( QDir::Dirs | QDir::NoDotAndDotDot );
146}
147
148bool QgsUserProfileManager::profileExists( const QString &name ) const
149{
150 return allProfiles().contains( name );
151}
152
154{
155 const QString profilePath = mRootProfilePath + QDir::separator() + name;
156 return new QgsUserProfile( profilePath );
157}
158
160{
161 QgsError error;
162
163 // TODO Replace with safe folder name
164
165 const QDir folder( mRootProfilePath + QDir::separator() + name );
166 if ( !folder.exists() )
167 {
168 if ( !QDir().mkpath( folder.absolutePath() ) )
169 {
170 error.append( tr( "Cannot write '%1'" ).arg( folder.absolutePath() ) );
171 return error;
172 }
173 }
174
175 QFile qgisPrivateDbFile( folder.absolutePath() + QDir::separator() + "qgis.db" );
176
177 // first we look for ~/.qgis/qgis.db
178 if ( !qgisPrivateDbFile.exists() )
179 {
180 // if it doesn't exist we copy it from the global resources dir
181 const QString qgisMasterDbFileName = QgsApplication::qgisMasterDatabaseFilePath();
182 QFile masterFile( qgisMasterDbFileName );
183
184 //now copy the master file into the users .qgis dir
185 masterFile.copy( qgisPrivateDbFile.fileName() );
186
187 // In some packaging systems, the master can be read-only. Make sure to make
188 // the copy user writable.
189 const QFile::Permissions perms = QFile( qgisPrivateDbFile.fileName() ).permissions();
190 if ( !( perms & QFile::WriteOwner ) )
191 {
192 if ( !qgisPrivateDbFile.setPermissions( perms | QFile::WriteOwner ) )
193 {
194 error.append( tr( "Can not make '%1' user writable" ).arg( qgisPrivateDbFile.fileName() ) );
195 }
196 }
197 }
198
199 if ( error.isEmpty() )
200 {
201 emit profilesChanged();
202 }
203
204 return error;
205}
206
208{
209 QgsError error;
210 QDir folder( mRootProfilePath + QDir::separator() + name );
211
212 // This might have to be changed to something better.
213 const bool deleted = folder.removeRecursively();
214 if ( !deleted )
215 {
216 error.append( ( tr( "Unable to fully delete user profile folder" ) ) );
217 }
218 else
219 {
220 emit profilesChanged();
221 }
222 return error;
223}
224
225QString QgsUserProfileManager::settingsFile() const
226{
227 return mRootProfilePath + QDir::separator() + "profiles.ini";
228}
229
231{
232 return mSettings.get();
233}
234
236{
237 return mUserProfile.get();
238}
239
240void QgsUserProfileManager::loadUserProfile( const QString &name )
241{
242#if QT_CONFIG(process)
243 const QString path = QDir::toNativeSeparators( QCoreApplication::applicationFilePath() );
244 QStringList arguments;
245 arguments << QCoreApplication::arguments();
246 // The first is the path to the application
247 // on Windows this might not be case so we need to handle that
248 // http://doc.qt.io/qt-5/qcoreapplication.html#arguments
249 arguments.removeFirst();
250 arguments << QStringLiteral( "--profile" ) << name;
251 QgsDebugMsgLevel( QStringLiteral( "Starting instance from %1 with %2" ).arg( path ).arg( arguments.join( " " ) ), 2 );
252 QProcess::startDetached( path, arguments, QDir::toNativeSeparators( QCoreApplication::applicationDirPath() ) );
253#else
254 Q_UNUSED( name )
255 Q_ASSERT( "Starting the user profile is not supported on the platform" );
256#endif //QT_CONFIG(process)
257}
258
260{
261 if ( ! mUserProfile.get() )
262 {
263 mUserProfile.reset( profileForName( profile ) );
264 }
265}
UserProfileSelectionPolicy
User profile selection policy.
Definition qgis.h:5047
static QString qgisMasterDatabaseFilePath()
Returns the path to the master qgis.db file.
A container for error messages.
Definition qgserror.h:81
bool isEmpty() const
Test if any error is set.
Definition qgserror.h:110
void append(const QString &message, const QString &tag)
Append new error message.
Definition qgserror.cpp:39
This class is a composition of two QSettings instances:
Definition qgssettings.h:64
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
QgsUserProfile * getProfile(const QString &defaultProfile="default", bool createNew=true, bool initSettings=true)
Returns the profile from the given root profile location.
void setRootLocation(const QString &rootProfileLocation)
Set the root profile location for the profile manager.
QgsError createUserProfile(const QString &name)
Create a user profile given by the name.
void setActiveUserProfile(const QString &profile)
Sets the active profile in the manager.
bool profileExists(const QString &name) const
Check if a profile exists.
QgsUserProfile * userProfile()
The currently active user profile.
void setDefaultProfileName(const QString &name)
Sets the default profile name.
QString rootLocation()
Returns the path to the root profiles location.
void setDefaultFromActive()
Set the default profile name from the current active profile.
QStringList allProfiles() const
Returns a list of all found profile names.
bool rootLocationIsSet() const
Check if the root location has been set for the manager.
QgsError deleteProfile(const QString &name)
Deletes a profile from the root profiles folder.
QSettings * settings()
Returns the settings for the profile manager.
static QString resolveProfilesFolder(const QString &basePath=QString())
Resolves the profiles folder for the given path.
void setUserProfileSelectionPolicy(Qgis::UserProfileSelectionPolicy policy)
Sets the user profile selection policy.
void setNewProfileNotificationEnabled(bool enabled)
Sets whether the manager should watch for the creation of new user profiles and emit the profilesChan...
QString defaultProfileName() const
Returns the name of the default profile that has been set in .default.
QgsUserProfileManager(const QString &rootLocation=QString(), QObject *parent=nullptr)
User profile manager used to manage user profiles for the instance of QGIS.
Qgis::UserProfileSelectionPolicy userProfileSelectionPolicy() const
Returns the user profile selection policy.
void profilesChanged()
Emitted when the list of profiles is changed.
QString lastProfileName() const
Returns the name of the most recently closed profile.
void updateLastProfileName()
Updates the last closed profile name.
QgsUserProfile * profileForName(const QString &name) const
Returns the profile found for a given name.
void loadUserProfile(const QString &name)
Starts a new instance of QGIS for the given profile.
bool isNewProfileNotificationEnabled() const
Returns whether the manager is watching for the creation of new user profiles and emitting the profil...
User profile contains information about the user profile folders on the machine.
void initSettings() const
Init the settings from the user folder.
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:39