#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"
+#include "wx/msgout.h"
#if wxUSE_THREADS
#include "wx/thread.h"
#if CAN_SAVE_FILES
void OnSave(wxCommandEvent& event);
#endif // CAN_SAVE_FILES
- void OnListSelect(wxListEvent& event);
void OnListItemActivated(wxListEvent& event);
private:
static size_t ms_maxLength;
DECLARE_EVENT_TABLE()
- DECLARE_NO_COPY_CLASS(wxLogDialog)
+ wxDECLARE_NO_COPY_CLASS(wxLogDialog);
};
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()
#else
wxLog::OnLog(wxLOG_Status, msg, time(NULL));
#endif
- gs_pFrame = (wxFrame *) NULL;
+ gs_pFrame = NULL;
}
}
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()
{
if ( !m_bHasMessages )
// 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
#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);
m_aTimes.Add((long)t);
m_bHasMessages = true;
break;
+
+ default:
+ // let the base class deal with debug/trace messages as well as any
+ // custom levels
+ wxLog::DoLog(level, szString, t);
}
}
DECLARE_EVENT_TABLE()
- DECLARE_NO_COPY_CLASS(wxLogFrame)
+ wxDECLARE_NO_COPY_CLASS(wxLogFrame);
};
BEGIN_EVENT_TABLE(wxLogFrame, wxFrame)
void wxLogWindow::OnFrameDelete(wxFrame * WXUNUSED(frame))
{
- m_pLogFrame = (wxLogFrame *)NULL;
+ m_pLogFrame = NULL;
}
wxLogWindow::~wxLogWindow()
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
// open file
// ---------
- bool bOk = false;
+ bool bOk;
if ( wxFile::Exists(filename) ) {
bool bAppend = false;
wxString strMsg;