environmenteditmodel.cpp 13.2 KB
Newer Older
1
/**************************************************************************
con's avatar
con committed
2
3
4
**
** This file is part of Qt Creator
**
5
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
con's avatar
con committed
6
7
8
**
** Contact:  Qt Software Information (qt-info@nokia.com)
**
9
** Commercial Usage
10
**
11
12
13
14
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
15
**
16
** GNU Lesser General Public License Usage
17
**
18
19
20
21
22
23
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24
**
25
26
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
con's avatar
con committed
27
**
28
**************************************************************************/
hjk's avatar
hjk committed
29

con's avatar
con committed
30
31
32
33
34
35
36
#include "environmenteditmodel.h"

using namespace ProjectExplorer;

EnvironmentModel::EnvironmentModel()
    : m_mergedEnvironments(false)
{}
hjk's avatar
hjk committed
37
38
39

EnvironmentModel::~EnvironmentModel()
{}
con's avatar
con committed
40
41
42

QString EnvironmentModel::indexToVariable(const QModelIndex &index) const
{
hjk's avatar
hjk committed
43
    if (m_mergedEnvironments)
con's avatar
con committed
44
45
46
47
48
49
50
51
52
53
        return m_resultEnvironment.key(m_resultEnvironment.constBegin() + index.row());
    else
        return m_items.at(index.row()).name;
}

void EnvironmentModel::updateResultEnvironment()
{
    m_resultEnvironment = m_baseEnvironment;
    m_resultEnvironment.modify(m_items);
    foreach (const EnvironmentItem &item, m_items) {
hjk's avatar
hjk committed
54
        if (item.unset) {
con's avatar
con committed
55
56
57
58
59
60
61
62
63
64
65
66
67
68
            m_resultEnvironment.set(item.name, "<UNSET>");
        }
    }
}

void EnvironmentModel::setBaseEnvironment(const ProjectExplorer::Environment &env)
{
    m_baseEnvironment = env;
    updateResultEnvironment();
    reset();
}

void EnvironmentModel::setMergedEnvironments(bool b)
{
hjk's avatar
hjk committed
69
    if (m_mergedEnvironments == b)
con's avatar
con committed
70
71
        return;
    m_mergedEnvironments = b;
hjk's avatar
hjk committed
72
    if (b)
con's avatar
con committed
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
        updateResultEnvironment();
    reset();
}

bool EnvironmentModel::mergedEnvironments()
{
    return m_mergedEnvironments;
}

int EnvironmentModel::rowCount(const QModelIndex &parent) const
{
    if (parent.isValid())
        return 0;

    return m_mergedEnvironments ? m_resultEnvironment.size() : m_items.count();
}
int EnvironmentModel::columnCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return 2;
}

bool EnvironmentModel::changes(const QString &name) const
{
hjk's avatar
hjk committed
97
98
    foreach (const EnvironmentItem& item, m_items)
        if (item.name == name)
con's avatar
con committed
99
100
101
102
103
104
            return true;
    return false;
}

