all repos — mgba @ 1093849ad5f6103d8eb1817e9b913255a3218eb9

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	if (!levels(mLogCategoryById("gba.bios"))) {
 49		mLogFilterSet(&m_filter, "gba.bios", mLOG_STUB | mLOG_FATAL);
 50	}
 51	if (!levels(mLogCategoryById("core.status"))) {
 52		mLogFilterSet(&m_filter, "core.status", mLOG_ALL & ~mLOG_DEBUG);
 53	}
 54	setLogFile(config->getOption("logFile"));
 55	logToStdout(config->getOption("logToStdout").toInt());
 56	logToFile(config->getOption("logToFile").toInt());
 57}
 58
 59void LogController::save(ConfigController* config) const {
 60	mLogFilterSave(&m_filter, config->config());
 61}
 62
 63void LogController::postLog(int level, int category, const QString& string) {
 64	if (!mLogFilterTest(&m_filter, category, static_cast<mLogLevel>(level))) {
 65		return;
 66	}
 67	if (m_logToStdout || m_logToFile) {
 68		QString line = tr("[%1] %2: %3").arg(LogController::toString(level)).arg(mLogCategoryName(category)).arg(string);
 69
 70		if (m_logToStdout) {
 71			QTextStream out(stdout);
 72			out << line << endl;
 73		}
 74		if (m_logToFile && m_logStream) {
 75			*m_logStream << line << endl;
 76		}
 77	}
 78	if (category == s_qtCat && level == mLOG_ERROR && this == &s_global) {
 79		QMessageBox* dialog = new QMessageBox(QMessageBox::Critical, tr("An error occurred"), string, QMessageBox::Ok);
 80		dialog->setAttribute(Qt::WA_DeleteOnClose);
 81		dialog->show();
 82	}
 83	emit logPosted(level, category, string);
 84}
 85
 86void LogController::setLevels(int levels) {
 87	m_filter.defaultLevels = levels;
 88	emit levelsSet(levels);
 89}
 90
 91void LogController::enableLevels(int levels) {
 92	m_filter.defaultLevels |= levels;
 93	emit levelsEnabled(levels);
 94}
 95
 96void LogController::disableLevels(int levels) {
 97	m_filter.defaultLevels &= ~levels;
 98	emit levelsDisabled(levels);
 99}
100
101void LogController::setLevels(int levels, int category) {
102	auto id = mLogCategoryId(category);
103	mLogFilterSet(&m_filter, id, levels);
104	emit levelsSet(levels, category);
105}
106
107void LogController::enableLevels(int levels, int category) {
108	auto id = mLogCategoryId(category);
109	int newLevels = mLogFilterLevels(&m_filter, category) | levels;
110	mLogFilterSet(&m_filter, id, newLevels);
111	emit levelsEnabled(levels, category);
112}
113
114void LogController::disableLevels(int levels, int category) {
115	auto id = mLogCategoryId(category);
116	int newLevels = mLogFilterLevels(&m_filter, category) & ~levels;
117	mLogFilterSet(&m_filter, id, newLevels);
118	emit levelsDisabled(levels, category);
119}
120
121void LogController::clearLevels(int category) {
122	auto id = mLogCategoryId(category);
123	mLogFilterReset(&m_filter, id);
124}
125
126void LogController::logToFile(bool log) {
127	m_logToFile = log;
128}
129
130void LogController::logToStdout(bool log) {
131	m_logToStdout = log;
132}
133
134void LogController::setLogFile(const QString& file) {
135	m_logStream.reset();
136	if (file.isEmpty()) {
137		return;
138	}
139	m_logFile = std::make_unique<QFile>(file);
140	m_logFile->open(QIODevice::Append | QIODevice::Text);
141	m_logStream = std::make_unique<QTextStream>(m_logFile.get());
142}
143
144LogController* LogController::global() {
145	return &s_global;
146}
147
148QString LogController::toString(int level) {
149	switch (level) {
150	case mLOG_DEBUG:
151		return tr("DEBUG");
152	case mLOG_STUB:
153		return tr("STUB");
154	case mLOG_INFO:
155		return tr("INFO");
156	case mLOG_WARN:
157		return tr("WARN");
158	case mLOG_ERROR:
159		return tr("ERROR");
160	case mLOG_FATAL:
161		return tr("FATAL");
162	case mLOG_GAME_ERROR:
163		return tr("GAME ERROR");
164	}
165	return QString();
166}
167
168LogController::Stream::Stream(LogController* controller, int level, int category)
169	: m_level(level)
170	, m_category(category)
171	, m_log(controller)
172{
173}
174
175LogController::Stream::~Stream() {
176	m_log->postLog(m_level, m_category, m_queue.join(" "));
177}
178
179LogController::Stream& LogController::Stream::operator<<(const QString& string) {
180	m_queue.append(string);
181	return *this;
182}