X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/0758c46ee65053bc70bd0ef5a73fb30aeec7986c..6f026b5b63fe7ccb025e84509886f74772b9df13:/src/generic/logg.cpp?ds=sidebyside diff --git a/src/generic/logg.cpp b/src/generic/logg.cpp index ae690ab5ff..6204463346 100644 --- a/src/generic/logg.cpp +++ b/src/generic/logg.cpp @@ -5,7 +5,6 @@ // Author: Vadim Zeitlin // Modified by: // Created: 20.09.99 (extracted from src/common/log.cpp) -// RCS-ID: $Id$ // Copyright: (c) 1998 Vadim Zeitlin // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -53,10 +52,6 @@ #include "wx/arrstr.h" #include "wx/msgout.h" -#if wxUSE_THREADS - #include "wx/thread.h" -#endif // wxUSE_THREADS - #ifdef __WXMSW__ // for OutputDebugString() #include "wx/msw/private.h" @@ -73,14 +68,10 @@ #include "wx/image.h" #endif // wxUSE_LOG_DIALOG/!wxUSE_LOG_DIALOG -#if defined(__MWERKS__) && wxUSE_UNICODE - #include -#endif - -#include "wx/datetime.h" +#include "wx/time.h" // the suffix we add to the button to show that the dialog can be expanded -#define EXPAND_SUFFIX _T(" >>") +#define EXPAND_SUFFIX wxT(" >>") #define CAN_SAVE_FILES (wxUSE_FILE && wxUSE_FILEDLG) @@ -94,18 +85,14 @@ // allows to exclude the usage of wxDateTime static wxString TimeStamp(const wxString& format, time_t t) { -#if wxUSE_DATETIME wxChar buf[4096]; struct tm tm; if ( !wxStrftime(buf, WXSIZEOF(buf), format, wxLocaltime_r(&t, &tm)) ) { // buffer is too small? - wxFAIL_MSG(_T("strftime() failed")); + wxFAIL_MSG(wxT("strftime() failed")); } return wxString(buf); -#else // !wxUSE_DATETIME - return wxEmptyString; -#endif // wxUSE_DATETIME/!wxUSE_DATETIME } @@ -298,6 +285,8 @@ wxLogGui::DoShowMultipleLogMessages(const wxArrayString& messages, void wxLogGui::Flush() { + wxLog::Flush(); + if ( !m_bHasMessages ) return; @@ -373,7 +362,7 @@ void wxLogGui::DoLogRecord(wxLogLevel level, wxFrame *pFrame = NULL; // check if the frame was passed to us explicitly - wxUIntPtr ptr = NULL; + wxUIntPtr ptr = 0; if ( info.GetNumValue(wxLOG_KEY_FRAME, &ptr) ) { pFrame = static_cast(wxUIntToPtr(ptr)); @@ -382,7 +371,7 @@ void wxLogGui::DoLogRecord(wxLogLevel level, // find the top window and set it's status text if it has any if ( pFrame == NULL ) { wxWindow *pWin = wxTheApp->GetTopWindow(); - if ( pWin != NULL && pWin->IsKindOf(CLASSINFO(wxFrame)) ) { + if ( wxDynamicCast(pWin, wxFrame) ) { pFrame = (wxFrame *)pWin; } } @@ -419,10 +408,25 @@ void wxLogGui::DoLogRecord(wxLogLevel level, m_bHasMessages = true; break; - default: - // let the base class deal with debug/trace messages as well as any - // custom levels + case wxLOG_Debug: + case wxLOG_Trace: + // let the base class deal with debug/trace messages wxLog::DoLogRecord(level, msg, info); + break; + + case wxLOG_FatalError: + case wxLOG_Max: + // fatal errors are shown immediately and terminate the program so + // we should never see them here + wxFAIL_MSG("unexpected log level"); + break; + + case wxLOG_Progress: + case wxLOG_User: + // just ignore those: passing them to the base class would result + // in asserts from DoLogText() because DoLogTextAtLevel() would + // call it as it doesn't know how to handle these levels otherwise + break; } } @@ -443,6 +447,9 @@ public: wxLogFrame(wxWindow *pParent, wxLogWindow *log, const wxString& szTitle); virtual ~wxLogFrame(); + // Don't prevent the application from exiting if just this frame remains. + virtual bool ShouldPreventAppExit() const { return false; } + // menu callbacks void OnClose(wxCommandEvent& event); void OnCloseWindow(wxCloseEvent& event); @@ -451,14 +458,11 @@ public: #endif // CAN_SAVE_FILES void OnClear(wxCommandEvent& event); - // this function is safe to call from any thread (notice that it should be - // also called from the main thread to ensure that the messages logged from - // it appear in correct order with the messages from the other threads) - void AddLogMessage(const wxString& message); - - // actually append the messages logged from secondary threads to the text - // control during idle time in the main thread - virtual void OnInternalIdle(); + // do show the message in the text control + void ShowLogMessage(const wxString& message) + { + m_pTextCtrl->AppendText(message + wxS('\n')); + } private: // use standard ids for our commands! @@ -472,24 +476,9 @@ private: // common part of OnClose() and OnCloseWindow() void DoClose(); - // do show the message in the text control - void DoShowLogMessage(const wxString& message) - { - m_pTextCtrl->AppendText(message + wxS('\n')); - } - wxTextCtrl *m_pTextCtrl; wxLogWindow *m_log; - // queue of messages logged from other threads which need to be displayed - wxArrayString m_pendingMessages; - -#if wxUSE_THREADS - // critical section to protect access to m_pendingMessages - wxCriticalSection m_critSection; -#endif // wxUSE_THREADS - - DECLARE_EVENT_TABLE() wxDECLARE_NO_COPY_CLASS(wxLogFrame); }; @@ -526,7 +515,7 @@ wxLogFrame::wxLogFrame(wxWindow *pParent, wxLogWindow *log, const wxString& szTi wxMenuBar *pMenuBar = new wxMenuBar; wxMenu *pMenu = new wxMenu; #if CAN_SAVE_FILES - pMenu->Append(Menu_Save, _("&Save..."), _("Save log contents to file")); + pMenu->Append(Menu_Save, _("Save &As..."), _("Save log contents to file")); #endif // CAN_SAVE_FILES pMenu->Append(Menu_Clear, _("C&lear"), _("Clear the log contents")); pMenu->AppendSeparator(); @@ -539,8 +528,6 @@ wxLogFrame::wxLogFrame(wxWindow *pParent, wxLogWindow *log, const wxString& szTi // status bar for menu prompts CreateStatusBar(); #endif // wxUSE_STATUSBAR - - m_log->OnFrameCreate(this); } void wxLogFrame::DoClose() @@ -602,43 +589,6 @@ void wxLogFrame::OnClear(wxCommandEvent& WXUNUSED(event)) m_pTextCtrl->Clear(); } -void wxLogFrame::OnInternalIdle() -{ - { - wxCRIT_SECT_LOCKER(locker, m_critSection); - - const size_t count = m_pendingMessages.size(); - for ( size_t n = 0; n < count; n++ ) - { - DoShowLogMessage(m_pendingMessages[n]); - } - - m_pendingMessages.clear(); - } // release m_critSection - - wxFrame::OnInternalIdle(); -} - -void wxLogFrame::AddLogMessage(const wxString& message) -{ - wxCRIT_SECT_LOCKER(locker, m_critSection); - -#if wxUSE_THREADS - if ( !wxThread::IsMain() || !m_pendingMessages.empty() ) - { - // message needs to be queued for later showing - m_pendingMessages.Add(message); - - wxWakeUpIdle(); - } - else // we are the main thread and no messages are queued, so we can - // log the message directly -#endif // wxUSE_THREADS - { - DoShowLogMessage(message); - } -} - wxLogFrame::~wxLogFrame() { m_log->OnFrameDelete(this); @@ -652,6 +602,11 @@ wxLogWindow::wxLogWindow(wxWindow *pParent, bool bShow, bool bDoPass) { + // Initialize it to NULL to ensure that we don't crash if any log messages + // are generated before the frame is fully created (while this doesn't + // happen normally, it might, in principle). + m_pLogFrame = NULL; + PassMessages(bDoPass); m_pLogFrame = new wxLogFrame(pParent, this, szTitle); @@ -667,9 +622,6 @@ void wxLogWindow::Show(bool bShow) void wxLogWindow::DoLogTextAtLevel(wxLogLevel level, const wxString& msg) { - // first let the previous logger show it - wxLogPassThrough::DoLogTextAtLevel(level, msg); - if ( !m_pLogFrame ) return; @@ -681,7 +633,7 @@ void wxLogWindow::DoLogTextAtLevel(wxLogLevel level, const wxString& msg) if ( level == wxLOG_Trace ) return; - m_pLogFrame->AddLogMessage(msg); + m_pLogFrame->ShowLogMessage(msg); } wxFrame *wxLogWindow::GetFrame() const @@ -689,10 +641,6 @@ wxFrame *wxLogWindow::GetFrame() const return m_pLogFrame; } -void wxLogWindow::OnFrameCreate(wxFrame * WXUNUSED(frame)) -{ -} - bool wxLogWindow::OnFrameClose(wxFrame * WXUNUSED(frame)) { // allow to close @@ -766,7 +714,7 @@ wxLogDialog::wxLogDialog(wxWindow *parent, 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 + // sizers even though our window is not resizable to calculate the size of // the dialog properly wxBoxSizer *sizerTop = new wxBoxSizer(wxVERTICAL); wxBoxSizer *sizerAll = new wxBoxSizer(isPda ? wxVERTICAL : wxHORIZONTAL); @@ -797,11 +745,17 @@ wxLogDialog::wxLogDialog(wxWindow *parent, // add the details pane #ifndef __SMARTPHONE__ + +#if wxUSE_COLLPANE wxCollapsiblePane * const collpane = new wxCollapsiblePane(this, wxID_ANY, ms_details); sizerTop->Add(collpane, wxSizerFlags(1).Expand().Border()); wxWindow *win = collpane->GetPane(); +#else + wxPanel* win = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, + wxBORDER_NONE); +#endif wxSizer * const paneSz = new wxBoxSizer(wxVERTICAL); CreateDetailsControls(win); @@ -822,7 +776,7 @@ wxLogDialog::wxLogDialog(wxWindow *parent, btnSizer->Add(new wxButton(win, wxID_SAVE), flagsBtn); #endif // CAN_SAVE_FILES - paneSz->Add(btnSizer, wxSizerFlags().Right().Border(wxTOP)); + paneSz->Add(btnSizer, wxSizerFlags().Right().Border(wxTOP|wxBOTTOM)); #endif // wxUSE_CLIPBOARD || CAN_SAVE_FILES win->SetSizer(paneSz); @@ -852,7 +806,7 @@ void wxLogDialog::CreateDetailsControls(wxWindow *parent) // create the list ctrl now m_listctrl = new wxListCtrl(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, - wxSUNKEN_BORDER | + wxBORDER_SIMPLE | wxLC_REPORT | wxLC_NO_HEADER | wxLC_SINGLE_SEL); @@ -864,17 +818,17 @@ void wxLogDialog::CreateDetailsControls(wxWindow *parent) // no need to translate these strings as they're not shown to the // user anyhow (we use wxLC_NO_HEADER style) - m_listctrl->InsertColumn(0, _T("Message")); + m_listctrl->InsertColumn(0, wxT("Message")); if (hasTimeStamp) - m_listctrl->InsertColumn(1, _T("Time")); + m_listctrl->InsertColumn(1, wxT("Time")); // prepare the imagelist static const int ICON_SIZE = 16; wxImageList *imageList = new wxImageList(ICON_SIZE, ICON_SIZE); // order should be the same as in the switch below! - static const wxChar* icons[] = + static const char* const icons[] = { wxART_ERROR, wxART_WARNING, @@ -890,7 +844,7 @@ void wxLogDialog::CreateDetailsControls(wxWindow *parent) // This may very well fail if there are insufficient colours available. // Degrade gracefully. - if ( !bmp.Ok() ) + if ( !bmp.IsOk() ) { loadedIcons = false;