src/platform/qt/LogView.cpp (view raw)
1/* Copyright (c) 2013-2014 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 "LogView.h"
7
8#include "LogController.h"
9
10#include <QTextBlock>
11#include <QTextCursor>
12
13using namespace QGBA;
14
15LogView::LogView(LogController* log, QWidget* parent)
16 : QWidget(parent)
17 , m_lines(0)
18 , m_lineLimit(DEFAULT_LINE_LIMIT)
19{
20 m_ui.setupUi(this);
21 connect(m_ui.levelDebug, &QAbstractButton::toggled, [this](bool set) {
22 setLevel(GBA_LOG_DEBUG, set);
23 });
24 connect(m_ui.levelStub, &QAbstractButton::toggled, [this](bool set) {
25 setLevel(GBA_LOG_STUB, set);
26 });
27 connect(m_ui.levelInfo, &QAbstractButton::toggled, [this](bool set) {
28 setLevel(GBA_LOG_INFO, set);
29 });
30 connect(m_ui.levelWarn, &QAbstractButton::toggled, [this](bool set) {
31 setLevel(GBA_LOG_WARN, set);
32 });
33 connect(m_ui.levelError, &QAbstractButton::toggled, [this](bool set) {
34 setLevel(GBA_LOG_ERROR, set);
35 });
36 connect(m_ui.levelFatal, &QAbstractButton::toggled, [this](bool set) {
37 setLevel(GBA_LOG_FATAL, set);
38 });
39 connect(m_ui.levelGameError, &QAbstractButton::toggled, [this](bool set) {
40 setLevel(GBA_LOG_GAME_ERROR, set);
41 });
42 connect(m_ui.levelSWI, &QAbstractButton::toggled, [this](bool set) {
43 setLevel(GBA_LOG_SWI, set);
44 });
45 connect(m_ui.levelStatus, &QAbstractButton::toggled, [this](bool set) {
46 setLevel(GBA_LOG_STATUS, set);
47 });
48 connect(m_ui.levelSIO, &QAbstractButton::toggled, [this](bool set) {
49 setLevel(GBA_LOG_SIO, set);
50 });
51 connect(m_ui.clear, SIGNAL(clicked()), this, SLOT(clear()));
52 connect(m_ui.maxLines, SIGNAL(valueChanged(int)), this, SLOT(setMaxLines(int)));
53 m_ui.maxLines->setValue(DEFAULT_LINE_LIMIT);
54
55 connect(log, SIGNAL(logPosted(int, const QString&)), this, SLOT(postLog(int, const QString&)));
56 connect(log, SIGNAL(levelsSet(int)), this, SLOT(setLevels(int)));
57 connect(log, &LogController::levelsEnabled, [this](int level) {
58 bool s = blockSignals(true);
59 setLevel(level, true);
60 blockSignals(s);
61 });
62 connect(log, &LogController::levelsDisabled, [this](int level) {
63 bool s = blockSignals(true);
64 setLevel(level, false);
65 blockSignals(s);
66 });
67 connect(this, SIGNAL(levelsEnabled(int)), log, SLOT(enableLevels(int)));
68 connect(this, SIGNAL(levelsDisabled(int)), log, SLOT(disableLevels(int)));
69}
70
71void LogView::postLog(int level, const QString& log) {
72 QString line = QString("%1:\t%2").arg(LogController::toString(level)).arg(log);
73 // TODO: Log to file
74 m_pendingLines.enqueue(line);
75 ++m_lines;
76 if (m_lines > m_lineLimit) {
77 clearLine();
78 }
79 update();
80}
81
82void LogView::clear() {
83 m_ui.view->clear();
84 m_lines = 0;
85}
86
87void LogView::setLevels(int levels) {
88 m_ui.levelDebug->setCheckState(levels & GBA_LOG_DEBUG ? Qt::Checked : Qt::Unchecked);
89 m_ui.levelStub->setCheckState(levels & GBA_LOG_STUB ? Qt::Checked : Qt::Unchecked);
90 m_ui.levelInfo->setCheckState(levels & GBA_LOG_INFO ? Qt::Checked : Qt::Unchecked);
91 m_ui.levelWarn->setCheckState(levels & GBA_LOG_WARN ? Qt::Checked : Qt::Unchecked);
92 m_ui.levelError->setCheckState(levels & GBA_LOG_ERROR ? Qt::Checked : Qt::Unchecked);
93 m_ui.levelFatal->setCheckState(levels & GBA_LOG_FATAL ? Qt::Checked : Qt::Unchecked);
94 m_ui.levelGameError->setCheckState(levels & GBA_LOG_GAME_ERROR ? Qt::Checked : Qt::Unchecked);
95 m_ui.levelSWI->setCheckState(levels & GBA_LOG_SWI ? Qt::Checked : Qt::Unchecked);
96 m_ui.levelStatus->setCheckState(levels & GBA_LOG_STATUS ? Qt::Checked : Qt::Unchecked);
97 m_ui.levelSIO->setCheckState(levels & GBA_LOG_SIO ? Qt::Checked : Qt::Unchecked);
98}
99
100void LogView::setLevel(int level, bool set) {
101 if (level & GBA_LOG_DEBUG) {
102 m_ui.levelDebug->setCheckState(set ? Qt::Checked : Qt::Unchecked);
103 }
104 if (level & GBA_LOG_STUB) {
105 m_ui.levelStub->setCheckState(set ? Qt::Checked : Qt::Unchecked);
106 }
107 if (level & GBA_LOG_INFO) {
108 m_ui.levelInfo->setCheckState(set ? Qt::Checked : Qt::Unchecked);
109 }
110 if (level & GBA_LOG_WARN) {
111 m_ui.levelWarn->setCheckState(set ? Qt::Checked : Qt::Unchecked);
112 }
113 if (level & GBA_LOG_ERROR) {
114 m_ui.levelError->setCheckState(set ? Qt::Checked : Qt::Unchecked);
115 }
116 if (level & GBA_LOG_FATAL) {
117 m_ui.levelFatal->setCheckState(set ? Qt::Checked : Qt::Unchecked);
118 }
119 if (level & GBA_LOG_GAME_ERROR) {
120 m_ui.levelGameError->setCheckState(set ? Qt::Checked : Qt::Unchecked);
121 }
122 if (level & GBA_LOG_SWI) {
123 m_ui.levelSWI->setCheckState(set ? Qt::Checked : Qt::Unchecked);
124 }
125 if (level & GBA_LOG_STATUS) {
126 m_ui.levelStatus->setCheckState(set ? Qt::Checked : Qt::Unchecked);
127 }
128 if (level & GBA_LOG_SIO) {
129 m_ui.levelSIO->setCheckState(set ? Qt::Checked : Qt::Unchecked);
130 }
131
132 if (set) {
133 emit levelsEnabled(level);
134 } else {
135 emit levelsDisabled(level);
136 }
137}
138
139void LogView::setMaxLines(int limit) {
140 m_lineLimit = limit;
141 while (m_lines > m_lineLimit) {
142 clearLine();
143 }
144}
145
146void LogView::paintEvent(QPaintEvent* event) {
147 while (!m_pendingLines.isEmpty()) {
148 m_ui.view->appendPlainText(m_pendingLines.dequeue());
149 }
150 QWidget::paintEvent(event);
151}
152
153void LogView::clearLine() {
154 if (m_ui.view->document()->isEmpty()) {
155 m_pendingLines.dequeue();
156 } else {
157 QTextCursor cursor(m_ui.view->document());
158 cursor.setPosition(0);
159 cursor.select(QTextCursor::BlockUnderCursor);
160 cursor.removeSelectedText();
161 cursor.deleteChar();
162 }
163 --m_lines;
164}