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:
@@ -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 )
|
||||
|
Reference in New Issue
Block a user