QGIS API Documentation 3.99.0-Master (d270888f95f)
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 "qgssettings.h"
21#include "qgssettingsproxy.h"
22
23#include <QDir>
24#include <QString>
25
26#include "moc_qgssettingstreenode.cpp"
27
28using namespace Qt::StringLiterals;
29
31{
33 mParent->unregisterChildNode( this );
34
35 // do not use qDeleteAll
36 // the destructor of QgsSettingsTreeNode and QgsSettingsEntry
37 // will call unregister on the parent (see above)
38 // and will modify the containers at the same time
39 const auto nodes = mChildrenNodes;
40 for ( const auto *node : nodes )
41 delete node;
42 const auto settings = mChildrenSettings;
43 for ( const auto *setting : settings )
44 delete setting;
45}
46
48{
49 QgsSettingsTreeNode *te = new QgsSettingsTreeNode();
51 te->mKey = QString();
52 te->mCompleteKey = u"/"_s;
53 return te;
54}
55
56QgsSettingsTreeNode *QgsSettingsTreeNode::createChildNode( const QString &key )
57{
58 QgsSettingsTreeNode *te = childNode( key );
59 if ( te )
60 return te;
61 if ( childSetting( key ) )
62 throw QgsSettingsException( QObject::tr( "Settings tree node '%1' already holds a child setting with key '%2'." ).arg( this->key(), key ) );
63
64 te = new QgsSettingsTreeNode();
66 te->init( this, key );
68 return te;
69}
70
72{
73 QgsSettingsTreeNode *nte = childNode( key );
74 if ( nte )
75 {
77 return dynamic_cast<QgsSettingsTreeNamedListNode *>( nte );
78 else
79 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 ) );
80 }
81 if ( childSetting( key ) )
82 throw QgsSettingsException( QObject::tr( "Settings tree node '%1' already holds a child setting with key '%2'." ).arg( this->key(), key ) );
83
86 te->init( this, key );
87 te->initNamedList( options );
89 return te;
90}
91
92
93QgsSettingsTreeNode *QgsSettingsTreeNode::childNode( const QString &key ) const
94{
95 QList<QgsSettingsTreeNode *>::const_iterator it = mChildrenNodes.constBegin();
96 for ( ; it != mChildrenNodes.constEnd(); ++it )
97 {
98 if ( ( *it )->key() == key )
99 return *it;
100 }
101 return nullptr;
102}
103
105{
106 const QString testCompleteKey = u"%1%2"_s.arg( mCompleteKey, key );
107 QList<const QgsSettingsEntryBase *>::const_iterator it = mChildrenSettings.constBegin();
108 for ( ; it != mChildrenSettings.constEnd(); ++it )
109 {
110 if ( ( *it )->definitionKey() == testCompleteKey )
111 return *it;
112 }
113 return nullptr;
114}
115
117{
118 if ( childNode( key ) )
119 throw QgsSettingsException( QObject::tr( "Settings tree node '%1' already holds a child tree node with key '%2'." ).arg( this->key(), key ) );
120 if ( childSetting( key ) )
121 throw QgsSettingsException( QObject::tr( "Settings tree node '%1' already holds a child setting with key '%2'." ).arg( this->key(), key ) );
122
123 mChildrenSettings.append( setting );
124}
125
126
127void QgsSettingsTreeNode::registerChildNode( QgsSettingsTreeNode *node )
128{
129 mChildrenNodes.append( node );
130}
131
132void QgsSettingsTreeNode::unregisterChildSetting( const QgsSettingsEntryBase *setting, bool deleteSettingValues, const QStringList &parentsNamedItems )
133{
134 if ( deleteSettingValues )
135 setting->remove( parentsNamedItems );
136
137 mChildrenSettings.removeAll( setting );
138}
139
140void QgsSettingsTreeNode::unregisterChildNode( QgsSettingsTreeNode *node )
141{
142 mChildrenNodes.removeAll( node );
143}
144
145void QgsSettingsTreeNode::init( QgsSettingsTreeNode *parent, const QString &key )
146{
147 mParent = parent;
148 mKey = key;
149 mCompleteKey = QDir::cleanPath( u"%1/%2"_s.arg( parent->completeKey(), key ) ) + '/';
150}
151
153
155{
156 mOptions = options;
158 {
159 // this must be done before completing the key
160 mSelectedItemSetting = std::make_unique<QgsSettingsEntryString>( u"%1/selected"_s.arg( mCompleteKey ), nullptr );
161 }
162
163 mNamedNodesCount = mParent->namedNodesCount() + 1;
164 mItemsCompleteKey = u"%1items/"_s.arg( mCompleteKey );
165 mCompleteKey.append( u"items/%%1/"_s.arg( mNamedNodesCount ) );
166}
167
172
173
174QStringList QgsSettingsTreeNamedListNode::items( const QStringList &parentsNamedItems ) const
175{
176 return items( Qgis::SettingsOrigin::Any, parentsNamedItems );
177}
178
179QStringList QgsSettingsTreeNamedListNode::items( Qgis::SettingsOrigin origin, const QStringList &parentsNamedItems ) const
180{
181 if ( namedNodesCount() - 1 != parentsNamedItems.count() )
182 throw QgsSettingsException( 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)." ).arg( QString::number( parentsNamedItems.count() ), mCompleteKey, QString::number( namedNodesCount() ) ) );
183
184
185 const QString completeKeyParam = completeKeyWithNamedItems( mItemsCompleteKey, parentsNamedItems );
186 auto settings = QgsSettings::get();
187 settings->beginGroup( completeKeyParam );
188 const QStringList res = settings->childGroups( origin );
189 settings->endGroup();
190 return res;
191}
192
193void QgsSettingsTreeNamedListNode::setSelectedItem( const QString &item, const QStringList &parentsNamedItems )
194{
195 if ( namedNodesCount() - 1 != parentsNamedItems.count() )
196 throw QgsSettingsException( 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)." ).arg( QString::number( parentsNamedItems.count() ), mCompleteKey, QString::number( namedNodesCount() ) ) );
198 throw QgsSettingsException( QObject::tr( "The named list node '%1' has no option to set the current selected entry." ).arg( mCompleteKey ) );
199
200 mSelectedItemSetting->setValue( item, parentsNamedItems );
201}
202
203QString QgsSettingsTreeNamedListNode::selectedItem( const QStringList &parentsNamedItems )
204{
205 if ( namedNodesCount() - 1 != parentsNamedItems.count() )
206 throw QgsSettingsException( 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)." ).arg( QString::number( parentsNamedItems.count() ), mCompleteKey, QString::number( namedNodesCount() ) ) );
208 throw QgsSettingsException( QObject::tr( "The named list node '%1' has no option to set the current selected entry." ).arg( mCompleteKey ) );
209
210 return mSelectedItemSetting->value( parentsNamedItems );
211}
212
213void QgsSettingsTreeNamedListNode::deleteItem( const QString &item, const QStringList &parentsNamedItems )
214{
215 if ( namedNodesCount() - 1 != parentsNamedItems.count() )
216 throw QgsSettingsException( 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() ) );
217
218 QStringList args = parentsNamedItems;
219 args << item;
220 QString key = completeKeyWithNamedItems( mCompleteKey, args );
222}
223
224void QgsSettingsTreeNamedListNode::deleteAllItems( const QStringList &parentsNamedItems )
225{
226 if ( namedNodesCount() - 1 != parentsNamedItems.count() )
227 throw QgsSettingsException( 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() ) );
228
229 const QStringList children = items( parentsNamedItems );
230 auto settings = QgsSettings::get();
231 for ( const QString &child : children )
232 {
233 QStringList args = parentsNamedItems;
234 args << child;
235 QString key = completeKeyWithNamedItems( mCompleteKey, args );
236 settings->remove( key );
237 }
238}
239
240QString QgsSettingsTreeNamedListNode::completeKeyWithNamedItems( const QString &key, const QStringList &namedItems ) const
241{
242 switch ( namedItems.count() )
243 {
244 case 0:
245 return key;
246 case 1:
247 return key.arg( namedItems[0] );
248 case 2:
249 return key.arg( namedItems[0], namedItems[1] );
250 case 3:
251 return key.arg( namedItems[0], namedItems[1], namedItems[2] );
252 case 4:
253 return key.arg( namedItems[0], namedItems[1], namedItems[2], namedItems[3] );
254 case 5:
255 return key.arg( namedItems[0], namedItems[1], namedItems[2], namedItems[3], namedItems[4] );
256 default:
257 throw QgsSettingsException( QObject::tr( "Current implementation of QgsSettingsTreeNamedListNode::items doesn't handle more than 5 parent named items" ) );
258 break;
259 }
260}
@ Standard
Normal Node.
Definition qgis.h:675
@ NamedList
Named List Node.
Definition qgis.h:676
QFlags< SettingsTreeNodeOption > SettingsTreeNodeOptions
Definition qgis.h:690
@ NamedListSelectedItemSetting
Creates a setting to store which is the current item.
Definition qgis.h:686
SettingsOrigin
The setting origin describes where a setting is stored.
Definition qgis.h:4524
@ Any
From any origin.
Definition qgis.h:4525
Represents a settings entry and provides methods for reading and writing settings values.
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.
void remove(const QString &key, QgsSettings::Section section=QgsSettings::NoSection)
Removes the setting key and any sub-settings of key in a section.
static QgsSettingsProxy get()
Returns a proxy for a QgsSettings object.