QVariant EnvironmentModel::data(const QModelIndex &index, int role) const
{
hjk's avatar
hjk committed
105
106
    if ((role == Qt::DisplayRole || role == Qt::EditRole) && index.isValid()) {
        if ((m_mergedEnvironments && index.row() >= m_resultEnvironment.size()) ||
con's avatar
con committed
107
108
109
110
           (!m_mergedEnvironments && index.row() >= m_items.count())) {
            return QVariant();
        }

hjk's avatar
hjk committed
111
112
        if (index.column() == 0) {
            if (m_mergedEnvironments) {
con's avatar
con committed
113
114
115
116
                return m_resultEnvironment.key(m_resultEnvironment.constBegin() + index.row());
            } else {
                return m_items.at(index.row()).name;
            }
hjk's avatar
hjk committed
117
118
119
        } else if (index.column() == 1) {
            if (m_mergedEnvironments) {
                if (role == Qt::EditRole) {
con's avatar
con committed
120
                    int pos = findInChanges(indexToVariable(index));
hjk's avatar
hjk committed
121
                    if (pos != -1)
con's avatar
con committed
122
123
124
125
                        return m_items.at(pos).value;
                }
                return m_resultEnvironment.value(m_resultEnvironment.constBegin() + index.row());
            } else {
hjk's avatar
hjk committed
126
                if (m_items.at(index.row()).unset)
con's avatar
con committed
127
128
129
130
131
132
                    return "<UNSET>";
                else
                    return m_items.at(index.row()).value;
            }
        }
    }
hjk's avatar
hjk committed
133
134
    if (role == Qt::FontRole) {
        if (m_mergedEnvironments) {
con's avatar
con committed
135
            // check wheter this environment variable exists in m_items
hjk's avatar
hjk committed
136
            if (changes(m_resultEnvironment.key(m_resultEnvironment.constBegin() + index.row()))) {
con's avatar
con committed
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
                QFont f;
                f.setBold(true);
                return QVariant(f);
            }
        }
        return QFont();
    }
    return QVariant();
}


Qt::ItemFlags EnvironmentModel::flags(const QModelIndex &index) const
{
    Q_UNUSED(index);
    return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled;
}

bool EnvironmentModel::hasChildren(const QModelIndex &index) const
{
hjk's avatar
hjk committed
156
    if (!index.isValid())
con's avatar
con committed
157
158
159
160
161
162
163
        return true;
    else
        return false;
}

QVariant EnvironmentModel::headerData(int section, Qt::Orientation orientation, int role) const
{
hjk's avatar
hjk committed
164
    if (orientation == Qt::Vertical || role != Qt::DisplayRole)
con's avatar
con committed
165
166
167
168
169
170
        return QVariant();
    return section == 0 ? tr("Variable") : tr("Value");
}

QModelIndex EnvironmentModel::index(int row, int column, const QModelIndex &parent) const
{
hjk's avatar
hjk committed
171
    if (!parent.isValid())
con's avatar
con committed
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
        return createIndex(row, column, 0);
    return QModelIndex();
}

QModelIndex EnvironmentModel::parent(const QModelIndex &index) const
{
    Q_UNUSED(index);
    return QModelIndex();
}

/// *****************
/// Utility functions
/// *****************
int EnvironmentModel::findInChanges(const QString &name) const
{
hjk's avatar
hjk committed
187
188
    for (int i=0; i<m_items.size(); ++i)
        if (m_items.at(i).name == name)
con's avatar
con committed
189
190
191
192
193
194
            return i;
    return -1;
}

int EnvironmentModel::findInChangesInsertPosition(const QString &name) const
{
hjk's avatar
hjk committed
195
196
    for (int i=0; i<m_items.size(); ++i)
        if (m_items.at(i).name > name)
con's avatar
con committed
197
198
199
200
201
202
203
204
            return i;
    return m_items.size();
}

int EnvironmentModel::findInResult(const QString &name) const
{
    Environment::const_iterator it;
    int i = 0;
hjk's avatar
hjk committed
205
206
    for (it = m_resultEnvironment.constBegin(); it != m_resultEnvironment.constEnd(); ++it, ++i)
        if (m_resultEnvironment.key(it) == name)
con's avatar
con committed
207
208
209
210
211
212
213
214
            return i;
    return -1;
}

int EnvironmentModel::findInResultInsertPosition(const QString &name) const
{
    Environment::const_iterator it;
    int i = 0;
hjk's avatar
hjk committed
215
216
    for (it = m_resultEnvironment.constBegin(); it != m_resultEnvironment.constEnd(); ++it, ++i)
        if (m_resultEnvironment.key(it) > name)
con's avatar
con committed
217
218
219
220
221
222
            return i;
    return m_resultEnvironment.size();
}

