~ubuntu-branches/ubuntu/karmic/psi/karmic

« back to all changes in this revision

Viewing changes to src/tools/optionstree/optionstreemodel.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jan Niehusmann
  • Date: 2008-08-28 18:46:52 UTC
  • mfrom: (1.2.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20080828184652-iiik12dl91nq7cdi
Tags: 0.12-2
Uploading to unstable (Closes: Bug#494352)

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
 */
20
20
 
21
21
#include "optionstreemodel.h"
 
22
 
 
23
#include <QStringList>
 
24
 
22
25
#include "optionstree.h"
23
26
 
24
 
OptionsTreeModel::OptionsTreeModel(OptionsTree* tree, QObject* parent) : QAbstractItemModel(parent), tree_(tree), flat_(false)
 
27
 
 
28
// Enable this if you have Trolltech Labs' ModelTest and are not going
 
29
// to distribute the source or binary. You need to include modeltest.pri
 
30
// somewhere too.
 
31
//#define HAVE_MODELTEST
 
32
 
 
33
#ifdef HAVE_MODELTEST
 
34
#include <modeltest.h>
 
35
#endif
 
36
 
 
37
OptionsTreeModel::OptionsTreeModel(OptionsTree* tree, QObject* parent)
 
38
                : QAbstractItemModel(parent),
 
39
                tree_(tree), 
 
40
                flat_(false), 
 
41
                nextIdx(0)
25
42
{
 
43
        connect(tree_, SIGNAL(optionChanged(const QString&)), SLOT(optionChanged(const QString&)));
 
44
        connect(tree_, SIGNAL(optionAboutToBeInserted(const QString&)), SLOT(optionAboutToBeInserted(const QString&)));
 
45
        connect(tree_, SIGNAL(optionInserted(const QString&)), SLOT(optionInserted(const QString&)));
 
46
        connect(tree_, SIGNAL(optionAboutToBeRemoved(const QString&)), SLOT(optionAboutToBeRemoved(const QString&)));
 
47
        connect(tree_, SIGNAL(optionRemoved(const QString&)), SLOT(optionRemoved(const QString&)));
 
48
 
 
49
#ifdef HAVE_MODELTEST
 
50
        new ModelTest(this, this);
 
51
#endif
26
52
}
27
53
 
28
54
void OptionsTreeModel::setFlat(bool b)
33
59
        }
34
60
}
35
61
 
 
62
 
 
63
/**
 
64
 * Get the parent option of @a option
 
65
 * @param option the option name to be splitted
 
66
 * @return the part of option until the last dot (or empty)
 
67
 */
 
68
QString OptionsTreeModel::getParentName(const QString &option) const
 
69
{
 
70
        QString parentname;
 
71
        int dot_index = option.lastIndexOf('.');
 
72
        if (dot_index != -1) {
 
73
                parentname = option.left(dot_index);
 
74
        }
 
75
        return parentname;
 
76
}
 
77
 
 
78
 
 
79
 
 
80
/**
 
81
 * Get index of given @a option
 
82
 * @param option the option to retrieve the index for
 
83
 * @param sec Section the new index should point to
 
84
 * @return a QModelIndex to @a option
 
85
 */
 
86
QModelIndex OptionsTreeModel::index(const QString &option, Section sec) const
 
87
{
 
88
        if (option == "") {
 
89
                return QModelIndex();
 
90
        }
 
91
        
 
92
        if (flat_) {
 
93
                QStringList options = tree_->getChildOptionNames("",false,false);
 
94
                options.sort();
 
95
                int row = options.indexOf(option);
 
96
                return createIndex(row, sec, nameToIndex(options.at(row)));
 
97
        } else {
 
98
                QString parentname(getParentName(option));
 
99
                
 
100
                QStringList children = tree_->getChildOptionNames(parentname,true,true);
 
101
                children.sort();
 
102
                int row = children.indexOf(option);
 
103
                
 
104
                return createIndex(row, sec, nameToIndex(option));
 
105
        }
 
106
}
 
107
 
 
108
 
36
109
Qt::ItemFlags OptionsTreeModel::flags(const QModelIndex& index) const
37
110
{
 
111
        if (!index.isValid()) {
 
112
                // Root item
 
113
                return 0;
 
114
        }
38
115
        Qt::ItemFlags f = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
39
 
        if (index.column() == Value)
 
116
        if ((index.column() == Value) && !internalNode(indexToOptionName(index)))
40
117
                f |= Qt::ItemIsEditable;
41
118
        return f;
42
119
}
43
120
 
