use wxCollapsiblePane in the log dialog (patch 1624796)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@44914 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2007-03-19 01:23:03 +00:00
parent 96360917d3
commit a14670e28e

View File

@@ -46,6 +46,7 @@
#include "wx/textfile.h"
#include "wx/statline.h"
#include "wx/artprov.h"
#include "wx/collpane.h"
#ifdef __WXMSW__
// for OutputDebugString()
@@ -109,27 +110,36 @@ public:
// event handlers
void OnOk(wxCommandEvent& event);
void OnDetails(wxCommandEvent& event);
#if wxUSE_FILE
void OnSave(wxCommandEvent& event);
#endif // wxUSE_FILE
void OnListSelect(wxListEvent& event);
void OnListItemActivated(wxListEvent& event);
private:
// create controls needed for the details display
void CreateDetailsControls();
void CreateDetailsControls(wxWindow *);
// if necessary truncates the given string and adds an ellipsis
wxString EllipsizeString(const wxString &text)
{
if (ms_maxLength > 0 &&
text.length() > ms_maxLength)
{
wxString ret(text);
ret.Truncate(ms_maxLength);
ret << "...";
return ret;
}
return text;
}
// the data for the listctrl
wxArrayString m_messages;
wxArrayInt m_severity;
wxArrayLong m_times;
// the "toggle" button and its state
#ifndef __SMARTPHONE__
wxButton *m_btnDetails;
#endif
bool m_showingDetails;
// the controls which are not shown initially (but only when details
// button is pressed)
wxListCtrl *m_listctrl;
@@ -145,17 +155,20 @@ private:
// the translated "Details" string
static wxString ms_details;
// the maximum length of the log message
static size_t ms_maxLength;
DECLARE_EVENT_TABLE()
DECLARE_NO_COPY_CLASS(wxLogDialog)
};
BEGIN_EVENT_TABLE(wxLogDialog, wxDialog)
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(wxID_ANY, wxLogDialog::OnListSelect)
EVT_LIST_ITEM_ACTIVATED(wxID_ANY, wxLogDialog::OnListItemActivated)
END_EVENT_TABLE()
#endif // wxUSE_LOG_DIALOG
@@ -705,6 +718,7 @@ static const size_t MARGIN = 0;
#endif
wxString wxLogDialog::ms_details;
size_t wxLogDialog::ms_maxLength = 0;
wxLogDialog::wxLogDialog(wxWindow *parent,
const wxArrayString& messages,
@@ -716,6 +730,8 @@ wxLogDialog::wxLogDialog(wxWindow *parent,
wxDefaultPosition, wxDefaultSize,
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{
// init the static variables:
if ( ms_details.empty() )
{
// ensure that we won't loop here if wxGetTranslation()
@@ -727,6 +743,11 @@ wxLogDialog::wxLogDialog(wxWindow *parent,
#endif
}
if ( ms_maxLength == 0 )
{
ms_maxLength = (2 * wxGetDisplaySize().x/3) / GetCharWidth();
}
size_t count = messages.GetCount();
m_messages.Alloc(count);
m_severity.Alloc(count);
@@ -734,14 +755,11 @@ wxLogDialog::wxLogDialog(wxWindow *parent,
for ( size_t n = 0; n < count; n++ )
{
wxString msg = messages[n];
msg.Replace(wxT("\n"), wxT(" "));
m_messages.Add(msg);
m_messages.Add(messages[n]);
m_severity.Add(severity[n]);
m_times.Add(times[n]);
}
m_showingDetails = false; // not initially
m_listctrl = (wxListCtrl *)NULL;
#ifndef __SMARTPHONE__
@@ -762,21 +780,8 @@ wxLogDialog::wxLogDialog(wxWindow *parent,
// sizers even though our window is not resizeable to calculate the size of
// the dialog properly
wxBoxSizer *sizerTop = new wxBoxSizer(wxVERTICAL);
#ifndef __SMARTPHONE__
wxBoxSizer *sizerButtons = new wxBoxSizer(isPda ? wxHORIZONTAL : wxVERTICAL);
#endif
wxBoxSizer *sizerAll = new wxBoxSizer(isPda ? wxVERTICAL : wxHORIZONTAL);
#ifdef __SMARTPHONE__
SetLeftMenu(wxID_OK);
SetRightMenu(wxID_MORE, ms_details + EXPAND_SUFFIX);
#else
wxButton *btnOk = new wxButton(this, wxID_OK);
sizerButtons->Add(btnOk, 0, isPda ? wxCENTRE : wxCENTRE|wxBOTTOM, MARGIN/2);
m_btnDetails = new wxButton(this, wxID_MORE, ms_details + EXPAND_SUFFIX);
sizerButtons->Add(m_btnDetails, 0, isPda ? wxCENTRE|wxLEFT : wxCENTRE | wxTOP, MARGIN/2 - 1);
#endif
wxBitmap bitmap;
switch ( style & wxICON_MASK )
{
@@ -809,34 +814,45 @@ wxLogDialog::wxLogDialog(wxWindow *parent,
sizerAll->Add(new wxStaticBitmap(this, wxID_ANY, bitmap), 0,
wxALIGN_CENTRE_VERTICAL);
const wxString& message = messages.Last();
sizerAll->Add(CreateTextSizer(message), 1,
// create the text sizer with a minimal size so that we are sure it won't be too small
wxString message = EllipsizeString(messages.Last());
wxSizer *szText = CreateTextSizer(message);
szText->SetMinSize(wxMin(300, wxGetDisplaySize().x / 3), -1);
sizerAll->Add(szText, 1,
wxALIGN_CENTRE_VERTICAL | wxLEFT | wxRIGHT, MARGIN);
#ifndef __SMARTPHONE__
sizerAll->Add(sizerButtons, 0, isPda ? wxCENTRE|wxTOP|wxBOTTOM : (wxALIGN_RIGHT | wxLEFT), MARGIN);
#endif
wxButton *btnOk = new wxButton(this, wxID_OK);
sizerAll->Add(btnOk, 0, isPda ? wxCENTRE : wxCENTRE|wxBOTTOM, MARGIN/2);
sizerTop->Add(sizerAll, 0, wxALL | wxEXPAND, MARGIN);
SetSizer(sizerTop);
// 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.
wxSize size = sizerTop->Fit(this);
m_maxHeight = size.y;
SetSizeHints(size.x, size.y, m_maxWidth, m_maxHeight);
// add the details pane
#ifndef __SMARTPHONE__
btnOk->SetFocus();
#endif
wxCollapsiblePane *collpane = new wxCollapsiblePane(this, wxID_ANY, ms_details);
sizerTop->Add(collpane, 1, wxGROW|wxALL, MARGIN);
wxWindow *win = collpane->GetPane();
wxSizer *paneSz = new wxBoxSizer(wxVERTICAL);
CreateDetailsControls(win);
paneSz->Add(m_listctrl, 1, wxEXPAND | wxTOP, MARGIN);
#if wxUSE_FILE && !defined(__SMARTPHONE__)
paneSz->Add(m_btnSave, 0, wxALIGN_RIGHT | wxTOP, MARGIN);
#endif // wxUSE_FILE
win->SetSizer(paneSz);
paneSz->SetSizeHints(win);
#else // __SMARTPHONE__
SetLeftMenu(wxID_OK);
SetRightMenu(wxID_MORE, ms_details + EXPAND_SUFFIX);
#endif // __SMARTPHONE__/!__SMARTPHONE__
SetSizerAndFit(sizerTop);
Centre();
@@ -848,29 +864,25 @@ wxLogDialog::wxLogDialog(wxWindow *parent,
}
}
void wxLogDialog::CreateDetailsControls()
void wxLogDialog::CreateDetailsControls(wxWindow *parent)
{
#ifndef __SMARTPHONE__
// create the save button and separator line if possible
#if wxUSE_FILE
m_btnSave = new wxButton(this, wxID_SAVE);
m_btnSave = new wxButton(parent, wxID_SAVE);
#endif // wxUSE_FILE
#if wxUSE_STATLINE
m_statline = new wxStaticLine(this, wxID_ANY);
#endif // wxUSE_STATLINE
#endif // __SMARTPHONE__
// create the list ctrl now
m_listctrl = new wxListCtrl(this, wxID_ANY,
m_listctrl = new wxListCtrl(parent, wxID_ANY,
wxDefaultPosition, wxDefaultSize,
wxSUNKEN_BORDER |
wxLC_REPORT |
wxLC_NO_HEADER |
wxLC_SINGLE_SEL);
#ifdef __WXWINCE__
// This maks a big aesthetic difference on WinCE but I
// This makes a big aesthetic difference on WinCE but I
// don't want to risk problems on other platforms
m_listctrl->Hide();
#endif
@@ -947,7 +959,11 @@ void wxLogDialog::CreateDetailsControls()
image = -1;
}
m_listctrl->InsertItem(n, m_messages[n], image);
wxString msg = m_messages[n];
msg.Replace(wxT("\n"), wxT(" "));
msg = EllipsizeString(msg);
m_listctrl->InsertItem(n, msg, image);
m_listctrl->SetItem(n, 1, TimeStamp(fmt, (time_t)m_times[n]));
}
@@ -980,6 +996,23 @@ void wxLogDialog::OnListSelect(wxListEvent& event)
m_listctrl->SetItemState(event.GetIndex(), 0, wxLIST_STATE_SELECTED);
}
void wxLogDialog::OnListItemActivated(wxListEvent& event)
{
// show the activated item in a message box
// This allow the user to correctly display the logs which are longer
// than the listctrl and thus gets truncated or those which contains
// newlines.
// NB: don't do:
// wxString str = m_listctrl->GetItemText(event.GetIndex());
// as there's a 260 chars limit on the items inside a wxListCtrl in wxMSW.
wxString str = m_messages[event.GetIndex()];
// wxMessageBox will nicely handle the '\n' in the string (if any)
// and supports long strings
wxMessageBox(str, wxT("Log message"), wxOK, this);
}
void wxLogDialog::OnOk(wxCommandEvent& WXUNUSED(event))
{
EndModal(wxID_OK);
@@ -1029,111 +1062,6 @@ void wxLogDialog::OnSave(wxCommandEvent& WXUNUSED(event))
#endif // wxUSE_FILE
void wxLogDialog::OnDetails(wxCommandEvent& WXUNUSED(event))
{
wxSizer *sizer = GetSizer();
if ( m_showingDetails )
{
#ifdef __SMARTPHONE__
SetRightMenu(wxID_MORE, ms_details + EXPAND_SUFFIX);
#else
m_btnDetails->SetLabel(ms_details + EXPAND_SUFFIX);
#endif
sizer->Detach( m_listctrl );
#ifndef __SMARTPHONE__
#if wxUSE_STATLINE
sizer->Detach( m_statline );
#endif // wxUSE_STATLINE
#if wxUSE_FILE
sizer->Detach( m_btnSave );
#endif // wxUSE_FILE
#endif // __SMARTPHONE__
}
else // show details now
{
#ifdef __SMARTPHONE__
SetRightMenu(wxID_MORE, wxString(_T("<< ")) + ms_details);
#else
m_btnDetails->SetLabel(wxString(_T("<< ")) + ms_details);
#endif
if ( !m_listctrl )
{
CreateDetailsControls();
}
#if wxUSE_STATLINE && !defined(__SMARTPHONE__)
bool isPda = (wxSystemSettings::GetScreenType() <= wxSYS_SCREEN_PDA);
if (!isPda)
sizer->Add(m_statline, 0, wxEXPAND | (wxALL & ~wxTOP), MARGIN);
#endif // wxUSE_STATLINE
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 && !defined(__SMARTPHONE__)
sizer->Add(m_btnSave, 0, wxALIGN_RIGHT | (wxALL & ~wxTOP), MARGIN);
#endif // wxUSE_FILE
}
m_showingDetails = !m_showingDetails;
// 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);
#ifdef __WXWINCE__
if (m_showingDetails)
m_listctrl->Show();
#endif
// don't change the width when expanding/collapsing
SetSize(wxDefaultCoord, size.y);
#ifdef __WXGTK__
// VS: this is necessary in order to force frame redraw under
// WindowMaker or fvwm2 (and probably other broken WMs).
// Otherwise, detailed list wouldn't be displayed.
Show();
#endif // wxGTK
}
wxLogDialog::~wxLogDialog()
{
if ( m_listctrl )