vcsbaseclientsettings.cpp 10.8 KB
Newer Older
cerf's avatar
cerf committed
1 2
/**************************************************************************
**
3
** Copyright (c) 2014 Brian McGillion and Hugues Delorme
hjk's avatar
hjk committed
4
** Contact: http://www.qt-project.org/legal
cerf's avatar
cerf committed
5
**
hjk's avatar
hjk committed
6
** This file is part of Qt Creator.
cerf's avatar
cerf committed
7
**
hjk's avatar
hjk committed
8 9 10 11 12 13 14
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
cerf's avatar
cerf committed
15 16
**
** GNU Lesser General Public License Usage
hjk's avatar
hjk committed
17 18 19 20 21 22 23 24 25
** 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.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
cerf's avatar
cerf committed
26 27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
hjk's avatar
hjk committed
28
****************************************************************************/
cerf's avatar
cerf committed
29 30 31

#include "vcsbaseclientsettings.h"

32
#include <utils/environment.h>
33
#include <utils/hostosinfo.h>
34
#include <utils/qtcassert.h>
35

36
#include <QSettings>
37
#include <QVariant>
cerf's avatar
cerf committed
38

39
namespace {
cerf's avatar
cerf committed
40

41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
class SettingValue
{
public:
    union Composite
    {
        QString *strPtr; // Union can't store class objects ...
        int intValue;
        bool boolValue;
    };

    SettingValue() :
        m_type(QVariant::Invalid)
    {
    }

    explicit SettingValue(const QVariant &v) :
        m_type(v.type())
    {
        switch (v.type()) {
        case QVariant::UInt:
            m_type = QVariant::Int;
        case QVariant::Int:
            m_comp.intValue = v.toInt();
            break;
        case QVariant::Bool:
            m_comp.boolValue = v.toBool();
            break;
        case QVariant::String:
            m_comp.strPtr = new QString(v.toString());
            break;
        default:
            m_type = QVariant::Invalid;
            break;
        }
    }

    SettingValue(const SettingValue &other) :
        m_comp(other.m_comp),
        m_type(other.type())
    {
        copyInternalString(other);
    }

    ~SettingValue()
    {
        deleteInternalString();
    }

    SettingValue &operator=(const SettingValue &other)
    {
        if (this != &other) {
            deleteInternalString();
            m_type = other.type();
            m_comp = other.m_comp;
            copyInternalString(other);
        }
        return *this;
    }

    QString stringValue(const QString &defaultString = QString()) const
    {
        if (type() == QVariant::String && m_comp.strPtr != 0)
            return *(m_comp.strPtr);
        return defaultString;
    }

    QVariant::Type type() const
    {
        return m_type;
    }

    static bool isUsableVariantType(QVariant::Type varType)
    {
        return varType == QVariant::UInt || varType == QVariant::Int ||
                varType == QVariant::Bool || varType == QVariant::String;
    }

    Composite m_comp;

private:
    void deleteInternalString()
    {
        if (m_type == QVariant::String && m_comp.strPtr != 0) {
            delete m_comp.strPtr;
            m_comp.strPtr = 0;
        }
    }

    void copyInternalString(const SettingValue &other)
    {
        if (type() == QVariant::String) {
            const QString *otherString = other.m_comp.strPtr;
            m_comp.strPtr = new QString(otherString != 0 ? *otherString : QString());
        }
    }

    QVariant::Type m_type;
};

bool operator==(const SettingValue &lhs, const SettingValue &rhs)
{
    if (lhs.type() == rhs.type()) {
        switch (lhs.type()) {
        case QVariant::Int:
            return lhs.m_comp.intValue == rhs.m_comp.intValue;
        case QVariant::Bool:
            return lhs.m_comp.boolValue == rhs.m_comp.boolValue;
        case QVariant::String:
            return lhs.stringValue() == rhs.stringValue();
        default:
            return false;
        }
    }
    return false;
}

} // Anonymous namespace

