Krita Source Code Documentation
Loading...
Searching...
No Matches
LogDockerDock.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2018 Boudewijn Rempt <boud@valdyas.org>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7
8#include "LogDockerDock.h"
9
10#include <QHBoxLayout>
11#include <QScrollBar>
12#include <QStandardPaths>
13#include <QDateTime>
14#include <QCheckBox>
15
16#include <klocalizedstring.h>
17#include <ksharedconfig.h>
18#include <kconfiggroup.h>
19
20#include <KisPart.h>
21#include <KoDialog.h>
22#include <KoCanvasBase.h>
23#include <KoIcon.h>
24#include <KoFileDialog.h>
25
26#include "kis_canvas2.h"
27#include "KisViewManager.h"
28#include "KisMainWindow.h"
29#include "kis_config.h"
30
32QTextCharFormat LogDockerDock::s_debug;
33QTextCharFormat LogDockerDock::s_info;
34QTextCharFormat LogDockerDock::s_warning;
35QTextCharFormat LogDockerDock::s_critical;
36QTextCharFormat LogDockerDock::s_fatal;
37
38static QtMessageHandler s_originalMessageHandler{nullptr};
39
41 : QDockWidget(i18n("Log Viewer"))
42{
43 QWidget *page = new QWidget(this);
44 setupUi(page);
45 setWidget(page);
46
47 bnToggle->setIcon(koIcon("view-list-text-16"));
48 connect(bnToggle, SIGNAL(clicked(bool)), SLOT(toggleLogging(bool)));
49 bnToggle->setChecked(KisConfig(true).readEntry<bool>("logviewer_enabled", false));
50 toggleLogging(KisConfig(true).readEntry<bool>("logviewer_enabled", false));
51
52 bnClear->setIcon(koIcon("edit-clear-16"));
53 connect(bnClear, SIGNAL(clicked(bool)), SLOT(clearLog()));
54
55 bnSave->setIcon(koIcon("document-save-16"));
56 connect(bnSave, SIGNAL(clicked(bool)), SLOT(saveLog()));
57
58 bnSettings->setIcon(koIcon("configure-thicker"));
59 connect(bnSettings, SIGNAL(clicked(bool)), SLOT(settings()));
60
61 qRegisterMetaType<QtMsgType>("QtMsgType");
62 connect(s_messageSender, SIGNAL(emitMessage(QtMsgType,QString)), this, SLOT(insertMessage(QtMsgType,QString)), Qt::AutoConnection);
63
65}
66
68{
69 setEnabled(true);
70}
71
73{
74 connect(kisview->mainWindow(), SIGNAL(themeChanged()), SLOT(changeTheme()));
75}
76
78{
79 KisConfig(false).writeEntry<bool>("logviewer_enabled", toggle);
80 if (toggle) {
81 const QtMessageHandler oldHandler = qInstallMessageHandler(messageHandler);
83 s_originalMessageHandler = oldHandler;
84 }
86 }
87 else {
88 qInstallMessageHandler(nullptr);
89 QLoggingCategory::setFilterRules(QString());
90 }
91
92}
93
95{
96 txtLogViewer->document()->clear();
97}
98
100{
101 KoFileDialog fileDialog(this, KoFileDialog::SaveFile, "logfile");
102 fileDialog.setDefaultDir(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation) + "/" + QString("krita_%1.log").arg(QDateTime::currentDateTime().toString("yyyy-MM-ddThh")));
103 QString filename = fileDialog.filename();
104 if (!filename.isEmpty()) {
105 QFile f(filename);
106 f.open(QFile::WriteOnly);
107 f.write(txtLogViewer->document()->toPlainText().toUtf8());
108 f.close();
109 }
110}
111
113{
114 KoDialog dlg(this);
116 dlg.setCaption(i18n("Log Settings"));
117 QWidget *page = new QWidget(&dlg);
118 dlg.setMainWidget(page);
119 QVBoxLayout *layout = new QVBoxLayout(page);
120
121 KConfigGroup cfg( KSharedConfig::openConfig(), "LogDocker");
122
123 QCheckBox *chkKrita = new QCheckBox(i18n("General"), page);
124 chkKrita->setChecked(cfg.readEntry("krita_41000", false));
125 layout->addWidget(chkKrita);
126
127 QCheckBox *chkResources = new QCheckBox(i18n("Resource Management"), page);
128 chkResources->setChecked(cfg.readEntry("resources_30009", false));
129 layout->addWidget(chkResources);
130
131 QCheckBox *chkImage = new QCheckBox(i18n("Image Core"), page);
132 chkImage->setChecked(cfg.readEntry("image_41001", false));
133 layout->addWidget(chkImage);
134
135 QCheckBox *chkRegistry = new QCheckBox(i18n("Registries"), page);
136 chkRegistry->setChecked(cfg.readEntry("registry_41002", false));
137 layout->addWidget(chkRegistry);
138
139 QCheckBox *chkTools = new QCheckBox(i18n("Tools"), page);
140 chkTools->setChecked(cfg.readEntry("tools_41003", false));
141 layout->addWidget(chkTools);
142
143 QCheckBox *chkTiles = new QCheckBox(i18n("Tile Engine"), page);
144 chkTiles->setChecked(cfg.readEntry("tiles_41004", false));
145 layout->addWidget(chkTiles);
146
147 QCheckBox *chkFilters = new QCheckBox(i18nc("Filter as an effect", "Filters"), page);
148 chkFilters->setChecked(cfg.readEntry("filters_41005", false));
149 layout->addWidget(chkFilters);
150
151 QCheckBox *chkPlugins = new QCheckBox(i18n("Plugin Management"), page);
152 chkPlugins->setChecked(cfg.readEntry("plugins_41006", false));
153 layout->addWidget(chkPlugins);
154
155 QCheckBox *chkUi = new QCheckBox(i18n("User Interface"), page);
156 chkUi->setChecked(cfg.readEntry("ui_41007", false));
157 layout->addWidget(chkUi);
158
159 QCheckBox *chkFile = new QCheckBox(i18n("File loading and saving"), page);
160 chkFile->setChecked(cfg.readEntry("file_41008", false));
161 layout->addWidget(chkFile);
162
163 QCheckBox *chkMath = new QCheckBox(i18n("Mathematics and calculations"), page);
164 chkMath->setChecked(cfg.readEntry("math_41009", false));
165 layout->addWidget(chkMath);
166
167 QCheckBox *chkRender = new QCheckBox(i18n("Image Rendering"), page);
168 chkRender->setChecked(cfg.readEntry("render_41010", false));
169 layout->addWidget(chkRender);
170
171 QCheckBox *chkScript = new QCheckBox(i18n("Scripting"), page);
172 chkScript->setChecked(cfg.readEntry("script_41011", false));
173 layout->addWidget(chkScript);
174
175 QCheckBox *chkInput = new QCheckBox(i18n("Input handling"), page);
176 chkInput->setChecked(cfg.readEntry("input_41012", false));
177 layout->addWidget(chkInput);
178
179 QCheckBox *chkAction = new QCheckBox(i18n("Actions"), page);
180 chkAction->setChecked(cfg.readEntry("action_41013", false));
181 layout->addWidget(chkAction);
182
183 QCheckBox *chkTablet = new QCheckBox(i18n("Tablet Handling"), page);
184 chkTablet->setChecked(cfg.readEntry("tablet_41014", false));
185 layout->addWidget(chkTablet);
186
187 QCheckBox *chkOpenGL = new QCheckBox(i18n("GPU Canvas"), page);
188 chkOpenGL->setChecked(cfg.readEntry("opengl_41015", false));
189 layout->addWidget(chkOpenGL);
190
191 QCheckBox *chkMetaData = new QCheckBox(i18n("Metadata"), page);
192 chkMetaData->setChecked(cfg.readEntry("metadata_41016", false));
193 layout->addWidget(chkMetaData);
194
195 QCheckBox *chkPigment = new QCheckBox(i18n("Color Management"), page);
196 chkPigment->setChecked(cfg.readEntry("pigment", false));
197 layout->addWidget(chkPigment);
198
199
200 if (dlg.exec()) {
201 // Apply the new settings
202 cfg.writeEntry("resources_30009", chkResources->isChecked());
203 cfg.writeEntry("krita_41000", chkKrita->isChecked());
204 cfg.writeEntry("image_41001", chkImage->isChecked());
205 cfg.writeEntry("registry_41002", chkRegistry->isChecked());
206 cfg.writeEntry("tools_41003", chkTools->isChecked());
207 cfg.writeEntry("tiles_41004", chkTiles->isChecked());
208 cfg.writeEntry("filters_41005", chkFilters->isChecked());
209 cfg.writeEntry("plugins_41006", chkPlugins->isChecked());
210 cfg.writeEntry("ui_41007", chkUi->isChecked());
211 cfg.writeEntry("file_41008", chkFile->isChecked());
212 cfg.writeEntry("math_41009", chkMath->isChecked());
213 cfg.writeEntry("render_41010", chkRender->isChecked());
214 cfg.writeEntry("script_41011", chkScript->isChecked());
215 cfg.writeEntry("input_41012", chkInput->isChecked());
216 cfg.writeEntry("action_41013", chkAction->isChecked());
217 cfg.writeEntry("tablet_41014", chkTablet->isChecked());
218 cfg.writeEntry("opengl_41015", chkOpenGL->isChecked());
219 cfg.writeEntry("metadata_41016", chkMetaData->isChecked());
220 cfg.writeEntry("pigment", chkPigment->isChecked());
221
222 if (bnToggle->isChecked()) {
224 }
225 }
226
227}
228
229QString cfgToString(const char *category, bool cfg)
230{
231 if (cfg) {
232 return QStringLiteral("%0=true").arg(QLatin1String(category));
233 }
234 return QStringLiteral("%0.debug=false").arg(QLatin1String(category));
235}
236
238{
239 QStringList filters;
240 KConfigGroup cfg( KSharedConfig::openConfig(), "LogDocker");
241
242 filters << cfgToString("krita.general", cfg.readEntry("krita_41000", false));
243 filters << cfgToString("krita.lib.resources", cfg.readEntry("resources_30009", false));
244 filters << cfgToString("krita.core", cfg.readEntry("image_41001", false));
245 filters << cfgToString("krita.registry", cfg.readEntry("registry_41002", false));
246
247 filters << cfgToString("krita.tools", cfg.readEntry("tools_41003", false));
248 filters << cfgToString("krita.lib.flake", cfg.readEntry("tools_41003", false));
249
250 filters << cfgToString("krita.tiles", cfg.readEntry("tiles_41004", false));
251 filters << cfgToString("krita.filters", cfg.readEntry("filters_41005", false));
252
253 filters << cfgToString("krita.plugins", cfg.readEntry("plugins_41006", false));
254 filters << cfgToString("krita.lib.plugin", cfg.readEntry("plugins_41006", false));
255
256 filters << cfgToString("krita.ui", cfg.readEntry("ui_41007", false));
257 filters << cfgToString("krita.widgets", cfg.readEntry("ui_41007", false));
258 filters << cfgToString("krita.widgetutils", cfg.readEntry("ui_41007", false));
259
260 filters << cfgToString("krita.file", cfg.readEntry("file_41008", false));
261 filters << cfgToString("krita.lib.store", cfg.readEntry("file_41008", false));
262 filters << cfgToString("krita.lib.odf", cfg.readEntry("file_41008", false));
263
264 filters << cfgToString("krita.math", cfg.readEntry("math_41009", false));
265 filters << cfgToString("krita.grender", cfg.readEntry("render_41010", false));
266 filters << cfgToString("krita.scripting", cfg.readEntry("script_41011", false));
267 filters << cfgToString("krita.input", cfg.readEntry("input_41012", false));
268 filters << cfgToString("krita.action", cfg.readEntry("action_41013", false));
269 filters << cfgToString("krita.tablet", cfg.readEntry("tablet_41014", false));
270 filters << cfgToString("krita.opengl", cfg.readEntry("opengl_41015", false));
271 filters << cfgToString("krita.metadata", cfg.readEntry("metadata_41016", false));
272
273 filters << cfgToString("krita.lib.pigment", cfg.readEntry("pigment", false));
274
275 QLoggingCategory::setFilterRules(filters.join("\n"));
276}
277
278void LogDockerDock::messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
279{
280 s_messageSender->sendMessage(type, msg);
282 s_originalMessageHandler(type, context, msg);
283 }
284}
285
286void LogDockerDock::insertMessage(QtMsgType type, const QString &msg)
287{
288 QTextDocument *doc = txtLogViewer->document();
289 QTextCursor cursor(doc);
290 cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
291 cursor.beginEditBlock();
292
293 switch (type) {
294 case QtDebugMsg:
295 cursor.insertText(msg + "\n", s_debug);
296 break;
297 case QtInfoMsg:
298 cursor.insertText(msg + "\n", s_info);
299 break;
300 case QtWarningMsg:
301 cursor.insertText(msg + "\n", s_warning);
302 break;
303 case QtCriticalMsg:
304 cursor.insertText(msg + "\n", s_critical);
305 break;
306 case QtFatalMsg:
307 cursor.insertText(msg + "\n", s_fatal);
308 break;
309 }
310
311 cursor.endEditBlock();
312 txtLogViewer->verticalScrollBar()->setValue(txtLogViewer->verticalScrollBar()->maximum());
313}
314
316{
317 clearLog();
318 QColor background = qApp->palette().window().color();
319 if (background.value() > 100) {
320 s_debug.setForeground(Qt::black);
321 s_info.setForeground(Qt::darkGreen);
322 s_warning.setForeground(Qt::darkYellow);
323 s_critical.setForeground(Qt::darkRed);
324 s_fatal.setForeground(Qt::darkRed);
325 }
326 else {
327 s_debug.setForeground(Qt::white);
328 s_info.setForeground(Qt::green);
329 s_warning.setForeground(Qt::yellow);
330 s_critical.setForeground(Qt::red);
331 s_fatal.setForeground(Qt::red);
332 }
333 s_fatal.setFontWeight(QFont::Bold);
334}
335
336void MessageSender::sendMessage(QtMsgType type, const QString &msg)
337{
338 Q_EMIT emitMessage(type, msg);
339}
QString cfgToString(const char *category, bool cfg)
static QtMessageHandler s_originalMessageHandler
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
void writeEntry(const QString &name, const T &value)
Definition kis_config.h:779
KisMainWindow * mainWindow() const
A dialog base class with standard buttons and predefined layouts.
Definition KoDialog.h:116
void setMainWidget(QWidget *widget)
Definition KoDialog.cpp:354
virtual void setCaption(const QString &caption)
Definition KoDialog.cpp:498
void setButtons(ButtonCodes buttonMask)
Definition KoDialog.cpp:195
@ Ok
Show Ok button. (this button accept()s the dialog; result set to QDialog::Accepted)
Definition KoDialog.h:127
@ Cancel
Show Cancel-button. (this button reject()s the dialog; result set to QDialog::Rejected)
Definition KoDialog.h:130
QString filename()
Get the file name the user selected in the file dialog.
void setDefaultDir(const QString &defaultDir, bool force=false)
setDefaultDir set the default directory to defaultDir.
static QTextCharFormat s_critical
void setCanvas(KoCanvasBase *canvas) override
void setViewManager(KisViewManager *kisview) override
void insertMessage(QtMsgType type, const QString &msg)
static QTextCharFormat s_info
static void messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
static QTextCharFormat s_debug
static QTextCharFormat s_warning
void toggleLogging(bool toggle)
static QTextCharFormat s_fatal
static MessageSender * s_messageSender
void emitMessage(QtMsgType type, const QString &msg)
void sendMessage(QtMsgType type, const QString &msg)
#define koIcon(name)
Use these macros for icons without any issues.
Definition kis_icon.h:25