kdebugsettingsdialog.cpp 10.3 KB
Newer Older
Laurent Montel's avatar
Laurent Montel committed
1
/*
Laurent Montel's avatar
Laurent Montel committed
2
  Copyright (c) 2015-2016 Montel Laurent <montel@kde.org>
Laurent Montel's avatar
Laurent Montel committed
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

  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.

*/

Yuri Chornoivan's avatar
Yuri Chornoivan committed
21
#include "kdebugsettingsdialog.h"
Laurent Montel's avatar
Laurent Montel committed
22
23
#include "customdebugsettingspage.h"
#include "kdeapplicationdebugsettingpage.h"
Laurent Montel's avatar
Laurent Montel committed
24
#include "environmentsettingsrulespage.h"
Laurent Montel's avatar
Laurent Montel committed
25
#include "kdebugsettingsutil.h"
Laurent Montel's avatar
Laurent Montel committed
26
#include "categorywarning.h"
Laurent Montel's avatar
Laurent Montel committed
27
#include "loadcategoriesjob.h"
Laurent Montel's avatar
Laurent Montel committed
28
29

#include <KLocalizedString>
Laurent Montel's avatar
Laurent Montel committed
30
31
#include <KConfigGroup>
#include <KSharedConfig>
32
#include <KMessageBox>
Laurent Montel's avatar
Laurent Montel committed
33

34
#include <QFileDialog>
Laurent Montel's avatar
Laurent Montel committed
35
#include <QDialogButtonBox>
Laurent Montel's avatar
Improve    
Laurent Montel committed
36
#include <QTabWidget>
Laurent Montel's avatar
Laurent Montel committed
37
#include <QVBoxLayout>
38
#include <QPushButton>
39
#include <QDir>
Laurent Montel's avatar
Laurent Montel committed
40
41
#include <QDesktopServices>
#include <QUrl>
Laurent Montel's avatar
Laurent Montel committed
42
#include <QTextStream>
43
#include "kdebugsettings_debug.h"
Laurent Montel's avatar
Laurent Montel committed
44
45
46
47

KDebugSettingsDialog::KDebugSettingsDialog(QWidget *parent)
    : QDialog(parent)
{
Laurent Montel's avatar
Improve    
Laurent Montel committed
48
49
50
    QVBoxLayout *mainLayout = new QVBoxLayout;
    setLayout(mainLayout);

Laurent Montel's avatar
Laurent Montel committed
51
52
53
54
    mCategoryWarning = new CategoryWarning(this);
    mCategoryWarning->setObjectName(QStringLiteral("categorywarning"));
    mainLayout->addWidget(mCategoryWarning);

Laurent Montel's avatar
Improve    
Laurent Montel committed
55
56
57
58
    mTabWidget = new QTabWidget;
    mTabWidget->setObjectName(QStringLiteral("tabwidget"));
    mainLayout->addWidget(mTabWidget);

Laurent Montel's avatar
Laurent Montel committed
59
    mKdeApplicationSettingsPage = new KDEApplicationDebugSettingPage(this);
Laurent Montel's avatar
Laurent Montel committed
60
61
62
    mKdeApplicationSettingsPage->setObjectName(QStringLiteral("kdeapplicationsettingspage"));
    mCustomSettingsPage = new CustomDebugSettingsPage(this);
    mCustomSettingsPage->setObjectName(QStringLiteral("customsettingspage"));
Laurent Montel's avatar
Laurent Montel committed
63
64
    mEnvironmentSettingsRulesPage = new EnvironmentSettingsRulesPage(this);
    mEnvironmentSettingsRulesPage->setObjectName(QStringLiteral("environmentsettingsrulespage"));
Laurent Montel's avatar
Laurent Montel committed
65
    mTabWidget->addTab(mKdeApplicationSettingsPage, i18n("KDE Application"));
66
    mTabWidget->addTab(mCustomSettingsPage, i18n("Custom Rules"));
Laurent Montel's avatar
Laurent Montel committed
67
    mTabWidget->addTab(mEnvironmentSettingsRulesPage, i18n("Rules Settings With Environment Variable"));
Laurent Montel's avatar
Laurent Montel committed
68

69
    QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Help | QDialogButtonBox::Apply);
