X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b6d2b072d84916bd5c84cb927612dd2e2505c362..6f026b5b63fe7ccb025e84509886f74772b9df13:/src/generic/logg.cpp?ds=inline diff --git a/src/generic/logg.cpp b/src/generic/logg.cpp index 4f3eb8e64e..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 ///////////////////////////////////////////////////////////////////////////// @@ -45,15 +44,13 @@ #include "wx/file.h" #include "wx/clipbrd.h" +#include "wx/dataobj.h" #include "wx/textfile.h" #include "wx/statline.h" #include "wx/artprov.h" #include "wx/collpane.h" #include "wx/arrstr.h" - -#if wxUSE_THREADS - #include "wx/thread.h" -#endif // wxUSE_THREADS +#include "wx/msgout.h" #ifdef __WXMSW__ // for OutputDebugString() @@ -71,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) @@ -92,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 } @@ -126,7 +115,6 @@ public: #if CAN_SAVE_FILES void OnSave(wxCommandEvent& event); #endif // CAN_SAVE_FILES - void OnListSelect(wxListEvent& event); void OnListItemActivated(wxListEvent& event); private: @@ -170,7 +158,7 @@ private: static size_t ms_maxLength; DECLARE_EVENT_TABLE() - DECLARE_NO_COPY_CLASS(wxLogDialog) + wxDECLARE_NO_COPY_CLASS(wxLogDialog); }; BEGIN_EVENT_TABLE(wxLogDialog, wxDialog) @@ -181,7 +169,6 @@ BEGIN_EVENT_TABLE(wxLogDialog, wxDialog) #if CAN_SAVE_FILES EVT_BUTTON(wxID_SAVE, wxLogDialog::OnSave) #endif // CAN_SAVE_FILES - EVT_LIST_ITEM_SELECTED(wxID_ANY, wxLogDialog::OnListSelect) EVT_LIST_ITEM_ACTIVATED(wxID_ANY, wxLogDialog::OnListItemActivated) END_EVENT_TABLE() @@ -201,63 +188,10 @@ static int OpenLogFile(wxFile& file, wxString *filename = NULL, wxWindow *parent #endif // CAN_SAVE_FILES -// ---------------------------------------------------------------------------- -// global variables -// ---------------------------------------------------------------------------- - -// we use a global variable to store the frame pointer for wxLogStatus - bad, -// but it's the easiest way -static wxFrame *gs_pFrame = NULL; // FIXME MT-unsafe - // ============================================================================ // implementation // ============================================================================ -// ---------------------------------------------------------------------------- -// global functions -// ---------------------------------------------------------------------------- - -// accepts an additional argument which tells to which frame the output should -// be directed -void wxVLogStatus(wxFrame *pFrame, const wxString& format, va_list argptr) -{ - wxString msg; - - wxLog *pLog = wxLog::GetActiveTarget(); - if ( pLog != NULL ) { - msg.PrintfV(format, argptr); - - wxASSERT( gs_pFrame == NULL ); // should be reset! - gs_pFrame = pFrame; -#ifdef __WXWINCE__ - wxLog::OnLog(wxLOG_Status, msg, 0); -#else - wxLog::OnLog(wxLOG_Status, msg, time(NULL)); -#endif - gs_pFrame = (wxFrame *) NULL; - } -} - -#if !wxUSE_UTF8_LOCALE_ONLY -void wxDoLogStatusWchar(wxFrame *pFrame, const wxChar *format, ...) -{ - va_list argptr; - va_start(argptr, format); - wxVLogStatus(pFrame, format, argptr); - va_end(argptr); -} -#endif // !wxUSE_UTF8_LOCALE_ONLY - -#if wxUSE_UNICODE_UTF8 -void wxDoLogStatusUtf8(wxFrame *pFrame, const char *format, ...) -{ - va_list argptr; - va_start(argptr, format); - wxVLogStatus(pFrame, format, argptr); - va_end(argptr); -} -#endif // wxUSE_UNICODE_UTF8 - // ---------------------------------------------------------------------------- // wxLogGui implementation (FIXME MT-unsafe) // ---------------------------------------------------------------------------- @@ -280,113 +214,124 @@ void wxLogGui::Clear() m_aTimes.Empty(); } +int wxLogGui::GetSeverityIcon() const +{ + return m_bErrors ? wxICON_STOP + : m_bWarnings ? wxICON_EXCLAMATION + : wxICON_INFORMATION; +} + +wxString wxLogGui::GetTitle() const +{ + wxString titleFormat; + switch ( GetSeverityIcon() ) + { + case wxICON_STOP: + titleFormat = _("%s Error"); + break; + + case wxICON_EXCLAMATION: + titleFormat = _("%s Warning"); + break; + + default: + wxFAIL_MSG( "unexpected icon severity" ); + // fall through + + case wxICON_INFORMATION: + titleFormat = _("%s Information"); + } + + return wxString::Format(titleFormat, wxTheApp->GetAppDisplayName()); +} + +void +wxLogGui::DoShowSingleLogMessage(const wxString& message, + const wxString& title, + int style) +{ + wxMessageBox(message, title, wxOK | style); +} + +void +wxLogGui::DoShowMultipleLogMessages(const wxArrayString& messages, + const wxArrayInt& severities, + const wxArrayLong& times, + const wxString& title, + int style) +{ +#if wxUSE_LOG_DIALOG + wxLogDialog dlg(NULL, + messages, severities, times, + title, style); + + // clear the message list before showing the dialog because while it's + // shown some new messages may appear + Clear(); + + (void)dlg.ShowModal(); +#else // !wxUSE_LOG_DIALOG + // start from the most recent message + wxString message; + const size_t nMsgCount = messages.size(); + message.reserve(nMsgCount*100); + for ( size_t n = nMsgCount; n > 0; n-- ) { + message << m_aMessages[n - 1] << wxT("\n"); + } + + DoShowSingleLogMessage(message, title, style); +#endif // wxUSE_LOG_DIALOG/!wxUSE_LOG_DIALOG +} + void wxLogGui::Flush() { + wxLog::Flush(); + if ( !m_bHasMessages ) return; // do it right now to block any new calls to Flush() while we're here m_bHasMessages = false; + // note that this must be done before examining m_aMessages as it may log + // yet another message const unsigned repeatCount = LogLastRepeatIfNeeded(); - wxString appName = wxTheApp->GetAppDisplayName(); + const size_t nMsgCount = m_aMessages.size(); - long style; - wxString titleFormat; - if ( m_bErrors ) { - titleFormat = _("%s Error"); - style = wxICON_STOP; - } - else if ( m_bWarnings ) { - titleFormat = _("%s Warning"); - style = wxICON_EXCLAMATION; - } - else { - titleFormat = _("%s Information"); - style = wxICON_INFORMATION; + if ( repeatCount > 0 ) + { + m_aMessages[nMsgCount - 1] << " (" << m_aMessages[nMsgCount - 2] << ")"; } - wxString title; - title.Printf(titleFormat, appName.c_str()); - - size_t nMsgCount = m_aMessages.GetCount(); + const wxString title = GetTitle(); + const int style = GetSeverityIcon(); // avoid showing other log dialogs until we're done with the dialog we're // showing right now: nested modal dialogs make for really bad UI! Suspend(); - wxString str; if ( nMsgCount == 1 ) { - str = m_aMessages[0]; - } - else // more than one message - { -#if wxUSE_LOG_DIALOG - - if ( repeatCount > 0 ) - { - m_aMessages[nMsgCount - 1] - << " (" << m_aMessages[nMsgCount - 2] << ")"; - } - - wxLogDialog dlg(NULL, - m_aMessages, m_aSeverity, m_aTimes, - title, style); - - // clear the message list before showing the dialog because while it's - // shown some new messages may appear + // make a copy before calling Clear() + const wxString message(m_aMessages[0]); Clear(); - (void)dlg.ShowModal(); -#else // !wxUSE_LOG_DIALOG - // concatenate all strings (but not too many to not overfill the msg box) - size_t nLines = 0; - - // start from the most recent message - for ( size_t n = nMsgCount; n > 0; n-- ) { - // for Windows strings longer than this value are wrapped (NT 4.0) - const size_t nMsgLineWidth = 156; - - nLines += (m_aMessages[n - 1].Len() + nMsgLineWidth - 1) / nMsgLineWidth; - - if ( nLines > 25 ) // don't put too many lines in message box - break; - - str << m_aMessages[n - 1] << wxT("\n"); - } -#endif // wxUSE_LOG_DIALOG/!wxUSE_LOG_DIALOG + DoShowSingleLogMessage(message, title, style); } - - // this catches both cases of 1 message with wxUSE_LOG_DIALOG and any - // situation without it - if ( !str.empty() ) + else // more than one message { - // we use a message dialog with 2 buttons to be able to use one of them - // for copying the message text to clipboard -#if wxUSE_CLIPBOARD - wxMessageDialog dlg(NULL, str, title, style | wxYES_NO); - if ( !dlg.SetYesNoLabels(wxID_COPY, wxID_OK) ) -#endif // wxUSE_CLIPBOARD - { - // but if custom labels are not supported it makes no sense to keep - // two buttons so revert to a single one - dlg.SetMessageDialogStyle(style | wxOK); - } + wxArrayString messages; + wxArrayInt severities; + wxArrayLong times; -#if wxUSE_CLIPBOARD - if ( dlg.ShowModal() == wxID_YES ) - { - // this means the wxID_COPY button was selected - wxClipboardLocker clip; - if ( !clip || !wxTheClipboard->AddData(new wxTextDataObject(str)) ) - wxLogError(_("Failed to copy dialog contents to the clipboard.")); - } -#endif // wxUSE_CLIPBOARD + messages.swap(m_aMessages); + severities.swap(m_aSeverity); + times.swap(m_aTimes); - // no undisplayed messages whatsoever Clear(); + + DoShowMultipleLogMessages(messages, severities, times, title, style); } // allow flushing the logs again @@ -394,16 +339,19 @@ void wxLogGui::Flush() } // log all kinds of messages -void wxLogGui::DoLog(wxLogLevel level, const wxString& szString, time_t t) +void wxLogGui::DoLogRecord(wxLogLevel level, + const wxString& msg, + const wxLogRecordInfo& info) { - switch ( level ) { + switch ( level ) + { case wxLOG_Info: if ( GetVerbose() ) case wxLOG_Message: { - m_aMessages.Add(szString); + m_aMessages.Add(msg); m_aSeverity.Add(wxLOG_Message); - m_aTimes.Add((long)t); + m_aTimes.Add((long)info.timestamp); m_bHasMessages = true; } break; @@ -411,53 +359,29 @@ void wxLogGui::DoLog(wxLogLevel level, const wxString& szString, time_t t) case wxLOG_Status: #if wxUSE_STATUSBAR { + wxFrame *pFrame = NULL; + + // check if the frame was passed to us explicitly + wxUIntPtr ptr = 0; + if ( info.GetNumValue(wxLOG_KEY_FRAME, &ptr) ) + { + pFrame = static_cast(wxUIntToPtr(ptr)); + } + // 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)) ) { + if ( wxDynamicCast(pWin, wxFrame) ) { pFrame = (wxFrame *)pWin; } } if ( pFrame && pFrame->GetStatusBar() ) - pFrame->SetStatusText(szString); + pFrame->SetStatusText(msg); } #endif // wxUSE_STATUSBAR break; - case wxLOG_Trace: - case wxLOG_Debug: - #ifdef __WXDEBUG__ - { - wxString str; - TimeStamp(&str); - str += szString; - - #if defined(__WXMSW__) && !defined(__WXMICROWIN__) - // don't prepend debug/trace here: it goes to the - // debug window anyhow - str += wxT("\r\n"); - OutputDebugString(str.wx_str()); - #else - // send them to stderr - wxFprintf(stderr, wxT("[%s] %s\n"), - level == wxLOG_Trace ? wxT("Trace") - : wxT("Debug"), - str.c_str()); - fflush(stderr); - #endif - } - #endif // __WXDEBUG__ - - break; - - case wxLOG_FatalError: - // show this one immediately - wxMessageBox(szString, _("Fatal error"), wxICON_HAND); - wxExit(); - break; - case wxLOG_Error: if ( !m_bErrors ) { #if !wxUSE_LOG_DIALOG @@ -478,11 +402,31 @@ void wxLogGui::DoLog(wxLogLevel level, const wxString& szString, time_t t) m_bWarnings = true; } - m_aMessages.Add(szString); + m_aMessages.Add(msg); m_aSeverity.Add((int)level); - m_aTimes.Add((long)t); + m_aTimes.Add((long)info.timestamp); m_bHasMessages = true; break; + + 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; } } @@ -503,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); @@ -511,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! @@ -532,26 +476,11 @@ 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); - } - 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() - DECLARE_NO_COPY_CLASS(wxLogFrame) + wxDECLARE_NO_COPY_CLASS(wxLogFrame); }; BEGIN_EVENT_TABLE(wxLogFrame, wxFrame) @@ -586,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(); @@ -599,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() @@ -662,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); @@ -712,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); @@ -725,46 +620,20 @@ void wxLogWindow::Show(bool bShow) m_pLogFrame->Show(bShow); } -void wxLogWindow::DoLog(wxLogLevel level, const wxString& 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 ( !szString.empty() ) - { - wxString str; - str << _("Status: ") << szString; - LogString(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 wxString& szString, time_t WXUNUSED(t)) +void wxLogWindow::DoLogTextAtLevel(wxLogLevel level, const wxString& msg) { - wxString msg; + if ( !m_pLogFrame ) + return; - TimeStamp(&msg); - msg << szString << wxT('\n'); + // 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 (e.g. wxMSW code uses + // wxLogTrace to log Windows messages and adding text to the control + // sends more of them) thus sending a program into an infinite loop + if ( level == wxLOG_Trace ) + return; - m_pLogFrame->AddLogMessage(msg); + m_pLogFrame->ShowLogMessage(msg); } wxFrame *wxLogWindow::GetFrame() const @@ -772,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 @@ -784,7 +649,7 @@ bool wxLogWindow::OnFrameClose(wxFrame * WXUNUSED(frame)) void wxLogWindow::OnFrameDelete(wxFrame * WXUNUSED(frame)) { - m_pLogFrame = (wxLogFrame *)NULL; + m_pLogFrame = NULL; } wxLogWindow::~wxLogWindow() @@ -849,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); @@ -880,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); @@ -905,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); @@ -929,10 +800,13 @@ wxLogDialog::wxLogDialog(wxWindow *parent, void wxLogDialog::CreateDetailsControls(wxWindow *parent) { + wxString fmt = wxLog::GetTimestamp(); + bool hasTimeStamp = !fmt.IsEmpty(); + // 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); @@ -944,15 +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(1, _T("Time")); + m_listctrl->InsertColumn(0, wxT("Message")); + + if (hasTimeStamp) + 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, @@ -968,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; @@ -980,14 +856,7 @@ void wxLogDialog::CreateDetailsControls(wxWindow *parent) m_listctrl->SetImageList(imageList, wxIMAGE_LIST_SMALL); - // and fill it - wxString fmt = wxLog::GetTimestamp(); - if ( !fmt ) - { - // default format - fmt = _T("%c"); - } - + // fill the listctrl size_t count = m_messages.GetCount(); for ( size_t n = 0; n < count; n++ ) { @@ -1019,12 +888,15 @@ void wxLogDialog::CreateDetailsControls(wxWindow *parent) msg = EllipsizeString(msg); m_listctrl->InsertItem(n, msg, image); - m_listctrl->SetItem(n, 1, TimeStamp(fmt, (time_t)m_times[n])); + + if (hasTimeStamp) + m_listctrl->SetItem(n, 1, TimeStamp(fmt, (time_t)m_times[n])); } // let the columns size themselves m_listctrl->SetColumnWidth(0, wxLIST_AUTOSIZE); - m_listctrl->SetColumnWidth(1, wxLIST_AUTOSIZE); + if (hasTimeStamp) + m_listctrl->SetColumnWidth(1, wxLIST_AUTOSIZE); // calculate an approximately nice height for the listctrl int height = GetCharHeight()*(count + 4); @@ -1043,14 +915,6 @@ void wxLogDialog::CreateDetailsControls(wxWindow *parent) m_listctrl->SetSize(wxDefaultCoord, wxMin(height, heightMax)); } -void wxLogDialog::OnListSelect(wxListEvent& event) -{ - // we can't just disable the control because this looks ugly under Windows - // (wrong bg colour, no scrolling...), but we still want to disable - // selecting items - it makes no sense here - m_listctrl->SetItemState(event.GetIndex(), 0, wxLIST_STATE_SELECTED); -} - void wxLogDialog::OnListItemActivated(wxListEvent& event) { // show the activated item in a message box @@ -1128,7 +992,9 @@ void wxLogDialog::OnSave(wxCommandEvent& WXUNUSED(event)) } if ( !rc || !file.Write(GetLogMessages()) || !file.Close() ) + { wxLogError(_("Can't save log contents to file.")); + } } #endif // CAN_SAVE_FILES @@ -1161,7 +1027,7 @@ static int OpenLogFile(wxFile& file, wxString *pFilename, wxWindow *parent) // open file // --------- - bool bOk = false; + bool bOk = true; // suppress warning about it being possible uninitialized if ( wxFile::Exists(filename) ) { bool bAppend = false; wxString strMsg; @@ -1216,13 +1082,9 @@ wxLogTextCtrl::wxLogTextCtrl(wxTextCtrl *pTextCtrl) m_pTextCtrl = pTextCtrl; } -void wxLogTextCtrl::DoLogString(const wxString& szString, time_t WXUNUSED(t)) +void wxLogTextCtrl::DoLogText(const wxString& msg) { - wxString msg; - TimeStamp(&msg); - - msg << szString << wxT('\n'); - m_pTextCtrl->AppendText(msg); + m_pTextCtrl->AppendText(msg + wxS('\n')); } #endif // wxUSE_LOG && wxUSE_TEXTCTRL