X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/03147cd08e78ba8a709ee019a8a51ac6b57e6f32..eb3d60a26ffb31824b3600281e1f4944c153241b:/src/generic/logg.cpp diff --git a/src/generic/logg.cpp b/src/generic/logg.cpp index 911c39c5a7..cda1784ab1 100644 --- a/src/generic/logg.cpp +++ b/src/generic/logg.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: logg.cpp +// Name: src/generic/logg.cpp // Purpose: wxLog-derived classes which need GUI support (the rest is in // src/common/log.cpp) // Author: Vadim Zeitlin @@ -7,7 +7,7 @@ // Created: 20.09.99 (extracted from src/common/log.cpp) // RCS-ID: $Id$ // Copyright: (c) 1998 Vadim Zeitlin -// Licence: wxWindows license +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// // ============================================================================ @@ -18,7 +18,9 @@ // headers // ---------------------------------------------------------------------------- -// no #pragma implementation "log.h" because it's already in src/common/log.cpp +#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) + #pragma implementation "logg.h" +#endif // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" @@ -27,10 +29,6 @@ #pragma hdrstop #endif -#if !wxUSE_GUI - #error "This file can't be compiled without GUI!" -#endif - #ifndef WX_PRECOMP #include "wx/app.h" #include "wx/button.h" @@ -44,6 +42,7 @@ #include "wx/sizer.h" #include "wx/statbmp.h" #include "wx/button.h" + #include "wx/settings.h" #endif // WX_PRECOMP #if wxUSE_LOGGUI || wxUSE_LOGWINDOW @@ -51,12 +50,17 @@ #include "wx/file.h" #include "wx/textfile.h" #include "wx/statline.h" +#include "wx/artprov.h" #ifdef __WXMSW__ // for OutputDebugString() #include "wx/msw/private.h" #endif // Windows +#ifdef __WXPM__ + #include +#endif + #if wxUSE_LOG_DIALOG #include "wx/listctrl.h" #include "wx/imaglist.h" @@ -65,6 +69,15 @@ #include "wx/msgdlg.h" #endif // wxUSE_LOG_DIALOG/!wxUSE_LOG_DIALOG +#if defined(__MWERKS__) && wxUSE_UNICODE + #include +#endif + +#include "wx/datetime.h" + +// the suffix we add to the button to show that the dialog can be expanded +#define EXPAND_SUFFIX _T(" >>") + // ---------------------------------------------------------------------------- // private classes // ---------------------------------------------------------------------------- @@ -75,6 +88,10 @@ // allows to exclude the usage of wxDateTime static wxString TimeStamp(const wxChar *format, time_t t) { +#ifdef __WXWINCE__ + // FIXME + return wxEmptyString; +#else wxChar buf[4096]; if ( !wxStrftime(buf, WXSIZEOF(buf), format, localtime(&t)) ) { @@ -82,6 +99,7 @@ static wxString TimeStamp(const wxChar *format, time_t t) wxFAIL_MSG(_T("strftime() failed")); } return wxString(buf); +#endif } @@ -131,15 +149,16 @@ private: static wxString ms_details; DECLARE_EVENT_TABLE() + DECLARE_NO_COPY_CLASS(wxLogDialog) }; BEGIN_EVENT_TABLE(wxLogDialog, wxDialog) - EVT_BUTTON(wxID_CANCEL, wxLogDialog::OnOk) + EVT_BUTTON(wxID_OK, wxLogDialog::OnOk) EVT_BUTTON(wxID_MORE, wxLogDialog::OnDetails) #if wxUSE_FILE EVT_BUTTON(wxID_SAVE, wxLogDialog::OnSave) #endif // wxUSE_FILE - EVT_LIST_ITEM_SELECTED(-1, wxLogDialog::OnListSelect) + EVT_LIST_ITEM_SELECTED(wxID_ANY, wxLogDialog::OnListSelect) END_EVENT_TABLE() #endif // wxUSE_LOG_DIALOG @@ -151,10 +170,10 @@ END_EVENT_TABLE() #if wxUSE_FILE && wxUSE_FILEDLG // pass an uninitialized file object, the function will ask the user for the -// filename and try to open it, returns TRUE on success (file was opened), -// FALSE if file couldn't be opened/created and -1 if the file selection +// filename and try to open it, returns true on success (file was opened), +// false if file couldn't be opened/created and -1 if the file selection // dialog was cancelled -static int OpenLogFile(wxFile& file, wxString *filename = NULL); +static int OpenLogFile(wxFile& file, wxString *filename = NULL, wxWindow *parent = NULL); #endif // wxUSE_FILE @@ -164,7 +183,7 @@ static int OpenLogFile(wxFile& file, wxString *filename = NULL); // we use a global variable to store the frame pointer for wxLogStatus - bad, // but it's the easiest way -static wxFrame *gs_pFrame; // FIXME MT-unsafe +static wxFrame *gs_pFrame = NULL; // FIXME MT-unsafe // ============================================================================ // implementation @@ -176,28 +195,39 @@ static wxFrame *gs_pFrame; // FIXME MT-unsafe // accepts an additional argument which tells to which frame the output should // be directed -void wxLogStatus(wxFrame *pFrame, const wxChar *szFormat, ...) +void wxVLogStatus(wxFrame *pFrame, const wxChar *szFormat, va_list argptr) { wxString msg; wxLog *pLog = wxLog::GetActiveTarget(); if ( pLog != NULL ) { - va_list argptr; - va_start(argptr, szFormat); msg.PrintfV(szFormat, argptr); - va_end(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; } } +void wxLogStatus(wxFrame *pFrame, const wxChar *szFormat, ...) +{ + va_list argptr; + va_start(argptr, szFormat); + wxVLogStatus(pFrame, szFormat, argptr); + va_end(argptr); +} + // ---------------------------------------------------------------------------- // wxLogGui implementation (FIXME MT-unsafe) // ---------------------------------------------------------------------------- +#if wxUSE_LOGGUI + wxLogGui::wxLogGui() { Clear(); @@ -207,7 +237,7 @@ void wxLogGui::Clear() { m_bErrors = m_bWarnings = - m_bHasMessages = FALSE; + m_bHasMessages = false; m_aMessages.Empty(); m_aSeverity.Empty(); @@ -220,11 +250,11 @@ void wxLogGui::Flush() return; // do it right now to block any new calls to Flush() while we're here - m_bHasMessages = FALSE; + m_bHasMessages = false; wxString appName = wxTheApp->GetAppName(); - if ( !!appName ) - appName[0u] = wxToupper(appName[0u]); + if ( !appName.empty() ) + appName[0u] = (wxChar)wxToupper(appName[0u]); long style; wxString titleFormat; @@ -244,11 +274,12 @@ void wxLogGui::Flush() wxString title; title.Printf(titleFormat, appName.c_str()); - // this is the best we can do here - wxWindow *parent = wxTheApp->GetTopWindow(); - size_t nMsgCount = m_aMessages.Count(); + // 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 ) { @@ -258,7 +289,7 @@ void wxLogGui::Flush() { #if wxUSE_LOG_DIALOG - wxLogDialog dlg(parent, + wxLogDialog dlg(NULL, m_aMessages, m_aSeverity, m_aTimes, title, style); @@ -288,13 +319,16 @@ void wxLogGui::Flush() // this catches both cases of 1 message with wxUSE_LOG_DIALOG and any // situation without it - if ( !!str ) + if ( !str.empty() ) { - wxMessageBox(str, title, wxOK | style, parent); + wxMessageBox(str, title, wxOK | style); // no undisplayed messages whatsoever Clear(); } + + // allow flushing the logs again + Resume(); } // log all kinds of messages @@ -305,12 +339,10 @@ void wxLogGui::DoLog(wxLogLevel level, const wxChar *szString, time_t t) if ( GetVerbose() ) case wxLOG_Message: { - if ( !m_bErrors ) { - m_aMessages.Add(szString); - m_aSeverity.Add(wxLOG_Message); - m_aTimes.Add((long)t); - m_bHasMessages = TRUE; - } + m_aMessages.Add(szString); + m_aSeverity.Add(wxLOG_Message); + m_aTimes.Add((long)t); + m_bHasMessages = true; } break; @@ -336,19 +368,21 @@ void wxLogGui::DoLog(wxLogLevel level, const wxChar *szString, time_t t) 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, but do put a timestamp - wxString str; - TimeStamp(&str); - str << szString << wxT("\r\n"); + // debug window anyhow + str += wxT("\r\n"); OutputDebugString(str); #else // send them to stderr - wxFprintf(stderr, wxT("%s: %s\n"), + wxFprintf(stderr, wxT("[%s] %s\n"), level == wxLOG_Trace ? wxT("Trace") : wxT("Debug"), - szString); + str.c_str()); fflush(stderr); #endif } @@ -372,24 +406,26 @@ void wxLogGui::DoLog(wxLogLevel level, const wxChar *szString, time_t t) m_aSeverity.Empty(); m_aTimes.Empty(); #endif // wxUSE_LOG_DIALOG - m_bErrors = 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_bWarnings = true; } m_aMessages.Add(szString); m_aSeverity.Add((int)level); m_aTimes.Add((long)t); - m_bHasMessages = TRUE; + m_bHasMessages = true; break; } } +#endif // wxUSE_LOGGUI + // ---------------------------------------------------------------------------- // wxLogWindow and wxLogFrame implementation // ---------------------------------------------------------------------------- @@ -400,7 +436,7 @@ class wxLogFrame : public wxFrame { public: // ctor & dtor - wxLogFrame(wxFrame *pParent, wxLogWindow *log, const wxChar *szTitle); + wxLogFrame(wxWindow *pParent, wxLogWindow *log, const wxChar *szTitle); virtual ~wxLogFrame(); // menu callbacks @@ -411,8 +447,6 @@ public: #endif // wxUSE_FILE void OnClear(wxCommandEvent& event); - void OnIdle(wxIdleEvent&); - // accessors wxTextCtrl *TextCtrl() const { return m_pTextCtrl; } @@ -432,6 +466,7 @@ private: wxLogWindow *m_log; DECLARE_EVENT_TABLE() + DECLARE_NO_COPY_CLASS(wxLogFrame) }; BEGIN_EVENT_TABLE(wxLogFrame, wxFrame) @@ -445,15 +480,20 @@ BEGIN_EVENT_TABLE(wxLogFrame, wxFrame) EVT_CLOSE(wxLogFrame::OnCloseWindow) END_EVENT_TABLE() -wxLogFrame::wxLogFrame(wxFrame *pParent, wxLogWindow *log, const wxChar *szTitle) - : wxFrame(pParent, -1, szTitle) +wxLogFrame::wxLogFrame(wxWindow *pParent, wxLogWindow *log, const wxChar *szTitle) + : wxFrame(pParent, wxID_ANY, szTitle) { m_log = log; - m_pTextCtrl = new wxTextCtrl(this, -1, wxEmptyString, wxDefaultPosition, + 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 @@ -484,7 +524,7 @@ void wxLogFrame::DoClose() { // instead of closing just hide the window to be able to Show() it // later - Show(FALSE); + Show(false); } } @@ -504,7 +544,7 @@ void wxLogFrame::OnSave(wxCommandEvent& WXUNUSED(event)) #if wxUSE_FILEDLG wxString filename; wxFile file; - int rc = OpenLogFile(file, &filename); + int rc = OpenLogFile(file, &filename, this); if ( rc == -1 ) { // cancelled @@ -547,7 +587,7 @@ wxLogFrame::~wxLogFrame() // wxLogWindow // ----------- -wxLogWindow::wxLogWindow(wxFrame *pParent, +wxLogWindow::wxLogWindow(wxWindow *pParent, const wxChar *szTitle, bool bShow, bool bDoPass) @@ -557,7 +597,7 @@ wxLogWindow::wxLogWindow(wxFrame *pParent, m_pLogFrame = new wxLogFrame(pParent, this, szTitle); if ( bShow ) - m_pLogFrame->Show(TRUE); + m_pLogFrame->Show(); } void wxLogWindow::Show(bool bShow) @@ -595,8 +635,6 @@ void wxLogWindow::DoLog(wxLogLevel level, const wxChar *szString, time_t t) wxLog::DoLog(level, szString, t); } } - - m_bHasMessages = TRUE; } void wxLogWindow::DoLogString(const wxChar *szString, time_t WXUNUSED(t)) @@ -606,7 +644,7 @@ void wxLogWindow::DoLogString(const wxChar *szString, time_t WXUNUSED(t)) // remove selection (WriteText is in fact ReplaceSelection) #ifdef __WXMSW__ - long nLen = pText->GetLastPosition(); + wxTextPos nLen = pText->GetLastPosition(); pText->SetSelection(nLen, nLen); #endif // Windows @@ -631,7 +669,7 @@ void wxLogWindow::OnFrameCreate(wxFrame * WXUNUSED(frame)) bool wxLogWindow::OnFrameClose(wxFrame * WXUNUSED(frame)) { // allow to close - return TRUE; + return true; } void wxLogWindow::OnFrameDelete(wxFrame * WXUNUSED(frame)) @@ -661,9 +699,11 @@ wxLogDialog::wxLogDialog(wxWindow *parent, const wxArrayLong& times, const wxString& caption, long style) - : wxDialog(parent, -1, caption) + : wxDialog(parent, wxID_ANY, caption, + wxDefaultPosition, wxDefaultSize, + wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) { - if ( ms_details.IsEmpty() ) + if ( ms_details.empty() ) { // ensure that we won't loop here if wxGetTranslation() // happens to pop up a Log message while translating this :-) @@ -679,18 +719,13 @@ wxLogDialog::wxLogDialog(wxWindow *parent, for ( size_t n = 0; n < count; n++ ) { wxString msg = messages[n]; - do - { - m_messages.Add(msg.BeforeFirst(_T('\n'))); - msg = msg.AfterFirst(_T('\n')); - - m_severity.Add(severity[n]); - m_times.Add(times[n]); - } - while ( !!msg ); + 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_showingDetails = false; // not initially m_listctrl = (wxListCtrl *)NULL; #if wxUSE_STATLINE @@ -708,42 +743,65 @@ wxLogDialog::wxLogDialog(wxWindow *parent, wxBoxSizer *sizerButtons = new wxBoxSizer(wxVERTICAL); wxBoxSizer *sizerAll = new wxBoxSizer(wxHORIZONTAL); - // this "Ok" button has wxID_CANCEL id - not very logical, but this allows - // to close the log dialog with which wouldn't work otherwise (as it - // translates into click on cancel button) - wxButton *btnOk = new wxButton(this, wxID_CANCEL, _("OK")); - sizerButtons->Add(btnOk, 0, wxCENTRE|wxBOTTOM, MARGIN/2); - m_btnDetails = new wxButton(this, wxID_MORE, ms_details + _T(" >>")); - sizerButtons->Add(m_btnDetails, 0, wxCENTRE|wxTOP, MARGIN/2 - 1); + wxButton *btnOk = new wxButton(this, wxID_OK); + sizerButtons->Add(btnOk, 0, wxCENTRE | wxBOTTOM, MARGIN/2); + m_btnDetails = new wxButton(this, wxID_MORE, ms_details + EXPAND_SUFFIX); + sizerButtons->Add(m_btnDetails, 0, wxCENTRE | wxTOP, MARGIN/2 - 1); + + wxBitmap bitmap; + switch ( style & wxICON_MASK ) + { + case wxICON_ERROR: + bitmap = wxArtProvider::GetIcon(wxART_ERROR, wxART_MESSAGE_BOX); +#ifdef __WXPM__ + bitmap.SetId(wxICON_SMALL_ERROR); +#endif + break; + + case wxICON_INFORMATION: + bitmap = wxArtProvider::GetIcon(wxART_INFORMATION, wxART_MESSAGE_BOX); +#ifdef __WXPM__ + bitmap.SetId(wxICON_SMALL_INFO); +#endif + break; + + case wxICON_WARNING: + bitmap = wxArtProvider::GetIcon(wxART_WARNING, wxART_MESSAGE_BOX); +#ifdef __WXPM__ + bitmap.SetId(wxICON_SMALL_WARNING); +#endif + break; -#ifndef __WIN16__ - wxIcon icon = wxTheApp->GetStdIcon((int)(style & wxICON_MASK)); - sizerAll->Add(new wxStaticBitmap(this, -1, icon), 0, wxCENTRE); -#endif // !Win16 + default: + wxFAIL_MSG(_T("incorrect log style")); + } + sizerAll->Add(new wxStaticBitmap(this, wxID_ANY, bitmap), 0, + wxALIGN_CENTRE_VERTICAL); const wxString& message = messages.Last(); - sizerAll->Add(CreateTextSizer(message), 0, wxCENTRE|wxLEFT|wxRIGHT, MARGIN); - sizerAll->Add(sizerButtons, 0, wxALIGN_RIGHT|wxLEFT, MARGIN); + sizerAll->Add(CreateTextSizer(message), 1, + wxALIGN_CENTRE_VERTICAL | wxLEFT | wxRIGHT, MARGIN); + sizerAll->Add(sizerButtons, 0, wxALIGN_RIGHT | wxLEFT, MARGIN); - sizerTop->Add(sizerAll, 0, wxCENTRE|wxALL, MARGIN); + sizerTop->Add(sizerAll, 0, wxALL | wxEXPAND, MARGIN); - SetAutoLayout(TRUE); SetSizer(sizerTop); - sizerTop->SetSizeHints(this); - sizerTop->Fit(this); + // see comments in OnDetails() + // + // Note: Doing this, this way, triggered a nasty bug in + // wxTopLevelWindowGTK::GtkOnSize which took -1 literally once + // either of maxWidth or maxHeight was set. This symptom has been + // fixed there, but it is a problem that remains as long as we allow + // unchecked access to the internal size members. We really need to + // encapuslate window sizes more cleanly and make it clear when -1 will + // be substituted and when it will not. - btnOk->SetFocus(); + wxSize size = sizerTop->Fit(this); + m_maxHeight = size.y; + SetSizeHints(size.x, size.y, m_maxWidth, m_maxHeight); - // this can't happen any more as we don't use this dialog in this case -#if 0 - if ( count == 1 ) - { - // no details... it's easier to disable a button than to change the - // dialog layout depending on whether we have details or not - m_btnDetails->Disable(); - } -#endif // 0 + btnOk->SetFocus(); Centre(); } @@ -752,15 +810,15 @@ void wxLogDialog::CreateDetailsControls() { // create the save button and separator line if possible #if wxUSE_FILE - m_btnSave = new wxButton(this, wxID_SAVE, _("&Save...")); + m_btnSave = new wxButton(this, wxID_SAVE); #endif // wxUSE_FILE #if wxUSE_STATLINE - m_statline = new wxStaticLine(this, -1); + m_statline = new wxStaticLine(this, wxID_ANY); #endif // wxUSE_STATLINE // create the list ctrl now - m_listctrl = new wxListCtrl(this, -1, + m_listctrl = new wxListCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER | wxLC_REPORT | @@ -777,87 +835,91 @@ void wxLogDialog::CreateDetailsControls() wxImageList *imageList = new wxImageList(ICON_SIZE, ICON_SIZE); // order should be the same as in the switch below! - static const int icons[] = + static const wxChar* icons[] = { - wxICON_ERROR, - wxICON_EXCLAMATION, - wxICON_INFORMATION + wxART_ERROR, + wxART_WARNING, + wxART_INFORMATION }; - bool loadedIcons = TRUE; + bool loadedIcons = true; -#ifndef __WIN16__ for ( size_t icon = 0; icon < WXSIZEOF(icons); icon++ ) { - wxBitmap bmp = wxTheApp->GetStdIcon(icons[icon]); + wxBitmap bmp = wxArtProvider::GetBitmap(icons[icon], wxART_MESSAGE_BOX, + wxSize(ICON_SIZE, ICON_SIZE)); + + // This may very well fail if there are insufficient colours available. + // Degrade gracefully. + if ( !bmp.Ok() ) + { + loadedIcons = false; - // This may very well fail if there are insufficient - // colours available. Degrade gracefully. + break; + } - if (!bmp.Ok()) - loadedIcons = FALSE; - else - imageList->Add(wxImage(bmp). - Rescale(ICON_SIZE, ICON_SIZE). - ConvertToBitmap()); + imageList->Add(bmp); } m_listctrl->SetImageList(imageList, wxIMAGE_LIST_SMALL); -#endif // !Win16 // and fill it wxString fmt = wxLog::GetTimestamp(); if ( !fmt ) { // default format - fmt = _T("%c"); + fmt = wxDefaultDateTimeFormat; } size_t count = m_messages.GetCount(); for ( size_t n = 0; n < count; n++ ) { - int image = -1; -#ifndef __WIN16__ - switch ( m_severity[n] ) + int image; + + if ( loadedIcons ) { - case wxLOG_Error: - image = 0; - break; + switch ( m_severity[n] ) + { + case wxLOG_Error: + image = 0; + break; - case wxLOG_Warning: - image = 1; - break; + case wxLOG_Warning: + image = 1; + break; - default: - image = 2; + default: + image = 2; + } } -#endif // !Win16 - - if (!loadedIcons) + else // failed to load images + { image = -1; + } - if (image > -1) - m_listctrl->InsertItem(n, m_messages[n], image); - else - m_listctrl->InsertItem(n, m_messages[n]); - - m_listctrl->SetItem(n, 1, - TimeStamp(fmt, (time_t)m_times[n])); + m_listctrl->InsertItem(n, m_messages[n], image); + 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); - // get the approx height of the listctrl - wxFont font = GetFont(); - if ( !font.Ok() ) - font = *wxSWISS_FONT; + // calculate an approximately nice height for the listctrl + int height = GetCharHeight()*(count + 4); + + // but check that the dialog won't fall fown from the screen + // + // we use GetMinHeight() to get the height of the dialog part without the + // details and we consider that the "Save" button below and the separator + // line (and the margins around it) take about as much, hence double it + int heightMax = wxGetDisplaySize().y - GetPosition().y - 2*GetMinHeight(); - int y; - GetTextExtent(_T("H"), (int*)NULL, &y, (int*)NULL, (int*)NULL, &font); - int height = wxMax(y*(count + 3), 100); - m_listctrl->SetSize(-1, height); + // we should leave a margin + heightMax *= 9; + heightMax /= 10; + + m_listctrl->SetSize(wxDefaultCoord, wxMin(height, heightMax)); } void wxLogDialog::OnListSelect(wxListEvent& event) @@ -879,7 +941,7 @@ void wxLogDialog::OnSave(wxCommandEvent& WXUNUSED(event)) { #if wxUSE_FILEDLG wxFile file; - int rc = OpenLogFile(file); + int rc = OpenLogFile(file, NULL, this); if ( rc == -1 ) { // cancelled @@ -892,7 +954,7 @@ void wxLogDialog::OnSave(wxCommandEvent& WXUNUSED(event)) if ( !fmt ) { // default format - fmt = _T("%c"); + fmt = wxDefaultDateTimeFormat; } size_t count = m_messages.GetCount(); @@ -912,7 +974,7 @@ void wxLogDialog::OnSave(wxCommandEvent& WXUNUSED(event)) if ( !ok ) wxLogError(_("Can't save log contents to file.")); -#endif +#endif // wxUSE_FILEDLG } #endif // wxUSE_FILE @@ -923,16 +985,16 @@ void wxLogDialog::OnDetails(wxCommandEvent& WXUNUSED(event)) if ( m_showingDetails ) { - m_btnDetails->SetLabel(ms_details + _T(">>")); + m_btnDetails->SetLabel(ms_details + EXPAND_SUFFIX); - sizer->Remove(m_listctrl); + sizer->Detach( m_listctrl ); #if wxUSE_STATLINE - sizer->Remove(m_statline); + sizer->Detach( m_statline ); #endif // wxUSE_STATLINE #if wxUSE_FILE - sizer->Remove(m_btnSave); + sizer->Detach( m_btnSave ); #endif // wxUSE_FILE } else // show details now @@ -950,6 +1012,15 @@ void wxLogDialog::OnDetails(wxCommandEvent& WXUNUSED(event)) sizer->Add(m_listctrl, 1, wxEXPAND | (wxALL & ~wxTOP), MARGIN); + // VZ: this doesn't work as this becomes the initial (and not only + // minimal) listctrl height as well - why? +#if 0 + // allow the user to make the dialog shorter than its initial height - + // without this it wouldn't work as the list ctrl would have been + // incompressible + sizer->SetItemMinSize(m_listctrl, 100, 3*GetCharHeight()); +#endif // 0 + #if wxUSE_FILE sizer->Add(m_btnSave, 0, wxALIGN_RIGHT | (wxALL & ~wxTOP), MARGIN); #endif // wxUSE_FILE @@ -957,15 +1028,40 @@ void wxLogDialog::OnDetails(wxCommandEvent& WXUNUSED(event)) m_showingDetails = !m_showingDetails; - // in any case, our size changed - update - sizer->SetSizeHints(this); - sizer->Fit(this); + // in any case, our size changed - relayout everything and set new hints + // --------------------------------------------------------------------- + + // we have to reset min size constraints or Fit() would never reduce the + // dialog size when collapsing it and we have to reset max constraint + // because it wouldn't expand it otherwise + + m_minHeight = + m_maxHeight = -1; + + // wxSizer::FitSize() is private, otherwise we might use it directly... + wxSize sizeTotal = GetSize(), + sizeClient = GetClientSize(); + + wxSize size = sizer->GetMinSize(); + size.x += sizeTotal.x - sizeClient.x; + size.y += sizeTotal.y - sizeClient.y; + + // we don't want to allow expanding the dialog in vertical direction as + // this would show the "hidden" details but we can resize the dialog + // vertically while the details are shown + if ( !m_showingDetails ) + m_maxHeight = size.y; + + SetSizeHints(size.x, size.y, m_maxWidth, m_maxHeight); + + // don't change the width when expanding/collapsing + SetSize(wxDefaultCoord, size.y); #ifdef __WXGTK__ // VS: this is neccessary in order to force frame redraw under // WindowMaker or fvwm2 (and probably other broken WMs). // Otherwise, detailed list wouldn't be displayed. - Show(TRUE); + Show(); #endif // wxGTK } @@ -982,14 +1078,14 @@ wxLogDialog::~wxLogDialog() #if wxUSE_FILE && wxUSE_FILEDLG // pass an uninitialized file object, the function will ask the user for the -// filename and try to open it, returns TRUE on success (file was opened), -// FALSE if file couldn't be opened/created and -1 if the file selection +// filename and try to open it, returns true on success (file was opened), +// false if file couldn't be opened/created and -1 if the file selection // dialog was cancelled -static int OpenLogFile(wxFile& file, wxString *pFilename) +static int OpenLogFile(wxFile& file, wxString *pFilename, wxWindow *parent) { // get the file name // ----------------- - wxString filename = wxSaveFileSelector(wxT("log"), wxT("txt"), wxT("log.txt")); + wxString filename = wxSaveFileSelector(wxT("log"), wxT("txt"), wxT("log.txt"), parent); if ( !filename ) { // cancelled return -1; @@ -997,20 +1093,20 @@ static int OpenLogFile(wxFile& file, wxString *pFilename) // open file // --------- - bool bOk = FALSE; + bool bOk; if ( wxFile::Exists(filename) ) { - bool bAppend = FALSE; + bool bAppend = false; wxString strMsg; strMsg.Printf(_("Append log to file '%s' (choosing [No] will overwrite it)?"), filename.c_str()); switch ( wxMessageBox(strMsg, _("Question"), wxICON_QUESTION | wxYES_NO | wxCANCEL) ) { case wxYES: - bAppend = TRUE; + bAppend = true; break; case wxNO: - bAppend = FALSE; + bAppend = false; break; case wxCANCEL: @@ -1024,7 +1120,7 @@ static int OpenLogFile(wxFile& file, wxString *pFilename) bOk = file.Open(filename, wxFile::write_append); } else { - bOk = file.Create(filename, TRUE /* overwrite */); + bOk = file.Create(filename, true /* overwrite */); } } else { @@ -1041,7 +1137,7 @@ static int OpenLogFile(wxFile& file, wxString *pFilename) #endif // !(wxUSE_LOGGUI || wxUSE_LOGWINDOW) -#if wxUSE_TEXTCTRL +#if wxUSE_LOG && wxUSE_TEXTCTRL // ---------------------------------------------------------------------------- // wxLogTextCtrl implementation @@ -1057,16 +1153,9 @@ void wxLogTextCtrl::DoLogString(const wxChar *szString, time_t WXUNUSED(t)) wxString msg; TimeStamp(&msg); -#ifdef __WXMAC__ - // VZ: this is a bug in wxMac, it *must* accept '\n' as new line, the - // translation must be done in wxTextCtrl, not here! (FIXME) - msg << szString << wxT('\r'); -#else msg << szString << wxT('\n'); -#endif - m_pTextCtrl->AppendText(msg); } -#endif // wxUSE_TEXTCTRL +#endif // wxUSE_LOG && wxUSE_TEXTCTRL