Laurent Montel's avatar
Improve    
Laurent Montel committed
70
    buttonBox->setObjectName(QStringLiteral("buttonbox"));
Laurent Montel's avatar
Laurent Montel committed
71

72
73
74
75
    QPushButton *saveAs = new QPushButton(i18n("Save As..."), this);
    saveAs->setObjectName(QStringLiteral("saveas_button"));
    buttonBox->addButton(saveAs, QDialogButtonBox::ActionRole);
    connect(saveAs, &QPushButton::clicked, this, &KDebugSettingsDialog::slotSaveAs);
Laurent Montel's avatar
Laurent Montel committed
76
77
78
79
80
81

    QPushButton *load = new QPushButton(i18n("Load..."), this);
    load->setObjectName(QStringLiteral("load_button"));
    buttonBox->addButton(load, QDialogButtonBox::ActionRole);
    connect(load, &QPushButton::clicked, this, &KDebugSettingsDialog::slotLoad);

82
83
84
85
86
    QPushButton *insertCategories = new QPushButton(i18n("Insert..."), this);
    insertCategories->setObjectName(QStringLiteral("insert_button"));
    buttonBox->addButton(insertCategories, QDialogButtonBox::ActionRole);
    connect(insertCategories, &QPushButton::clicked, this, &KDebugSettingsDialog::slotInsertCategories);

Laurent Montel's avatar
Laurent Montel committed
87
    connect(buttonBox, &QDialogButtonBox::accepted, this, &KDebugSettingsDialog::slotAccepted);
Laurent Montel's avatar
Improve    
Laurent Montel committed
88
    connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
Laurent Montel's avatar
Laurent Montel committed
89
    connect(buttonBox, &QDialogButtonBox::helpRequested, this, &KDebugSettingsDialog::slotHelpRequested);
90
    connect(buttonBox->button(QDialogButtonBox::Apply), &QPushButton::clicked, this, &KDebugSettingsDialog::slotApply);
Laurent Montel's avatar
Improve    
Laurent Montel committed
91
    mainLayout->addWidget(buttonBox);
Laurent Montel's avatar
Laurent Montel committed
92
    readConfig();
Laurent Montel's avatar
Laurent Montel committed
93
    readQtLoggingFile();
Laurent Montel's avatar
Laurent Montel committed
94
95
96
97
}

KDebugSettingsDialog::~KDebugSettingsDialog()
{
Laurent Montel's avatar
Laurent Montel committed
98
99
100
101
102
103
104
105
106
107
    saveConfig();
}

void KDebugSettingsDialog::readConfig()
{
    KConfigGroup group(KSharedConfig::openConfig(), "KDebugSettingsDialog");
    const QSize size = group.readEntry("Size", QSize(600, 400));
    if (size.isValid()) {
        resize(size);
    }
Laurent Montel's avatar
Laurent Montel committed
108
109
}

Laurent Montel's avatar
Laurent Montel committed
110
111
112
113
114
115
void KDebugSettingsDialog::saveConfig()
{
    KConfigGroup group(KSharedConfig::openConfig(), "KDebugSettingsDialog");
    group.writeEntry("Size", size());
    group.sync();
}
Laurent Montel's avatar
Laurent Montel committed
116

Laurent Montel's avatar
Laurent Montel committed
117
118
119
120
121
122
123
void KDebugSettingsDialog::readQtLoggingFile()
{
    const QString envPath = QStandardPaths::locate(QStandardPaths::GenericConfigLocation, QStringLiteral("QtProject/qtlogging.ini"));
    readCategoriesFiles(envPath);
}

