+void wxLogGui::DoLog(wxLogLevel level, const wxChar *szString, time_t t)
+{
+ switch ( level ) {
+ case wxLOG_Info:
+ if ( GetVerbose() )
+ case wxLOG_Message:
+ if ( !m_bErrors ) {
+ m_aMessages.Add(szString);
+ m_aTimes.Add((long)t);
+ m_bHasMessages = TRUE;
+ }
+ break;
+
+ case wxLOG_Status:
+#if wxUSE_STATUSBAR
+ {
+ // find the top window and set it's status text if it has any
+ wxFrame *pFrame = gs_pFrame;
+ if ( pFrame == NULL ) {
+ wxWindow *pWin = wxTheApp->GetTopWindow();
+ if ( pWin != NULL && pWin->IsKindOf(CLASSINFO(wxFrame)) ) {
+ pFrame = (wxFrame *)pWin;
+ }
+ }
+
+ if ( pFrame != NULL )
+ pFrame->SetStatusText(szString);
+ }
+#endif // wxUSE_STATUSBAR
+ break;
+
+ case wxLOG_Trace:
+ case wxLOG_Debug:
+ #ifdef __WXDEBUG__
+ {
+ #ifdef __WXMSW__
+ // don't prepend debug/trace here: it goes to the
+ // debug window anyhow, but do put a timestamp
+ wxString str;
+ TimeStamp(&str);
+ str << szString << _T("\n\r");
+ OutputDebugString(str);
+ #else
+ // send them to stderr
+ wxFprintf(stderr, _T("%s: %s\n"),
+ level == wxLOG_Trace ? _T("Trace")
+ : _T("Debug"),
+ szString);
+ fflush(stderr);
+ #endif
+ }
+ #endif // __WXDEBUG__
+
+ break;
+
+ case wxLOG_FatalError:
+ // show this one immediately
+ wxMessageBox(szString, _("Fatal error"), wxICON_HAND);
+ break;
+
+ case wxLOG_Error:
+ // discard earlier informational messages if this is the 1st
+ // error because they might not make sense any more
+ if ( !m_bErrors ) {
+ m_aMessages.Empty();
+ m_aTimes.Empty();
+ m_bHasMessages = TRUE;
+ m_bErrors = TRUE;
+ }
+ // 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_aTimes.Add((long)t);
+ break;
+ }
+}
+
+// ----------------------------------------------------------------------------
+// wxLogWindow and wxLogFrame implementation
+// ----------------------------------------------------------------------------
+
+// log frame class
+// ---------------
+class wxLogFrame : public wxFrame
+{
+public:
+ // ctor & dtor
+ wxLogFrame(wxFrame *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);
+
+ void OnIdle(wxIdleEvent&);
+
+ // accessors
+ wxTextCtrl *TextCtrl() const { return m_pTextCtrl; }
+
+private:
+ enum
+ {
+ Menu_Close = 100,
+ Menu_Save,
+ Menu_Clear
+ };
+
+ // instead of closing just hide the window to be able to Show() it later
+ void DoClose() { Show(FALSE); }
+
+ wxTextCtrl *m_pTextCtrl;
+ wxLogWindow *m_log;
+
+ DECLARE_EVENT_TABLE()
+};
+
+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(wxFrame *pParent, wxLogWindow *log, const wxChar *szTitle)
+ : wxFrame(pParent, -1, szTitle)
+{
+ m_log = log;
+
+ m_pTextCtrl = new wxTextCtrl(this, -1, wxEmptyString, wxDefaultPosition,
+ wxDefaultSize,
+ wxTE_MULTILINE |
+ wxHSCROLL |
+ wxTE_READONLY);
+
+ // 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);
+
+#if wxUSE_STATUSBAR
+ // status bar for menu prompts
+ CreateStatusBar();
+#endif // wxUSE_STATUSBAR
+
+ m_log->OnFrameCreate(this);
+}
+
+void wxLogFrame::OnClose(wxCommandEvent& WXUNUSED(event))
+{
+ DoClose();
+}
+
+void wxLogFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
+{
+ DoClose();
+}
+
+#if wxUSE_FILE
+void wxLogFrame::OnSave(wxCommandEvent& WXUNUSED(event))
+{
+ // get the file name
+ // -----------------
+ const wxChar *szFileName = wxSaveFileSelector(_T("log"), _T("txt"), _T("log.txt"));
+ if ( szFileName == NULL ) {
+ // cancelled
+ return;
+ }
+
+ // open file
+ // ---------
+ wxFile file;
+ bool bOk = FALSE;
+ if ( wxFile::Exists(szFileName) ) {
+ bool bAppend = FALSE;
+ wxString strMsg;
+ strMsg.Printf(_("Append log to file '%s' "
+ "(choosing [No] will overwrite it)?"), szFileName);
+ switch ( wxMessageBox(strMsg, _("Question"), wxYES_NO | wxCANCEL) ) {
+ case wxYES:
+ bAppend = TRUE;
+ break;
+
+ case wxNO:
+ bAppend = FALSE;
+ break;
+
+ case wxCANCEL:
+ return;
+
+ default:
+ wxFAIL_MSG(_("invalid message box return value"));