44
121
int OptionsTreeModel::rowCount(const QModelIndex& parent) const
45
122
{
46
 
        if (flat_) {
47
 
                return (parent.isValid() ? 0 : tree_->getChildOptionNames("",!flat_).count());
48
 
        }
49
 
        else {
50
 
                QString option;
51
 
                if (parent.isValid())
52
 
                        option = tree_->getChildOptionNames("",false,true).at(parent.internalId());
53
 
                return tree_->getChildOptionNames(option,true,true).count();
54
 
        }
 
123
        if ((Section)parent.column() == Name || !parent.isValid()) {
 
124
                if (flat_) {
 
125
                        return (parent.isValid() ? 0 : tree_->getChildOptionNames("",false,false).count());
 
126
                } else {
 
127
                        QString option;
 
128
                        if (parent.isValid())
 
129
                                option = indexToOptionName(parent);
 
130
                        return tree_->getChildOptionNames(option,true,true).count();
 
131
                }
 
132
        }
 
133
        return 0;
55
134
}
56
135
 
57
136
int OptionsTreeModel::columnCount(const QModelIndex&) const 
64
143
        if (!index.isValid())
65
144
                return QVariant();
66
145
 
67
 
        QString option = tree_->getChildOptionNames("",false,true).at(index.internalId());
 
146
        QString option = indexToOptionName(index);
68
147
        Section section = (Section) index.column();
69
 
        if (role == Qt::DisplayRole) {
 
148
        if ((role == Qt::DisplayRole) || (role == Qt::EditRole)) {
70
149
                if (section == Name) {
71
150
                        if (flat_) {
72
151
                                return option;
73
 
                        }
74
 
                        else {
 
152
                        } else {
75
153
                                int dot_index = option.lastIndexOf('.');
76
 
                                return option.right(option.length() - dot_index - 1);
 
154
                                return option.mid(dot_index + 1);
77
155
                        }
78
156
                }
79
 
                else if (section == Type)
80
 
                        return tree_->getOption(option).typeName();
81
 
                else if (section == Value)
82
 
                        return tree_->getOption(option).toString();
83
 
                else if (section == Comment)
84
 
                        return tree_->getComment(option);
 
157
                else if (section == Comment) {
 
158
                        return tree_->getComment(option);
 
159
                } else if (!tree_->isInternalNode(option)) {
 
160
                        if (section == Type)
 
161
                                return tree_->getOption(option).typeName();
 
162
                        else if (section == Value)
 
163
                                return tree_->getOption(option);//.toString();
 
164
                }
 
165
        } else if (role == Qt::ToolTipRole) {
 
166
                if (!tree_->isInternalNode(option)) {
 
167
                        return tree_->getComment(option);
 
168
                }
85
169
        }
86
170
        return QVariant();
87
171
}
97
181
                case Type: return QString(tr("Type"));
98
182
                case Value: return QString(tr("Value"));
99
183
                case Comment: return QString(tr("Comment"));
 
184
                default:
 
185
                        return QVariant();
100
186
        }
101
 
 
102
 
        return QVariant();
103
187
}
104
188
 
105
189
QModelIndex OptionsTreeModel::index(int row, int column, const QModelIndex & parent) const
106
190
{
107
 
        // FIXME: Horribly inefficient
108
 
        QStringList all_options = tree_->getChildOptionNames("",false,true);
 
191
        if  (column < 0  || column >= SectionBound || row < 0) {
 
192
                return QModelIndex();
 
193
        }
109
194
        int id = 0;
 
195
        QStringList options;
110
196
        if (flat_) {
111
 
                QStringList options = tree_->getChildOptionNames("",false,false);
112
 
                id = all_options.indexOf(options.at(row));
113
 
        }
114
 
        else {
 
197
                options = tree_->getChildOptionNames("",false,false);
 
198
        } else {
115
199
                QString parent_option;
116
 
                if (parent.isValid()) 
117
 
                        parent_option = all_options.at(parent.internalId());
118
 
                QStringList children = tree_->getChildOptionNames(parent_option,true,true);
119
 
                if (row >= children.count())
120
 
                        return QModelIndex();
121
 
                id = all_options.indexOf(children.at(row));
122
 
        }
 
200
                if (parent.isValid()) {
 
201
                        parent_option = indexToOptionName(parent);
 
202
                }
 
203
                options = tree_->getChildOptionNames(parent_option,true,true);
 
204
        }
 
205
        if (row >= options.size()) {
 
206
                return QModelIndex();
 
207
        }
 
208
        options.sort();
 
209
        id = nameToIndex(options.at(row));
123
210
        return createIndex(row,column,id);
124
211
}
125
212
 
126
 
QModelIndex OptionsTreeModel::parent(const QModelIndex& index) const
127
 
