source: trunk/examples/tools/settingseditor/settingstree.cpp@ 987

Last change on this file since 987 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 7.8 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the examples of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:BSD$
10** You may use this file under the terms of the BSD license as follows:
11**
12** "Redistribution and use in source and binary forms, with or without
13** modification, are permitted provided that the following conditions are
14** met:
15** * Redistributions of source code must retain the above copyright
16** notice, this list of conditions and the following disclaimer.
17** * Redistributions in binary form must reproduce the above copyright
18** notice, this list of conditions and the following disclaimer in
19** the documentation and/or other materials provided with the
20** distribution.
21** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22** the names of its contributors may be used to endorse or promote
23** products derived from this software without specific prior written
24** permission.
25**
26** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
37** $QT_END_LICENSE$
38**
39****************************************************************************/
40
41#include <QtGui>
42
43#include "settingstree.h"
44#include "variantdelegate.h"
45
46SettingsTree::SettingsTree(QWidget *parent)
47 : QTreeWidget(parent)
48{
49 setItemDelegate(new VariantDelegate(this));
50
51 QStringList labels;
52 labels << tr("Setting") << tr("Type") << tr("Value");
53 setHeaderLabels(labels);
54 header()->setResizeMode(0, QHeaderView::Stretch);
55 header()->setResizeMode(2, QHeaderView::Stretch);
56
57 settings = 0;
58 refreshTimer.setInterval(2000);
59 autoRefresh = false;
60
61 groupIcon.addPixmap(style()->standardPixmap(QStyle::SP_DirClosedIcon),
62 QIcon::Normal, QIcon::Off);
63 groupIcon.addPixmap(style()->standardPixmap(QStyle::SP_DirOpenIcon),
64 QIcon::Normal, QIcon::On);
65 keyIcon.addPixmap(style()->standardPixmap(QStyle::SP_FileIcon));
66
67 connect(&refreshTimer, SIGNAL(timeout()), this, SLOT(maybeRefresh()));
68}
69
70void SettingsTree::setSettingsObject(QSettings *settings)
71{
72 delete this->settings;
73 this->settings = settings;
74 clear();
75
76 if (settings) {
77 settings->setParent(this);
78 refresh();
79 if (autoRefresh)
80 refreshTimer.start();
81 } else {
82 refreshTimer.stop();
83 }
84}
85
86QSize SettingsTree::sizeHint() const
87{
88 return QSize(800, 600);
89}
90
91void SettingsTree::setAutoRefresh(bool autoRefresh)
92{
93 this->autoRefresh = autoRefresh;
94 if (settings) {
95 if (autoRefresh) {
96 maybeRefresh();
97 refreshTimer.start();
98 } else {
99 refreshTimer.stop();
100 }
101 }
102}
103
104void SettingsTree::setFallbacksEnabled(bool enabled)
105{
106 if (settings) {
107 settings->setFallbacksEnabled(enabled);
108 refresh();
109 }
110}
111
112void SettingsTree::maybeRefresh()
113{
114 if (state() != EditingState)
115 refresh();
116}
117
118void SettingsTree::refresh()
119{
120 if (!settings)
121 return;
122
123 disconnect(this, SIGNAL(itemChanged(QTreeWidgetItem*,int)),
124 this, SLOT(updateSetting(QTreeWidgetItem*)));
125
126 settings->sync();
127 updateChildItems(0);
128
129 connect(this, SIGNAL(itemChanged(QTreeWidgetItem*,int)),
130 this, SLOT(updateSetting(QTreeWidgetItem*)));
131}
132
133bool SettingsTree::event(QEvent *event)
134{
135 if (event->type() == QEvent::WindowActivate) {
136 if (isActiveWindow() && autoRefresh)
137 maybeRefresh();
138 }
139 return QTreeWidget::event(event);
140}
141
142void SettingsTree::updateSetting(QTreeWidgetItem *item)
143{
144 QString key = item->text(0);
145 QTreeWidgetItem *ancestor = item->parent();
146 while (ancestor) {
147 key.prepend(ancestor->text(0) + "/");
148 ancestor = ancestor->parent();
149 }
150
151 settings->setValue(key, item->data(2, Qt::UserRole));
152 if (autoRefresh)
153 refresh();
154}
155
156void SettingsTree::updateChildItems(QTreeWidgetItem *parent)
157{
158 int dividerIndex = 0;
159
160 foreach (QString group, settings->childGroups()) {
161 QTreeWidgetItem *child;
162 int childIndex = findChild(parent, group, dividerIndex);
163 if (childIndex != -1) {
164 child = childAt(parent, childIndex);
165 child->setText(1, "");
166 child->setText(2, "");
167 child->setData(2, Qt::UserRole, QVariant());
168 moveItemForward(parent, childIndex, dividerIndex);
169 } else {
170 child = createItem(group, parent, dividerIndex);
171 }
172 child->setIcon(0, groupIcon);
173 ++dividerIndex;
174
175 settings->beginGroup(group);
176 updateChildItems(child);
177 settings->endGroup();
178 }
179
180 foreach (QString key, settings->childKeys()) {
181 QTreeWidgetItem *child;
182 int childIndex = findChild(parent, key, 0);
183
184 if (childIndex == -1 || childIndex >= dividerIndex) {
185 if (childIndex != -1) {
186 child = childAt(parent, childIndex);
187 for (int i = 0; i < child->childCount(); ++i)
188 delete childAt(child, i);
189 moveItemForward(parent, childIndex, dividerIndex);
190 } else {
191 child = createItem(key, parent, dividerIndex);
192 }
193 child->setIcon(0, keyIcon);
194 ++dividerIndex;
195 } else {
196 child = childAt(parent, childIndex);
197 }
198
199 QVariant value = settings->value(key);
200 if (value.type() == QVariant::Invalid) {
201 child->setText(1, "Invalid");
202 } else {
203 child->setText(1, value.typeName());
204 }
205 child->setText(2, VariantDelegate::displayText(value));
206 child->setData(2, Qt::UserRole, value);
207 }
208
209 while (dividerIndex < childCount(parent))
210 delete childAt(parent, dividerIndex);
211}
212
213QTreeWidgetItem *SettingsTree::createItem(const QString &text,
214 QTreeWidgetItem *parent, int index)
215{
216 QTreeWidgetItem *after = 0;
217 if (index != 0)
218 after = childAt(parent, index - 1);
219
220 QTreeWidgetItem *item;
221 if (parent)
222 item = new QTreeWidgetItem(parent, after);
223 else
224 item = new QTreeWidgetItem(this, after);
225
226 item->setText(0, text);
227 item->setFlags(item->flags() | Qt::ItemIsEditable);
228 return item;
229}
230
231QTreeWidgetItem *SettingsTree::childAt(QTreeWidgetItem *parent, int index)
232{
233 if (parent)
234 return parent->child(index);
235 else
236 return topLevelItem(index);
237}
238
239int SettingsTree::childCount(QTreeWidgetItem *parent)
240{
241 if (parent)
242 return parent->childCount();
243 else
244 return topLevelItemCount();
245}
246
247int SettingsTree::findChild(QTreeWidgetItem *parent, const QString &text,
248 int startIndex)
249{
250 for (int i = startIndex; i < childCount(parent); ++i) {
251 if (childAt(parent, i)->text(0) == text)
252 return i;
253 }
254 return -1;
255}
256
257void SettingsTree::moveItemForward(QTreeWidgetItem *parent, int oldIndex,
258 int newIndex)
259{
260 for (int i = 0; i < oldIndex - newIndex; ++i)
261 delete childAt(parent, newIndex);
262}
Note: See TracBrowser for help on using the repository browser.