all repos — mgba @ f6755a6e1b7b0cf2b944cd8ca842746f11d6bf82

mGBA Game Boy Advance Emulator

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	if (file.isEmpty()) {
131		return;
132	}
133	m_logFile = std::make_unique<QFile>(file);
134	m_logFile->open(QIODevice::Append | QIODevice::Text);
135	m_logStream = std::make_unique<QTextStream>(m_logFile.get());
136}
137
138LogController* LogController::global() {
139	return &s_global;
140}
141
142QString LogController::toString(int level) {
143	switch (level) {
144	case mLOG_DEBUG:
145		return tr("DEBUG");
146	case mLOG_STUB:
147		return tr("STUB");
148	case mLOG_INFO:
149		return tr("INFO");
150	case mLOG_WARN:
151		return tr("WARN");
152	case mLOG_ERROR:
153		return tr("ERROR");
154	case mLOG_FATAL:
155		return tr("FATAL");
156	case mLOG_GAME_ERROR:
157		return tr("GAME ERROR");
158	}
159	return QString();
160}
161
162LogController::Stream::Stream(LogController* controller, int level, int category)
163	: m_level(level)
164	, m_category(category)
165	, m_log(controller)
166{
167}
168
169LogController::Stream::~Stream() {
170	m_log->postLog(m_level, m_category, m_queue.join(" "));
171}
172
173LogController::Stream& LogController::Stream::operator<<(const QString& string) {
174	m_queue.append(string);
175	return *this;
176}