src/platform/qt/LogController.cpp (view raw)
1/* Copyright (c) 2013-2015 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#include "LogController.h"
7
8#include <QMessageBox>
9
10#include "ConfigController.h"
11
12using namespace QGBA;
13
14LogController LogController::s_global(mLOG_ALL);
15int LogController::s_qtCat{-1};
16
17LogController::LogController(int levels, QObject* parent)
18 : QObject(parent)
19{
20 mLogFilterInit(&m_filter);
21 mLogFilterSet(&m_filter, "gba.bios", mLOG_STUB | mLOG_FATAL);
22 mLogFilterSet(&m_filter, "core.status", mLOG_ALL & ~mLOG_DEBUG);
23 m_filter.defaultLevels = levels;
24 s_qtCat = mLogCategoryById("platform.qt");
25
26 if (this != &s_global) {
27 connect(&s_global, &LogController::logPosted, this, &LogController::postLog);
28 connect(this, static_cast<void (LogController::*)(int)>(&LogController::levelsSet), &s_global, static_cast<void (LogController::*)(int)>(&LogController::setLevels));
29 connect(this, static_cast<void (LogController::*)(int)>(&LogController::levelsEnabled), &s_global, static_cast<void (LogController::*)(int)>(&LogController::enableLevels));
30 connect(this, static_cast<void (LogController::*)(int)>(&LogController::levelsDisabled), &s_global, static_cast<void (LogController::*)(int)>(&LogController::disableLevels));
31 }
32}
33
34LogController::~LogController() {
35 mLogFilterDeinit(&m_filter);
36}
37
38int LogController::levels(int category) const {
39 return mLogFilterLevels(&m_filter, category);
40}
41
42LogController::Stream LogController::operator()(int category, int level) {
43 return Stream(this, category, level);
44}
45
46void LogController::load(const ConfigController* config) {
47 mLogFilterLoad(&m_filter, config->config());
48 setLogFile(config->getOption("logFile"));
49 logToStdout(config->getOption("logToStdout").toInt());
50 logToFile(config->getOption("logToFile").toInt());
51}
52
53void LogController::save(ConfigController* config) const {
54 mLogFilterSave(&m_filter, config->config());
55}
56
57void LogController::postLog(int level, int category, const QString& string) {
58 if (!mLogFilterTest(&m_filter, category, static_cast<mLogLevel>(level))) {
59 return;
60 }
61 if (m_logToStdout || m_logToFile) {
62 QString line = tr("[%1] %2: %3").arg(LogController::toString(level)).arg(mLogCategoryName(category)).arg(string);
63
64 if (m_logToStdout) {
65 QTextStream out(stdout);
66 out << line << endl;
67 }
68 if (m_logToFile && m_logStream) {
69 *m_logStream << line << endl;
70 }
71 }
72 if (category == s_qtCat && level == mLOG_ERROR && this == &s_global) {
73 QMessageBox* dialog = new QMessageBox(QMessageBox::Critical, tr("An error occurred"), string, QMessageBox::Ok);
74 dialog->setAttribute(Qt::WA_DeleteOnClose);
75 dialog->show();
76 }
77 emit logPosted(level, category, string);
78}
79
80void LogController::setLevels(int levels) {
81 m_filter.defaultLevels = levels;
82 emit levelsSet(levels);
83}
84
85void LogController::enableLevels(int levels) {
86 m_filter.defaultLevels |= levels;
87 emit levelsEnabled(levels);
88}
89
90void LogController::disableLevels(int levels) {
91 m_filter.defaultLevels &= ~levels;
92 emit levelsDisabled(levels);
93}
94
95void LogController::setLevels(int levels, int category) {
96 auto id = mLogCategoryId(category);
97 mLogFilterSet(&m_filter, id, levels);
98 emit levelsSet(levels, category);
99}
100
101void LogController::enableLevels(int levels, int category) {
102 auto id = mLogCategoryId(category);
103 int newLevels = mLogFilterLevels(&m_filter, category) | levels;
104 mLogFilterSet(&m_filter, id, newLevels);
105 emit levelsEnabled(levels, category);
106}
107
108void LogController::disableLevels(int levels, int category) {
109 auto id = mLogCategoryId(category);
110 int newLevels = mLogFilterLevels(&m_filter, category) & ~levels;
111 mLogFilterSet(&m_filter, id, newLevels);
112 emit levelsDisabled(levels, category);
113}
114
115void LogController::clearLevels(int category) {
116 auto id = mLogCategoryId(category);
117 mLogFilterReset (&m_filter, id);
118}
119
120void LogController::logToFile(bool log) {
121 m_logToFile = log;
122}
123
124void LogController::logToStdout(bool log) {
125 m_logToStdout = log;
126}
127
128void LogController::setLogFile(const QString& file) {
129 m_logStream.reset();
130 m_logFile = std::make_unique<QFile>(file);
131 m_logFile->open(QIODevice::Append | QIODevice::Text);
132 m_logStream = std::make_unique<QTextStream>(m_logFile.get());
133}
134
135LogController* LogController::global() {
136 return &s_global;
137}
138
139QString LogController::toString(int level) {
140 switch (level) {
141 case mLOG_DEBUG:
142 return tr("DEBUG");
143 case mLOG_STUB:
144 return tr("STUB");
145 case mLOG_INFO:
146 return tr("INFO");
147 case mLOG_WARN:
148 return tr("WARN");
149 case mLOG_ERROR:
150 return tr("ERROR");
151 case mLOG_FATAL:
152 return tr("FATAL");
153 case mLOG_GAME_ERROR:
154 return tr("GAME ERROR");
155 }
156 return QString();
157}
158
159LogController::Stream::Stream(LogController* controller, int level, int category)
160 : m_level(level)
161 , m_category(category)
162 , m_log(controller)
163{
164}
165
166LogController::Stream::~Stream() {
167 m_log->postLog(m_level, m_category, m_queue.join(" "));
168}
169
170LogController::Stream& LogController::Stream::operator<<(const QString& string) {
171 m_queue.append(string);
172 return *this;
173}