2007-07-26 09:54:14 -04:00
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Program: wxWidgets Widgets Sample
|
|
|
|
// Name: itemcontainer.cpp
|
|
|
|
// Purpose: Part of the widgets sample showing wxComboBox
|
|
|
|
// Created: 20.07.07
|
|
|
|
// Id: $Id$
|
|
|
|
// License: wxWindows license
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
// declarations
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// headers
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// for compilers that support precompilation, includes "wx/wx.h".
|
|
|
|
#include "wx/wxprec.h"
|
|
|
|
|
|
|
|
#ifdef __BORLANDC__
|
|
|
|
#pragma hdrstop
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// for all others, include the necessary headers
|
|
|
|
#ifndef WX_PRECOMP
|
|
|
|
#include "wx/log.h"
|
|
|
|
|
|
|
|
#include "wx/event.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "wx/ctrlsub.h"
|
|
|
|
#include "itemcontainer.h"
|
|
|
|
|
|
|
|
|
|
|
|
// Help track client data objects in wxItemContainer instances.
|
|
|
|
class TrackedClientData : public wxClientData
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
TrackedClientData(ItemContainerWidgetsPage* tracker, int value)
|
|
|
|
: m_tracker(tracker),
|
|
|
|
m_value(value)
|
|
|
|
{
|
|
|
|
m_tracker->StartTrackingData();
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual ~TrackedClientData()
|
|
|
|
{
|
|
|
|
m_tracker->StopTrackingData();
|
|
|
|
}
|
|
|
|
|
|
|
|
int GetValue() const
|
|
|
|
{
|
|
|
|
return m_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
ItemContainerWidgetsPage *m_tracker;
|
|
|
|
int m_value;
|
|
|
|
|
2009-02-08 06:45:59 -05:00
|
|
|
wxDECLARE_NO_COPY_CLASS(TrackedClientData);
|
2007-07-26 09:54:14 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
// implementation
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
ItemContainerWidgetsPage::ItemContainerWidgetsPage(WidgetsBookCtrl *book,
|
|
|
|
wxImageList *image_list,
|
2008-01-15 20:39:44 -05:00
|
|
|
const char *const icon[])
|
2007-07-26 09:54:14 -04:00
|
|
|
: WidgetsPage(book, image_list, icon), m_trackedDataObjects(0)
|
|
|
|
{
|
2009-07-23 16:30:22 -04:00
|
|
|
m_items.Add(wxT("This"));
|
|
|
|
m_items.Add(wxT("is"));
|
|
|
|
m_items.Add(wxT("a"));
|
|
|
|
m_items.Add(wxT("List"));
|
|
|
|
m_items.Add(wxT("of"));
|
|
|
|
m_items.Add(wxT("strings"));
|
2007-07-26 09:54:14 -04:00
|
|
|
m_itemsSorted = m_items;
|
|
|
|
}
|
|
|
|
|
|
|
|
ItemContainerWidgetsPage::~ItemContainerWidgetsPage()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
wxClientData* ItemContainerWidgetsPage::CreateClientData(int value)
|
|
|
|
{
|
|
|
|
return new TrackedClientData(this, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ItemContainerWidgetsPage::StartTrackingData()
|
|
|
|
{
|
|
|
|
++m_trackedDataObjects;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ItemContainerWidgetsPage::StopTrackingData()
|
|
|
|
{
|
|
|
|
--m_trackedDataObjects;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ItemContainerWidgetsPage::VerifyAllClientDataDestroyed()
|
|
|
|
{
|
|
|
|
if ( m_trackedDataObjects )
|
|
|
|
{
|
2009-07-23 16:30:22 -04:00
|
|
|
wxString message = wxT("Bug in managing wxClientData: ");
|
2007-07-26 09:54:14 -04:00
|
|
|
if ( m_trackedDataObjects > 0 )
|
2009-07-23 16:30:22 -04:00
|
|
|
message << m_trackedDataObjects << wxT(" lost objects");
|
2007-07-26 09:54:14 -04:00
|
|
|
else
|
2009-07-23 16:30:22 -04:00
|
|
|
message << (-m_trackedDataObjects) << wxT(" extra deletes");
|
2007-07-26 09:54:14 -04:00
|
|
|
wxFAIL_MSG(message);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ItemContainerWidgetsPage::StartTest(const wxString& label)
|
|
|
|
{
|
|
|
|
m_container->Clear();
|
2009-07-23 16:30:22 -04:00
|
|
|
wxLogMessage(wxT("Test - %s:"), label.c_str());
|
2007-07-26 09:54:14 -04:00
|
|
|
}
|
|
|
|
|
2008-08-31 11:05:02 -04:00
|
|
|
void ItemContainerWidgetsPage::EndTest(const wxArrayString& items)
|
2007-07-26 09:54:14 -04:00
|
|
|
{
|
|
|
|
const unsigned count = m_container->GetCount();
|
|
|
|
|
|
|
|
bool ok = count == items.GetCount();
|
|
|
|
if ( !ok )
|
|
|
|
{
|
2009-07-23 16:30:22 -04:00
|
|
|
wxFAIL_MSG(wxT("Item count does not match."));
|
2007-07-26 09:54:14 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for ( unsigned i = 0; i < count; ++i )
|
|
|
|
{
|
|
|
|
wxString str = m_container->GetString(i);
|
|
|
|
if ( str != items[i] )
|
|
|
|
{
|
|
|
|
wxFAIL_MSG(wxString::Format(
|
2009-07-23 16:30:22 -04:00
|
|
|
wxT("Wrong string \"%s\" at position %d (expected \"%s\")"),
|
2007-07-26 09:54:14 -04:00
|
|
|
str.c_str(), i, items[i].c_str()));
|
|
|
|
ok = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( m_container->HasClientUntypedData() )
|
|
|
|
{
|
|
|
|
void *data = m_container->GetClientData(i);
|
|
|
|
if ( data && !VerifyClientData((wxUIntPtr)data, str) )
|
|
|
|
{
|
|
|
|
ok = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ( m_container->HasClientObjectData() )
|
|
|
|
{
|
|
|
|
TrackedClientData* obj = (TrackedClientData*)m_container->GetClientObject(i);
|
|
|
|
if ( obj && !VerifyClientData(obj->GetValue(), str) )
|
|
|
|
{
|
|
|
|
ok = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !ok )
|
|
|
|
{
|
|
|
|
wxLogMessage(DumpContainerData(items));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
m_container->Clear();
|
|
|
|
ok &= VerifyAllClientDataDestroyed();
|
|
|
|
|
2009-07-23 16:30:22 -04:00
|
|
|
wxLogMessage(wxT("...%s"), ok ? wxT("passed") : wxT("failed"));
|
2007-07-26 09:54:14 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
wxString
|
2008-08-31 11:05:02 -04:00
|
|
|
ItemContainerWidgetsPage::DumpContainerData(const wxArrayString& expected) const
|
2007-07-26 09:54:14 -04:00
|
|
|
{
|
|
|
|
wxString str;
|
2009-07-23 16:30:22 -04:00
|
|
|
str << wxT("Current content:\n");
|
2007-07-26 09:54:14 -04:00
|
|
|
|
|
|
|
unsigned i;
|
|
|
|
for ( i = 0; i < m_container->GetCount(); ++i )
|
|
|
|
{
|
2009-07-23 16:30:22 -04:00
|
|
|
str << wxT(" - ") << m_container->GetString(i) << wxT(" [");
|
2007-07-26 09:54:14 -04:00
|
|
|
if ( m_container->HasClientObjectData() )
|
|
|
|
{
|
|
|
|
TrackedClientData *
|
|
|
|
obj = (TrackedClientData*)m_container->GetClientObject(i);
|
|
|
|
if ( obj )
|
|
|
|
str << obj->GetValue();
|
|
|
|
}
|
|
|
|
else if ( m_container->HasClientUntypedData() )
|
|
|
|
{
|
|
|
|
void *data = m_container->GetClientData(i);
|
|
|
|
if ( data )
|
|
|
|
str << (wxUIntPtr)data;
|
|
|
|
}
|
2009-07-23 16:30:22 -04:00
|
|
|
str << wxT("]\n");
|
2007-07-26 09:54:14 -04:00
|
|
|
}
|
|
|
|
|
2009-07-23 16:30:22 -04:00
|
|
|
str << wxT("Expected content:\n");
|
2007-07-26 09:54:14 -04:00
|
|
|
for ( i = 0; i < expected.GetCount(); ++i )
|
|
|
|
{
|
|
|
|
const wxString& item = expected[i];
|
2009-07-23 16:30:22 -04:00
|
|
|
str << wxT(" - ") << item << wxT("[");
|
2007-07-26 09:54:14 -04:00
|
|
|
for( unsigned j = 0; j < m_items.GetCount(); ++j )
|
|
|
|
{
|
|
|
|
if ( m_items[j] == item )
|
|
|
|
str << j;
|
|
|
|
}
|
2009-07-23 16:30:22 -04:00
|
|
|
str << wxT("]\n");
|
2007-07-26 09:54:14 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ItemContainerWidgetsPage::VerifyClientData(wxUIntPtr i, const wxString& str)
|
|
|
|
{
|
|
|
|
if ( i > m_items.GetCount() || m_items[i] != str )
|
|
|
|
{
|
2009-07-23 16:30:22 -04:00
|
|
|
wxLogMessage(wxT("Client data for '%s' does not match."), str.c_str());
|
2007-07-26 09:54:14 -04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2008-08-31 11:05:02 -04:00
|
|
|
/* static */
|
|
|
|
wxArrayString
|
|
|
|
ItemContainerWidgetsPage::MakeArray(const wxSortedArrayString& sorted)
|
|
|
|
{
|
|
|
|
wxArrayString a;
|
|
|
|
|
|
|
|
const size_t count = sorted.size();
|
|
|
|
a.reserve(count);
|
|
|
|
for ( size_t n = 0; n < count; n++ )
|
|
|
|
a.push_back(sorted[n]);
|
|
|
|
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
2007-07-26 09:54:14 -04:00
|
|
|
void ItemContainerWidgetsPage::OnButtonTestItemContainer(wxCommandEvent&)
|
|
|
|
{
|
|
|
|
m_container = GetContainer();
|
2009-07-23 16:30:22 -04:00
|
|
|
wxASSERT_MSG(m_container, wxT("Widget must have a test widget"));
|
2007-07-26 09:54:14 -04:00
|
|
|
|
2009-07-23 16:30:22 -04:00
|
|
|
wxLogMessage(wxT("wxItemContainer test for %s, %s:"),
|
2007-07-26 09:54:14 -04:00
|
|
|
GetWidget()->GetClassInfo()->GetClassName(),
|
|
|
|
(m_container->IsSorted() ? "Sorted" : "Unsorted"));
|
|
|
|
|
2008-08-31 11:05:02 -04:00
|
|
|
const wxArrayString
|
|
|
|
expected_result = m_container->IsSorted() ? MakeArray(m_itemsSorted)
|
|
|
|
: m_items;
|
2007-07-26 09:54:14 -04:00
|
|
|
|
2009-07-23 16:30:22 -04:00
|
|
|
StartTest(wxT("Append one item"));
|
2007-07-26 09:54:14 -04:00
|
|
|
wxString item = m_items[0];
|
|
|
|
m_container->Append(item);
|
|
|
|
EndTest(wxArrayString(1, &item));
|
|
|
|
|
2009-07-23 16:30:22 -04:00
|
|
|
StartTest(wxT("Append some items"));
|
2007-07-26 09:54:14 -04:00
|
|
|
m_container->Append(m_items);
|
|
|
|
EndTest(expected_result);
|
|
|
|
|
2009-07-23 16:30:22 -04:00
|
|
|
StartTest(wxT("Append some items with data objects"));
|
2007-07-26 09:54:14 -04:00
|
|
|
wxClientData **objects = new wxClientData *[m_items.GetCount()];
|
2007-08-07 09:55:12 -04:00
|
|
|
unsigned i;
|
|
|
|
for ( i = 0; i < m_items.GetCount(); ++i )
|
2007-07-26 09:54:14 -04:00
|
|
|
objects[i] = CreateClientData(i);
|
|
|
|
m_container->Append(m_items, objects);
|
|
|
|
EndTest(expected_result);
|
|
|
|
delete[] objects;
|
|
|
|
|
2009-07-23 16:30:22 -04:00
|
|
|
StartTest(wxT("Append some items with data"));
|
2007-07-26 09:54:14 -04:00
|
|
|
void **data = new void *[m_items.GetCount()];
|
2007-08-07 09:55:12 -04:00
|
|
|
for ( i = 0; i < m_items.GetCount(); ++i )
|
2008-07-20 18:11:20 -04:00
|
|
|
data[i] = wxUIntToPtr(i);
|
2007-07-26 09:54:14 -04:00
|
|
|
m_container->Append(m_items, data);
|
|
|
|
EndTest(expected_result);
|
|
|
|
delete[] data;
|
|
|
|
|
2009-07-23 16:30:22 -04:00
|
|
|
StartTest(wxT("Append some items with data, one by one"));
|
2007-08-07 09:55:12 -04:00
|
|
|
for ( i = 0; i < m_items.GetCount(); ++i )
|
2008-07-20 18:11:20 -04:00
|
|
|
m_container->Append(m_items[i], wxUIntToPtr(i));
|
2007-07-26 09:54:14 -04:00
|
|
|
EndTest(expected_result);
|
|
|
|
|
2009-07-23 16:30:22 -04:00
|
|
|
StartTest(wxT("Append some items with data objects, one by one"));
|
2007-08-07 09:55:12 -04:00
|
|
|
for ( i = 0; i < m_items.GetCount(); ++i )
|
2007-07-26 09:54:14 -04:00
|
|
|
m_container->Append(m_items[i], CreateClientData(i));
|
|
|
|
EndTest(expected_result);
|
|
|
|
|
|
|
|
if ( !m_container->IsSorted() )
|
|
|
|
{
|
2009-07-23 16:30:22 -04:00
|
|
|
StartTest(wxT("Insert in reverse order with data, one by one"));
|
2007-07-26 09:54:14 -04:00
|
|
|
for ( unsigned i = m_items.GetCount(); i; --i )
|
2008-07-20 18:11:20 -04:00
|
|
|
m_container->Insert(m_items[i - 1], 0, wxUIntToPtr(i - 1));
|
2007-07-26 09:54:14 -04:00
|
|
|
EndTest(expected_result);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|