void KDebugSettingsDialog::readCategoriesFiles(const QString &path)
Laurent Montel's avatar
Laurent Montel committed
124
{
Laurent Montel's avatar
Laurent Montel committed
125
    // KDE debug categories area
126
    const QString confAreasFile = QStandardPaths::locate(QStandardPaths::ConfigLocation, QStringLiteral("kde.categories"));
Laurent Montel's avatar
Laurent Montel committed
127
    KDebugSettingsUtil::readLoggingCategories(confAreasFile, mCategoriesList, false);
Laurent Montel's avatar
Laurent Montel committed
128

Laurent Montel's avatar
Laurent Montel committed
129
    // Load *.renamecategories file in QStandardPaths::ConfigLocation for kde apps.
130
    QStringList dirs = QStandardPaths::locateAll(QStandardPaths::ConfigLocation, QString(), QStandardPaths::LocateDirectory);
Laurent Montel's avatar
Laurent Montel committed
131
132
133
134
135
136
137
138
139
140
141
    Q_FOREACH (const QString &dir, dirs) {
        const QStringList fileNames = QDir(dir).entryList(QStringList() << QStringLiteral("*.renamecategories"));
        Q_FOREACH (const QString &file, fileNames) {
            if (file != QStringLiteral("kde.categories")) {
                mRenameCategoriesList.append(KDebugSettingsUtil::readRenameCategories(dir + file));
            }
        }
    }

    // Load *.categories file in QStandardPaths::ConfigLocation for kde apps.
    dirs = QStandardPaths::locateAll(QStandardPaths::ConfigLocation, QString(), QStandardPaths::LocateDirectory);
142
143
144
    Q_FOREACH (const QString &dir, dirs) {
        const QStringList fileNames = QDir(dir).entryList(QStringList() << QStringLiteral("*.categories"));
        Q_FOREACH (const QString &file, fileNames) {
145
            if (file != QStringLiteral("kde.categories")) {
Laurent Montel's avatar
Laurent Montel committed
146
                KDebugSettingsUtil::readLoggingCategories(dir + file, mCategoriesList, true);
147
            }
148
        }
149
    }
150

151
152
153
154
155
    // Load *.categories files. in qdebug.categories for external kde apps.
    dirs = QStandardPaths::locateAll(QStandardPaths::GenericConfigLocation, QStringLiteral("qdebug.categories/"), QStandardPaths::LocateDirectory);
    Q_FOREACH (const QString &dir, dirs) {
        const QStringList fileNames = QDir(dir).entryList(QStringList() << QStringLiteral("*.categories"));
        Q_FOREACH (const QString &file, fileNames) {
Laurent Montel's avatar
Laurent Montel committed
156
            KDebugSettingsUtil::readLoggingCategories(dir + QLatin1Char('/') + file, mCategoriesList, true);
157
        }
158
    }
Laurent Montel's avatar
Laurent Montel committed
159
160
161

    //TODO add load rename file from external kde apps.

162
163
    const QByteArray rulesFilePath = qgetenv("QT_LOGGING_CONF");
    if (!rulesFilePath.isEmpty()) {
Laurent Montel's avatar
Laurent Montel committed
164
        const QList<KDebugSettingsUtil::LoadLoggingCategory> envCategories = KDebugSettingsUtil::readLoggingQtCategories(QString::fromLatin1(rulesFilePath));
165
166
167
        //TODO
    }

Laurent Montel's avatar
Laurent Montel committed
168
169
170
171
    const QString environmentrules = QString::fromLatin1(qgetenv("QT_LOGGING_RULES"));
    if (!environmentrules.isEmpty()) {
        mEnvironmentSettingsRulesPage->setRules(environmentrules);
    }
Laurent Montel's avatar
Laurent Montel committed
172
    // qt logging.ini
Laurent Montel's avatar
Laurent Montel committed
173
174
    LoadCategoriesJob job;
    job.setFileName(path);
Laurent Montel's avatar
Laurent Montel committed
175
    job.setCategories(mCategoriesList);
Laurent Montel's avatar
Laurent Montel committed
176
177
178
179
180
    job.start();

    const LoggingCategory::List customCategories = job.customCategories();
    const LoggingCategory::List qtKdeCategories = job.qtKdeCategories();
    const bool foundOverrideRule = job.foundOverrideRule();
181

Laurent Montel's avatar
Laurent Montel committed
182
    mKdeApplicationSettingsPage->fillList(qtKdeCategories);
Laurent Montel's avatar
Laurent Montel committed
183
    mCustomSettingsPage->fillList(customCategories);
Laurent Montel's avatar
Laurent Montel committed
184
185
186
    if (foundOverrideRule) {
        mCategoryWarning->animatedShow();
    }
Laurent Montel's avatar
Laurent Montel committed
187
}
Laurent Montel's avatar
Laurent Montel committed
188