hjk's avatar
hjk committed
159
namespace VcsBase {
160

161
namespace Internal {
hjk's avatar
hjk committed
162

hjk's avatar
hjk committed
163
class VcsBaseClientSettingsPrivate : public QSharedData
164 165
{
public:
hjk's avatar
hjk committed
166
    VcsBaseClientSettingsPrivate() {}
167

hjk's avatar
hjk committed
168
    VcsBaseClientSettingsPrivate(const VcsBaseClientSettingsPrivate &other) :
169 170 171
        QSharedData(other),
        m_valueHash(other.m_valueHash),
        m_defaultValueHash(other.m_defaultValueHash),
172 173
        m_settingsGroup(other.m_settingsGroup),
        m_binaryFullPath(other.m_binaryFullPath)
174 175 176 177 178 179
    {
    }

    QHash<QString, SettingValue> m_valueHash;
    QVariantHash m_defaultValueHash;
    QString m_settingsGroup;
180
    mutable QString m_binaryFullPath;
181
};
cerf's avatar
cerf committed
182

183 184
} // namespace Internal

185
/*!
hjk's avatar
hjk committed
186
    \class VcsBase::VcsBaseClientSettings
187

188 189
    \brief The VcsBaseClientSettings class contains settings used in
    VcsBaseClient.
190

hjk's avatar
hjk committed
191
    \sa VcsBase::VcsBaseClient
192 193
*/

hjk's avatar
hjk committed
194 195 196 197 198 199
const QLatin1String VcsBaseClientSettings::binaryPathKey("BinaryPath");
const QLatin1String VcsBaseClientSettings::userNameKey("Username");
const QLatin1String VcsBaseClientSettings::userEmailKey("UserEmail");
const QLatin1String VcsBaseClientSettings::logCountKey("LogCount");
const QLatin1String VcsBaseClientSettings::promptOnSubmitKey("PromptOnSubmit");
const QLatin1String VcsBaseClientSettings::timeoutKey("Timeout");
200
const QLatin1String VcsBaseClientSettings::pathKey("Path");
201

hjk's avatar
hjk committed
202 203
VcsBaseClientSettings::VcsBaseClientSettings() :
    d(new Internal::VcsBaseClientSettingsPrivate)
cerf's avatar
cerf committed
204
{
205 206 207 208 209 210
    declareKey(binaryPathKey, QLatin1String(""));
    declareKey(userNameKey, QLatin1String(""));
    declareKey(userEmailKey, QLatin1String(""));
    declareKey(logCountKey, 100);
    declareKey(promptOnSubmitKey, true);
    declareKey(timeoutKey, 30);
211
    declareKey(pathKey, QString());
cerf's avatar
cerf committed
212 213
}

hjk's avatar
hjk committed
214
VcsBaseClientSettings::VcsBaseClientSettings(const VcsBaseClientSettings &other) :
215
    d(other.d)
cerf's avatar
cerf committed
216 217 218
{
}

hjk's avatar
hjk committed
219
VcsBaseClientSettings &VcsBaseClientSettings::operator=(const VcsBaseClientSettings &other)
cerf's avatar
cerf committed
220
{
221
    if (this != &other)
hjk's avatar
hjk committed
222
        d = other.d;
223
    return *this;
cerf's avatar
cerf committed
224 225
}

hjk's avatar
hjk committed
226
VcsBaseClientSettings::~VcsBaseClientSettings()
cerf's avatar
cerf committed
227 228 229
{
}

hjk's avatar
hjk committed
230
void VcsBaseClientSettings::writeSettings(QSettings *settings) const
cerf's avatar
cerf committed
231
{
232 233 234
    QTC_ASSERT(!settingsGroup().isEmpty(), return);

    settings->remove(settingsGroup());
235 236 237 238
    settings->beginGroup(settingsGroup());
    foreach (const QString &key, keys())
        settings->setValue(key, value(key));
    settings->endGroup();
cerf's avatar
cerf committed
239 240
}

hjk's avatar
hjk committed
241
void VcsBaseClientSettings::readSettings(const QSettings *settings)
cerf's avatar
cerf committed
242
{
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261
    const QString keyRoot = settingsGroup() + QLatin1Char('/');
    foreach (const QString &key, keys()) {
        const QVariant value = settings->value(keyRoot + key, keyDefaultValue(key));
        // For some reason QSettings always return QVariant(QString) when the
        // key exists. The type is explicited to avoid wrong conversions
        switch (valueType(key)) {
        case QVariant::Int:
            setValue(key, value.toInt());
            break;
        case QVariant::Bool:
            setValue(key, value.toBool());
            break;
        case QVariant::String:
            setValue(key, value.toString());
            break;
        default:
            break;
        }
    }
262 263

    this->readLegacySettings(settings);
cerf's avatar
cerf committed
264 265
}

hjk's avatar
hjk committed
266
bool VcsBaseClientSettings::equals(const VcsBaseClientSettings &rhs) const
cerf's avatar
cerf committed
267
{
268 269 270
    if (this == &rhs)
        return true;
    return d->m_valueHash == rhs.d->m_valueHash;
cerf's avatar
cerf committed
271 272
}

hjk's avatar
hjk committed
273
QStringList VcsBaseClientSettings::keys() const
cerf's avatar
cerf committed
274
{
275
    return d->m_valueHash.keys();
cerf's avatar
cerf committed
276 277
}

hjk's avatar
hjk committed
278
bool VcsBaseClientSettings::hasKey(const QString &key) const
cerf's avatar
cerf committed
279
{
280
    return d->m_valueHash.contains(key);
cerf's avatar
cerf committed
281 282
}

hjk's avatar
hjk committed
283
int *VcsBaseClientSettings::intPointer(const QString &key)
cerf's avatar
cerf committed
284
{
285 286 287
    if (hasKey(key))
        return &(d->m_valueHash[key].m_comp.intValue);
    return 0;
cerf's avatar
cerf committed
288 289
}

hjk's avatar
hjk committed
290
bool *VcsBaseClientSettings::boolPointer(const QString &key)
cerf's avatar
cerf committed
291
{
292 293 294
    if (hasKey(key))
        return &(d->m_valueHash[key].m_comp.boolValue);
    return 0;
cerf's avatar
cerf committed
295 296
}

hjk's avatar
hjk committed
297
QString *VcsBaseClientSettings::stringPointer(const QString &key)
cerf's avatar
cerf committed
298
{
299
    if (hasKey(key) && valueType(key) == QVariant::String)
300 301
        return d->m_valueHash[key].m_comp.strPtr;
    return 0;
cerf's avatar
cerf committed
302 303
}

hjk's avatar
hjk committed
304
int VcsBaseClientSettings::intValue(const QString &key, int defaultValue) const
cerf's avatar
cerf committed
305
{
306
    if (hasKey(key) && valueType(key) == QVariant::Int)
307 308
        return d->m_valueHash[key].m_comp.intValue;
    return defaultValue;
cerf's avatar
cerf committed
309 310
}

hjk's avatar
hjk committed
311
bool VcsBaseClientSettings::boolValue(const QString &key, bool defaultValue) const
cerf's avatar
cerf committed
312
{
313
    if (hasKey(key) && valueType(key) == QVariant::Bool)
314 315
        return d->m_valueHash[key].m_comp.boolValue;
    return defaultValue;
cerf's avatar
cerf committed
316 317
}

hjk's avatar
hjk committed
318
QString VcsBaseClientSettings::stringValue(const QString &key, const QString &defaultValue) const
cerf's avatar
cerf committed
319
{
320 321 322
    if (hasKey(key))
        return d->m_valueHash[key].stringValue(defaultValue);
    return defaultValue;
cerf's avatar
cerf committed
323 324
}

hjk's avatar
hjk committed
325
QVariant VcsBaseClientSettings::value(const QString &key) const
cerf's avatar
cerf committed
326
{
327 328 329 330 331 332 333 334 335 336 337 338
    switch (valueType(key)) {
    case QVariant::Int:
        return intValue(key);
    case QVariant::Bool:
        return boolValue(key);
    case QVariant::String:
        return stringValue(key);
    case QVariant::Invalid:
        return QVariant();
    default:
        return QVariant();
    }
339 340
}

hjk's avatar
hjk committed
341
void VcsBaseClientSettings::setValue(const QString &key, const QVariant &v)
342
{
343
    if (SettingValue::isUsableVariantType(valueType(key))) {
344
        d->m_valueHash.insert(key, SettingValue(v));
345
        d->m_binaryFullPath.clear();
346
    }
347 348
}

hjk's avatar
hjk committed
349
QVariant::Type VcsBaseClientSettings::valueType(const QString &key) const
350
{
351 352 353
    if (hasKey(key))
        return d->m_valueHash[key].type();
    return QVariant::Invalid;
cerf's avatar
cerf committed
354 355
}

356 357
QString VcsBaseClientSettings::binaryPath() const
{
358 359 360
    if (d->m_binaryFullPath.isEmpty()) {
        d->m_binaryFullPath = Utils::Environment::systemEnvironment().searchInPath(
                    stringValue(binaryPathKey), stringValue(pathKey).split(
361
                        Utils::HostOsInfo::pathListSeparator()));
362
    }
363 364 365
    return d->m_binaryFullPath;
}

hjk's avatar
hjk committed
366
QString VcsBaseClientSettings::settingsGroup() const
cerf's avatar
cerf committed
367
{
368
    return d->m_settingsGroup;
cerf's avatar
cerf committed
369 370
}

hjk's avatar
hjk committed
371
void VcsBaseClientSettings::setSettingsGroup(const QString &group)
cerf's avatar
cerf committed
372
{
373
    d->m_settingsGroup = group;
cerf's avatar
cerf committed
374
}
375

hjk's avatar
hjk committed
376
void VcsBaseClientSettings::declareKey(const QString &key, const QVariant &defaultValue)
377
{
378 379 380 381
    if (SettingValue::isUsableVariantType(defaultValue.type())) {
        d->m_valueHash.insert(key, SettingValue(defaultValue));
        d->m_defaultValueHash.insert(key, defaultValue);
    }
382 383
}

hjk's avatar
hjk committed
384
QVariant VcsBaseClientSettings::keyDefaultValue(const QString &key) const
385
{
386 387 388
    if (d->m_defaultValueHash.contains(key))
        return d->m_defaultValueHash.value(key);
    return QVariant(valueType(key));
389
}
390

391 392 393 394 395
void VcsBaseClientSettings::readLegacySettings(const QSettings *settings)
{
    Q_UNUSED(settings);
}

hjk's avatar
hjk committed
396
} // namespace VcsBase