{
128
 
        if (!index.isValid() || flat_) 
129
 
                return QModelIndex();
130
 
        
131
 
        QStringList all_options = tree_->getChildOptionNames("",false,true);
132
 
        QString option = all_options.at(index.internalId());
133
 
        
134
 
        // Determine the parent option
135
 
        int dot_index = option.lastIndexOf('.');
136
 
        if (dot_index == -1)
137
 
                return QModelIndex();
138
 
        QString parent_option = option.left(dot_index);
139
 
        
140
 
        // Determine the parent's parent
141
 
        QString parent_parent_option;
142
 
        dot_index = parent_option.lastIndexOf('.');
143
 
        if (dot_index != -1)
144
 
                parent_parent_option = parent_option.left(dot_index);
145
 
        int row = tree_->getChildOptionNames(parent_parent_option,true,true).indexOf(parent_option);
146
 
        
147
 
        return createIndex(row,0,all_options.indexOf(parent_option));
 
213
QModelIndex OptionsTreeModel::parent(const QModelIndex& modelindex) const
 
214
{
 
215
        if (!modelindex.isValid() || flat_) 
 
216
                return QModelIndex();
 
217
        
 
218
        QString option = indexToOptionName(modelindex);
 
219
        
 
220
        QString parent_option = getParentName(option);
 
221
        
 
222
        return index(parent_option);
 
223
}
 
224
 
 
225
bool OptionsTreeModel::setData ( const QModelIndex & index, const QVariant & value, int role)
 
226
{
 
227
        QString option = indexToOptionName(index);
 
228
        if ((role != Qt::EditRole) || ((Section) index.column() != Value) || internalNode(option)) {
 
229
                return false;
 
230
        }
 
231
        QVariant current = tree_->getOption(option);
 
232
        QVariant newval = value;
 
233
        if (!newval.canConvert(current.type())) {
 
234
                qWarning("Sorry don't know how to do that!");
 
235
                return false;
 
236
        }
 
237
        newval.convert(current.type());
 
238
        tree_->setOption(option, newval);
 
239
        return true;
 
240
}
 
241
 
 
242
 
 
243
 
 
244
 
 
245
void OptionsTreeModel::optionAboutToBeInserted(const QString& option)
 
246
{
 
247
        QString parentname(getParentName(option));
 
248
        
 
249
        // FIXME? handle cases when parent doesn't exist either.
 
250
        
 
251
        QModelIndex parent(index(parentname));
 
252
        
 
253
        QStringList children = tree_->getChildOptionNames(parentname,true,true);
 
254
        children << option;
 
255
        children.sort();
 
256
        int row = children.indexOf(option);
 
257
        
 
258
        emit beginInsertRows(parent, row, row);
 
259
        
 
260
}
 
261
 
 
262
void OptionsTreeModel::optionInserted(const QString& option)
 
263
{
 
264
        Q_UNUSED(option)
 
265
        endInsertRows ();
 
266
}
 
267
 
 
268
void OptionsTreeModel::optionAboutToBeRemoved(const QString& option)
 
269
{
 
270
        QString parentname(getParentName(option));
 
271
        
 
272
        QModelIndex parent(index(parentname));
 
273
        
 
274
        QStringList children = tree_->getChildOptionNames(parentname,true,true);
 
275
        children.sort();
 
276
        int row = children.indexOf(option);
 
277
        
 
278
        if (row != -1) {
 
279
                realRemove.push(true);
 
280
                emit beginRemoveRows(parent, row, row);
 
281
        } else {
 
282
                realRemove.push(false);
 
283
        }
 
284
}
 
285
void OptionsTreeModel::optionRemoved(const QString& option)
 
286
{
 
287
        Q_UNUSED(option)
 
288
        if (realRemove.pop()) endRemoveRows ();
 
289
}
 
290
 
 
291
 
 
292
void OptionsTreeModel::optionChanged(const QString& option)
 
293
{
 
294
        // only need to notify about options the view can possibly know anything about.
 
295
        if (nameMap.contains(option)) {
 
296
                QModelIndex modelindex(index(option, Value));
 
297
                emit dataChanged(modelindex, modelindex);
 
298
        }
 
299
}
 
300
bool OptionsTreeModel::internalNode(QString option) const
 
301
{
 
302
        return tree_->isInternalNode(option);
 
303
}
 
304
 
 
305
int OptionsTreeModel::nameToIndex(QString name) const
 
306
{
 
307
        if (!nameMap.contains(name)) {
 
308
                int idx = nextIdx++;
 
309
                //qDebug() << "adding " << name << " as " << idx;
 
310
                nameMap[name] = idx;
 
311
                indexMap[idx] = name;
 
312
                return idx;
 
313
        } else {
 
314
                return nameMap[name];
 
315
        }
 
316
}
 
317
 
 
318
QString OptionsTreeModel::indexToOptionName(QModelIndex idx) const
 
319
{
 
320
        return indexMap[idx.internalId()];
148
321
}