aboutsummaryrefslogtreecommitdiff
path: root/src/core/ksharedconfig.cpp
blob: f4b4c766fe19fac92a0651ecc55a89ec3b7636b0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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
/*
  This file is part of the KDE libraries
  Copyright (c) 1999 Preston Brown <pbrown@kde.org>
  Copyright (C) 1997-1999 Matthias Kalle Dalheimer (kalle@kde.org)

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Library General Public
  License as published by the Free Software Foundation; either
  version 2 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Library General Public License for more details.

  You should have received a copy of the GNU Library General Public License
  along with this library; see the file COPYING.LIB.  If not, write to
  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  Boston, MA 02110-1301, USA.
*/

#include "ksharedconfig.h"
#include "kconfigbackend.h"
#include "kconfiggroup.h"
#include "kconfig_p.h"
#include <QCoreApplication>

void _k_globalMainConfigSync();

class GlobalSharedConfigList : public QList<KSharedConfig *>
{
public:
    GlobalSharedConfigList()
    {
        // We want to force the sync() before the QCoreApplication
        // instance is gone. Otherwise we trigger a QLockFile::lock()
        // after QCoreApplication is gone, calling qAppName() for a non
        // existent app...
        qAddPostRoutine(&_k_globalMainConfigSync);
    }

    // in addition to the list, we need to hold the main config,
    // so that it's not created and destroyed all the time.
    KSharedConfigPtr mainConfig;
};

Q_GLOBAL_STATIC(GlobalSharedConfigList, globalSharedConfigList)

void _k_globalMainConfigSync()
{
    if (globalSharedConfigList->mainConfig) {
        globalSharedConfigList->mainConfig->sync();
    }
}

KSharedConfigPtr KSharedConfig::openConfig(const QString &_fileName,
        OpenFlags flags,
        QStandardPaths::StandardLocation resType)
{
    QString fileName(_fileName);
    GlobalSharedConfigList *list = globalSharedConfigList();
    if (fileName.isEmpty() && !flags.testFlag(KConfig::SimpleConfig)) {
        // Determine the config file name that KConfig will make up (see KConfigPrivate::changeFileName)
        fileName = KConfig::mainConfigName();
    }

    static bool wasTestModeEnabled = false;
    if (!wasTestModeEnabled && QStandardPaths::isTestModeEnabled()) {
        wasTestModeEnabled = true;
        list->clear();
        list->mainConfig = Q_NULLPTR;
    }

    if (list) {
        foreach (auto cfg, *static_cast<const GlobalSharedConfigList*>(list)) {
            if (cfg->name() == fileName &&
                    cfg->d_ptr->openFlags == flags &&
                    cfg->locationType() == resType
//                    cfg->backend()->type() == backend
               ) {
                return KSharedConfigPtr(cfg);
            }
        }
    }
    KSharedConfigPtr ptr(new KSharedConfig(fileName, flags, resType));
    if (_fileName.isEmpty() && flags == FullConfig && resType == QStandardPaths::GenericConfigLocation) {
        list->mainConfig = ptr;

        static bool userWarned = false;
        if (!userWarned) {
            userWarned = true;
            QByteArray readOnly = qgetenv("KDE_HOME_READONLY");
            if (readOnly.isEmpty() && QCoreApplication::applicationName() != QLatin1String("kdialog")) {
                if (ptr->group("General").readEntry(QLatin1String("warn_unwritable_config"), true)) {
                    ptr->isConfigWritable(true);
                }
            }
        }
    }

    return ptr;
}

KSharedConfig::KSharedConfig(const QString &fileName,
                             OpenFlags flags,
                             QStandardPaths::StandardLocation resType)
    : KConfig(fileName, flags, resType)
{
    globalSharedConfigList()->append(this);
}

KSharedConfig::~KSharedConfig()
{
    if (!globalSharedConfigList.isDestroyed()) {
        globalSharedConfigList()->removeAll(this);
    }
}

KConfigGroup KSharedConfig::groupImpl(const QByteArray &groupName)
{
    KSharedConfigPtr ptr(this);
    return KConfigGroup(ptr, groupName.constData());
}

const KConfigGroup KSharedConfig::groupImpl(const QByteArray &groupName) const
{
    const KSharedConfigPtr ptr(const_cast<KSharedConfig *>(this));
    return KConfigGroup(ptr, groupName.constData());
}