Skip to content

Commit 07762f5

Browse files
committedApr 23, 2023
add tree view + model to show/edit settings values
1 parent 77cc02f commit 07762f5

File tree

4 files changed

+731
-0
lines changed

4 files changed

+731
-0
lines changed
 
Lines changed: 426 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,426 @@
1+
/***************************************************************************
2+
qgssettingstreemodel.cpp
3+
--------------------------------------
4+
Date : January 2023
5+
Copyright : (C) 2023 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 <QFont>
17+
18+
#include "qgssettingstreemodel.h"
19+
#include "qgssettingsentry.h"
20+
#include "qgssettingstreenode.h"
21+
#include "qgssettingseditorwidgetwrapper.h"
22+
#include "qgssettingseditorwidgetregistry.h"
23+
#include "qgsgui.h"
24+
#include "qgslogger.h"
25+
26+
27+
QgsSettingsTreeModelNodeData *QgsSettingsTreeModelNodeData::createRootNodeData( const QgsSettingsTreeNode *rootNode, QObject *parent = nullptr )
28+
{
29+
QgsSettingsTreeModelNodeData *nodeData = new QgsSettingsTreeModelNodeData( parent );
30+
nodeData->mType = Type::RootNode;
31+
nodeData->mName = rootNode->key();
32+
nodeData->mTreeNode = rootNode;
33+
nodeData->fillChildren();
34+
return nodeData;
35+
}
36+
37+
void QgsSettingsTreeModelNodeData::applyChanges()
38+
{
39+
switch ( type() )
40+
{
41+
case Type::NamedListTreeNode:
42+
case Type::RootNode:
43+
case Type::TreeNode:
44+
case Type::NamedListItem:
45+
{
46+
QList<QgsSettingsTreeModelNodeData *>::iterator it = mChildren.begin();
47+
for ( ; it != mChildren.end(); ++it )
48+
( *it )->applyChanges();
49+
break;
50+
}
51+
case Type::Setting:
52+
{
53+
if ( isEdited() )
54+
{
55+
setting()->setVariantValue( mValue, mNamedParentNodes );
56+
}
57+
break;
58+
}
59+
}
60+
}
61+
62+
bool QgsSettingsTreeModelNodeData::setValue( const QVariant &value )
63+
{
64+
Q_ASSERT( mType == Type::Setting );
65+
if ( !value.isValid() && mValue.isValid() )
66+
{
67+
mExists = false;
68+
mIsEdited = true;
69+
mValue = QVariant();
70+
}
71+
else if ( !mValue.isValid() || mValue != value )
72+
{
73+
mValue = value;
74+
mIsEdited = ( value != mOriginalValue );
75+
}
76+
// TODO: check the value of setting is fullfilling the settings' contraints
77+
return true;
78+
}
79+
80+
81+
void QgsSettingsTreeModelNodeData::addChildForTreeNode( const QgsSettingsTreeNode *node )
82+
{
83+
QgsSettingsTreeModelNodeData *nodeData = new QgsSettingsTreeModelNodeData( this );
84+
nodeData->mParent = this;
85+
nodeData->mNamedParentNodes = mNamedParentNodes;
86+
nodeData->mName = node->key();
87+
nodeData->mTreeNode = node;
88+
if ( node->type() == Qgis::SettingsTreeNodeType::NamedList )
89+
{
90+
nodeData->mType = Type::NamedListTreeNode;
91+
const QgsSettingsTreeNamedListNode *nln = dynamic_cast<const QgsSettingsTreeNamedListNode *>( node );
92+
const QStringList items = nln->items( mNamedParentNodes );
93+
for ( const QString &item : items )
94+
{
95+
nodeData->addChildForNamedListItemNode( item, nln );
96+
}
97+
}
98+
else
99+
{
100+
nodeData->mType = Type::TreeNode;
101+
nodeData->fillChildren();
102+
}
103+
mChildren.append( nodeData );
104+
}
105+
106+
void QgsSettingsTreeModelNodeData::addChildForNamedListItemNode( const QString &item, const QgsSettingsTreeNamedListNode *namedListNode )
107+
{
108+
QgsSettingsTreeModelNodeData *nodeData = new QgsSettingsTreeModelNodeData( this );
109+
nodeData->mType = Type::NamedListItem;
110+
nodeData->mParent = this;
111+
nodeData->mNamedParentNodes = mNamedParentNodes;
112+
nodeData->mNamedParentNodes.append( item );
113+
nodeData->mName = item;
114+
nodeData->mTreeNode = namedListNode;
115+
nodeData->fillChildren();
116+
mChildren.append( nodeData );
117+
}
118+
119+
void QgsSettingsTreeModelNodeData::addChildForSetting( const QgsSettingsEntryBase *setting )
120+
{
121+
QgsSettingsTreeModelNodeData *nodeData = new QgsSettingsTreeModelNodeData( this );
122+
nodeData->mType = Type::Setting;
123+
nodeData->mParent = this;
124+
nodeData->mNamedParentNodes = mNamedParentNodes;
125+
nodeData->mSetting = setting;
126+
nodeData->mName = setting->name();
127+
nodeData->mValue = setting->valueAsVariant( mNamedParentNodes );
128+
nodeData->mOriginalValue = nodeData->mValue;
129+
nodeData->mExists = setting->exists( mNamedParentNodes );
130+
131+
switch ( mNamedParentNodes.count() )
132+
{
133+
case 1:
134+
QgsDebugMsg( QString( "getting %1 with %2" ).arg( setting->definitionKey(), mNamedParentNodes.at( 0 ) ) );
135+
break;
136+
case 2:
137+
QgsDebugMsg( QString( "getting %1 with %2" ).arg( setting->definitionKey(), mNamedParentNodes.at( 0 ), mNamedParentNodes.at( 1 ) ) );
138+
break;
139+
case 0:
140+
QgsDebugMsg( QString( "getting %1" ).arg( setting->definitionKey() ) );
141+
break;
142+
default:
143+
Q_ASSERT( false );
144+
QgsDebugMsg( QString( "Not handling that many named parent nodes for %1" ).arg( setting->definitionKey() ) );
145+
break;
146+
}
147+
148+
mChildren.append( nodeData );
149+
}
150+
151+
void QgsSettingsTreeModelNodeData::fillChildren()
152+
{
153+
const QList<QgsSettingsTreeNode *> childrenNodes = mTreeNode->childrenNodes();
154+
for ( const QgsSettingsTreeNode *childNode : childrenNodes )
155+
{
156+
addChildForTreeNode( childNode );
157+
}
158+
const QList<const QgsSettingsEntryBase *> childrenSettings = mTreeNode->childrenSettings();
159+
for ( const QgsSettingsEntryBase *setting : childrenSettings )
160+
{
161+
addChildForSetting( setting );
162+
}
163+
}
164+
165+
166+
167+
QgsSettingsTreeModel::QgsSettingsTreeModel( QgsSettingsTreeNode *rootNode, QObject *parent )
168+
: QAbstractItemModel( parent )
169+
{
170+
mRootNode = QgsSettingsTreeModelNodeData::createRootNodeData( rootNode, this );
171+
}
172+
173+
QgsSettingsTreeModel::~QgsSettingsTreeModel()
174+
{
175+
//delete mRootNode;
176+
}
177+
178+
void QgsSettingsTreeModel::applyChanges()
179+
{
180+
beginResetModel();
181+
mRootNode->applyChanges();
182+
endResetModel();
183+
}
184+
185+
QgsSettingsTreeModelNodeData *QgsSettingsTreeModel::index2node( const QModelIndex &index ) const
186+
{
187+
if ( !index.isValid() )
188+
return mRootNode;
189+
190+
QObject *obj = reinterpret_cast<QObject *>( index.internalPointer() );
191+
return qobject_cast<QgsSettingsTreeModelNodeData *>( obj );
192+
}
193+
194+
195+
QModelIndex QgsSettingsTreeModel::index( int row, int column, const QModelIndex &parent ) const
196+
{
197+
if ( column < 0 || column >= columnCount( parent ) ||
198+
row < 0 || row >= rowCount( parent ) )
199+
return QModelIndex();
200+
201+
QgsSettingsTreeModelNodeData *n = index2node( parent );
202+
if ( !n )
203+
return QModelIndex(); // have no children
204+
205+
206+
return createIndex( row, column, static_cast<QObject *>( n->children().at( row ) ) );
207+
}
208+
209+
QModelIndex QgsSettingsTreeModel::parent( const QModelIndex &child ) const
210+
{
211+
if ( !child.isValid() )
212+
return QModelIndex();
213+
214+
if ( QgsSettingsTreeModelNodeData *n = index2node( child ) )
215+
{
216+
return indexOfParentSettingsTreeNode( n->parent() ); // must not be null
217+
}
218+
else
219+
{
220+
Q_ASSERT( false ); // no other node types!
221+
return QModelIndex();
222+
}
223+
}
224+
225+
QModelIndex QgsSettingsTreeModel::indexOfParentSettingsTreeNode( QgsSettingsTreeModelNodeData *parentNode ) const
226+
{
227+
Q_ASSERT( parentNode );
228+
229+
const QgsSettingsTreeModelNodeData *grandParentNode = parentNode->parent();
230+
if ( !grandParentNode )
231+
return QModelIndex(); // root node -> invalid index
232+
233+
int row = grandParentNode->children().indexOf( parentNode );
234+
Q_ASSERT( row >= 0 );
235+
236+
return createIndex( row, 0, static_cast<QObject *>( parentNode ) );
237+
}
238+
239+
int QgsSettingsTreeModel::rowCount( const QModelIndex &parent ) const
240+
{
241+
QgsSettingsTreeModelNodeData *n = index2node( parent );
242+
if ( !n )
243+
return 0;
244+
245+
return n->children().count();
246+
}
247+
248+
int QgsSettingsTreeModel::columnCount( const QModelIndex &parent ) const
249+
{
250+
Q_UNUSED( parent )
251+
return 3;
252+
}
253+
254+
QVariant QgsSettingsTreeModel::data( const QModelIndex &index, int role ) const
255+
{
256+
if ( !index.isValid() || index.column() > columnCount( index ) )
257+
return QVariant();
258+
259+
QgsSettingsTreeModelNodeData *node = index2node( index );
260+
261+
switch ( static_cast<Column>( index.column() ) )
262+
{
263+
case Column::Name:
264+
{
265+
if ( role == Qt::DisplayRole || role == Qt::EditRole )
266+
{
267+
return node->name();
268+
}
269+
break;
270+
}
271+
272+
case Column::Value:
273+
{
274+
if ( role == Qt::DisplayRole || role == Qt::EditRole )
275+
{
276+
return node->value();
277+
}
278+
else if ( role == Qt::FontRole )
279+
{
280+
if ( !node->exists() )
281+
{
282+
QFont font;
283+
font.setItalic( true );
284+
return font;
285+
}
286+
}
287+
else if ( role == Qt::ForegroundRole )
288+
{
289+
if ( node->isEdited() )
290+
return QColorConstants::Red;
291+
}
292+
else if ( role == Qt::BackgroundRole )
293+
{
294+
if ( node->type() == QgsSettingsTreeModelNodeData::Type::Setting )
295+
{
296+
switch ( node->setting()->settingsType() )
297+
{
298+
case Qgis::SettingsType::Custom:
299+
case Qgis::SettingsType::Variant:
300+
case Qgis::SettingsType::String:
301+
case Qgis::SettingsType::StringList:
302+
case Qgis::SettingsType::VariantMap:
303+
case Qgis::SettingsType::Bool:
304+
case Qgis::SettingsType::Integer:
305+
case Qgis::SettingsType::Double:
306+
case Qgis::SettingsType::EnumFlag:
307+
break;
308+
309+
case Qgis::SettingsType::Color:
310+
return node->value();
311+
}
312+
}
313+
}
314+
break;
315+
}
316+
317+
case Column::Description:
318+
{
319+
if ( node->type() == QgsSettingsTreeModelNodeData::Type::Setting )
320+
{
321+
if ( role == Qt::DisplayRole || role == Qt::EditRole )
322+
{
323+
return node->setting()->description();
324+
}
325+
}
326+
break;
327+
}
328+
329+
default:
330+
break;
331+
}
332+
333+
return QVariant();
334+
}
335+
336+
337+
QVariant QgsSettingsTreeModel::headerData( int section, Qt::Orientation orientation, int role ) const
338+
{
339+
if ( orientation == Qt::Orientation::Horizontal && role == Qt::DisplayRole )
340+
{
341+
switch ( static_cast<Column>( section ) )
342+
{
343+
case Column::Name:
344+
return tr( "Name" );
345+
case Column::Value:
346+
return tr( "Value" );
347+
case Column::Description:
348+
return tr( "Description" );
349+
};
350+
}
351+
352+
return QVariant();
353+
}
354+
355+
Qt::ItemFlags QgsSettingsTreeModel::flags( const QModelIndex &index ) const
356+
{
357+
if ( index.column() == static_cast<int>( Column::Value ) )
358+
{
359+
QgsSettingsTreeModelNodeData *nodeData = index2node( index );
360+
if ( nodeData->type() == QgsSettingsTreeModelNodeData::Type::Setting )
361+
{
362+
return Qt::ItemIsEnabled | Qt::ItemIsEditable;
363+
}
364+
}
365+
else
366+
{
367+
return Qt::ItemIsEnabled;
368+
}
369+
return Qt::NoItemFlags;
370+
}
371+
372+
bool QgsSettingsTreeModel::setData( const QModelIndex &index, const QVariant &value, int role )
373+
{
374+
if ( role == Qt::EditRole && index.column() == static_cast<int>( Column::Value ) )
375+
{
376+
QgsSettingsTreeModelNodeData *nodeData = index2node( index );
377+
if ( nodeData->type() == QgsSettingsTreeModelNodeData::Type::Setting )
378+
{
379+
nodeData->setValue( value );
380+
emit dataChanged( index, index );
381+
return true;
382+
}
383+
}
384+
return false;
385+
}
386+
387+
388+
QgsSettingsTreeItemDelegate::QgsSettingsTreeItemDelegate( QgsSettingsTreeModel *model, QObject *parent )
389+
: QItemDelegate( parent )
390+
, mModel( model )
391+
{
392+
}
393+
394+
QWidget *QgsSettingsTreeItemDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const
395+
{
396+
Q_UNUSED( option )
397+
if ( static_cast<QgsSettingsTreeModel::Column>( index.column() ) == QgsSettingsTreeModel::Column::Value )
398+
{
399+
QgsSettingsTreeModelNodeData *nodeData = mModel->index2node( index );
400+
if ( nodeData->type() == QgsSettingsTreeModelNodeData::Type::Setting )
401+
{
402+
return QgsGui::settingsEditorWidgetRegistry()->createEditor( nodeData->setting(), nodeData->namedParentNodes(), parent );
403+
}
404+
}
405+
return nullptr;
406+
}
407+
408+
void QgsSettingsTreeItemDelegate::setEditorData( QWidget *editor, const QModelIndex &index ) const
409+
{
410+
Q_UNUSED( index )
411+
QgsSettingsEditorWidgetWrapper *eww = QgsSettingsEditorWidgetWrapper::fromWidget( editor );
412+
if ( eww )
413+
eww->setWidgetFromVariant( mModel->data( index, Qt::DisplayRole ) );
414+
}
415+
416+
void QgsSettingsTreeItemDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
417+
{
418+
Q_UNUSED( index )
419+
QgsSettingsEditorWidgetWrapper *eww = QgsSettingsEditorWidgetWrapper::fromWidget( editor );
420+
if ( eww )
421+
model->setData( index, eww->variantValueFromWidget(), Qt::EditRole );
422+
}
423+
424+
425+
426+
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
/***************************************************************************
2+
qgssettingstreemodel.h
3+
--------------------------------------
4+
Date : January 2023
5+
Copyright : (C) 2023 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+
#ifndef QGSSETTINGSTREEMODEL_H
17+
#define QGSSETTINGSTREEMODEL_H
18+
19+
20+
#include "qgis_sip.h"
21+
#include "qgis_gui.h"
22+
23+
#include <QAbstractItemModel>
24+
#include <QItemDelegate>
25+
26+
class QgsSettingsEntryBase;
27+
class QgsSettingsTreeNode;
28+
class QgsSettingsTreeModel;
29+
class QgsSettingsTreeNamedListNode;
30+
31+
#ifndef SIP_RUN
32+
33+
///@cond PRIVATE
34+
35+
/**
36+
* \ingroup gui
37+
* \class QgsSettingsTreeNodeData
38+
* \brief QgsSettingsTree holds data of the tree model for the settings tree.
39+
*
40+
* \note Not available in Python bindings
41+
*
42+
* \since QGIS 3.32
43+
*/
44+
class GUI_EXPORT QgsSettingsTreeModelNodeData : public QObject
45+
{
46+
Q_OBJECT
47+
public:
48+
49+
//! Type of tree element
50+
enum class Type
51+
{
52+
RootNode,
53+
TreeNode,
54+
NamedListTreeNode,
55+
NamedListItem,
56+
Setting
57+
};
58+
59+
//! Constructor for the tree node data
60+
static QgsSettingsTreeModelNodeData *createRootNodeData( const QgsSettingsTreeNode *rootNode, QObject *parent );
61+
62+
//! Apply changes to the settings
63+
void applyChanges();
64+
65+
//! Returns if the node is the root node
66+
bool isRoot() const {return mParent == nullptr;}
67+
68+
//! Returns the dynamic key parts of the named list parent tree nodes
69+
QStringList namedParentNodes() const {return mNamedParentNodes;}
70+
71+
//! Returns the children nodes of the node (setting or tree node)
72+
QList<QgsSettingsTreeModelNodeData *> children() const {return mChildren;}
73+
74+
//! Returns the parent of the node
75+
QgsSettingsTreeModelNodeData *parent() const {return mParent;}
76+
77+
//! Returns the type of the node (setting or tree node)
78+
Type type() const {return mType;}
79+
80+
//! Returns the name of the node (setting or tree node)
81+
QString name() const {return mName;}
82+
83+
//! Returns the value of the node (setting or tree node)
84+
QVariant value() const {return mValue;}
85+
86+
//! Returns the value of the node (setting or tree node)
87+
QVariant originalValue() const {return mOriginalValue;}
88+
89+
//! Sets the value of the setting node
90+
bool setValue( const QVariant &value );
91+
92+
//! Returns if the setting exists (value is set)
93+
bool exists() const {return mExists;}
94+
95+
//! Returns if the setting is edited
96+
bool isEdited() const {return mIsEdited;}
97+
98+
/**
99+
* Returns the setting of the node
100+
* It returns a nullptr if the setting does not exist
101+
*/
102+
const QgsSettingsEntryBase *setting() const {return mSetting;}
103+
104+
private:
105+
//! Private constructor, use createRootNodeData instead
106+
QgsSettingsTreeModelNodeData( QObject *parent ) : QObject( parent ) {}
107+
void addChildForTreeNode( const QgsSettingsTreeNode *node );
108+
void addChildForNamedListItemNode( const QString &item, const QgsSettingsTreeNamedListNode *namedListNode );
109+
void addChildForSetting( const QgsSettingsEntryBase *setting );
110+
void fillChildren();
111+
112+
Type mType = Type::TreeNode;
113+
QString mName;
114+
QVariant mValue;
115+
QVariant mOriginalValue;
116+
QStringList mNamedParentNodes;
117+
bool mExists = false;
118+
bool mIsEdited = false;
119+
120+
QList<QgsSettingsTreeModelNodeData *> mChildren;
121+
QgsSettingsTreeModelNodeData *mParent = nullptr;
122+
123+
const QgsSettingsTreeNode *mTreeNode = nullptr;
124+
const QgsSettingsEntryBase *mSetting = nullptr;
125+
};
126+
127+
128+
/**
129+
* \ingroup gui
130+
* \class QgsSettingsTreeItemDelegate
131+
* \brief QgsSettingsTreeItemDelegate allows editing the settings in the settings tree
132+
*
133+
* \note Not available in Python bindings
134+
*
135+
* \since QGIS 3.32
136+
*/
137+
class GUI_EXPORT QgsSettingsTreeItemDelegate : public QItemDelegate
138+
{
139+
Q_OBJECT
140+
141+
public:
142+
//! Constructor
143+
explicit QgsSettingsTreeItemDelegate( QgsSettingsTreeModel *model, QObject *parent = nullptr );
144+
145+
QWidget *createEditor( QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const override;
146+
void setEditorData( QWidget *editor, const QModelIndex &index ) const override;
147+
void setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const override;
148+
149+
private:
150+
QgsSettingsTreeModel *mModel = nullptr;
151+
};
152+
153+
///@endcond
154+
155+
#endif
156+
157+
158+
/**
159+
* \ingroup gui
160+
* \class QgsSettingsTreeModel
161+
* \brief QgsSettingsTreeModel is a tree model for the settings tree.
162+
*
163+
* \since QGIS 3.32
164+
*/
165+
class GUI_EXPORT QgsSettingsTreeModel : public QAbstractItemModel
166+
{
167+
public:
168+
169+
//! Columns
170+
enum class Column
171+
{
172+
Name, //!< Name
173+
Value, //!< Value
174+
Description, //!< Description
175+
};
176+
177+
//! Constructor
178+
QgsSettingsTreeModel( QgsSettingsTreeNode *rootNode = nullptr, QObject *parent = nullptr );
179+
180+
~QgsSettingsTreeModel();
181+
182+
void applyChanges();
183+
184+
/**
185+
* Returns settings tree node for given index. Returns root node for invalid index.
186+
*/
187+
QgsSettingsTreeModelNodeData *index2node( const QModelIndex &index ) const SIP_SKIP;
188+
189+
190+
QModelIndex index( int row, int column, const QModelIndex &parent ) const override;
191+
QModelIndex parent( const QModelIndex &child ) const override;
192+
int rowCount( const QModelIndex &parent ) const override;
193+
int columnCount( const QModelIndex &parent ) const override;
194+
QVariant data( const QModelIndex &index, int role ) const override;
195+
QVariant headerData( int section, Qt::Orientation orientation, int role ) const override;
196+
Qt::ItemFlags flags( const QModelIndex &index ) const override;
197+
bool setData( const QModelIndex &index, const QVariant &value, int role ) override;
198+
199+
private:
200+
QModelIndex indexOfParentSettingsTreeNode( QgsSettingsTreeModelNodeData *parentNode ) const;
201+
202+
QgsSettingsTreeModelNodeData *mRootNode = nullptr;
203+
204+
};
205+
206+
#endif // QGSSETTINGSTREEMODEL_H
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/***************************************************************************
2+
qgssettingstreewidget.h
3+
--------------------------------------
4+
Date : April 2023
5+
Copyright : (C) 2023 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 "qgssettingstreewidget.h"
17+
#include "qgssettingstreemodel.h"
18+
#include "qgssettingstree.h"
19+
20+
#include <QAction>
21+
#include <QTreeView>
22+
#include <QHBoxLayout>
23+
#include <QVBoxLayout>
24+
25+
26+
QgsSettingsTreeWidget::QgsSettingsTreeWidget( QWidget *parent )
27+
: QWidget( parent )
28+
{
29+
QVBoxLayout *mainLayout = new QVBoxLayout( this );
30+
mainLayout->setContentsMargins( 0, 0, 0, 0 );
31+
32+
mTreeModel = new QgsSettingsTreeModel( QgsSettingsTree::treeRoot() );
33+
34+
mTreeView = new QTreeView( this );
35+
mTreeView->setModel( mTreeModel );
36+
mTreeView->setItemDelegate( new QgsSettingsTreeItemDelegate( mTreeModel, this ) );
37+
mTreeView->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding );
38+
mTreeView->setMinimumWidth( 400 );
39+
mTreeView->resizeColumnToContents( 0 );
40+
41+
mainLayout->addWidget( mTreeView );
42+
}
43+
44+
void QgsSettingsTreeWidget::applyChanges() const
45+
{
46+
mTreeModel->applyChanges();
47+
}
48+
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/***************************************************************************
2+
qgssettingstreewidget.h
3+
--------------------------------------
4+
Date : April 2023
5+
Copyright : (C) 2023 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+
#ifndef QGSSETTINGSTREEWIDGET_H
17+
#define QGSSETTINGSTREEWIDGET_H
18+
19+
#include "qgis_gui.h"
20+
21+
#include "qwidget.h"
22+
23+
class QTreeView;
24+
25+
class QgsSettingsTreeModel;
26+
27+
/**
28+
* \ingroup gui
29+
* \class QgsSettingsTreeWidget
30+
* \brief QgsSettingsTreeWidget is a widget with the settings tree to visualize, search and edit settings
31+
*
32+
* \since QGIS 3.32
33+
*/
34+
class GUI_EXPORT QgsSettingsTreeWidget : public QWidget
35+
{
36+
37+
public:
38+
//! Constructor
39+
explicit QgsSettingsTreeWidget( QWidget *parent = nullptr );
40+
41+
42+
// Apply changes to settings value
43+
void applyChanges() const;
44+
45+
private:
46+
QgsSettingsTreeModel *mTreeModel = nullptr;
47+
QTreeView *mTreeView = nullptr;
48+
49+
};
50+
51+
#endif // QGSSETTINGSTREEWIDGET_H

0 commit comments

Comments
 (0)
Please sign in to comment.