mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-28 16:55:31 +01:00
4e9746877e
1) The new ERROR, WARN, INFO, DEBUG _LOG macros were used ERROR, // Bad errors - that still don't deserve a PanicAlert. WARNING, // Something is suspicious. INFO, // General information. DEBUG, // Strictly for detailed debugging - might make things slow. 2) Made all LOG macro use into some of the logging level supporting macros LOG is commented out on linux can someone try it on windows? (it's in Log.h) 3) Added ERROR_lOG next to each panic alert I hope I helped making the logs a bit more useful/readble git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2510 8ced0084-cf51-0410-be5f-012b33b47a6e
517 lines
16 KiB
C++
517 lines
16 KiB
C++
// Copyright (C) 2003-2008 Dolphin Project.
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2.0.
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License 2.0 for more details.
|
|
|
|
// A copy of the GPL 2.0 should have been included with the program.
|
|
// If not, see http://www.gnu.org/licenses/
|
|
|
|
// Official SVN repository and contact information can be found at
|
|
// http://code.google.com/p/dolphin-emu/
|
|
|
|
#include "Debugger.h"
|
|
#include "LogManager.h"
|
|
|
|
#include <wx/button.h>
|
|
#include <wx/textctrl.h>
|
|
#include <wx/listbox.h>
|
|
#include <wx/checklst.h>
|
|
|
|
#include "Core.h" // for Core::GetState()
|
|
#include "LogWindow.h"
|
|
#include "Console.h"
|
|
|
|
BEGIN_EVENT_TABLE(CLogWindow, wxDialog)
|
|
EVT_BUTTON(IDM_SUBMITCMD, CLogWindow::OnSubmit)
|
|
EVT_BUTTON(IDM_UPDATELOG, CLogWindow::OnUpdateLog)
|
|
EVT_BUTTON(IDM_CLEARLOG, CLogWindow::OnClear)
|
|
EVT_BUTTON(IDM_ENABLEALL, CLogWindow::OnEnableAll)
|
|
EVT_CHECKLISTBOX(IDM_OPTIONS, CLogWindow::OnOptionsCheck)
|
|
EVT_CHECKLISTBOX(IDM_LOGCHECKS, CLogWindow::OnLogCheck)
|
|
EVT_RADIOBOX(IDM_RADIO0, CLogWindow::OnRadioChange)
|
|
END_EVENT_TABLE()
|
|
|
|
|
|
CLogWindow::CLogWindow(wxWindow* parent)
|
|
: wxDialog(parent, wxID_ANY, _T("Log/Console"), wxPoint(100, 700), wxSize(800, 270),
|
|
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
|
|
{
|
|
wxBoxSizer* sizerTop = new wxBoxSizer(wxHORIZONTAL), // buttons
|
|
* sizerUber = new wxBoxSizer(wxHORIZONTAL), // whole plane
|
|
* sizerBig = new wxBoxSizer(wxVERTICAL), // RIGHT sizer
|
|
* sizerBottom = new wxBoxSizer(wxHORIZONTAL), // submit row
|
|
* sizerLeft = new wxBoxSizer(wxVERTICAL); // LEFT sizer
|
|
|
|
// left checkboxes and radio boxes -----------------------------------
|
|
int m_radioBoxNChoices[1];
|
|
wxString m_radioBoxChoices0[] = { wxT("0"), wxT("1"), wxT("2"), wxT("3") };
|
|
m_radioBoxNChoices[0] = sizeof( m_radioBoxChoices0 ) / sizeof( wxString );
|
|
m_RadioBox[0] = new wxRadioBox( this, IDM_RADIO0, wxT("Verbosity"),
|
|
wxDefaultPosition, wxDefaultSize, m_radioBoxNChoices[0], m_radioBoxChoices0, 1, wxRA_SPECIFY_ROWS);
|
|
|
|
wxStaticBoxSizer * m_optionsSizer = new wxStaticBoxSizer(wxVERTICAL, this, wxT("Settings"));
|
|
m_options = new wxCheckListBox(this, IDM_OPTIONS, wxDefaultPosition, wxDefaultSize,
|
|
0, NULL, wxNO_BORDER);
|
|
m_options->Append(wxT("Unify"));
|
|
m_options->Append(wxT("Resolve symbols"));
|
|
m_options->Append(wxT("Write master"));
|
|
m_options->Append(wxT("Show unique"));
|
|
m_optionsSizer->Add(m_options, 0, 0, 0);
|
|
|
|
// I could not find any transparency setting and it would not automatically space correctly
|
|
m_options->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
|
|
//m_options->SetMinSize(wxSize(m_options->GetSize().GetWidth() - 40,m_options->GetCount() * 15));
|
|
#ifdef _WIN32
|
|
for (unsigned int i = 0; i < m_options->GetCount(); ++i)
|
|
m_options->GetItem(i)->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
|
|
#endif
|
|
|
|
m_checks = new wxCheckListBox(this, IDM_LOGCHECKS, wxDefaultPosition, wxSize(120, 280));
|
|
|
|
// finally add it to the sizer
|
|
sizerLeft->Add(m_RadioBox[0], 0, wxGROW);
|
|
sizerLeft->Add(m_optionsSizer, 0, wxGROW);
|
|
sizerLeft->Add(m_checks, 1, wxGROW);
|
|
|
|
|
|
// right windows -----------------------------------------------------
|
|
m_log = new wxTextCtrl(this, IDM_LOG, _T(""), wxDefaultPosition, wxSize(600, 120),
|
|
wxTE_MULTILINE | wxTE_READONLY | wxTE_DONTWRAP);
|
|
m_log->SetFont(DebuggerFont);
|
|
m_cmdline = new wxTextCtrl(this, wxID_ANY, _T(""), wxDefaultPosition);
|
|
m_cmdline->SetFont(DebuggerFont);
|
|
wxButton* btn = new wxButton(this, IDM_SUBMITCMD, _T("Submit"));
|
|
|
|
sizerTop->Add(new wxButton(this, IDM_UPDATELOG, _T("Update")));
|
|
sizerTop->Add(new wxButton(this, IDM_CLEARLOG, _T("Clear")));
|
|
sizerTop->Add(new wxButton(this, IDM_ENABLEALL, _T("Enable all")));
|
|
|
|
sizerBottom->Add(m_cmdline, 8, wxGROW | wxRIGHT, 5);
|
|
sizerBottom->Add(btn, 1, wxGROW, 0);
|
|
|
|
sizerBig->Add(sizerTop, 0, wxGROW);
|
|
sizerBig->Add(m_log, 1, wxGROW | wxSHRINK);
|
|
sizerBig->Add(sizerBottom, 0, wxGROW);
|
|
|
|
sizerUber->Add(sizerLeft, 0, wxGROW);
|
|
sizerUber->Add(sizerBig, 1, wxGROW);
|
|
|
|
SetSizer(sizerUber);
|
|
SetAffirmativeId(IDM_SUBMITCMD);
|
|
|
|
// declare this now to be able to use it in Load()
|
|
LogManager::m_LogSettings = new CDebugger_LogSettings;
|
|
|
|
//sizerTop->SetSizeHints(this);
|
|
//sizerTop->Fit(this);
|
|
UpdateChecks();
|
|
m_cmdline->SetFocus();
|
|
m_bCheckDirty = false;
|
|
|
|
/* Load ini from here instead of from CodeWindow.cpp to make sure that
|
|
settings are loaded if the window is showing */
|
|
IniFile file;
|
|
file.Load(DEBUGGER_CONFIG_FILE);
|
|
Load(file);
|
|
}
|
|
|
|
|
|
// =======================================================
|
|
// This is called from the CodeWindow deconstruction function.
|
|
// -------------
|
|
void CLogWindow::Save(IniFile& _IniFile) const
|
|
{
|
|
_IniFile.Set("LogWindow", "x", GetPosition().x);
|
|
_IniFile.Set("LogWindow", "y", GetPosition().y);
|
|
_IniFile.Set("LogWindow", "w", GetSize().GetWidth());
|
|
_IniFile.Set("LogWindow", "h", GetSize().GetHeight());
|
|
}
|
|
|
|
|
|
// =======================================================
|
|
// This is called from the class construction function.
|
|
// -------------
|
|
void CLogWindow::Load(IniFile& _IniFile)
|
|
{
|
|
int x,y,w,h;
|
|
_IniFile.Get("LogWindow", "x", &x, GetPosition().x);
|
|
_IniFile.Get("LogWindow", "y", &y, GetPosition().y);
|
|
_IniFile.Get("LogWindow", "w", &w, GetSize().GetWidth());
|
|
_IniFile.Get("LogWindow", "h", &h, GetSize().GetHeight());
|
|
SetSize(x, y, w, h);
|
|
|
|
// Load verbosity setting
|
|
int v;
|
|
_IniFile.Get("LogWindow", "Verbosity", &v, m_RadioBox[0]->GetSelection());
|
|
m_RadioBox[0]->SetSelection(v);
|
|
LogManager::m_LogSettings->m_iVerbosity = v;
|
|
|
|
// Load options
|
|
_IniFile.Get("LogWindow", "Unify", &LogManager::m_LogSettings->bUnify, false);
|
|
_IniFile.Get("LogWindow", "ResolveSymbols", &LogManager::m_LogSettings->bResolve, false);
|
|
_IniFile.Get("LogWindow", "WriteMaster", &LogManager::m_LogSettings->bWriteMaster, false);
|
|
_IniFile.Get("LogWindow", "OnlyUnique", &bOnlyUnique, false);
|
|
m_options->Check(0, LogManager::m_LogSettings->bUnify);
|
|
m_options->Check(1, LogManager::m_LogSettings->bResolve);
|
|
m_options->Check(2, LogManager::m_LogSettings->bWriteMaster);
|
|
m_options->Check(3, bOnlyUnique);
|
|
|
|
// If we use the Unify option
|
|
if(LogManager::m_LogSettings->bUnify)
|
|
{
|
|
m_RadioBox[0]->SetSelection(LogManager::VERBOSITY_LEVELS);
|
|
LogManager::m_LogSettings->m_iVerbosity = LogManager::VERBOSITY_LEVELS;
|
|
m_RadioBox[0]->Disable();
|
|
}
|
|
}
|
|
|
|
void CLogWindow::OnSubmit(wxCommandEvent& event)
|
|
{
|
|
Console_Submit(m_cmdline->GetValue().To8BitData());
|
|
m_cmdline->SetValue(_T(""));
|
|
NotifyUpdate();
|
|
}
|
|
|
|
|
|
void CLogWindow::OnClear(wxCommandEvent& event)
|
|
{
|
|
if (Core::GetState() != Core::CORE_UNINITIALIZED) // avoid crash
|
|
{
|
|
LogManager::Clear();
|
|
INFO_LOG(MASTER_LOG, "(log cleared).");
|
|
NotifyUpdate();
|
|
}
|
|
}
|
|
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
// Enable or disable all boxes for the current verbosity level and save the changes.
|
|
// -------------
|
|
void CLogWindow::OnEnableAll(wxCommandEvent& event)
|
|
{
|
|
if (!LogManager::m_Log[0])
|
|
return;
|
|
static bool enable = true;
|
|
int v = LogManager::m_LogSettings->m_iVerbosity;
|
|
IniFile ini;
|
|
ini.Load(DEBUGGER_CONFIG_FILE);
|
|
|
|
// Unified case. Write the same to all levels.
|
|
if(m_options->IsChecked(0))
|
|
{
|
|
for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++)
|
|
{
|
|
m_checks->Check(i, enable); // get all from the current selection
|
|
for (int j = 0; j <= LogManager::VERBOSITY_LEVELS; j++)
|
|
{
|
|
LogManager::m_Log[i + j*100]->m_bEnable = enable;
|
|
LogManager::m_Log[i + j*100]->m_bShowInLog = enable;
|
|
ini.Set("LogManager", LogManager::m_Log[i + j*100]->m_szShortName, enable);
|
|
}
|
|
}
|
|
}
|
|
else // otherwise only update the current shown level
|
|
{
|
|
for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++)
|
|
{
|
|
m_checks->Check(i, enable);
|
|
LogManager::m_Log[i + v*100]->m_bEnable = enable;
|
|
LogManager::m_Log[i + v*100]->m_bShowInLog = enable;
|
|
ini.Set("LogManager", LogManager::m_Log[i + v*100]->m_szShortName, enable);
|
|
}
|
|
}
|
|
|
|
|
|
ini.Save(DEBUGGER_CONFIG_FILE);
|
|
enable = !enable;
|
|
}
|
|
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
// Append checkboxes and update checked groups.
|
|
// -------------
|
|
void CLogWindow::UpdateChecks()
|
|
{
|
|
if (!LogManager::m_bInitialized)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// This is only run once to append checkboxes to the wxCheckListBox.
|
|
if (m_checks->GetCount() == 0)
|
|
{
|
|
// [F|RES] hide the window while we fill it... wxwidgets gets trouble if you don't do it
|
|
// (at least the win version)
|
|
m_checks->Show(false);
|
|
|
|
for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++)
|
|
{
|
|
m_checks->Append(wxString::FromAscii(LogManager::m_Log[i]->m_szName));
|
|
}
|
|
|
|
m_checks->Show(true);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
// Load the correct values and enable/disable the right groups
|
|
// -------------
|
|
int v = LogManager::m_LogSettings->m_iVerbosity;
|
|
IniFile ini;
|
|
ini.Load(DEBUGGER_CONFIG_FILE);
|
|
|
|
for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++)
|
|
{
|
|
for (int j = 0; j <= LogManager::VERBOSITY_LEVELS; j++)
|
|
{
|
|
bool Enabled = false;
|
|
ini.Get("LogManager", LogManager::m_Log[i + j*100]->m_szShortName, &Enabled, false);
|
|
LogManager::m_Log[i + j*100]->m_bEnable = Enabled;
|
|
LogManager::m_Log[i + j*100]->m_bShowInLog = Enabled;
|
|
if(j == v) m_checks->Check(i, Enabled);
|
|
}
|
|
}
|
|
|
|
m_bCheckDirty = true;
|
|
}
|
|
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
// When an option is changed, save the change
|
|
// ---------------
|
|
void CLogWindow::OnOptionsCheck(wxCommandEvent& event)
|
|
{
|
|
IniFile ini;
|
|
ini.Load(DEBUGGER_CONFIG_FILE);
|
|
|
|
//PanicAlert("%i", (int)Core::GetState());
|
|
|
|
// Unified case. If the core is uninitialized we only disable the radio boxes
|
|
if(m_options->IsChecked(0) && Core::GetState() == Core::CORE_UNINITIALIZED)
|
|
{
|
|
m_RadioBox[0]->SetSelection(LogManager::VERBOSITY_LEVELS);
|
|
LogManager::m_LogSettings->m_iVerbosity = LogManager::VERBOSITY_LEVELS;
|
|
m_RadioBox[0]->Disable();
|
|
}
|
|
// otherwise we both disable them and update all blocks
|
|
else if(m_options->IsChecked(0) && Core::GetState() != Core::CORE_UNINITIALIZED)
|
|
{
|
|
m_RadioBox[0]->SetSelection(LogManager::VERBOSITY_LEVELS);
|
|
LogManager::m_LogSettings->m_iVerbosity = LogManager::VERBOSITY_LEVELS;
|
|
m_RadioBox[0]->Disable();
|
|
|
|
for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++)
|
|
{
|
|
bool Enabled = m_checks->IsChecked(i); // get all from the current i
|
|
for (int j = 0; j <= LogManager::VERBOSITY_LEVELS; j++)
|
|
{
|
|
// update groups to enabled or disabled
|
|
LogManager::m_Log[i + 100*j]->m_bEnable = Enabled;
|
|
LogManager::m_Log[i + 100*j]->m_bShowInLog = Enabled;
|
|
|
|
// update all verbosity levels to this level's Enabled
|
|
ini.Set("LogManager", LogManager::m_Log[i + 100*j]->m_szShortName, Enabled);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_RadioBox[0]->Enable(true);
|
|
}
|
|
|
|
LogManager::m_LogSettings->bUnify = m_options->IsChecked(0);
|
|
LogManager::m_LogSettings->bResolve = m_options->IsChecked(1);
|
|
LogManager::m_LogSettings->bWriteMaster = m_options->IsChecked(2);
|
|
bOnlyUnique = m_options->IsChecked(3);
|
|
|
|
ini.Set("LogWindow", "Unify", m_options->IsChecked(0));
|
|
ini.Set("LogWindow", "ResolveSymbols", m_options->IsChecked(1));
|
|
ini.Set("LogWindow", "WriteMaster", m_options->IsChecked(2));
|
|
ini.Set("LogWindow", "OnlyUnique", m_options->IsChecked(3));
|
|
ini.Save(DEBUGGER_CONFIG_FILE);
|
|
if (Core::GetState() != Core::CORE_UNINITIALIZED) UpdateLog();
|
|
}
|
|
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
// When a checkbox is changed
|
|
// ---------------
|
|
void CLogWindow::OnLogCheck(wxCommandEvent& event)
|
|
{
|
|
if (!LogManager::m_bInitialized) return;
|
|
|
|
IniFile ini;
|
|
ini.Load(DEBUGGER_CONFIG_FILE);
|
|
int v = LogManager::m_LogSettings->m_iVerbosity; // current radio button
|
|
int uni = LogManager::m_LogSettings->bUnify;
|
|
|
|
// Unified case
|
|
if(uni)
|
|
{
|
|
for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++)
|
|
{
|
|
for (int j = 0; j <= LogManager::VERBOSITY_LEVELS; j++)
|
|
{
|
|
// update groups to enabled or disabled
|
|
bool Enabled = m_checks->IsChecked(i); // get all from the current i
|
|
LogManager::m_Log[i + 100*j]->m_bEnable = Enabled;
|
|
LogManager::m_Log[i + 100*j]->m_bShowInLog = Enabled;
|
|
|
|
ini.Set("LogManager", LogManager::m_Log[i + 100*j]->m_szShortName, Enabled);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++)
|
|
{
|
|
// update groups to enabled or disabled
|
|
bool Enabled = m_checks->IsChecked(i);
|
|
LogManager::m_Log[i + 100*v]->m_bEnable = Enabled;
|
|
LogManager::m_Log[i + 100*v]->m_bShowInLog = Enabled;
|
|
|
|
ini.Set("LogManager", LogManager::m_Log[i + 100*v]->m_szShortName, Enabled);
|
|
}
|
|
}
|
|
|
|
ini.Save(DEBUGGER_CONFIG_FILE);
|
|
|
|
m_bCheckDirty = true;
|
|
if (Core::GetState() != Core::CORE_UNINITIALIZED) UpdateLog();
|
|
}
|
|
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
// When the verbosity level is changed
|
|
// -------------
|
|
void CLogWindow::OnRadioChange(wxCommandEvent& event)
|
|
{
|
|
// get selection
|
|
int v = m_RadioBox[0]->GetSelection();
|
|
|
|
// save it
|
|
LogManager::m_LogSettings->m_iVerbosity = v;
|
|
IniFile ini;
|
|
ini.Load(DEBUGGER_CONFIG_FILE);
|
|
ini.Set("LogWindow", "Verbosity", v);
|
|
ini.Save(DEBUGGER_CONFIG_FILE);
|
|
|
|
// This check is because we allow this to be changed before a game has been loaded so
|
|
// that the boxes do not exist yet
|
|
if (Core::GetState() != Core::CORE_UNINITIALIZED)
|
|
{
|
|
for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++)
|
|
{
|
|
// update groups to enabled or disabled
|
|
bool Enabled;
|
|
ini.Get("LogManager", LogManager::m_Log[i + 100*v]->m_szShortName, &Enabled, false);
|
|
LogManager::m_Log[i + 100*v]->m_bEnable = Enabled;
|
|
LogManager::m_Log[i + 100*v]->m_bShowInLog = Enabled;
|
|
m_checks->Check(i, Enabled);
|
|
}
|
|
|
|
m_bCheckDirty = true;
|
|
UpdateLog();
|
|
}
|
|
}
|
|
|
|
|
|
void CLogWindow::OnUpdateLog(wxCommandEvent& event)
|
|
{
|
|
if (Core::GetState() != Core::CORE_UNINITIALIZED) UpdateLog();
|
|
}
|
|
|
|
|
|
void CLogWindow::NotifyUpdate()
|
|
{
|
|
UpdateChecks();
|
|
UpdateLog();
|
|
}
|
|
|
|
|
|
void CLogWindow::UpdateLog()
|
|
{
|
|
static int last = -1;
|
|
int v = LogManager::m_LogSettings->m_iVerbosity;
|
|
int i = LogManager::m_nextMessages[v];
|
|
|
|
// check if the the log has been updated (ie if it's dirty)
|
|
if ((last == i) && !m_bCheckDirty)
|
|
{
|
|
return;
|
|
}
|
|
m_bCheckDirty = false;
|
|
last = i;
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
// Prepare a selection of the memory log to show to screen
|
|
// ---------------
|
|
int count = 0;
|
|
char* p = m_logBuffer;
|
|
|
|
// go through all rows
|
|
while (count < MAX_MESSAGES)
|
|
{
|
|
count++;
|
|
const LogManager::SMessage& message = LogManager::m_Messages[v][i];
|
|
|
|
if (message.m_bInUse) // check if the line has a value
|
|
{
|
|
int len = message.m_dwMsgLen;
|
|
|
|
// this is what we use, I'm not sure why we have this option
|
|
if (LogManager::m_activeLog == LogTypes::MASTER_LOG)
|
|
{
|
|
// only show checkboxed logs
|
|
if (LogManager::m_Log[message.m_type]->m_bShowInLog)
|
|
{
|
|
if(bOnlyUnique) /* don't show lower level messages that have fallen through
|
|
to this higher level */
|
|
{
|
|
if(message.m_verbosity == v)
|
|
{
|
|
// memcpy is faster than strcpy
|
|
memcpy(p, message.m_szMessage, len);
|
|
p += len;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// memcpy is faster than strcpy
|
|
memcpy(p, message.m_szMessage, len);
|
|
p += len;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (message.m_type == LogManager::m_activeLog)
|
|
{
|
|
memcpy(p, message.m_szMessage, len);
|
|
p += len;
|
|
}
|
|
}
|
|
}
|
|
|
|
i++;
|
|
|
|
if (i >= MAX_MESSAGES)
|
|
{
|
|
i = 0;
|
|
}
|
|
}
|
|
// ---------------
|
|
|
|
*p = 0; //end the string
|
|
m_log->SetValue(wxString::FromAscii(m_logBuffer));
|
|
m_log->SetInsertionPoint(p - m_logBuffer - 1);
|
|
m_log->ShowPosition( m_log->GetLastPosition()); // show last line
|
|
m_log->SetFont(DebuggerFont);
|
|
m_cmdline->SetFont(DebuggerFont);
|
|
}
|