QGIS API Documentation 3.41.0-Master (fda2aa46e9a)
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#include "moc_qgssettingstreenode.cpp"
19#include "qgsexception.h"
20#include "qgssettings.h"
21#include "qgssettingsproxy.h"
22
23#include <QDir>
24
26{
28 mParent->unregisterChildNode( this );
29
30 // do not use qDeleteAll
31 // the destructor of QgsSettingsTreeNode and QgsSettingsEntry
32 // will call unregister on the parent (see above)
33 // and will modify the containers at the same time
34 const auto nodes = mChildrenNodes;
35 for ( const auto *node : nodes )
36 delete node;
37 const auto settings = mChildrenSettings;
38 for ( const auto *setting : settings )
39 delete setting;
40}
41
43{
46 te->mKey = QString();
47 te->mCompleteKey = QStringLiteral( "/" );
48 return te;
49}
50
52{
54 if ( te )
55 return te;
56 if ( childSetting( key ) )
57 throw QgsSettingsException( QObject::tr( "Settings tree node '%1' already holds a child setting with key '%2'." ).arg( this->key(), key ) );
58
59 te = new QgsSettingsTreeNode();
61 te->init( this, key );
63 return te;
64}
65
67{
69 if ( nte )
70 {
72 return dynamic_cast<QgsSettingsTreeNamedListNode *>( nte );
73 else
74 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 ) );
75 }
76 if ( childSetting( key ) )
77 throw QgsSettingsException( QObject::tr( "Settings tree node '%1' already holds a child setting with key '%2'." ).arg( this->key(), key ) );
78
81 te->init( this, key );
82 te->initNamedList( options );
84 return te;
85}
86
87
89{
90 QList<QgsSettingsTreeNode *>::const_iterator it = mChildrenNodes.constBegin();
91 for ( ; it != mChildrenNodes.constEnd(); ++it )
92 {
93 if ( ( *it )->key() == key )
94 return *it;
95 }
96 return nullptr;
97}
98
100{
101 const QString testCompleteKey = QStringLiteral( "%1%2" ).arg( mCompleteKey, key );
102 QList<const QgsSettingsEntryBase *>::const_iterator it = mChildrenSettings.constBegin();
103 for ( ; it != mChildrenSettings.constEnd(); ++it )
104 {
105 if ( ( *it )->definitionKey() == testCompleteKey )
106 return *it;
107 }
108 return nullptr;
109}
110
111void QgsSettingsTreeNode::registerChildSetting( const QgsSettingsEntryBase *setting, const QString &key )
112{
113 if ( childNode( key ) )
114 throw QgsSettingsException( QObject::tr( "Settings tree node '%1' already holds a child tree node with key '%2'." ).arg( this->key(), key ) );
115 if ( childSetting( key ) )
116 throw QgsSettingsException( QObject::tr( "Settings tree node '%1' already holds a child setting with key '%2'." ).arg( this->key(), key ) );
117
118 mChildrenSettings.append( setting );
119}
120
121
123{
124 mChildrenNodes.append( node );
125}
126
127void QgsSettingsTreeNode::unregisterChildSetting( const QgsSettingsEntryBase *setting, bool deleteSettingValues, const QStringList &parentsNamedItems )
128{
129 if ( deleteSettingValues )
130 setting->remove( parentsNamedItems );
131
132 mChildrenSettings.removeAll( setting );
133}
134
136{
137 mChildrenNodes.removeAll( node );
138}
139
140void QgsSettingsTreeNode::init( QgsSettingsTreeNode *parent, const QString &key )
141{
142 mParent = parent;
143 mKey = key;
144 mCompleteKey = QDir::cleanPath( QStringLiteral( "%1/%2" ).arg( parent->completeKey(), key ) ) + '/';
145}
146
147
149{
150 mOptions = options;
152 {
153 // this must be done before completing the key
154 mSelectedItemSetting = new QgsSettingsEntryString( QStringLiteral( "%1/selected" ).arg( mCompleteKey ), nullptr );
155 }
156
157 mNamedNodesCount = mParent->namedNodesCount() + 1;
158 mItemsCompleteKey = QStringLiteral( "%1items/" ).arg( mCompleteKey );
159 mCompleteKey.append( QStringLiteral( "items/%%1/" ).arg( mNamedNodesCount ) );
160}
161
163{
164 delete mSelectedItemSetting;
165}
166
167
168QStringList QgsSettingsTreeNamedListNode::items( const QStringList &parentsNamedItems ) const
169{
170 return items( Qgis::SettingsOrigin::Any, parentsNamedItems );
171}
172
173QStringList QgsSettingsTreeNamedListNode::items( Qgis::SettingsOrigin origin, const QStringList &parentsNamedItems ) const
174{
175 if ( namedNodesCount() - 1 != parentsNamedItems.count() )
176 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() ) ) );
177
178
179 const QString completeKeyParam = completeKeyWithNamedItems( mItemsCompleteKey, parentsNamedItems );
180 auto settings = QgsSettings::get();
181 settings->beginGroup( completeKeyParam );
182 const QStringList res = settings->childGroups( origin );
183 settings->endGroup();
184 return res;
185}
186
187void QgsSettingsTreeNamedListNode::setSelectedItem( const QString &item, const QStringList &parentsNamedItems )
188{
189 if ( namedNodesCount() - 1 != parentsNamedItems.count() )
190 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() ) ) );
192 throw QgsSettingsException( QObject::tr( "The named list node '%1' has no option to set the current selected entry." ).arg( mCompleteKey ) );
193
194 mSelectedItemSetting->setValue( item, parentsNamedItems );
195}
196
197QString QgsSettingsTreeNamedListNode::selectedItem( const QStringList &parentsNamedItems )
198{
199 if ( namedNodesCount() - 1 != parentsNamedItems.count() )
200 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() ) ) );
202 throw QgsSettingsException( QObject::tr( "The named list node '%1' has no option to set the current selected entry." ).arg( mCompleteKey ) );
203
204 return mSelectedItemSetting->value( parentsNamedItems );
205}
206
207void QgsSettingsTreeNamedListNode::deleteItem( const QString &item, const QStringList &parentsNamedItems )
208{
209 if ( namedNodesCount() - 1 != parentsNamedItems.count() )
210 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() ) );
211
212 QStringList args = parentsNamedItems;
213 args << item;
214 QString key = completeKeyWithNamedItems( mCompleteKey, args );
216}
217
218void QgsSettingsTreeNamedListNode::deleteAllItems( const QStringList &parentsNamedItems )
219{
220 if ( namedNodesCount() - 1 != parentsNamedItems.count() )
221 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() ) );
222
223 const QStringList children = items( parentsNamedItems );
224 auto settings = QgsSettings::get();
225 for ( const QString &child : children )
226 {
227 QStringList args = parentsNamedItems;
228 args << child;
229 QString key = completeKeyWithNamedItems( mCompleteKey, args );
230 settings->remove( key );
231 }
232}
233
234QString QgsSettingsTreeNamedListNode::completeKeyWithNamedItems( const QString &key, const QStringList &namedItems ) const
235{
236 switch ( namedItems.count() )
237 {
238 case 0:
239 return key;
240 case 1:
241 return key.arg( namedItems[0] );
242 case 2:
243 return key.arg( namedItems[0], namedItems[1] );
244 case 3:
245 return key.arg( namedItems[0], namedItems[1], namedItems[2] );
246 case 4:
247 return key.arg( namedItems[0], namedItems[1], namedItems[2], namedItems[3] );
248 case 5:
249 return key.arg( namedItems[0], namedItems[1], namedItems[2], namedItems[3], namedItems[4] );
250 default:
251 throw QgsSettingsException( QObject::tr( "Current implementation of QgsSettingsTreeNamedListNode::items doesn't handle more than 5 parent named items" ) );
252 break;
253 }
254}
@ NamedList
Named List Node.
QFlags< SettingsTreeNodeOption > SettingsTreeNodeOptions
Definition qgis.h:635
@ NamedListSelectedItemSetting
Creates a setting to store which is the current item.
SettingsOrigin
The setting origin describes where a setting is stored.
Definition qgis.h:4160
@ Any
From any origin.
T value(const QString &dynamicKeyPart=QString()) const
Returns settings value.
bool setValue(const T &value, const QString &dynamicKeyPart=QString()) const
Set settings value.
Represent 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.
A string settings entry.
Custom exception class for settings related exceptions.
QgsSettingsTreeNamedListNode is a named list tree node for the settings tree to help organizing and i...
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.
QgsSettingsTreeNode is a tree node for the settings tree to help organizing and introspecting the tre...
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.