189
bool KDebugSettingsDialog::saveRules(const QString &path)
Laurent Montel's avatar
Laurent Montel committed
190
{
191
192
    QFile qtlogging(path);
    if (!qtlogging.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) {
Yuri Chornoivan's avatar
Yuri Chornoivan committed
193
        KMessageBox::error(this, i18n("\'%1\' cannot be opened. Please verify it.", path));
194
195
        return false;
    }
Laurent Montel's avatar
Laurent Montel committed
196
    //Save Rules
Laurent Montel's avatar
Laurent Montel committed
197
198
    const LoggingCategory::List lstKde = mKdeApplicationSettingsPage->rules();
    const LoggingCategory::List lstCustom = mCustomSettingsPage->rules();
199
200
    QTextStream out(&qtlogging);
    out << QLatin1String("[Rules]\n");
Laurent Montel's avatar
Laurent Montel committed
201
    Q_FOREACH (LoggingCategory cat, lstKde) {
202
203
        out << cat.createRule() + QLatin1Char('\n');
    }
Laurent Montel's avatar
Laurent Montel committed
204
    Q_FOREACH (LoggingCategory cat, lstCustom) {
Laurent Montel's avatar
Laurent Montel committed
205
        out << cat.createCustomRule() + QLatin1Char('\n');
Laurent Montel's avatar
Laurent Montel committed
206
    }
207
208
209
210
211
    return true;
}

bool KDebugSettingsDialog::saveInQtLogging()
{
Laurent Montel's avatar
Laurent Montel committed
212
213
214
    const QString envPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QLatin1String("/QtProject");
    QDir().mkpath(envPath);
    return saveRules(envPath + QStringLiteral("/qtlogging.ini"));
215
216
217
218
}

void KDebugSettingsDialog::slotAccepted()
{
219
220
221
    if (saveInQtLogging()) {
        accept();
    }
Laurent Montel's avatar
Laurent Montel committed
222
}
Laurent Montel's avatar
Laurent Montel committed
223
224
225
226
227

void KDebugSettingsDialog::slotHelpRequested()
{
    QDesktopServices::openUrl(QUrl(QStringLiteral("http://doc.qt.io/qt-5/qloggingcategory.html#details")));
}
228

229
230
void KDebugSettingsDialog::slotApply()
{
231
    saveInQtLogging();
232
}
233

234
235
236
237
void KDebugSettingsDialog::slotInsertCategories()
{
    const QString path = QFileDialog::getOpenFileName(this, i18n("Insert Categories"));
    if (!path.isEmpty()) {
Laurent Montel's avatar
Laurent Montel committed
238
        const KdeLoggingCategory::List insertCategoriesList = KDebugSettingsUtil::readLoggingCategoriesForInserting(path, mCategoriesList);
Laurent Montel's avatar
Laurent Montel committed
239
        LoggingCategory::List newCategories;
Laurent Montel's avatar
Laurent Montel committed
240
        Q_FOREACH (const KdeLoggingCategory &cat, insertCategoriesList) {
Laurent Montel's avatar
Laurent Montel committed
241
242
243
244
245
246
247
248
            LoggingCategory loggingCat;
            loggingCat.description = cat.description;
            loggingCat.logName = cat.logName;
            if (loggingCat.isValid()) {
                newCategories.append(loggingCat);
            }
        }
        mKdeApplicationSettingsPage->insertCategories(newCategories);
249
250
251
    }
}

252
253
254
255
256
257
258
void KDebugSettingsDialog::slotSaveAs()
{
    const QString path = QFileDialog::getSaveFileName(this, i18n("Save As"));
    if (!path.isEmpty()) {
        saveRules(path);
    }
}
Laurent Montel's avatar
Laurent Montel committed
259
260
261

void KDebugSettingsDialog::slotLoad()
{
Laurent Montel's avatar
Laurent Montel committed
262
    const QString path = QFileDialog::getOpenFileName(this, i18n("Load Debug Settings Files"));
Laurent Montel's avatar
Laurent Montel committed
263
264
265
266
    if (!path.isEmpty()) {
        readCategoriesFiles(path);
    }
}