bool EnvironmentModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
hjk's avatar
hjk committed
223
224
    if (role == Qt::EditRole && index.isValid()) {
        if (index.column() == 0) {
con's avatar
con committed
225
226
            //fail if a variable with the same name already exists
#ifdef Q_OS_WIN
hjk's avatar
hjk committed
227
            if (findInChanges(value.toString().toUpper()) != -1)
con's avatar
con committed
228
229
                return false;
#else
hjk's avatar
hjk committed
230
            if (findInChanges(value.toString()) != -1)
con's avatar
con committed
231
232
233
                return false;
#endif
            EnvironmentItem old("", "");
hjk's avatar
hjk committed
234
            if (m_mergedEnvironments) {
con's avatar
con committed
235
                int pos = findInChanges(indexToVariable(index));
hjk's avatar
hjk committed
236
                if (pos != -1) {
con's avatar
con committed
237
238
239
240
241
242
243
244
245
246
247
248
249
250
                    old = m_items.at(pos);
                } else {
                    old.name = m_resultEnvironment.key(m_resultEnvironment.constBegin() + index.row());
                    old.value = m_resultEnvironment.value(m_resultEnvironment.constBegin() + index.row());
                    old.unset = false;
                }
            } else {
                old = m_items.at(index.row());
            }
#ifdef Q_OS_WIN
            const QString &newName = value.toString().toUpper();
#else
            const QString &newName = value.toString();
#endif
hjk's avatar
hjk committed
251
            if (changes(old.name))
con's avatar
con committed
252
253
254
255
                removeVariable(old.name);
            old.name = newName;
            addVariable(old);
            return true;
hjk's avatar
hjk committed
256
257
        } else if (index.column() == 1) {
            if (m_mergedEnvironments) {
con's avatar
con committed
258
259
                const QString &name = indexToVariable(index);
                int pos = findInChanges(name);
hjk's avatar
hjk committed
260
                if (pos != -1) {
con's avatar
con committed
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
                    m_items[pos].value = value.toString();
                    m_items[pos].unset = false;
                    updateResultEnvironment();
                    emit dataChanged(index, index);
                    emit userChangesUpdated();
                    return true;
                }
                // not found in m_items, so add it as a new variable
                addVariable(EnvironmentItem(name, value.toString()));
                return true;
            } else {
                m_items[index.row()].value = value.toString();
                m_items[index.row()].unset = false;
                emit dataChanged(index, index);
                emit userChangesUpdated();
                return true;
            }
        }
    }
    return false;
}

QModelIndex EnvironmentModel::addVariable()
{
    const QString &name = "<VARIABLE>";
hjk's avatar
hjk committed
286
    if (m_mergedEnvironments) {
con's avatar
con committed
287
        int i = findInResult(name);
hjk's avatar
hjk committed
288
        if (i != -1)
con's avatar
con committed
289
290
291
            return index(i, 0, QModelIndex());
    } else {
        int i = findInChanges(name);
hjk's avatar
hjk committed
292
        if (i != -1)
con's avatar
con committed
293
294
295
296
297
298
299
300
            return index(i, 0, QModelIndex());
    }
    // Don't exist, really add them
    return addVariable(EnvironmentItem(name, "<VALUE>"));
}

