QGIS API Documentation 4.1.0-Master (376402f9aeb)
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
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 Q_UNUSED( origin )
179
180 if ( namedNodesCount() - 1 != parentsNamedItems.count() )
182 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)." )
183 .arg( QString::number( parentsNamedItems.count() ), mCompleteKey, QString::number( namedNodesCount() ) )
184 );
185
186 const QString completeKeyParam = completeKeyWithNamedItems( mItemsCompleteKey, parentsNamedItems );
187
188 QSettings &settings = QgsSettingsEntryBase::userSettings();
189 settings.beginGroup( completeKeyParam );
190 const QStringList res = settings.childGroups();
191 settings.endGroup();
192 return res;
193}
194
195void QgsSettingsTreeNamedListNode::setSelectedItem( const QString &item, const QStringList &parentsNamedItems )
196{
197 if ( namedNodesCount() - 1 != parentsNamedItems.count() )
199 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)." )
200 .arg( QString::number( parentsNamedItems.count() ), mCompleteKey, QString::number( namedNodesCount() ) )
201 );
203 throw QgsSettingsException( QObject::tr( "The named list node '%1' has no option to set the current selected entry." ).arg( mCompleteKey ) );
204
205 mSelectedItemSetting->setValue( item, parentsNamedItems );
206}
207
208QString QgsSettingsTreeNamedListNode::selectedItem( const QStringList &parentsNamedItems )
209{
210 if ( namedNodesCount() - 1 != parentsNamedItems.count() )
212 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)." )
213 .arg( QString::number( parentsNamedItems.count() ), mCompleteKey, QString::number( namedNodesCount() ) )
214 );
216 throw QgsSettingsException( QObject::tr( "The named list node '%1' has no option to set the current selected entry." ).arg( mCompleteKey ) );
217
218 return mSelectedItemSetting->value( parentsNamedItems );
219}
220
221void QgsSettingsTreeNamedListNode::deleteItem( const QString &item, const QStringList &parentsNamedItems )
222{
223 if ( namedNodesCount() - 1 != parentsNamedItems.count() )
225 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() )
226 );
227
228 QStringList args = parentsNamedItems;
229 args << item;
230 QString key = completeKeyWithNamedItems( mCompleteKey, args );
232}
233
234void QgsSettingsTreeNamedListNode::deleteAllItems( const QStringList &parentsNamedItems )
235{
236 if ( namedNodesCount() - 1 != parentsNamedItems.count() )
238 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() )
239 );
240
241 const QStringList children = items( parentsNamedItems );
242 QSettings &settings = QgsSettingsEntryBase::userSettings();
243 for ( const QString &child : children )
244 {
245 QStringList args = parentsNamedItems;
246 args << child;
247 QString key = completeKeyWithNamedItems( mCompleteKey, args );
248 settings.remove( key );
249 }
250}
251
252QString QgsSettingsTreeNamedListNode::completeKeyWithNamedItems( const QString &key, const QStringList &namedItems ) const
253{
254 switch ( namedItems.count() )
255 {
256 case 0:
257 return key;
258 case 1:
259 return key.arg( namedItems[0] );
260 case 2:
261 return key.arg( namedItems[0], namedItems[1] );
262 case 3:
263 return key.arg( namedItems[0], namedItems[1], namedItems[2] );
264 case 4:
265 return key.arg( namedItems[0], namedItems[1], namedItems[2], namedItems[3] );
266 case 5:
267 return key.arg( namedItems[0], namedItems[1], namedItems[2], namedItems[3], namedItems[4] );
268 default:
269 throw QgsSettingsException( QObject::tr( "Current implementation of QgsSettingsTreeNamedListNode::items doesn't handle more than 5 parent named items" ) );
270 break;
271 }
272}
@ Standard
Normal Node.
Definition qgis.h:683
@ NamedList
Named List Node.
Definition qgis.h:684
QFlags< SettingsTreeNodeOption > SettingsTreeNodeOptions
Definition qgis.h:698
@ NamedListSelectedItemSetting
Creates a setting to store which is the current item.
Definition qgis.h:694
SettingsOrigin
The setting origin describes where a setting is stored.
Definition qgis.h:4765
@ Any
From any origin.
Definition qgis.h:4766
Represents a settings entry and provides methods for reading and writing settings values.
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.