logg.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 1,225 行 · 第 1/3 页
CPP
1,225 行
// fall through
case wxLOG_Warning:
if ( !m_bErrors ) {
// for the warning we don't discard the info messages
m_bWarnings = true;
}
m_aMessages.Add(szString);
m_aSeverity.Add((int)level);
m_aTimes.Add((long)t);
m_bHasMessages = true;
break;
}
}
#endif // wxUSE_LOGGUI
// ----------------------------------------------------------------------------
// wxLogWindow and wxLogFrame implementation
// ----------------------------------------------------------------------------
#if wxUSE_LOGWINDOW
// log frame class
// ---------------
class wxLogFrame : public wxFrame
{
public:
// ctor & dtor
wxLogFrame(wxWindow *pParent, wxLogWindow *log, const wxChar *szTitle);
virtual ~wxLogFrame();
// menu callbacks
void OnClose(wxCommandEvent& event);
void OnCloseWindow(wxCloseEvent& event);
#if wxUSE_FILE
void OnSave (wxCommandEvent& event);
#endif // wxUSE_FILE
void OnClear(wxCommandEvent& event);
// accessors
wxTextCtrl *TextCtrl() const { return m_pTextCtrl; }
private:
// use standard ids for our commands!
enum
{
Menu_Close = wxID_CLOSE,
Menu_Save = wxID_SAVE,
Menu_Clear = wxID_CLEAR
};
// common part of OnClose() and OnCloseWindow()
void DoClose();
wxTextCtrl *m_pTextCtrl;
wxLogWindow *m_log;
DECLARE_EVENT_TABLE()
DECLARE_NO_COPY_CLASS(wxLogFrame)
};
BEGIN_EVENT_TABLE(wxLogFrame, wxFrame)
// wxLogWindow menu events
EVT_MENU(Menu_Close, wxLogFrame::OnClose)
#if wxUSE_FILE
EVT_MENU(Menu_Save, wxLogFrame::OnSave)
#endif // wxUSE_FILE
EVT_MENU(Menu_Clear, wxLogFrame::OnClear)
EVT_CLOSE(wxLogFrame::OnCloseWindow)
END_EVENT_TABLE()
wxLogFrame::wxLogFrame(wxWindow *pParent, wxLogWindow *log, const wxChar *szTitle)
: wxFrame(pParent, wxID_ANY, szTitle)
{
m_log = log;
m_pTextCtrl = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition,
wxDefaultSize,
wxTE_MULTILINE |
wxHSCROLL |
// needed for Win32 to avoid 65Kb limit but it doesn't work well
// when using RichEdit 2.0 which we always do in the Unicode build
#if !wxUSE_UNICODE
wxTE_RICH |
#endif // !wxUSE_UNICODE
wxTE_READONLY);
#if wxUSE_MENUS
// create menu
wxMenuBar *pMenuBar = new wxMenuBar;
wxMenu *pMenu = new wxMenu;
#if wxUSE_FILE
pMenu->Append(Menu_Save, _("&Save..."), _("Save log contents to file"));
#endif // wxUSE_FILE
pMenu->Append(Menu_Clear, _("C&lear"), _("Clear the log contents"));
pMenu->AppendSeparator();
pMenu->Append(Menu_Close, _("&Close"), _("Close this window"));
pMenuBar->Append(pMenu, _("&Log"));
SetMenuBar(pMenuBar);
#endif // wxUSE_MENUS
#if wxUSE_STATUSBAR
// status bar for menu prompts
CreateStatusBar();
#endif // wxUSE_STATUSBAR
m_log->OnFrameCreate(this);
}
void wxLogFrame::DoClose()
{
if ( m_log->OnFrameClose(this) )
{
// instead of closing just hide the window to be able to Show() it
// later
Show(false);
}
}
void wxLogFrame::OnClose(wxCommandEvent& WXUNUSED(event))
{
DoClose();
}
void wxLogFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
{
DoClose();
}
#if wxUSE_FILE
void wxLogFrame::OnSave(wxCommandEvent& WXUNUSED(event))
{
#if wxUSE_FILEDLG
wxString filename;
wxFile file;
int rc = OpenLogFile(file, &filename, this);
if ( rc == -1 )
{
// cancelled
return;
}
bool bOk = rc != 0;
// retrieve text and save it
// -------------------------
int nLines = m_pTextCtrl->GetNumberOfLines();
for ( int nLine = 0; bOk && nLine < nLines; nLine++ ) {
bOk = file.Write(m_pTextCtrl->GetLineText(nLine) +
wxTextFile::GetEOL());
}
if ( bOk )
bOk = file.Close();
if ( !bOk ) {
wxLogError(_("Can't save log contents to file."));
}
else {
wxLogStatus(this, _("Log saved to the file '%s'."), filename.c_str());
}
#endif
}
#endif // wxUSE_FILE
void wxLogFrame::OnClear(wxCommandEvent& WXUNUSED(event))
{
m_pTextCtrl->Clear();
}
wxLogFrame::~wxLogFrame()
{
m_log->OnFrameDelete(this);
}
// wxLogWindow
// -----------
wxLogWindow::wxLogWindow(wxWindow *pParent,
const wxChar *szTitle,
bool bShow,
bool bDoPass)
{
PassMessages(bDoPass);
m_pLogFrame = new wxLogFrame(pParent, this, szTitle);
if ( bShow )
m_pLogFrame->Show();
}
void wxLogWindow::Show(bool bShow)
{
m_pLogFrame->Show(bShow);
}
void wxLogWindow::DoLog(wxLogLevel level, const wxChar *szString, time_t t)
{
// first let the previous logger show it
wxLogPassThrough::DoLog(level, szString, t);
if ( m_pLogFrame ) {
switch ( level ) {
case wxLOG_Status:
// by default, these messages are ignored by wxLog, so process
// them ourselves
if ( !wxIsEmpty(szString) )
{
wxString str;
str << _("Status: ") << szString;
DoLogString(str, t);
}
break;
// don't put trace messages in the text window for 2 reasons:
// 1) there are too many of them
// 2) they may provoke other trace messages thus sending a program
// into an infinite loop
case wxLOG_Trace:
break;
default:
// and this will format it nicely and call our DoLogString()
wxLog::DoLog(level, szString, t);
}
}
}
void wxLogWindow::DoLogString(const wxChar *szString, time_t WXUNUSED(t))
{
// put the text into our window
wxTextCtrl *pText = m_pLogFrame->TextCtrl();
// remove selection (WriteText is in fact ReplaceSelection)
#ifdef __WXMSW__
wxTextPos nLen = pText->GetLastPosition();
pText->SetSelection(nLen, nLen);
#endif // Windows
wxString msg;
TimeStamp(&msg);
msg << szString << wxT('\n');
pText->AppendText(msg);
// TODO ensure that the line can be seen
}
wxFrame *wxLogWindow::GetFrame() const
{
return m_pLogFrame;
}
void wxLogWindow::OnFrameCreate(wxFrame * WXUNUSED(frame))
{
}
bool wxLogWindow::OnFrameClose(wxFrame * WXUNUSED(frame))
{
// allow to close
return true;
}
void wxLogWindow::OnFrameDelete(wxFrame * WXUNUSED(frame))
{
m_pLogFrame = (wxLogFrame *)NULL;
}
wxLogWindow::~wxLogWindow()
{
// may be NULL if log frame already auto destroyed itself
delete m_pLogFrame;
}
#endif // wxUSE_LOGWINDOW
// ----------------------------------------------------------------------------
// wxLogDialog
// ----------------------------------------------------------------------------
#if wxUSE_LOG_DIALOG
#ifndef __SMARTPHONE__
static const size_t MARGIN = 10;
#else
static const size_t MARGIN = 0;
#endif
wxString wxLogDialog::ms_details;
wxLogDialog::wxLogDialog(wxWindow *parent,
const wxArrayString& messages,
const wxArrayInt& severity,
const wxArrayLong& times,
const wxString& caption,
long style)
: wxDialog(parent, wxID_ANY, caption,
wxDefaultPosition, wxDefaultSize,
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{
if ( ms_details.empty() )
{
// ensure that we won't loop here if wxGetTranslation()
// happens to pop up a Log message while translating this :-)
ms_details = wxTRANSLATE("&Details");
ms_details = wxGetTranslation(ms_details);
#ifdef __SMARTPHONE__
ms_details = wxStripMenuCodes(ms_details);
#endif
}
size_t count = messages.GetCount();
m_messages.Alloc(count);
m_severity.Alloc(count);
m_times.Alloc(count);
for ( size_t n = 0; n < count; n++ )
{
wxString msg = messages[n];
msg.Replace(wxT("\n"), wxT(" "));
m_messages.Add(msg);
m_severity.Add(severity[n]);
m_times.Add(times[n]);
}
m_showingDetails = false; // not initially
m_listctrl = (wxListCtrl *)NULL;
#ifndef __SMARTPHONE__
#if wxUSE_STATLINE
m_statline = (wxStaticLine *)NULL;
#endif // wxUSE_STATLINE
#if wxUSE_FILE
m_btnSave = (wxButton *)NULL;
#endif // wxUSE_FILE
#endif // __SMARTPHONE__
bool isPda = (wxSystemSettings::GetScreenType() <= wxSYS_SCREEN_PDA);
// create the controls which are always shown and layout them: we use
// sizers even though our window is not resizeable to calculate the size of
// the dialog properly
wxBoxSizer *sizerTop = new wxBoxSizer(wxVERTICAL);
#ifndef __SMARTPHONE__
wxBoxSizer *sizerButtons = new wxBoxSizer(isPda ? wxHORIZONTAL : wxVERTICAL);
#endif
wxBoxSizer *sizerAll = new wxBoxSizer(isPda ? wxVERTICAL : wxHORIZONTAL);
#ifdef __SMARTPHONE__
SetLeftMenu(wxID_OK);
SetRightMenu(wxID_MORE, ms_details + EXPAND_SUFFIX);
#else
wxButton *btnOk = new wxButton(this, wxID_OK);
sizerButtons->Add(btnOk, 0, isPda ? wxCENTRE : wxCENTRE|wxBOTTOM, MARGIN/2);
m_btnDetails = new wxButton(this, wxID_MORE, ms_details + EXPAND_SUFFIX);
sizerButtons->Add(m_btnDetails, 0, isPda ? wxCENTRE|wxLEFT : wxCENTRE | wxTOP, MARGIN/2 - 1);
#endif
wxBitmap bitmap;
switch ( style & wxICON_MASK )
{
case wxICON_ERROR:
bitmap = wxArtProvider::GetBitmap(wxART_ERROR, wxART_MESSAGE_BOX);
#ifdef __WXPM__
bitmap.SetId(wxICON_SMALL_ERROR);
#endif
break;
case wxICON_INFORMATION:
bitmap = wxArtProvider::GetBitmap(wxART_INFORMATION, wxART_MESSAGE_BOX);
#ifdef __WXPM__
bitmap.SetId(wxICON_SMALL_INFO);
#endif
break;
case wxICON_WARNING:
bitmap = wxArtProvider::GetBitmap(wxART_WARNING, wxART_MESSAGE_BOX);
#ifdef __WXPM__
bitmap.SetId(wxICON_SMALL_WARNING);
#endif
break;
default:
wxFAIL_MSG(_T("incorrect log style"));
}
if (!isPda)
sizerAll->Add(new wxStaticBitmap(this, wxID_ANY, bitmap), 0,
wxALIGN_CENTRE_VERTICAL);
const wxString& message = messages.Last();
sizerAll->Add(CreateTextSizer(message), 1,
wxALIGN_CENTRE_VERTICAL | wxLEFT | wxRIGHT, MARGIN);
#ifndef __SMARTPHONE__
sizerAll->Add(sizerButtons, 0, isPda ? wxCENTRE|wxTOP|wxBOTTOM : (wxALIGN_RIGHT | wxLEFT), MARGIN);
#endif
sizerTop->Add(sizerAll, 0, wxALL | wxEXPAND, MARGIN);
SetSizer(sizerTop);
// see comments in OnDetails()
//
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?