QGIS API Documentation 4.3.0-Master (e0370aa57ef)
Loading...
Searching...
No Matches
qgssettingstreenode.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgssettingstreenode.cpp
3 --------------------------------------
4 Date : December 2022
5 Copyright : (C) 2022 by Denis Rouzaud
6 Email : denis@opengis.ch
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 "qgssettingstreenode.h"
17
18#include "qgsexception.h"
19#include "qgssettingsentry.h"
21
22#include <QDir>
23#include <QString>
24
25#include "moc_qgssettingstreenode.cpp"
26
27using namespace Qt::StringLiterals;
28
30{
32 mParent->unregisterChildNode( this );
33
34 // do not use qDeleteAll
35 // the destructor of QgsSettingsTreeNode and QgsSettingsEntry
36 // will call unregister on the parent (see above)
37 // and will modify the containers at the same time
38 const auto nodes = mChildrenNodes;
39 for ( const auto *node : nodes )
40 delete node;
41 const auto settings = mChildrenSettings;
42 for ( const auto *setting : settings )
43 delete setting;
44}
45
47{
48 QgsSettingsTreeNode *te = new QgsSettingsTreeNode();
50 te->mKey = QString();
51 te->mCompleteKey = u"/"_s;
52 return te;
53}
54
55QgsSettingsTreeNode *QgsSettingsTreeNode::createChildNode( const QString &key )
56{
57 QgsSettingsTreeNode *te = childNode( key );
58 if ( te )
59 return te;
60 if ( childSetting( key ) )
61 throw QgsSettingsException( QObject::tr( "Settings tree node '%1' already holds a child setting with key '%2'." ).arg( this->key(), key ) );
62
63 te = new QgsSettingsTreeNode();
65 te->init( this, key );
67 return te;
68}
69
71{
72 QgsSettingsTreeNode *nte = childNode( key );
73 if ( nte )
74 {
76 return dynamic_cast<QgsSettingsTreeNamedListNode *>( nte );
77 else
78 throw QgsSettingsException( QObject::tr( "Settings tree node '%1' already holds a child node with key '%2', but it is not a named list.." ).arg( this->key(), key ) );
79 }
80 if ( childSetting( key ) )
81 throw QgsSettingsException( QObject::tr( "Settings tree node '%1' already holds a child setting with key '%2'." ).arg( this->key(), key ) );
82
85 te->init( this, key );
86 te->initNamedList( options );
88 return te;
89}
90
91
92QgsSettingsTreeNode *QgsSettingsTreeNode::childNode( const QString &key ) const
93{
94 QList<QgsSettingsTreeNode *>::const_iterator it = mChildrenNodes.constBegin();
95 for ( ; it != mChildrenNodes.constEnd(); ++it )
96 {
97 if ( ( *it )->key() == key )
98 return *it;
99 }
100 return nullptr;
101}
102
104{
105 const QString testCompleteKey = u"%1%2"_s.arg( mCompleteKey, key );
106 QList<const QgsSettingsEntryBase *>::const_iterator it = mChildrenSettings.constBegin();
107 for ( ; it != mChildrenSettings.constEnd(); ++it )
108 {
109 if ( ( *it )->definitionKey() == testCompleteKey )
110 return *it;
111 }
112 return nullptr;
113}
114
116{
117 if ( childNode( key ) )
118 throw QgsSettingsException( QObject::tr( "Settings tree node '%1' already holds a child tree node with key '%2'." ).arg( this->key(), key ) );
119 if ( childSetting( key ) )
120 throw QgsSettingsException( QObject::tr( "Settings tree node '%1' already holds a child setting with key '%2'." ).arg( this->key(), key ) );
121
122 mChildrenSettings.append( setting );
123}
124
125
126void QgsSettingsTreeNode::registerChildNode( QgsSettingsTreeNode *node )
127{
128 mChildrenNodes.append( node );
129}
130
131void QgsSettingsTreeNode::unregisterChildSetting( const QgsSettingsEntryBase *setting, bool deleteSettingValues, const QStringList &parentsNamedItems )
132{
133 if ( deleteSettingValues )
134 setting->remove( parentsNamedItems );
135
136 mChildrenSettings.removeAll( setting );
137}
138
139void QgsSettingsTreeNode::unregisterChildNode( QgsSettingsTreeNode *node )
140{
141 mChildrenNodes.removeAll( node );
142}
143
144void QgsSettingsTreeNode::init( QgsSettingsTreeNode *parent, const QString &key )
145{
146 mParent = parent;
147 mKey = key;
148 mCompleteKey = QDir::cleanPath( u"%1/%2"_s.arg( parent->completeKey(), key ) ) + '/';
149}
150
152
154{
155 mOptions = options;
157 {
158 // this must be done before completing the key
159 mSelectedItemSetting = std::make_unique<QgsSettingsEntryString>( u"%1/selected"_s.arg( mCompleteKey ), nullptr );
160 }
161
162 mNamedNodesCount = mParent->namedNodesCount() + 1;
163 mItemsCompleteKey = u"%1items/"_s.arg( mCompleteKey );
164 mCompleteKey.append( u"items/%%1/"_s.arg( mNamedNodesCount ) );
165}
166
169
170
171QStringList QgsSettingsTreeNamedListNode::items( const QStringList &parentsNamedItems ) const
172{
173 return items( Qgis::SettingsOrigin::Any, parentsNamedItems );
174}
175
176QStringList QgsSettingsTreeNamedListNode::items( Qgis::SettingsOrigin origin, const QStringList &parentsNamedItems ) const
177{
178 if ( namedNodesCount() - 1 != parentsNamedItems.count() )
180 QObject::tr( "The number of given parent named items (%1) for the node '%2' doesn't match with the number of named items in the key (%3)." )
181 .arg( QString::number( parentsNamedItems.count() ), mCompleteKey, QString::number( namedNodesCount() ) )
182 );
183
184 const QString completeKeyParam = completeKeyWithNamedItems( mItemsCompleteKey, parentsNamedItems );
185
186 QStringList res;
187
188 // Collect items from the user QSettings
189 if ( origin != Qgis::SettingsOrigin::Global )
190 {
191 QSettings &settings = QgsSettingsEntryBase::userSettings();
192 settings.beginGroup( completeKeyParam );
193 res = settings.childGroups();
194 settings.endGroup();
195 }
196
197 // Collect items from the global defaults hash
198 if ( origin != Qgis::SettingsOrigin::Local )
199 {
200 const QStringList globalGroups = QgsSettingsEntryBase::globalChildGroups( completeKeyParam );
201 for ( const QString &group : globalGroups )
202 {
203 if ( !res.contains( group ) )
204 res.append( group );
205 }
206 }
207
208 return res;
209}
210
211void QgsSettingsTreeNamedListNode::setSelectedItem( const QString &item, const QStringList &parentsNamedItems )
212{
213 if ( namedNodesCount() - 1 != parentsNamedItems.count() )
215 QObject::tr( "The number of given parent named items (%1) for the node '%2' doesn't match with the number of named items in the key (%3)." )
216 .arg( QString::number( parentsNamedItems.count() ), mCompleteKey, QString::number( namedNodesCount() ) )
217 );
219 throw QgsSettingsException( QObject::tr( "The named list node '%1' has no option to set the current selected entry." ).arg( mCompleteKey ) );
220
221 mSelectedItemSetting->setValue( item, parentsNamedItems );
222}
223
224QString QgsSettingsTreeNamedListNode::selectedItem( const QStringList &parentsNamedItems )
225{
226 if ( namedNodesCount() - 1 != parentsNamedItems.count() )
228 QObject::tr( "The number of given parent named items (%1) for the node '%2' doesn't match with the number of named items in the key (%3)." )
229 .arg( QString::number( parentsNamedItems.count() ), mCompleteKey, QString::number( namedNodesCount() ) )
230 );
232 throw QgsSettingsException( QObject::tr( "The named list node '%1' has no option to set the current selected entry." ).arg( mCompleteKey ) );
233
234 return mSelectedItemSetting->value( parentsNamedItems );
235}
236
237void QgsSettingsTreeNamedListNode::deleteItem( const QString &item, const QStringList &parentsNamedItems )
238{
239 if ( namedNodesCount() - 1 != parentsNamedItems.count() )
241 QObject::tr( "The number of given parent named items (%1) doesn't match with the number of named items in the key (%2)." ).arg( parentsNamedItems.count(), namedNodesCount() )
242 );
243
244 QStringList args = parentsNamedItems;
245 args << item;
246 QString key = completeKeyWithNamedItems( mCompleteKey, args );
248}
249
250void QgsSettingsTreeNamedListNode::deleteAllItems( const QStringList &parentsNamedItems )
251{
252 if ( namedNodesCount() - 1 != parentsNamedItems.count() )
254 QObject::tr( "The number of given parent named items (%1) doesn't match with the number of named items in the key (%2)." ).arg( parentsNamedItems.count(), namedNodesCount() )
255 );
256
257 const QStringList children = items( parentsNamedItems );
258 QSettings &settings = QgsSettingsEntryBase::userSettings();
259 for ( const QString &child : children )
260 {
261 QStringList args = parentsNamedItems;
262 args << child;
263 QString key = completeKeyWithNamedItems( mCompleteKey, args );
264 settings.remove( key );
265 }
266}
267
268QString QgsSettingsTreeNamedListNode::completeKeyWithNamedItems( const QString &key, const QStringList &namedItems ) const
269{
270 switch ( namedItems.count() )
271 {
272 case 0:
273 return key;
274 case 1:
275 return key.arg( namedItems[0] );
276 case 2:
277 return key.arg( namedItems[0], namedItems[1] );
278 case 3:
279 return key.arg( namedItems[0], namedItems[1], namedItems[2] );
280 case 4:
281 return key.arg( namedItems[0], namedItems[1], namedItems[2], namedItems[3] );
282 case 5:
283 return key.arg( namedItems[0], namedItems[1], namedItems[2], namedItems[3], namedItems[4] );
284 default:
285 throw QgsSettingsException( QObject::tr( "Current implementation of QgsSettingsTreeNamedListNode::items doesn't handle more than 5 parent named items" ) );
286 break;
287 }
288}
@ Standard
Normal Node.
Definition qgis.h:717
@ NamedList
Named List Node.
Definition qgis.h:718
QFlags< SettingsTreeNodeOption > SettingsTreeNodeOptions
Definition qgis.h:732
@ NamedListSelectedItemSetting
Creates a setting to store which is the current item.
Definition qgis.h:728
SettingsOrigin
The setting origin describes where a setting is stored.
Definition qgis.h:4977
@ Global
Global settings are stored in qgis_global_settings.ini.
Definition qgis.h:4979
@ Local
Local settings are stored in the user profile.
Definition qgis.h:4980
@ Any
From any origin.
Definition qgis.h:4978
Represents a settings entry and provides methods for reading and writing settings values.
static QStringList globalChildGroups(const QString &prefix)
Returns the list of child group names found under prefix in the global defaults hash.
static QSettings & userSettings()
Returns a reference to the thread-local QSettings instance used internally by all QgsSettingsEntry op...
void remove(const QString &dynamicKeyPart=QString()) const
Removes the settings from the underlying QSettings.
Custom exception class for settings related exceptions.
void deleteAllItems(const QStringList &parentsNamedItems=QStringList())
Deletes all items from the named list node.
void deleteItem(const QString &item, const QStringList &parentsNamedItems=QStringList())
Deletes a named item from the named list node.
void initNamedList(const Qgis::SettingsTreeNodeOptions &options)
Init the nodes with the specific options.
QString selectedItem(const QStringList &parentsNamedItems=QStringList())
Returns the selected named item from the named list node.
void setSelectedItem(const QString &item, const QStringList &parentsNamedItems=QStringList())
Sets the selected named item from the named list node.
QStringList items(const QStringList &parentsNamedItems=QStringList()) const
Returns the list of items.
A tree node for the settings tree to help organizing and introspecting the tree.
void registerChildNode(QgsSettingsTreeNode *node)
Registers a child nodes.
Qgis::SettingsTreeNodeType type() const
Returns the type of node.
QgsSettingsTreeNode * createChildNode(const QString &key)
Creates a normal tree node It will return the existing child node if it exists at the given key.
Qgis::SettingsTreeNodeType mType
QgsSettingsTreeNode * childNode(const QString &key) const
Returns the existing child node if it exists at the given key.
QString completeKey() const
Returns the complete key of the node (including its parents).
int namedNodesCount() const
Returns the number of named nodes in the complete key.
static QgsSettingsTreeNode * createRootNode()
Creates a tree root node.
QString key() const
Returns the key of the node (without its parents).
friend class QgsSettingsTreeNamedListNode
void unregisterChildSetting(const QgsSettingsEntryBase *setting, bool deleteSettingValues=false, const QStringList &parentsNamedItems=QStringList())
Unregisters the child setting.
QgsSettingsTreeNode * parent() const
Returns the parent of the node or nullptr if it does not exists.
void unregisterChildNode(QgsSettingsTreeNode *node)
Unregisters the child tree node.
void registerChildSetting(const QgsSettingsEntryBase *setting, const QString &key)
Registers a child setting.
const QgsSettingsEntryBase * childSetting(const QString &key) const
Returns the existing child settings if it exists at the given key.
QgsSettingsTreeNamedListNode * createNamedListNode(const QString &key, const Qgis::SettingsTreeNodeOptions &options=Qgis::SettingsTreeNodeOptions())
Creates a named list tree node.