QModelIndex EnvironmentModel::addVariable(const EnvironmentItem &item)
{
hjk's avatar
hjk committed
301
    if (m_mergedEnvironments) {
con's avatar
con committed
302
303
        bool existsInBaseEnvironment = (m_baseEnvironment.find(item.name) != m_baseEnvironment.constEnd());
        int rowInResult;
hjk's avatar
hjk committed
304
        if (existsInBaseEnvironment)
con's avatar
con committed
305
306
307
308
309
            rowInResult = findInResult(item.name);
        else
            rowInResult = findInResultInsertPosition(item.name);
        int rowInChanges = findInChangesInsertPosition(item.name);

310
        //qDebug() << "addVariable " << item.name << existsInBaseEnvironment << rowInResult << rowInChanges;
con's avatar
con committed
311

hjk's avatar
hjk committed
312
        if (existsInBaseEnvironment) {
con's avatar
con committed
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
            m_items.insert(rowInChanges, item);
            updateResultEnvironment();
            emit dataChanged(index(rowInResult, 0, QModelIndex()), index(rowInResult, 1, QModelIndex()));
            emit userChangesUpdated();
            return index(rowInResult, 0, QModelIndex());
        } else {
            beginInsertRows(QModelIndex(), rowInResult, rowInResult);
            m_items.insert(rowInChanges, item);
            updateResultEnvironment();
            endInsertRows();
            qDebug()<<"returning index: "<<rowInResult;
            emit userChangesUpdated();
            return index(rowInResult, 0, QModelIndex());
        }
    } else {
        int newPos = findInChangesInsertPosition(item.name);
        beginInsertRows(QModelIndex(), newPos, newPos);
        m_items.insert(newPos, item);
        endInsertRows();
        emit userChangesUpdated();
        return index(newPos, 0, QModelIndex());
    }
}

void EnvironmentModel::removeVariable(const QString &name)
{
hjk's avatar
hjk committed
339
    if (m_mergedEnvironments) {
con's avatar
con committed
340
341
342
        int rowInResult = findInResult(name);
        int rowInChanges = findInChanges(name);
        bool existsInBaseEnvironment = m_baseEnvironment.find(name) != m_baseEnvironment.constEnd();
hjk's avatar
hjk committed
343
        if (existsInBaseEnvironment) {
con's avatar
con committed
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
            m_items.removeAt(rowInChanges);
            updateResultEnvironment();
            emit dataChanged(index(rowInResult, 0, QModelIndex()), index(rowInResult, 1, QModelIndex()));
            emit userChangesUpdated();
        } else {
            beginRemoveRows(QModelIndex(), rowInResult, rowInResult);
            m_items.removeAt(rowInChanges);
            updateResultEnvironment();
            endRemoveRows();
            emit userChangesUpdated();
        }
    } else {
        int removePos = findInChanges(name);
        beginRemoveRows(QModelIndex(), removePos, removePos);
        m_items.removeAt(removePos);
        updateResultEnvironment();
        endRemoveRows();
        emit userChangesUpdated();
    }
}

void EnvironmentModel::unset(const QString &name)
{
hjk's avatar
hjk committed
367
    if (m_mergedEnvironments) {
con's avatar
con committed
368
369
370
        int row = findInResult(name);
        // look in m_items for the variable
        int pos = findInChanges(name);
hjk's avatar
hjk committed
371
        if (pos != -1) {
con's avatar
con committed
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
            m_items[pos].unset = true;
            updateResultEnvironment();
            emit dataChanged(index(row, 0, QModelIndex()), index(row, 1, QModelIndex()));
            emit userChangesUpdated();
            return;
        }
        pos = findInChangesInsertPosition(name);
        m_items.insert(pos, EnvironmentItem(name, ""));
        m_items[pos].unset = true;
        updateResultEnvironment();
        emit dataChanged(index(row, 0, QModelIndex()), index(row, 1, QModelIndex()));
        emit userChangesUpdated();
        return;
    } else {
        int pos = findInChanges(name);
        m_items[pos].unset = true;
        emit dataChanged(index(pos, 1, QModelIndex()), index(pos, 1, QModelIndex()));
        emit userChangesUpdated();
        return;
    }
}

bool EnvironmentModel::isUnset(const QString &name)
{
    int pos = findInChanges(name);
hjk's avatar
hjk committed
397
    if (pos != -1)
con's avatar
con committed
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
        return m_items.at(pos).unset;
    else
        return false;
}

bool EnvironmentModel::isInBaseEnvironment(const QString &name)
{
    return m_baseEnvironment.find(name) != m_baseEnvironment.constEnd();
}

QList<EnvironmentItem> EnvironmentModel::userChanges() const
{
    return m_items;
}

void EnvironmentModel::setUserChanges(QList<EnvironmentItem> list)
{
    m_items = list;
    updateResultEnvironment();
    emit reset();
}