diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl index c2d4f7884a..d17fe62995 100644 --- a/build/bakefiles/files.bkl +++ b/build/bakefiles/files.bkl @@ -1369,6 +1369,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! wx/generic/colrdlgg.h + wx/generic/ctrlsub.h wx/generic/dirdlgg.h wx/generic/fdrepdlg.h wx/generic/fontdlgg.h @@ -1391,6 +1392,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! wx/motif/colour.h wx/motif/combobox.h wx/motif/control.h + wx/motif/ctrlsub.h wx/motif/cursor.h wx/motif/dataform.h wx/motif/dataobj.h @@ -1642,6 +1644,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! wx/msw/combo.h wx/msw/combobox.h wx/msw/control.h + wx/msw/ctrlsub.h wx/msw/cursor.h wx/msw/dc.h wx/msw/dcclient.h @@ -2634,6 +2637,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! wx/generic/accel.h + wx/generic/ctrlsub.h wx/generic/dirdlgg.h wx/generic/fdrepdlg.h wx/generic/fontdlgg.h diff --git a/docs/changes.txt b/docs/changes.txt index 75824c0085..bd7acde67a 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -155,6 +155,7 @@ wxGTK: - Support for markup and ellipsization in wxStaticText (Francesco Montorsi) - Native implementation for wxHyperlinkCtrl (Francesco Montorsi) - Native keyboard navigation implementation +- Added wxCB_SORT support to wxComboBox (Evgeniy Tarassov) - Don't overwrite primary selection with clipboard and vice versa - Implemented support for underlined fonts in wxStaticText. - wxTopLevelWindow::SetSizeHints size increments now work. diff --git a/docs/latex/wx/ctrlsub.tex b/docs/latex/wx/ctrlsub.tex index afb99c037b..1a430cd202 100644 --- a/docs/latex/wx/ctrlsub.tex +++ b/docs/latex/wx/ctrlsub.tex @@ -61,15 +61,27 @@ untyped, client data pointer with the item. \func{void}{Append}{\param{const wxArrayString\& }{strings}} +\func{void}{Append}{\param{unsigned int }{n},\param{const wxString* }{strings}} + +\func{void}{Append}{\param{unsigned int }{n},\param{const wxString* }{strings}, \param{void **}{clientData}} + +\func{void}{Append}{\param{unsigned int }{n},\param{const wxString* }{strings}, \param{wxClientData **}{clientData}} + Appends several items at once to the control. Notice that calling this method -may be much faster than appending the items one by one if you need to add a lot +is usually much faster than appending them one by one if you need to add a lot of items. \wxheading{Parameters} \docparam{item}{String to add.} -\docparam{clientData}{Client data to associate with the item.} +\docparam{stringsArray}{Contains items to append to the control.} + +\docparam{strings}{Array of strings of size \arg{n}.} + +\docparam{n}{Number of items in the \arg{strings} array.} + +\docparam{clientData}{Array of client data pointers of size \arg{n} to associate with the new items.} \wxheading{Return value} @@ -242,13 +254,34 @@ Inserts the item into the list before pos, associating the given, typed or untyped, client data pointer with the item. Not valid for {\tt wxLB\_SORT} or {\tt wxCB\_SORT} styles, use Append instead. +\func{void}{Insert}{\param{const wxArrayString\& }{strings}, \param{unsigned int }{pos}} + +\func{void}{Insert}{\param{const wxArrayString\& }{strings}, \param{unsigned int }{pos}} + +\func{void}{Insert}{\param{unsigned int }{n},\param{const wxString* }{strings}, \param{unsigned int }{pos}} + +\func{void}{Insert}{\param{unsigned int }{n},\param{const wxString* }{strings}, \param{unsigned int }{pos}, \param{void **}{clientData}} + +\func{void}{Insert}{\param{unsigned int }{n},\param{const wxString* }{strings}, \param{unsigned int }{pos}, \param{wxClientData **}{clientData}} + +Inserts several items at once into the control. Notice that calling this method +is usually much faster than inserting them one by one if you need to insert a lot +of items. + + \wxheading{Parameters} \docparam{item}{String to add.} \docparam{pos}{Position to insert item before, zero based.} -\docparam{clientData}{Client data to associate with the item.} +\docparam{stringsArray}{Contains items to insert into the control content} + +\docparam{strings}{Array of strings of size \arg{n}.} + +\docparam{n}{Number of items in the \arg{strings} array.} + +\docparam{clientData}{Array of client data pointers of size \arg{n} to associate with the new items.} \wxheading{Return value} @@ -276,6 +309,53 @@ exists only because it is slightly more natural for controls which support multiple selection. +\membersection{wxControlWithItems::Set}\label{wxcontrolwithitemsset} + +\func{int}{Set}{\param{const wxString\& }{ item}} + +\func{int}{Set}{\param{const wxString\& }{ item}, \param{void *}{clientData}} + +\func{int}{Set}{\param{const wxString\& }{ item}, \param{wxClientData *}{clientData}} + +Replace control items with the (only) item specified, associating the typed or +untyped client data pointer with it if given. + +\func{void}{Set}{\param{const wxArrayString\& }{stringsArray}} + +\func{void}{Set}{\param{unsigned int }{n},\param{const wxString* }{strings}} + +\func{void}{Set}{\param{unsigned int }{n},\param{const wxString* }{strings}, \param{void **}{clientData}} + +\func{void}{Set}{\param{unsigned int }{n},\param{const wxString* }{strings}, \param{wxClientData **}{clientData}} + +Replaces the current control contents with the given items. Notice that calling +this method is much faster than appending the items one by one if you need to +append a lot of them. + +\wxheading{Parameters} + +\docparam{item}{The single item to insert into the control.} + +\docparam{stringsArray}{Contains items to set as control content.} + +\docparam{strings}{Raw C++ array of strings. Only used in conjunction with 'n'.} + +\docparam{n}{Number of items passed in 'strings'. Only used in conjunction with 'strings'.} + +\docparam{clientData}{Client data to associate with the item(s).} + +\wxheading{Return value} + +When the control is sorted (e.g. has {\tt wxLB\_SORT} or {\tt wxCB\_SORT} style) +the return value could be different from (GetCount() - 1). +When setting a single item to the container, the return value is the index of the +newly added item which may be different from the last one if the control is sorted +(e.g. has {\tt wxLB\_SORT} or {\tt wxCB\_SORT} style). + +By default this method subsequently calls \helpref{Clear}{wxcontrolwithitemsclear} +and \helpref{Append}{wxcontrolwithitemsappend}. + + \membersection{wxControlWithItems::SetClientData}\label{wxcontrolwithitemssetclientdata} \func{void}{SetClientData}{\param{unsigned int}{ n}, \param{void *}{data}} diff --git a/include/wx/arrstr.h b/include/wx/arrstr.h index ac59ff6483..a78d09e9dd 100644 --- a/include/wx/arrstr.h +++ b/include/wx/arrstr.h @@ -362,4 +362,81 @@ WXDLLIMPEXP_BASE wxArrayString wxSplit(const wxString& str, const wxChar sep, const wxChar escape = wxT('\\')); + +// ---------------------------------------------------------------------------- +// This helper class allows to pass both C array of wxStrings or wxArrayString +// using the same interface. +// +// Use it when you have two methods taking wxArrayString or (int, wxString[]), +// that do the same thing. This class lets you iterate over input data in the +// same way whether it is a raw array of strings or wxArrayString. +// +// The object does not take ownership of the data -- internally it keeps +// pointers to the data, therefore the data must be disposed of by user +// and only after this object is destroyed. Usually it is not a problem as +// only temporary objects of this class are used. +// ---------------------------------------------------------------------------- + +class wxArrayStringsAdapter +{ +public: + // construct an adapter from a wxArrayString + wxArrayStringsAdapter(const wxArrayString& strings) + : m_type(wxSTRING_ARRAY), m_size(strings.size()) + { + m_data.array = &strings; + } + + // construct an adapter from a wxString[] + wxArrayStringsAdapter(unsigned int n, const wxString *strings) + : m_type(wxSTRING_POINTER), m_size(n) + { + m_data.ptr = strings; + } + + // construct an adapter from a single wxString + wxArrayStringsAdapter(const wxString& s) + : m_type(wxSTRING_POINTER), m_size(1) + { + m_data.ptr = &s; + } + + // default copy constructor is ok + + // iteration interface + unsigned int GetCount() const { return m_size; } + bool IsEmpty() const { return GetCount() == 0; } + const wxString& operator[] (unsigned int i) const + { + wxASSERT_MSG( i < GetCount(), wxT("index out of bounds") ); + if(m_type == wxSTRING_POINTER) + return m_data.ptr[i]; + return m_data.array->Item(i); + } + wxArrayString AsArrayString() const + { + if(m_type == wxSTRING_ARRAY) + return *m_data.array; + return wxArrayString(GetCount(), m_data.ptr); + } + +private: + // type of the data being held + enum wxStringContainerType + { + wxSTRING_ARRAY, // wxArrayString + wxSTRING_POINTER // wxString[] + }; + + wxStringContainerType m_type; + unsigned int m_size; + union + { + const wxString * ptr; + const wxArrayString * array; + } m_data; + + DECLARE_NO_ASSIGN_CLASS(wxArrayStringsAdapter) +}; + #endif // _WX_ARRSTR_H diff --git a/include/wx/choice.h b/include/wx/choice.h index 16017f87ec..164aac07a5 100644 --- a/include/wx/choice.h +++ b/include/wx/choice.h @@ -55,6 +55,9 @@ public: // emulate selecting the item event.GetInt() void Command(wxCommandEvent& event); + // override wxItemContainer::IsSorted + virtual bool IsSorted() const { return HasFlag(wxCB_SORT); } + private: DECLARE_NO_COPY_CLASS(wxChoiceBase) }; diff --git a/include/wx/clntdata.h b/include/wx/clntdata.h index aba1cf71ef..c0f33dbb38 100644 --- a/include/wx/clntdata.h +++ b/include/wx/clntdata.h @@ -159,109 +159,5 @@ protected: }; -#include "wx/vector.h" - -struct WXDLLIMPEXP_BASE wxClientDataDictionaryPair -{ - wxClientDataDictionaryPair( size_t idx ) : index( idx ), data( 0 ) { } - - size_t index; - wxClientData* data; -}; - -// this class is used internally to maintain the association between items -// of (some subclasses of) wxControlWithItems and their client data -// NOTE: this class does not keep track of whether it contains -// wxClientData or void*. The client must ensure that -// it does not contain a mix of the two, and that -// DestroyData is called if it contains wxClientData -class WXDLLIMPEXP_BASE wxClientDataDictionary -{ -public: - wxClientDataDictionary() {} - - // deletes all the data - void DestroyData() - { - for( size_t i = 0, end = m_vec.size(); i != end; ++i ) - delete m_vec[i].data; - m_vec.clear(); - } - - // if data for the given index is not present, add it, - // if it is present, delete the old data and replace it with - // the new one - void Set( size_t index, wxClientData* data, bool doDelete ) - { - size_t ptr = Find( index ); - - if( !data ) - { - if( ptr == m_vec.size() ) return; - if( doDelete ) - delete m_vec[ptr].data; - m_vec.erase( m_vec.begin() + ptr ); - } - else - { - if( ptr == m_vec.size() ) - { - m_vec.push_back( wxClientDataDictionaryPair( index ) ); - ptr = m_vec.size() - 1; - } - - if( doDelete ) - delete m_vec[ptr].data; - m_vec[ptr].data = data; - } - } - - // get the data associated with the given index, - // return 0 if not found - wxClientData* Get( size_t index ) const - { - size_t it = Find( index ); - if( it == m_vec.size() ) return 0; - return (wxClientData*)m_vec[it].data; // const cast - } - - // delete the data associated with the given index - // it also decreases by one the indices of all the elements - // with an index greater than the given index - void Delete( size_t index, bool doDelete ) - { - size_t todel = m_vec.size(); - - for( size_t i = 0, end = m_vec.size(); i != end; ++i ) - { - if( m_vec[i].index == index ) - todel = i; - else if( m_vec[i].index > index ) - --(m_vec[i].index); - } - - if( todel != m_vec.size() ) - { - if( doDelete ) - delete m_vec[todel].data; - m_vec.erase( m_vec.begin() + todel ); - } - } -private: - // returns MyVec.size() if not found - size_t Find( size_t index ) const - { - for( size_t i = 0, end = m_vec.size(); i != end; ++i ) - { - if( m_vec[i].index == index ) - return i; - } - - return m_vec.size(); - } - - wxVector m_vec; -}; - #endif // _WX_CLNTDATAH__ diff --git a/include/wx/cocoa/choice.h b/include/wx/cocoa/choice.h index 1057527bae..e0ad953c9a 100644 --- a/include/wx/cocoa/choice.h +++ b/include/wx/cocoa/choice.h @@ -80,19 +80,19 @@ protected: // Implementation // ------------------------------------------------------------------------ public: - virtual void Clear(); - virtual void Delete(unsigned int n); + virtual void DoClear(); + virtual void DoDelete(unsigned int n); virtual unsigned int GetCount() const; virtual wxString GetString(unsigned int) const; virtual void SetString(unsigned int pos, const wxString&); virtual int FindString(const wxString& s, bool bCase = false) const; virtual int GetSelection() const; - virtual int DoAppend(const wxString&); - virtual int DoInsert(const wxString&, unsigned int pos); + virtual int DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, wxClientDataType type); + virtual void DoDeleteOneItem(unsigned int pos); virtual void DoSetItemClientData(unsigned int, void*); virtual void* DoGetItemClientData(unsigned int) const; - virtual void DoSetItemClientObject(unsigned int, wxClientData*); - virtual wxClientData* DoGetItemClientObject(unsigned int) const; virtual void SetSelection(int pos); protected: wxSortedArrayString *m_sortedStrings; diff --git a/include/wx/cocoa/combobox.h b/include/wx/cocoa/combobox.h index cc262de82d..9423b28d94 100644 --- a/include/wx/cocoa/combobox.h +++ b/include/wx/cocoa/combobox.h @@ -106,19 +106,19 @@ public: // Overlapping methods virtual wxString GetStringSelection(); // wxItemContainer - virtual void Clear(); - virtual void Delete(unsigned int n); + virtual void DoClear(); + virtual void DoDeleteOneItem(unsigned int n); virtual unsigned int GetCount() const; virtual wxString GetString(unsigned int) const; virtual void SetString(unsigned int pos, const wxString&); virtual int FindString(const wxString& s, bool bCase = false) const; virtual int GetSelection() const; - virtual int DoAppend(const wxString&); - virtual int DoInsert(const wxString&, unsigned int pos); + virtual int DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, wxClientDataType type); virtual void DoSetItemClientData(unsigned int, void*); virtual void* DoGetItemClientData(unsigned int) const; - virtual void DoSetItemClientObject(unsigned int, wxClientData*); - virtual wxClientData* DoGetItemClientObject(unsigned int) const; + virtual bool IsSorted() const { return HasFlag(wxCB_SORT); } // wxComboBoxBase pure virtuals virtual wxString GetValue() const { return wxTextCtrl::GetValue(); } diff --git a/include/wx/cocoa/listbox.h b/include/wx/cocoa/listbox.h index 0002435bbc..e21a39c3e1 100644 --- a/include/wx/cocoa/listbox.h +++ b/include/wx/cocoa/listbox.h @@ -84,16 +84,14 @@ public: virtual bool IsSelected(int n) const; virtual int GetSelections(wxArrayInt& aSelections) const; protected: - virtual void DoInsertItems(const wxArrayString& items, unsigned int pos); - virtual void DoSetItems(const wxArrayString& items, void **clientData); virtual void DoSetFirstItem(int n); virtual void DoSetSelection(int n, bool select); // pure virtuals from wxItemContainer public: // deleting items - virtual void Clear(); - virtual void Delete(unsigned int n); + virtual void DoClear(); + virtual void DoDeleteOneItem(unsigned int n); // accessing strings virtual unsigned int GetCount() const; virtual wxString GetString(unsigned int n) const; @@ -102,11 +100,11 @@ public: // selection virtual int GetSelection() const; protected: - virtual int DoAppend(const wxString& item); + virtual int DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, wxClientDataType type); virtual void DoSetItemClientData(unsigned int n, void* clientData); virtual void* DoGetItemClientData(unsigned int n) const; - virtual void DoSetItemClientObject(unsigned int n, wxClientData* clientData); - virtual wxClientData* DoGetItemClientObject(unsigned int n) const; }; #endif // __WX_COCOA_LISTBOX_H__ diff --git a/include/wx/ctrlsub.h b/include/wx/ctrlsub.h index 9939f9a7df..901f52c45d 100644 --- a/include/wx/ctrlsub.h +++ b/include/wx/ctrlsub.h @@ -16,6 +16,7 @@ #if wxUSE_CONTROLS +#include "wx/arrstr.h" #include "wx/control.h" // base class // ---------------------------------------------------------------------------- @@ -80,14 +81,109 @@ public: protected: - // check that the index is valid - inline bool IsValid(unsigned int n) const { return n < GetCount(); } - inline bool IsValidInsert(unsigned int n) const { return n <= GetCount(); } + bool IsValid(unsigned int n) const { return n < GetCount(); } + bool IsValidInsert(unsigned int n) const { return n <= GetCount(); } }; +// ---------------------------------------------------------------------------- +// wxItemContainer extends wxItemContainerImmutable interface with methods +// for adding/removing items. +// +// Classes deriving from this one must override DoInsertItems() to implement +// adding items to the control. This can often be implemented more efficiently +// than simply looping over the elements and inserting them but if this is not +// the case, the generic DoInsertItemsInLoop can be used in implementation, but +// in this case DoInsertItem() needs to be overridden. +// ---------------------------------------------------------------------------- + class WXDLLEXPORT wxItemContainer : public wxItemContainerImmutable { +private: + // AppendItems() and InsertItems() helpers just call DoAppend/InsertItems() + // after doing some checks + // + // NB: they're defined here so that they're inlined when used in public part + int AppendItems(const wxArrayStringsAdapter& items, + void **clientData, + wxClientDataType type) + { + if ( items.IsEmpty() ) + return wxNOT_FOUND; + + return DoAppendItems(items, clientData, type); + } + + int AppendItems(const wxArrayStringsAdapter& items) + { + return AppendItems(items, NULL, wxClientData_None); + } + + int AppendItems(const wxArrayStringsAdapter& items, void **clientData) + { + wxASSERT_MSG( m_clientDataItemsType != wxClientData_Object, + _T("can't mix different types of client data") ); + + return AppendItems(items, clientData, wxClientData_Void); + } + + int AppendItems(const wxArrayStringsAdapter& items, + wxClientData **clientData) + { + wxASSERT_MSG( m_clientDataItemsType != wxClientData_Void, + _T("can't mix different types of client data") ); + + return AppendItems(items, wx_reinterpret_cast(void **, clientData), + wxClientData_Object); + } + + int InsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, + wxClientDataType type) + { + wxASSERT_MSG( !IsSorted(), _T("can't insert items in sorted control") ); + + wxCHECK_MSG( pos <= GetCount(), wxNOT_FOUND, + _T("position out of range") ); + + // not all derived classes handle empty arrays correctly in + // DoInsertItems() and besides it really doesn't make much sense to do + // this (for append it could correspond to creating an initially empty + // control but why would anybody need to insert 0 items?) + wxCHECK_MSG( !items.IsEmpty(), wxNOT_FOUND, + _T("need something to insert") ); + + return DoInsertItems(items, pos, clientData, type); + } + + int InsertItems(const wxArrayStringsAdapter& items, unsigned int pos) + { + return InsertItems(items, pos, NULL, wxClientData_None); + } + + int InsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData) + { + wxASSERT_MSG( m_clientDataItemsType != wxClientData_Object, + _T("can't mix different types of client data") ); + + return InsertItems(items, pos, clientData, wxClientData_Void); + } + + int InsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + wxClientData **clientData) + { + wxASSERT_MSG( m_clientDataItemsType != wxClientData_Void, + _T("can't mix different types of client data") ); + + return InsertItems(items, pos, + wx_reinterpret_cast(void **, clientData), + wxClientData_Object); + } + public: wxItemContainer() { m_clientDataItemsType = wxClientData_None; } virtual ~wxItemContainer(); @@ -95,54 +191,178 @@ public: // adding items // ------------ + // append single item, return its position in the control (which can be + // different from the last one if the control is sorted) int Append(const wxString& item) - { return DoAppend(item); } + { return AppendItems(item); } int Append(const wxString& item, void *clientData) - { int n = DoAppend(item); SetClientData(n, clientData); return n; } + { return AppendItems(item, &clientData); } int Append(const wxString& item, wxClientData *clientData) - { int n = DoAppend(item); SetClientObject(n, clientData); return n; } + { return AppendItems(item, &clientData); } - // only for rtti needs (separate name) - void AppendString( const wxString& item) - { Append( item ); } + // append several items at once to the control, return the position of the + // last item appended + int Append(const wxArrayString& items) + { return AppendItems(items); } + int Append(const wxArrayString& items, void **clientData) + { return AppendItems(items, clientData); } + int Append(const wxArrayString& items, wxClientData **clientData) + { return AppendItems(items, clientData); } + int Append(unsigned int n, const wxString *items) + { return AppendItems(wxArrayStringsAdapter(n, items)); } + int Append(unsigned int n, const wxString *items, void **clientData) + { return AppendItems(wxArrayStringsAdapter(n, items), clientData); } + int Append(unsigned int n, + const wxString *items, + wxClientData **clientData) + { return AppendItems(wxArrayStringsAdapter(n, items), clientData); } - // append several items at once to the control - void Append(const wxArrayString& strings); + // only for RTTI needs (separate name) + void AppendString(const wxString& item) + { Append(item); } + + // inserting items: not for sorted controls! + // ----------------------------------------- + + // insert single item at the given position, return its effective position int Insert(const wxString& item, unsigned int pos) - { return DoInsert(item, pos); } - int Insert(const wxString& item, unsigned int pos, void *clientData); - int Insert(const wxString& item, unsigned int pos, wxClientData *clientData); + { return InsertItems(item, pos); } + int Insert(const wxString& item, unsigned int pos, void *clientData) + { return InsertItems(item, pos, &clientData); } + int Insert(const wxString& item, unsigned int pos, wxClientData *clientData) + { return InsertItems(item, pos, &clientData); } + + // insert several items at once into the control, return the index of the + // last item inserted + int Insert(const wxArrayString& items, unsigned int pos) + { return InsertItems(items, pos); } + int Insert(const wxArrayString& items, unsigned int pos, void **clientData) + { return InsertItems(items, pos, clientData); } + int Insert(const wxArrayString& items, + unsigned int pos, + wxClientData **clientData) + { return InsertItems(items, pos, clientData); } + int Insert(unsigned int n, const wxString *items, unsigned int pos) + { return InsertItems(wxArrayStringsAdapter(n, items), pos); } + int Insert(unsigned int n, + const wxString *items, + unsigned int pos, + void **clientData) + { return InsertItems(wxArrayStringsAdapter(n, items), pos, clientData); } + int Insert(unsigned int n, + const wxString *items, + unsigned int pos, + wxClientData **clientData) + { return InsertItems(wxArrayStringsAdapter(n, items), pos, clientData); } + + + // replacing items + // --------------- + + void Set(const wxArrayString& items) + { Clear(); Append(items); } + void Set(const wxArrayString& items, void **clientData) + { Clear(); Append(items, clientData); } + void Set(const wxArrayString& items, wxClientData **clientData) + { Clear(); Append(items, clientData); } + void Set(unsigned int n, const wxString *items) + { Clear(); Append(n, items); } + void Set(unsigned int n, const wxString *items, void **clientData) + { Clear(); Append(n, items, clientData); } + void Set(unsigned int n, const wxString *items, wxClientData **clientData) + { Clear(); Append(n, items, clientData); } // deleting items // -------------- - virtual void Clear() = 0; - virtual void Delete(unsigned int n) = 0; + void Clear(); + void Delete(unsigned int pos); - // misc - // ---- // client data stuff + // ----------------- + void SetClientData(unsigned int n, void* clientData); void* GetClientData(unsigned int n) const; void SetClientObject(unsigned int n, wxClientData* clientData); wxClientData* GetClientObject(unsigned int n) const; + bool HasClientData() const + { return m_clientDataItemsType != wxClientData_None; } bool HasClientObjectData() const { return m_clientDataItemsType == wxClientData_Object; } bool HasClientUntypedData() const { return m_clientDataItemsType == wxClientData_Void; } -protected: - virtual int DoAppend(const wxString& item) = 0; - virtual int DoInsert(const wxString& item, unsigned int pos) = 0; - virtual void DoSetItemClientData(unsigned int n, void* clientData) = 0; - virtual void* DoGetItemClientData(unsigned int n) const = 0; - virtual void DoSetItemClientObject(unsigned int n, wxClientData* clientData) = 0; - virtual wxClientData* DoGetItemClientObject(unsigned int n) const = 0; + // The control may maintain its items in a sorted order in which case + // items are automatically inserted at the right position when they are + // inserted or appended. Derived classes have to override this method if + // they implement sorting, typically by returning HasFlag(wxXX_SORT) + virtual bool IsSorted() const { return false; } + +protected: + // there is usually no need to override this method but you can do it if it + // is more convenient to only do "real" insertions in DoInsertItems() and + // to implement items appending here (in which case DoInsertItems() should + // call this method if pos == GetCount() as it can still be called in this + // case if public Insert() is called with such position) + virtual int DoAppendItems(const wxArrayStringsAdapter& items, + void **clientData, + wxClientDataType type) + { + return DoInsertItems(items, GetCount(), clientData, type); + } + + // this method must be implemented to insert the items into the control at + // position pos which can be GetCount() meaning that the items should be + // appended; for the sorted controls the position can be ignored + // + // the derived classes typically use AssignNewItemClientData() to + // associate the data with the items as they're being inserted + // + // the method should return the index of the position the last item was + // inserted into or wxNOT_FOUND if an error occurred + virtual int DoInsertItems(const wxArrayStringsAdapter & items, + unsigned int pos, + void **clientData, + wxClientDataType type) = 0; + + // before the client data is set for the first time for the control which + // hadn't had it before, DoInitItemClientData() is called which gives the + // derived class the possibility to initialize its client data storage only + // when client data is really used + virtual void DoInitItemClientData() { } + virtual void DoSetItemClientData(unsigned int n, void *clientData) = 0; + virtual void *DoGetItemClientData(unsigned int n) const = 0; + + virtual void DoClear() = 0; + virtual void DoDeleteOneItem(unsigned int pos) = 0; + + + // methods useful for the derived classes which don't have any better way + // of adding multiple items to the control than doing it one by one: such + // classes should call DoInsertItemsInLoop() from their DoInsert() and + // override DoInsertOneItem() to perform the real insertion + virtual int DoInsertOneItem(const wxString& item, unsigned int pos); + int DoInsertItemsInLoop(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, + wxClientDataType type); + + + // helper for DoInsertItems(): n is the index into clientData, pos is the + // position of the item in the control + void AssignNewItemClientData(unsigned int pos, + void **clientData, + unsigned int n, + wxClientDataType type); + + // free the client object associated with the item at given position and + // set it to NULL (must only be called if HasClientObjectData()) + void ResetItemClientObject(unsigned int n); // the type of the client data for the items @@ -171,11 +391,11 @@ protected: wxClientData* GetClientObject(unsigned int n) const \ { return wxItemContainer::GetClientObject(n); } -class WXDLLEXPORT wxControlWithItems : public wxControl, public wxItemContainer +class WXDLLEXPORT wxControlWithItemsBase : public wxControl, + public wxItemContainer { public: - wxControlWithItems() { } - virtual ~wxControlWithItems(); + wxControlWithItemsBase() { } // we have to redefine these functions here to avoid ambiguities in classes // deriving from us which would arise otherwise because both base classses @@ -196,14 +416,25 @@ protected: void InitCommandEventWithItems(wxCommandEvent& event, int n); private: - DECLARE_ABSTRACT_CLASS(wxControlWithItems) - DECLARE_NO_COPY_CLASS(wxControlWithItems) + DECLARE_NO_COPY_CLASS(wxControlWithItemsBase) }; +// define the platform-specific wxControlWithItems class +#if defined(__WXMSW__) + #include "wx/msw/ctrlsub.h" +#elif defined(__WXMOTIF__) + #include "wx/motif/ctrlsub.h" +#else + class wxControlWithItems : public wxControlWithItemsBase + { + public: + wxControlWithItems() { } -// ---------------------------------------------------------------------------- -// inline functions -// ---------------------------------------------------------------------------- + private: + DECLARE_ABSTRACT_CLASS(wxControlWithItems) + DECLARE_NO_COPY_CLASS(wxControlWithItems) + }; +#endif #endif // wxUSE_CONTROLS diff --git a/include/wx/generic/bmpcbox.h b/include/wx/generic/bmpcbox.h index 58f53627de..e192470c4e 100644 --- a/include/wx/generic/bmpcbox.h +++ b/include/wx/generic/bmpcbox.h @@ -86,13 +86,17 @@ public: virtual ~wxBitmapComboBox(); // Adds item with image to the end of the combo box. - int Append(const wxString& item, const wxBitmap& bitmap = wxNullBitmap) - { return DoAppendWithImage(item, bitmap); } + int Append(const wxString& item, const wxBitmap& bitmap = wxNullBitmap); + int Append(const wxString& item, const wxBitmap& bitmap, void *clientData); + int Append(const wxString& item, const wxBitmap& bitmap, wxClientData *clientData); - int Append(const wxString& item, const wxBitmap& bitmap, void *clientData) - { int n = DoAppendWithImage(item, bitmap); SetClientData(n, clientData); return n; } - int Append(const wxString& item, const wxBitmap& bitmap, wxClientData *clientData) - { int n = DoAppendWithImage(item, bitmap); SetClientObject(n, clientData); return n; } + // Inserts item with image into the list before pos. Not valid for wxCB_SORT + // styles, use Append instead. + int Insert(const wxString& item, const wxBitmap& bitmap, unsigned int pos); + int Insert(const wxString& item, const wxBitmap& bitmap, + unsigned int pos, void *clientData); + int Insert(const wxString& item, const wxBitmap& bitmap, + unsigned int pos, wxClientData *clientData); // Returns size of image used in list. virtual wxSize GetBitmapSize() const @@ -103,21 +107,11 @@ public: // Returns the image of the item with the given index. virtual wxBitmap GetItemBitmap(unsigned int n) const; - // Inserts item with image into the list before pos. Not valid for wxCB_SORT or wxCB_SORT - // styles, use Append instead. - int Insert(const wxString& item, const wxBitmap& bitmap, unsigned int pos) - { return DoInsertWithImage(item, bitmap, pos); } - - int Insert(const wxString& item, const wxBitmap& bitmap, - unsigned int pos, void *clientData); - int Insert(const wxString& item, const wxBitmap& bitmap, - unsigned int pos, wxClientData *clientData); - // Sets the image for the given item. virtual void SetItemBitmap(unsigned int n, const wxBitmap& bitmap); - virtual void Clear(); - virtual void Delete(unsigned int n); + virtual void DoClear(); + virtual void DoDeleteOneItem(unsigned int n); protected: @@ -126,12 +120,9 @@ protected: virtual wxCoord OnMeasureItem(size_t item) const; virtual wxCoord OnMeasureItemWidth(size_t item) const; - virtual int DoAppendWithImage(const wxString& item, const wxBitmap& bitmap); - virtual int DoInsertWithImage(const wxString& item, const wxBitmap& bitmap, - unsigned int pos); - - virtual int DoAppend(const wxString& item); - virtual int DoInsert(const wxString& item, unsigned int pos); + virtual int DoInsertItems(const wxArrayStringsAdapter & items, + unsigned int pos, + void **clientData, wxClientDataType type); virtual bool SetFont(const wxFont& font); diff --git a/include/wx/generic/ctrlsub.h b/include/wx/generic/ctrlsub.h new file mode 100644 index 0000000000..425380d602 --- /dev/null +++ b/include/wx/generic/ctrlsub.h @@ -0,0 +1,123 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/generic/ctrlsub.h +// Purpose: common functionality of wxItemContainer-derived controls +// Author: Vadim Zeitlin +// Created: 2007-07-25 +// RCS-ID: $Id$ +// Copyright: (c) 2007 Vadim Zeitlin +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_GENERIC_CTRLSUB_H_ +#define _WX_GENERIC_CTRLSUB_H_ + +#include "wx/dynarray.h" + +// ---------------------------------------------------------------------------- +// wxControlWithItemsGeneric: generic implementation of item client data +// ---------------------------------------------------------------------------- + +class wxControlWithItemsGeneric : public wxControlWithItemsBase +{ +public: + wxControlWithItemsGeneric() { } + + virtual void DoInitItemClientData() + { + m_itemsClientData.resize(GetCount(), NULL); + } + + virtual void DoSetItemClientData(unsigned int n, void *clientData) + { + m_itemsClientData[n] = clientData; + } + + virtual void *DoGetItemClientData(unsigned int n) const + { + return m_itemsClientData[n]; + } + + virtual void DoClear() { m_itemsClientData.clear(); } + virtual void DoDeleteOneItem(unsigned int pos) + { + if ( HasClientData() ) + m_itemsClientData.RemoveAt(pos); + } + +protected: + // preallocate memory for numItems new items: this should be called from + // the derived classes DoInsertItems() to speed up appending big numbers of + // items with client data; it is safe to call even if we don't use client + // data at all and does nothing in this case + void AllocClientData(unsigned int numItems) + { + if ( HasClientData() ) + m_itemsClientData.reserve(m_itemsClientData.size() + numItems); + } + + // this must be called by derived classes when a new item is added to the + // control to add storage for the corresponding client data pointer (before + // inserting many items, call AllocClientData()) + void InsertNewItemClientData(unsigned int pos, + void **clientData, + unsigned int n, + wxClientDataType type) + { + if ( InitClientDataIfNeeded(type) ) + m_itemsClientData.Insert(clientData[n], pos); + } + + // the same as InsertNewItemClientData() but for numItems consecutive items + // (this can only be used if the control doesn't support sorting as + // otherwise the items positions wouldn't be consecutive any more) + void InsertNewItemsClientData(unsigned int pos, + unsigned int numItems, + void **clientData, + wxClientDataType type) + { + if ( InitClientDataIfNeeded(type) ) + { + // it's more efficient to insert everything at once and then update + // for big number of items to avoid moving the array contents + // around (which would result in O(N^2) algorithm) + m_itemsClientData.Insert(NULL, pos, numItems); + + for ( unsigned int n = 0; n < numItems; ++n, ++pos ) + m_itemsClientData[pos] = clientData[n]; + } + } + + + // vector containing the client data pointers: it is either empty (if + // client data is not used) or has the same number of elements as the + // control + wxArrayPtrVoid m_itemsClientData; + +private: + // initialize client data if needed, return false if we don't have any + // client data and true otherwise + bool InitClientDataIfNeeded(wxClientDataType type) + { + if ( !HasClientData() ) + { + if ( type == wxClientData_None ) + { + // we didn't have the client data before and are not asked to + // store it now neither + return false; + } + + // this is the first time client data is used with this control + DoInitItemClientData(); + m_clientDataItemsType = type; + } + //else: we already have client data + + return true; + } + + DECLARE_NO_COPY_CLASS(wxControlWithItemsGeneric) +}; + +#endif // _WX_GENERIC_CTRLSUB_H_ + diff --git a/include/wx/gtk/choice.h b/include/wx/gtk/choice.h index 96830c5847..1606120b09 100644 --- a/include/wx/gtk/choice.h +++ b/include/wx/gtk/choice.h @@ -62,8 +62,8 @@ public: const wxString& name = wxChoiceNameStr ); // implement base class pure virtuals - void Delete(unsigned int n); - void Clear(); + void DoDeleteOneItem(unsigned int n); + void DoClear(); int GetSelection() const; void SetSelection(int n); @@ -77,22 +77,21 @@ public: GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL); protected: - wxList m_clientList; // contains the client data for the items + wxArrayPtrVoid m_clientData; // contains the client data for the items virtual wxSize DoGetBestSize() const; virtual void DoApplyWidgetStyle(GtkRcStyle *style); virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const; - virtual int DoAppend(const wxString& item); - virtual int DoInsert(const wxString& item, unsigned int pos); + virtual int DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, wxClientDataType type); virtual void DoSetItemClientData(unsigned int n, void* clientData); virtual void* DoGetItemClientData(unsigned int n) const; - virtual void DoSetItemClientObject(unsigned int n, wxClientData* clientData); - virtual wxClientData* DoGetItemClientObject(unsigned int n) const; private: - // common part of Create() and DoAppend() + // DoInsertItems() helper int GtkAddHelper(GtkWidget *menu, unsigned int pos, const wxString& item); // this array is only used for controls with wxCB_SORT style, so only diff --git a/include/wx/gtk/combobox.h b/include/wx/gtk/combobox.h index f8540a2bd8..f77165b975 100644 --- a/include/wx/gtk/combobox.h +++ b/include/wx/gtk/combobox.h @@ -18,7 +18,7 @@ class WXDLLIMPEXP_CORE wxComboBox : public wxControl, public wxComboBoxBase { public: - inline wxComboBox() {} + inline wxComboBox() { m_strings = NULL; } inline wxComboBox(wxWindow *parent, wxWindowID id, const wxString& value = wxEmptyString, const wxPoint& pos = wxDefaultPosition, @@ -71,8 +71,8 @@ public: wxString GetStringSelection() const; // not a virtual in parent class // From wxItemContainer: - virtual void Clear(); - virtual void Delete(unsigned int n); + virtual void DoClear(); + virtual void DoDeleteOneItem(unsigned int n); // From wxBomboBoxBase: virtual wxString GetValue() const; @@ -125,10 +125,9 @@ public: void OnUpdateDelete(wxUpdateUIEvent& event); void OnUpdateSelectAll(wxUpdateUIEvent& event); - bool m_ignoreNextUpdate:1; - wxList m_clientDataList; - wxList m_clientObjectList; - int m_prevSelection; + bool m_ignoreNextUpdate:1; + wxArrayPtrVoid m_clientData; + int m_prevSelection; void DisableEvents(); void EnableEvents(); @@ -145,13 +144,12 @@ protected: virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const; // From wxItemContainer: - virtual int DoAppend(const wxString& item); - virtual int DoInsert(const wxString& item, unsigned int pos); - + virtual int DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, wxClientDataType type); virtual void DoSetItemClientData(unsigned int n, void* clientData); virtual void* DoGetItemClientData(unsigned int n) const; - virtual void DoSetItemClientObject(unsigned int n, wxClientData* clientData); - virtual wxClientData* DoGetItemClientObject(unsigned int n) const; + virtual bool IsSorted() const { return HasFlag(wxCB_SORT); } // From wxControl: virtual wxSize DoGetBestSize() const; @@ -161,6 +159,10 @@ protected: virtual bool UseGTKStyleBase() const { return true; } private: + // this array is only used for controls with wxCB_SORT style, so only + // allocate it if it's needed (hence using pointer) + wxSortedArrayString *m_strings; + DECLARE_DYNAMIC_CLASS_NO_COPY(wxComboBox) DECLARE_EVENT_TABLE() }; diff --git a/include/wx/gtk/listbox.h b/include/wx/gtk/listbox.h index c855e3d688..aa38ecd895 100644 --- a/include/wx/gtk/listbox.h +++ b/include/wx/gtk/listbox.h @@ -65,8 +65,8 @@ public: const wxString& name = wxListBoxNameStr); // implement base class pure virtuals - virtual void Clear(); - virtual void Delete(unsigned int n); + virtual void DoClear(); + virtual void DoDeleteOneItem(unsigned int n); virtual unsigned int GetCount() const; virtual wxString GetString(unsigned int n) const; @@ -98,8 +98,6 @@ public: bool m_blockEvent; struct _GtkTreeEntry* GtkGetEntry(unsigned pos) const; - void GtkInsertItems(const wxArrayString& items, - void** clientData, unsigned int pos); void GtkDeselectAll(); void GtkSetSelection(int n, const bool select, const bool blockEvent); @@ -109,14 +107,14 @@ protected: virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const; virtual void DoSetSelection(int n, bool select); - virtual int DoAppend(const wxString& item); - virtual void DoInsertItems(const wxArrayString& items, unsigned int pos); - virtual void DoSetItems(const wxArrayString& items, void **clientData); + + virtual int DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, wxClientDataType type); + virtual void DoSetFirstItem(int n); virtual void DoSetItemClientData(unsigned int n, void* clientData); virtual void* DoGetItemClientData(unsigned int n) const; - virtual void DoSetItemClientObject(unsigned int n, wxClientData* clientData); - virtual wxClientData* DoGetItemClientObject(unsigned int n) const; virtual int DoListHitTest(const wxPoint& point) const; // get the iterator for the given index, returns false if invalid diff --git a/include/wx/gtk1/choice.h b/include/wx/gtk1/choice.h index 5d8579b731..c78e8308fe 100644 --- a/include/wx/gtk1/choice.h +++ b/include/wx/gtk1/choice.h @@ -62,8 +62,8 @@ public: const wxString& name = wxChoiceNameStr ); // implement base class pure virtuals - void Delete(unsigned int n); - void Clear(); + void DoDeleteOneItem(unsigned int n); + void DoClear(); int GetSelection() const; virtual void SetSelection(int n); @@ -80,20 +80,19 @@ protected: wxList m_clientList; // contains the client data for the items void DoApplyWidgetStyle(GtkRcStyle *style); - virtual int DoAppend(const wxString& item); - virtual int DoInsert(const wxString& item, unsigned int pos); + virtual int DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, wxClientDataType type); virtual void DoSetItemClientData(unsigned int n, void* clientData); virtual void* DoGetItemClientData(unsigned int n) const; - virtual void DoSetItemClientObject(unsigned int n, wxClientData* clientData); - virtual wxClientData* DoGetItemClientObject(unsigned int n) const; virtual wxSize DoGetBestSize() const; virtual bool IsOwnGtkWindow( GdkWindow *window ); private: - // common part of Create() and DoAppend() + // DoInsertItems() helper int GtkAddHelper(GtkWidget *menu, unsigned int pos, const wxString& item); // this array is only used for controls with wxCB_SORT style, so only diff --git a/include/wx/gtk1/combobox.h b/include/wx/gtk1/combobox.h index fd046fc073..e46402b839 100644 --- a/include/wx/gtk1/combobox.h +++ b/include/wx/gtk1/combobox.h @@ -80,8 +80,8 @@ public: const wxValidator& validator = wxDefaultValidator, const wxString& name = wxComboBoxNameStr); - void Clear(); - void Delete(unsigned int n); + void DoClear(); + void DoDeleteOneItem(unsigned int n); virtual int FindString(const wxString& s, bool bCase = false) const; int GetSelection() const; @@ -159,13 +159,12 @@ public: GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL); protected: - virtual int DoAppend(const wxString& item); - virtual int DoInsert(const wxString& item, unsigned int pos); + virtual int DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, wxClientDataType type); virtual void DoSetItemClientData(unsigned int n, void* clientData); virtual void* DoGetItemClientData(unsigned int n) const; - virtual void DoSetItemClientObject(unsigned int n, wxClientData* clientData); - virtual wxClientData* DoGetItemClientObject(unsigned int n) const; virtual wxSize DoGetBestSize() const; diff --git a/include/wx/gtk1/listbox.h b/include/wx/gtk1/listbox.h index 42cd90f1e9..be62c96846 100644 --- a/include/wx/gtk1/listbox.h +++ b/include/wx/gtk1/listbox.h @@ -67,8 +67,8 @@ public: const wxString& name = wxListBoxNameStr); // implement base class pure virtuals - virtual void Clear(); - virtual void Delete(unsigned int n); + virtual void DoClear(); + virtual void DoDeleteOneItem(unsigned int n); virtual unsigned int GetCount() const; virtual wxString GetString(unsigned int n) const; @@ -80,16 +80,14 @@ public: virtual int GetSelection() const; virtual int GetSelections(wxArrayInt& aSelections) const; - virtual int DoAppend(const wxString& item); - virtual void DoInsertItems(const wxArrayString& items, unsigned int pos); - virtual void DoSetItems(const wxArrayString& items, void **clientData); + virtual int DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, wxClientDataType type); virtual void DoSetFirstItem(int n); virtual void DoSetItemClientData(unsigned int n, void* clientData); virtual void* DoGetItemClientData(unsigned int n) const; - virtual void DoSetItemClientObject(unsigned int n, wxClientData* clientData); - virtual wxClientData* DoGetItemClientObject(unsigned int n) const; static wxVisualAttributes GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL); diff --git a/include/wx/htmllbox.h b/include/wx/htmllbox.h index 0cc43ef289..89c06d29dc 100644 --- a/include/wx/htmllbox.h +++ b/include/wx/htmllbox.h @@ -268,35 +268,19 @@ public: virtual void SetString(unsigned int n, const wxString& s); - virtual void Clear(); - virtual void Delete(unsigned int n); - - // override default unoptimized wxItemContainer::Append() function - void Append(const wxArrayString& strings); - - // since we override one Append() overload, we need to overload all others too - int Append(const wxString& item) - { return wxItemContainer::Append(item); } - int Append(const wxString& item, void *clientData) - { return wxItemContainer::Append(item, clientData); } - int Append(const wxString& item, wxClientData *clientData) - { return wxItemContainer::Append(item, clientData); } - + virtual void DoClear(); + virtual void DoDeleteOneItem(unsigned int n); protected: - - virtual int DoAppend(const wxString& item); - virtual int DoInsert(const wxString& item, unsigned int pos); + virtual int DoInsertItems(const wxArrayStringsAdapter & items, + unsigned int pos, + void **clientData, wxClientDataType type); virtual void DoSetItemClientData(unsigned int n, void *clientData) { m_HTMLclientData[n] = clientData; } virtual void *DoGetItemClientData(unsigned int n) const { return m_HTMLclientData[n]; } - virtual void DoSetItemClientObject(unsigned int n, wxClientData *clientData) - { m_HTMLclientData[n] = (void *)clientData; } - virtual wxClientData *DoGetItemClientObject(unsigned int n) const - { return (wxClientData *)m_HTMLclientData[n]; } // calls wxHtmlListBox::SetItemCount() and RefreshAll() void UpdateCount(); diff --git a/include/wx/listbox.h b/include/wx/listbox.h index 89a61df202..01604e47f6 100644 --- a/include/wx/listbox.h +++ b/include/wx/listbox.h @@ -42,13 +42,10 @@ public: wxListBoxBase() { } virtual ~wxListBoxBase(); - void InsertItems(unsigned int nItems, const wxString *items, unsigned int pos); + void InsertItems(unsigned int nItems, const wxString *items, unsigned int pos) + { Insert(nItems, items, pos); } void InsertItems(const wxArrayString& items, unsigned int pos) - { DoInsertItems(items, pos); } - - void Set(int n, const wxString* items, void **clientData = NULL); - void Set(const wxArrayString& items, void **clientData = NULL) - { DoSetItems(items, clientData); } + { Insert(items, pos); } // multiple selection logic virtual bool IsSelected(int n) const = 0; @@ -87,8 +84,8 @@ public: (m_windowStyle & wxLB_EXTENDED); } - // return true if this listbox is sorted - bool IsSorted() const { return (m_windowStyle & wxLB_SORT) != 0; } + // override wxItemContainer::IsSorted + virtual bool IsSorted() const { return HasFlag( wxLB_SORT ); } // emulate selecting or deselecting the item event.GetInt() (depending on // event.GetExtraLong()) @@ -104,15 +101,6 @@ public: #endif // WXWIN_COMPATIBILITY_2_6 protected: - // NB: due to wxGTK implementation details, DoInsert() is implemented - // using DoInsertItems() and not the other way round - virtual int DoInsert(const wxString& item, unsigned int pos) - { InsertItems(1, &item, pos); return pos; } - - // to be implemented in derived classes - virtual void DoInsertItems(const wxArrayString& items, unsigned int pos) = 0; - virtual void DoSetItems(const wxArrayString& items, void **clientData) = 0; - virtual void DoSetFirstItem(int n) = 0; virtual void DoSetSelection(int n, bool select) = 0; @@ -121,7 +109,7 @@ protected: virtual int DoListHitTest(const wxPoint& WXUNUSED(point)) const { return wxNOT_FOUND; } - +private: DECLARE_NO_COPY_CLASS(wxListBoxBase) }; diff --git a/include/wx/mac/carbon/choice.h b/include/wx/mac/carbon/choice.h index 57f765da1b..838da21dc0 100644 --- a/include/wx/mac/carbon/choice.h +++ b/include/wx/mac/carbon/choice.h @@ -69,8 +69,8 @@ public: const wxValidator& validator = wxDefaultValidator, const wxString& name = wxChoiceNameStr); - virtual void Delete(unsigned int n); - virtual void Clear(); + virtual void DoDeleteOneItem(unsigned int n); + virtual void DoClear(); virtual unsigned int GetCount() const ; virtual int GetSelection() const ; @@ -83,17 +83,12 @@ public: protected: virtual wxSize DoGetBestSize() const ; - virtual int DoAppend(const wxString& item); - virtual int DoInsert(const wxString& item, unsigned int pos); + virtual int DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, wxClientDataType type); virtual void DoSetItemClientData(unsigned int n, void* clientData); virtual void* DoGetItemClientData(unsigned int n) const; - virtual void DoSetItemClientObject(unsigned int n, wxClientData* clientData); - virtual wxClientData* DoGetItemClientObject(unsigned int n) const; - - // free all memory we have (used by Clear() and dtor) - // prevent collision with some BSD definitions of macro Free() - void FreeData(); wxArrayString m_strings; wxChoiceDataArray m_datas ; diff --git a/include/wx/mac/carbon/combobox.h b/include/wx/mac/carbon/combobox.h index 446b4b14a5..737f7b4423 100644 --- a/include/wx/mac/carbon/combobox.h +++ b/include/wx/mac/carbon/combobox.h @@ -85,8 +85,8 @@ class WXDLLEXPORT wxComboBox : public wxControl, public wxComboBoxBase const wxString& name = wxComboBoxNameStr); // List functions - virtual void Delete(unsigned int n); - virtual void Clear(); + virtual void DoDeleteOneItem(unsigned int n); + virtual void DoClear(); virtual int GetSelection() const; virtual void SetSelection(int n); @@ -135,19 +135,16 @@ protected: // common part of all ctors void Init(); - void FreeData(); - // override the base class virtuals involved in geometry calculations virtual wxSize DoGetBestSize() const; virtual void DoMoveWindow(int x, int y, int width, int height); - virtual int DoAppend(const wxString& item); - virtual int DoInsert(const wxString& item, unsigned int pos); + virtual int DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, wxClientDataType type); virtual void DoSetItemClientData(unsigned int n, void* clientData); virtual void * DoGetItemClientData(unsigned int n) const; - virtual void DoSetItemClientObject(unsigned int n, wxClientData* clientData); - virtual wxClientData * DoGetItemClientObject(unsigned int n) const; // the subcontrols wxComboBoxText* m_text; diff --git a/include/wx/mac/carbon/listbox.h b/include/wx/mac/carbon/listbox.h index 69e45871ef..91214b05b6 100644 --- a/include/wx/mac/carbon/listbox.h +++ b/include/wx/mac/carbon/listbox.h @@ -89,8 +89,8 @@ public: // implement base class pure virtuals virtual void Refresh(bool eraseBack = true, const wxRect *rect = NULL); - virtual void Clear(); - virtual void Delete(unsigned int n); + virtual void DoClear(); + virtual void DoDeleteOneItem(unsigned int n); virtual unsigned int GetCount() const; virtual wxString GetString(unsigned int n) const; @@ -111,16 +111,15 @@ public: protected: // from wxItemContainer - virtual int DoAppend(const wxString& item); + virtual int DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, wxClientDataType type); + virtual void DoSetItemClientData(unsigned int n, void* clientData); virtual void* DoGetItemClientData(unsigned int n) const; - virtual void DoSetItemClientObject(unsigned int n, wxClientData* clientData); - virtual wxClientData* DoGetItemClientObject(unsigned int n) const; // from wxListBoxBase virtual void DoSetSelection(int n, bool select); - virtual void DoInsertItems(const wxArrayString& items, unsigned int pos); - virtual void DoSetItems(const wxArrayString& items, void **clientData); virtual void DoSetFirstItem(int n); virtual int DoListHitTest(const wxPoint& point) const; diff --git a/include/wx/mac/carbon/private.h b/include/wx/mac/carbon/private.h index ecc66ddd19..6fc913dd2c 100644 --- a/include/wx/mac/carbon/private.h +++ b/include/wx/mac/carbon/private.h @@ -824,8 +824,7 @@ class wxMacListControl { public: virtual void MacDelete( unsigned int n ) = 0; - virtual void MacInsert( unsigned int n, const wxString& item, int column = -1 ) = 0; - virtual void MacInsert( unsigned int n, const wxArrayString& items, int column = -1 ) = 0; + virtual void MacInsert( unsigned int n, const wxArrayStringsAdapter& items, int column = -1 ) = 0; // returns index of newly created line virtual int MacAppend( const wxString& item ) = 0; virtual void MacSetString( unsigned int n, const wxString& item ) = 0; @@ -975,8 +974,7 @@ public : // add and remove virtual void MacDelete( unsigned int n ); - virtual void MacInsert( unsigned int n, const wxString& item, int column = -1 ); - virtual void MacInsert( unsigned int n, const wxArrayString& items, int column = -1 ); + virtual void MacInsert( unsigned int n, const wxArrayStringsAdapter& items, int column = -1 ); virtual int MacAppend( const wxString& item ); virtual void MacClear(); diff --git a/include/wx/motif/checklst.h b/include/wx/motif/checklst.h index 78bb982180..7ec30059eb 100644 --- a/include/wx/motif/checklst.h +++ b/include/wx/motif/checklst.h @@ -60,13 +60,13 @@ public: void Check(unsigned int uiIndex, bool bCheck = true); // override base class functions - virtual int DoAppend(const wxString& item); + virtual int DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, wxClientDataType type); virtual int FindString(const wxString& s, bool bCase = false) const; virtual void SetString(unsigned int n, const wxString& s); virtual wxString GetString(unsigned int n) const; - virtual void DoInsertItems(const wxArrayString& items, unsigned int pos); - virtual void DoSetItems(const wxArrayString& items, void **clientData); private: void DoToggleItem( int item, int x ); private: diff --git a/include/wx/motif/choice.h b/include/wx/motif/choice.h index bc8f39cf7d..7532c50ba2 100644 --- a/include/wx/motif/choice.h +++ b/include/wx/motif/choice.h @@ -72,15 +72,9 @@ public: // implementation of wxControlWithItems virtual unsigned int GetCount() const; - virtual int DoAppend(const wxString& item); - virtual int DoInsert(const wxString& item, unsigned int pos); - virtual void DoSetItemClientData(unsigned int n, void* clientData); - virtual void* DoGetItemClientData(unsigned int n) const; - virtual void DoSetItemClientObject(unsigned int n, wxClientData* clientData); - virtual wxClientData* DoGetItemClientObject(unsigned int n) const; virtual int GetSelection() const; - virtual void Delete(unsigned int n); - virtual void Clear(); + virtual void DoDeleteOneItem(unsigned int n); + virtual void DoClear(); virtual void SetString(unsigned int n, const wxString& s); virtual wxString GetString(unsigned int n) const; @@ -118,12 +112,15 @@ protected: wxWidgetArray m_widgetArray; WXWidget m_formWidget; wxStringList m_stringList; - wxClientDataDictionary m_clientDataDict; virtual void DoSetSize(int x, int y, int width, int height, int sizeFlags = wxSIZE_AUTO); + + // implementation of wxControlWithItems + virtual int DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, wxClientDataType type); }; -#endif -// _WX_CHOICE_H_ +#endif // _WX_CHOICE_H_ diff --git a/include/wx/motif/combobox.h b/include/wx/motif/combobox.h index e47a4e8b64..d63326ba22 100644 --- a/include/wx/motif/combobox.h +++ b/include/wx/motif/combobox.h @@ -70,10 +70,11 @@ public: const wxString& name = wxComboBoxNameStr); // implementation of wxControlWithItems - virtual int DoAppend(const wxString& item); - virtual int DoInsert(const wxString& item, unsigned int pos); - virtual void Delete(unsigned int n); - virtual void Clear(); + virtual int DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, wxClientDataType type); + virtual void DoDeleteOneItem(unsigned int n); + virtual void DoClear(); virtual int GetSelection() const ; virtual void SetSelection(int n); virtual int FindString(const wxString& s, bool bCase = false) const; diff --git a/include/wx/motif/ctrlsub.h b/include/wx/motif/ctrlsub.h new file mode 100644 index 0000000000..dfa0915e6b --- /dev/null +++ b/include/wx/motif/ctrlsub.h @@ -0,0 +1,40 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/motif/ctrlsub.h +// Purpose: common functionality of wxItemContainer-derived controls +// Author: Vadim Zeitlin +// Created: 2007-07-25 +// RCS-ID: $Id$ +// Copyright: (c) 2007 Vadim Zeitlin +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_MOTIF_CTRLSUB_H_ +#define _WX_MOTIF_CTRLSUB_H_ + +#include "wx/dynarray.h" +#include "wx/generic/ctrlsub.h" + +// ---------------------------------------------------------------------------- +// wxControlWithItems +// ---------------------------------------------------------------------------- + +class wxControlWithItems : public wxControlWithItemsGeneric +{ +public: + wxControlWithItems() { } + +protected: + // Motif functions inserting items in the control interpret positions + // differently from wx: they're 1-based and 0 means to append + unsigned int GetMotifPosition(unsigned int pos) const + { + return pos == GetCount() ? 0 : pos + 1; + } + +private: + DECLARE_ABSTRACT_CLASS(wxControlWithItems) + DECLARE_NO_COPY_CLASS(wxControlWithItems) +}; + +#endif // _WX_MOTIF_CTRLSUB_H_ + diff --git a/include/wx/motif/listbox.h b/include/wx/motif/listbox.h index 29faf7d6dc..c743a98add 100644 --- a/include/wx/motif/listbox.h +++ b/include/wx/motif/listbox.h @@ -63,26 +63,20 @@ public: const wxValidator& validator = wxDefaultValidator, const wxString& name = wxListBoxNameStr); - virtual ~wxListBox(); - // implementation of wxControlWithItems virtual unsigned int GetCount() const; - virtual int DoAppend(const wxString& item); - virtual void DoSetItemClientData(unsigned int n, void* clientData); - virtual void* DoGetItemClientData(unsigned int n) const; - virtual void DoSetItemClientObject(unsigned int n, wxClientData* clientData); - virtual wxClientData* DoGetItemClientObject(unsigned int n) const; + virtual int DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, wxClientDataType type); virtual int GetSelection() const; - virtual void Delete(unsigned int n); + virtual void DoDeleteOneItem(unsigned int n); virtual int FindString(const wxString& s, bool bCase = false) const; - virtual void Clear(); + virtual void DoClear(); virtual void SetString(unsigned int n, const wxString& s); virtual wxString GetString(unsigned int n) const; // implementation of wxListBoxbase virtual void DoSetSelection(int n, bool select); - virtual void DoInsertItems(const wxArrayString& items, unsigned int pos); - virtual void DoSetItems(const wxArrayString& items, void **clientData); virtual void DoSetFirstItem(int n); virtual int GetSelections(wxArrayInt& aSelections) const; virtual bool IsSelected(int n) const; @@ -96,15 +90,13 @@ public: WXWidget GetTopWidget() const; #if wxUSE_CHECKLISTBOX - virtual void DoToggleItem(int WXUNUSED(item), int WXUNUSED(x)) {}; + virtual void DoToggleItem(int WXUNUSED(item), int WXUNUSED(x)) {} #endif protected: virtual wxSize DoGetBestSize() const; unsigned int m_noItems; - // List mapping positions->client data - wxClientDataDictionary m_clientDataDict; private: void SetSelectionPolicy(); }; diff --git a/include/wx/msw/choice.h b/include/wx/msw/choice.h index a2ca016367..3d004d2ab6 100644 --- a/include/wx/msw/choice.h +++ b/include/wx/msw/choice.h @@ -66,8 +66,8 @@ public: const wxValidator& validator = wxDefaultValidator, const wxString& name = wxChoiceNameStr); - virtual void Delete(unsigned int n); - virtual void Clear(); + virtual void DoDeleteOneItem(unsigned int n); + virtual void DoClear(); virtual unsigned int GetCount() const; virtual int GetSelection() const; @@ -89,13 +89,13 @@ protected: // common part of all ctors void Init() { m_lastAcceptedSelection = wxID_NONE; } - virtual int DoAppend(const wxString& item); - virtual int DoInsert(const wxString& item, unsigned int pos); + virtual int DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, wxClientDataType type); + virtual void DoMoveWindow(int x, int y, int width, int height); virtual void DoSetItemClientData(unsigned int n, void* clientData); virtual void* DoGetItemClientData(unsigned int n) const; - virtual void DoSetItemClientObject(unsigned int n, wxClientData* clientData); - virtual wxClientData* DoGetItemClientObject(unsigned int n) const; // MSW implementation virtual wxSize DoGetBestSize() const; diff --git a/include/wx/msw/ctrlsub.h b/include/wx/msw/ctrlsub.h new file mode 100644 index 0000000000..d197bb1b01 --- /dev/null +++ b/include/wx/msw/ctrlsub.h @@ -0,0 +1,43 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/msw/ctrlsub.h +// Purpose: common functionality of wxItemContainer-derived controls +// Author: Vadim Zeitlin +// Created: 2007-07-25 +// RCS-ID: $Id$ +// Copyright: (c) 2007 Vadim Zeitlin +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_MSW_CTRLSUB_H_ +#define _WX_MSW_CTRLSUB_H_ + +// ---------------------------------------------------------------------------- +// wxControlWithItems +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxControlWithItems : public wxControlWithItemsBase +{ +public: + wxControlWithItems() { } + +protected: + // preallocate memory for inserting the given new items into the control + // using the wm message (normally either LB_INITSTORAGE or CB_INITSTORAGE) + void MSWAllocStorage(const wxArrayStringsAdapter& items, unsigned wm); + + // insert or append a string to the controls using the given message + // (one of {CB,LB}_{ADD,INSERT}STRING, pos must be 0 when appending) + int MSWInsertOrAppendItem(unsigned pos, const wxString& item, unsigned wm); + + // normally the control containing the items is this window itself but if + // the derived control is composed of several windows, this method can be + // overridden to return the real list/combobox control + virtual WXHWND MSWGetItemsHWND() const { return GetHWND(); } + +private: + DECLARE_ABSTRACT_CLASS(wxControlWithItems) + DECLARE_NO_COPY_CLASS(wxControlWithItems) +}; + +#endif // _WX_MSW_CTRLSUB_H_ + diff --git a/include/wx/msw/listbox.h b/include/wx/msw/listbox.h index d4eb27141c..13daa8a232 100644 --- a/include/wx/msw/listbox.h +++ b/include/wx/msw/listbox.h @@ -78,8 +78,8 @@ public: virtual ~wxListBox(); // implement base class pure virtuals - virtual void Clear(); - virtual void Delete(unsigned int n); + virtual void DoClear(); + virtual void DoDeleteOneItem(unsigned int n); virtual unsigned int GetCount() const; virtual wxString GetString(unsigned int n) const; @@ -135,14 +135,14 @@ public: protected: virtual void DoSetSelection(int n, bool select); - virtual int DoAppend(const wxString& item); - virtual void DoInsertItems(const wxArrayString& items, unsigned int pos); - virtual void DoSetItems(const wxArrayString& items, void **clientData); + + virtual int DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, wxClientDataType type); + virtual void DoSetFirstItem(int n); virtual void DoSetItemClientData(unsigned int n, void* clientData); virtual void* DoGetItemClientData(unsigned int n) const; - virtual void DoSetItemClientObject(unsigned int n, wxClientData* clientData); - virtual wxClientData* DoGetItemClientObject(unsigned int n) const; virtual int DoListHitTest(const wxPoint& point) const; // free memory (common part of Clear() and dtor) diff --git a/include/wx/msw/wince/checklst.h b/include/wx/msw/wince/checklst.h index 01f0c23319..42cc6475db 100644 --- a/include/wx/msw/wince/checklst.h +++ b/include/wx/msw/wince/checklst.h @@ -50,7 +50,7 @@ public: const wxString& name = wxListBoxNameStr); // override base class virtuals - virtual void Delete(unsigned int n); + virtual void DoDeleteOneItem(unsigned int n); // items may be checked virtual bool IsChecked(unsigned int uiIndex) const; @@ -72,20 +72,18 @@ protected: void OnSize(wxSizeEvent& event); // protected interface derived from wxListBox and lower classes - virtual int DoAppend(const wxString& item); + virtual int DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, wxClientDataType type); + virtual void* DoGetItemClientData(unsigned int n) const; - virtual wxClientData* DoGetItemClientObject(unsigned int n) const; - virtual void DoInsertItems(const wxArrayString& items, unsigned int pos); - virtual void DoSetFirstItem(int n); virtual void DoSetItemClientData(unsigned int n, void* clientData); - virtual void DoSetItemClientObject(unsigned int n, wxClientData* clientData); - virtual void DoSetItems(const wxArrayString& items, void **clientData); + virtual void DoSetFirstItem(int n); virtual void DoSetSelection(int n, bool select); // convert our styles to Windows virtual WXDWORD MSWGetStyle(long style, WXDWORD *exstyle) const; private: - wxArrayPtrVoid m_itemsClientData; DECLARE_EVENT_TABLE() diff --git a/include/wx/msw/wince/choicece.h b/include/wx/msw/wince/choicece.h index 3b827e73a4..5f4e3302d5 100644 --- a/include/wx/msw/wince/choicece.h +++ b/include/wx/msw/wince/choicece.h @@ -78,10 +78,8 @@ public: const wxString& name = wxChoiceNameStr); // implement base class pure virtuals - virtual int DoAppend(const wxString& item); - virtual int DoInsert(const wxString& item, unsigned int pos); - virtual void Delete(unsigned int n); - virtual void Clear() ; + virtual void DoDeleteOneItem(unsigned int n); + virtual void DoClear(); virtual unsigned int GetCount() const; virtual int GetSelection() const; @@ -100,10 +98,14 @@ public: virtual bool MSWCommand(WXUINT param, WXWORD id); protected: + virtual int DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, wxClientDataType type); + virtual void DoSetItemClientData(unsigned int n, void* clientData); virtual void* DoGetItemClientData(unsigned int n) const; - virtual void DoSetItemClientObject(unsigned int n, wxClientData* clientData); - virtual wxClientData* DoGetItemClientObject(unsigned int n) const; + + virtual WXHWND MSWGetItemsHWND() const { return m_hwndBuddy; } // MSW implementation virtual void DoGetPosition(int *x, int *y) const; @@ -122,9 +124,6 @@ protected: const wxValidator& validator, const wxString& name); - // free all memory we have (used by Clear() and dtor) - void Free(); - // the data for the "buddy" list WXHWND m_hwndBuddy; WXFARPROC m_wndProcBuddy; diff --git a/include/wx/odcombo.h b/include/wx/odcombo.h index 334d725410..7efe58f9e4 100644 --- a/include/wx/odcombo.h +++ b/include/wx/odcombo.h @@ -304,8 +304,8 @@ public: } // wxControlWithItems methods - virtual void Clear(); - virtual void Delete(unsigned int n); + virtual void DoClear(); + virtual void DoDeleteOneItem(unsigned int n); virtual unsigned int GetCount() const; virtual wxString GetString(unsigned int n) const; virtual void SetString(unsigned int n, const wxString& s); @@ -327,6 +327,8 @@ public: // Return the index of the widest item (recalculating it if necessary) virtual int GetWidestItem() { EnsurePopupControl(); return GetVListBoxComboPopup()->GetWidestItem(); } + virtual bool IsSorted() const { return HasFlag(wxCB_SORT); } + wxCONTROL_ITEMCONTAINER_CLIENTDATAOBJECT_RECAST protected: @@ -359,12 +361,11 @@ protected: return (wxVListBoxComboPopup*) m_popupInterface; } - virtual int DoAppend(const wxString& item); - virtual int DoInsert(const wxString& item, unsigned int pos); + virtual int DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, wxClientDataType type); virtual void DoSetItemClientData(unsigned int n, void* clientData); virtual void* DoGetItemClientData(unsigned int n) const; - virtual void DoSetItemClientObject(unsigned int n, wxClientData* clientData); - virtual wxClientData* DoGetItemClientObject(unsigned int n) const; // temporary storage for the initial choices //const wxString* m_baseChoices; diff --git a/include/wx/os2/checklst.h b/include/wx/os2/checklst.h index 2a23c9645d..db4f841bc6 100644 --- a/include/wx/os2/checklst.h +++ b/include/wx/os2/checklst.h @@ -72,7 +72,9 @@ protected: virtual wxOwnerDrawn* CreateItem(size_t n); virtual long OS2OnMeasure(WXMEASUREITEMSTRUCT* pItem); - virtual void DoInsertItems(const wxArrayString& items, unsigned int pos); + virtual int DoInsertItems(const wxArrayStringsAdapter & items, + unsigned int pos, + void **clientData, wxClientDataType type); // // Pressing space or clicking the check box toggles the item diff --git a/include/wx/os2/choice.h b/include/wx/os2/choice.h index 8054f22344..5acbbf3d31 100644 --- a/include/wx/os2/choice.h +++ b/include/wx/os2/choice.h @@ -93,8 +93,8 @@ public: // // Implement base class virtuals // - virtual void Delete(unsigned int n); - virtual void Clear(void); + virtual void DoDeleteOneItem(unsigned int n); + virtual void DoClear(void); virtual unsigned int GetCount() const; virtual int GetSelection(void) const; @@ -115,12 +115,13 @@ public: ); protected: - virtual int DoAppend(const wxString& rsItem); - virtual int DoInsert(const wxString& rsItem, unsigned int pos); + virtual int DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, + wxClientDataType type); + virtual void DoSetItemClientData(unsigned int n, void* pClientData); virtual void* DoGetItemClientData(unsigned int n) const; - virtual void DoSetItemClientObject(unsigned int n, wxClientData* pClientData); - virtual wxClientData* DoGetItemClientObject(unsigned int n) const; virtual wxSize DoGetBestSize(void) const; virtual void DoSetSize( int nX ,int nY diff --git a/include/wx/os2/listbox.h b/include/wx/os2/listbox.h index 012d913b09..6b42cdc9f2 100644 --- a/include/wx/os2/listbox.h +++ b/include/wx/os2/listbox.h @@ -103,8 +103,8 @@ public: // // Implement base class pure virtuals // - virtual void Clear(void); - virtual void Delete(unsigned int n); + virtual void DoClear(void); + virtual void DoDeleteOneItem(unsigned int n); virtual unsigned int GetCount() const; virtual wxString GetString(unsigned int n) const; @@ -115,18 +115,10 @@ public: virtual int GetSelection(void) const; virtual int GetSelections(wxArrayInt& raSelections) const; - virtual int DoAppend(const wxString& rsItem); - virtual void DoInsertItems( const wxArrayString& raItems, unsigned int rPos ); - virtual void DoSetItems( const wxArrayString& raItems - ,void ** ppClientData - ); - virtual void DoSetFirstItem(int n); virtual void DoSetItemClientData(unsigned int n, void* pClientData); virtual void* DoGetItemClientData(unsigned int n) const; - virtual void DoSetItemClientObject(unsigned int n, wxClientData* pClientData); - virtual wxClientData* DoGetItemClientObject(unsigned int n) const; // // wxCheckListBox support @@ -160,7 +152,14 @@ protected: wxListBoxItemsArray m_aItems; #endif -private: + // + // Implement base wxItemContainer virtuals + // + virtual int DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, + wxClientDataType type); + DECLARE_DYNAMIC_CLASS(wxListBox) }; // end of wxListBox diff --git a/include/wx/palmos/choice.h b/include/wx/palmos/choice.h index e978c2d869..1cffe80f7b 100644 --- a/include/wx/palmos/choice.h +++ b/include/wx/palmos/choice.h @@ -64,10 +64,11 @@ public: const wxString& name = wxChoiceNameStr); // implement base class pure virtuals - virtual int DoAppend(const wxString& item); - virtual int DoInsert(const wxString& item, unsigned int pos); - virtual void Delete(unsigned int n); - virtual void Clear(); + virtual int DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, wxClientDataType type); + virtual void DoDeleteOneItem(unsigned int n); + virtual void DoClear(); virtual unsigned int GetCount() const; virtual int GetSelection() const; @@ -84,8 +85,6 @@ protected: virtual void DoMoveWindow(int x, int y, int width, int height); virtual void DoSetItemClientData(unsigned int n, void* clientData); virtual void* DoGetItemClientData(unsigned int n) const; - virtual void DoSetItemClientObject(unsigned int n, wxClientData* clientData); - virtual wxClientData* DoGetItemClientObject(unsigned int n) const; // MSW implementation virtual wxSize DoGetBestSize() const; diff --git a/include/wx/palmos/listbox.h b/include/wx/palmos/listbox.h index 0f6e6e7578..1bf96f567a 100644 --- a/include/wx/palmos/listbox.h +++ b/include/wx/palmos/listbox.h @@ -78,8 +78,8 @@ public: virtual ~wxListBox(); // implement base class pure virtuals - virtual void Clear(); - virtual void Delete(unsigned int n); + virtual void DoClear(); + virtual void DoDeleteOneItem(unsigned int n); virtual unsigned int GetCount() const; virtual wxString GetString(unsigned int n) const; @@ -90,16 +90,14 @@ public: virtual int GetSelection() const; virtual int GetSelections(wxArrayInt& aSelections) const; - virtual int DoAppend(const wxString& item); - virtual void DoInsertItems(const wxArrayString& items, unsigned int pos); - virtual void DoSetItems(const wxArrayString& items, void **clientData); + virtual int DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, wxClientDataType type); virtual void DoSetFirstItem(int n); virtual void DoSetItemClientData(unsigned int n, void* clientData); virtual void* DoGetItemClientData(unsigned int n) const; - virtual void DoSetItemClientObject(unsigned int n, wxClientData* clientData); - virtual wxClientData* DoGetItemClientObject(unsigned int n) const; // wxCheckListBox support #if wxUSE_OWNER_DRAWN diff --git a/include/wx/univ/checklst.h b/include/wx/univ/checklst.h index e6afd10a16..3df4668770 100644 --- a/include/wx/univ/checklst.h +++ b/include/wx/univ/checklst.h @@ -84,14 +84,11 @@ public: return GetStdInputHandler(handlerDef); } +protected: // override all methods which add/delete items to update m_checks array as // well - virtual void Delete(unsigned int n); - -protected: - virtual int DoAppend(const wxString& item); - virtual void DoInsertItems(const wxArrayString& items, unsigned int pos); - virtual void DoSetItems(const wxArrayString& items, void **clientData); + virtual void OnItemInserted(unsigned int pos); + virtual void DoDeleteOneItem(unsigned int n); virtual void DoClear(); // draw the check items instead of the usual ones diff --git a/include/wx/univ/combobox.h b/include/wx/univ/combobox.h index 830f3e2ef5..48fc4225f4 100644 --- a/include/wx/univ/combobox.h +++ b/include/wx/univ/combobox.h @@ -117,8 +117,8 @@ public: virtual bool CanRedo() const; // wxControlWithItems methods - virtual void Clear(); - virtual void Delete(unsigned int n); + virtual void DoClear(); + virtual void DoDeleteOneItem(unsigned int n); virtual unsigned int GetCount() const; virtual wxString GetString(unsigned int n) const; virtual void SetString(unsigned int n, const wxString& s); @@ -143,12 +143,12 @@ public: } protected: - virtual int DoAppend(const wxString& item); - virtual int DoInsert(const wxString& item, unsigned int pos); + virtual int DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, wxClientDataType type); + virtual void DoSetItemClientData(unsigned int n, void* clientData); virtual void* DoGetItemClientData(unsigned int n) const; - virtual void DoSetItemClientObject(unsigned int n, wxClientData* clientData); - virtual wxClientData* DoGetItemClientObject(unsigned int n) const; // common part of all ctors void Init(); diff --git a/include/wx/univ/listbox.h b/include/wx/univ/listbox.h index 2edbdc1003..a5ef8d0d87 100644 --- a/include/wx/univ/listbox.h +++ b/include/wx/univ/listbox.h @@ -96,8 +96,8 @@ public: const wxString& name = wxListBoxNameStr); // implement the listbox interface defined by wxListBoxBase - virtual void Clear(); - virtual void Delete(unsigned int n); + virtual void DoClear(); + virtual void DoDeleteOneItem(unsigned int n); virtual unsigned int GetCount() const { return (unsigned int)m_strings->GetCount(); } @@ -114,17 +114,19 @@ public: protected: virtual void DoSetSelection(int n, bool select); - virtual int DoAppendOnly(const wxString& item); - virtual int DoAppend(const wxString& item); - virtual void DoInsertItems(const wxArrayString& items, unsigned int pos); - virtual void DoSetItems(const wxArrayString& items, void **clientData); + + virtual int DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, + wxClientDataType type); + + // universal wxComboBox implementation internally uses wxListBox + friend class WXDLLEXPORT wxComboBox; virtual void DoSetFirstItem(int n); virtual void DoSetItemClientData(unsigned int n, void* clientData); virtual void* DoGetItemClientData(unsigned int n) const; - virtual void DoSetItemClientObject(unsigned int n, wxClientData* clientData); - virtual wxClientData* DoGetItemClientObject(unsigned int n) const; public: // override some more base class methods @@ -202,15 +204,17 @@ protected: virtual void DoDraw(wxControlRenderer *renderer); virtual wxBorder GetDefaultBorder() const; + // special hook for wxCheckListBox which allows it to update its internal + // data when a new item is inserted into the listbox + virtual void OnItemInserted(unsigned int WXUNUSED(pos)) { } + + // common part of all ctors void Init(); // event handlers void OnSize(wxSizeEvent& event); - // common part of Clear() and DoSetItems(): clears everything - virtual void DoClear(); - // refresh the given item(s) or everything void RefreshItems(int from, int count); void RefreshItem(int n); diff --git a/samples/widgets/Makefile.in b/samples/widgets/Makefile.in index 43923e57ec..06a21cf635 100644 --- a/samples/widgets/Makefile.in +++ b/samples/widgets/Makefile.in @@ -1,6 +1,6 @@ # ========================================================================= # This makefile was generated by -# Bakefile 0.2.1 (http://bakefile.sourceforge.net) +# Bakefile 0.2.2 (http://bakefile.sourceforge.net) # Do not modify, all changes will be overwritten! # ========================================================================= @@ -34,6 +34,7 @@ EXTRALIBS_XML = @EXTRALIBS_XML@ EXTRALIBS_HTML = @EXTRALIBS_HTML@ EXTRALIBS_GUI = @EXTRALIBS_GUI@ EXTRALIBS_SDL = @EXTRALIBS_SDL@ +CXXWARNINGS = @CXXWARNINGS@ HOST_SUFFIX = @HOST_SUFFIX@ SAMPLES_RPATH_FLAG = @SAMPLES_RPATH_FLAG@ SAMPLES_RPATH_POSTLINK = @SAMPLES_RPATH_POSTLINK@ @@ -47,12 +48,14 @@ WX_VERSION = $(WX_RELEASE).0 LIBDIRNAME = $(wx_top_builddir)/lib WIDGETS_CXXFLAGS = -D__WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p) \ $(__EXCEPTIONS_DEFINE_p) $(__RTTI_DEFINE_p) $(__THREAD_DEFINE_p) \ - -I$(srcdir) $(__DLLFLAG_p) -I$(srcdir)/../../samples $(CPPFLAGS) $(CXXFLAGS) + -I$(srcdir) $(__DLLFLAG_p) -I$(srcdir)/../../samples $(CXXWARNINGS) \ + $(CPPFLAGS) $(CXXFLAGS) WIDGETS_OBJECTS = \ $(__widgets_os2_lib_res) \ widgets_bmpcombobox.o \ widgets_button.o \ widgets_checkbox.o \ + widgets_choice.o \ widgets_clrpicker.o \ widgets_combobox.o \ widgets_datepick.o \ @@ -62,6 +65,7 @@ WIDGETS_OBJECTS = \ widgets_fontpicker.o \ widgets_gauge.o \ widgets_hyperlnk.o \ + widgets_itemcontainer.o \ widgets_listbox.o \ widgets_notebook.o \ widgets_odcombobox.o \ @@ -224,6 +228,9 @@ widgets_button.o: $(srcdir)/button.cpp widgets_checkbox.o: $(srcdir)/checkbox.cpp $(CXXC) -c -o $@ $(WIDGETS_CXXFLAGS) $(srcdir)/checkbox.cpp +widgets_choice.o: $(srcdir)/choice.cpp + $(CXXC) -c -o $@ $(WIDGETS_CXXFLAGS) $(srcdir)/choice.cpp + widgets_clrpicker.o: $(srcdir)/clrpicker.cpp $(CXXC) -c -o $@ $(WIDGETS_CXXFLAGS) $(srcdir)/clrpicker.cpp @@ -251,6 +258,9 @@ widgets_gauge.o: $(srcdir)/gauge.cpp widgets_hyperlnk.o: $(srcdir)/hyperlnk.cpp $(CXXC) -c -o $@ $(WIDGETS_CXXFLAGS) $(srcdir)/hyperlnk.cpp +widgets_itemcontainer.o: $(srcdir)/itemcontainer.cpp + $(CXXC) -c -o $@ $(WIDGETS_CXXFLAGS) $(srcdir)/itemcontainer.cpp + widgets_listbox.o: $(srcdir)/listbox.cpp $(CXXC) -c -o $@ $(WIDGETS_CXXFLAGS) $(srcdir)/listbox.cpp @@ -285,7 +295,7 @@ widgets_widgets.o: $(srcdir)/widgets.cpp $(CXXC) -c -o $@ $(WIDGETS_CXXFLAGS) $(srcdir)/widgets.cpp widgets_sample_rc.o: $(srcdir)/../sample.rc - $(WINDRES) -i$< -o$@ --define __WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p_2) $(__EXCEPTIONS_DEFINE_p_2) $(__RTTI_DEFINE_p_2) $(__THREAD_DEFINE_p_2) --include-dir $(srcdir) $(__DLLFLAG_p_2) --include-dir $(srcdir)/../../samples $(__RCDEFDIR_p_1) --include-dir $(top_srcdir)/include + $(WINDRES) -i$< -o$@ --define __WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p_2) $(__EXCEPTIONS_DEFINE_p_2) $(__RTTI_DEFINE_p_2) $(__THREAD_DEFINE_p_2) --include-dir $(srcdir) $(__DLLFLAG_p_2) --include-dir $(srcdir)/../../samples $(__RCDEFDIR_p_1) --include-dir $(top_srcdir)/include # Include dependency info, if present: diff --git a/samples/widgets/bmpcombobox.cpp b/samples/widgets/bmpcombobox.cpp index 5cd72b3e28..7f9388545f 100644 --- a/samples/widgets/bmpcombobox.cpp +++ b/samples/widgets/bmpcombobox.cpp @@ -52,6 +52,7 @@ #include "wx/imaglist.h" #include "wx/bmpcbox.h" +#include "itemcontainer.h" #include "widgets.h" #include "icons/bmpcombobox.xpm" @@ -82,7 +83,8 @@ enum BitmapComboBoxPage_Delete, BitmapComboBoxPage_DeleteText, BitmapComboBoxPage_DeleteSel, - BitmapComboBoxPage_Combo + BitmapComboBoxPage_Combo, + BitmapComboBoxPage_ContainerTests }; @@ -90,12 +92,13 @@ enum // BitmapComboBoxWidgetsPage // ---------------------------------------------------------------------------- -class BitmapComboBoxWidgetsPage : public WidgetsPage +class BitmapComboBoxWidgetsPage : public ItemContainerWidgetsPage { public: BitmapComboBoxWidgetsPage(WidgetsBookCtrl *book, wxImageList *imaglist); virtual wxControl *GetWidget() const { return m_combobox; } + virtual wxItemContainer* GetContainer() const { return m_combobox; } virtual void RecreateWidget() { CreateCombo(); } // lazy creation of the content @@ -195,6 +198,7 @@ BEGIN_EVENT_TABLE(BitmapComboBoxWidgetsPage, WidgetsPage) EVT_BUTTON(BitmapComboBoxPage_AddMany, BitmapComboBoxWidgetsPage::OnButtonAddMany) EVT_BUTTON(BitmapComboBoxPage_LoadFromFile, BitmapComboBoxWidgetsPage::OnButtonLoadFromFile) EVT_BUTTON(BitmapComboBoxPage_SetFromFile, BitmapComboBoxWidgetsPage::OnButtonSetFromFile) + EVT_BUTTON(BitmapComboBoxPage_ContainerTests, ItemContainerWidgetsPage::OnButtonTestItemContainer) EVT_TEXT_ENTER(BitmapComboBoxPage_InsertText, BitmapComboBoxWidgetsPage::OnButtonInsert) EVT_TEXT(BitmapComboBoxPage_ChangeHeight, BitmapComboBoxWidgetsPage::OnTextChangeHeight) @@ -233,7 +237,7 @@ IMPLEMENT_WIDGETS_PAGE(BitmapComboBoxWidgetsPage, _T("BitmapCombobox"), BitmapComboBoxWidgetsPage::BitmapComboBoxWidgetsPage(WidgetsBookCtrl *book, wxImageList *imaglist) - : WidgetsPage(book, imaglist, bmpcombobox_xpm) + : ItemContainerWidgetsPage(book, imaglist, bmpcombobox_xpm) { // init everything m_chkSort = @@ -308,6 +312,9 @@ void BitmapComboBoxWidgetsPage::CreateContent() _T("&Change wxBitmapComboBox contents")); wxSizer *sizerMiddle = new wxStaticBoxSizer(box2, wxVERTICAL); + btn = new wxButton(this, BitmapComboBoxPage_ContainerTests, _T("Run &tests")); + sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5); + #if wxUSE_IMAGE btn = new wxButton(this, BitmapComboBoxPage_AddWidgetIcons, _T("Add &widget icons")); sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5); diff --git a/samples/widgets/choice.cpp b/samples/widgets/choice.cpp new file mode 100644 index 0000000000..872c91a741 --- /dev/null +++ b/samples/widgets/choice.cpp @@ -0,0 +1,453 @@ +///////////////////////////////////////////////////////////////////////////// +// Program: wxWidgets Widgets Sample +// Name: choice.cpp +// Purpose: Part of the widgets sample showing wxChoice +// Created: 23.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 + +#if wxUSE_CHOICE + +// for all others, include the necessary headers +#ifndef WX_PRECOMP + #include "wx/log.h" + + #include "wx/bitmap.h" + #include "wx/button.h" + #include "wx/checkbox.h" + #include "wx/choice.h" + #include "wx/combobox.h" + #include "wx/radiobox.h" + #include "wx/statbox.h" + #include "wx/textctrl.h" +#endif + +#include "wx/sizer.h" + +#include "wx/checklst.h" + +#include "itemcontainer.h" +#include "widgets.h" + +#include "icons/choice.xpm" + +// ---------------------------------------------------------------------------- +// constants +// ---------------------------------------------------------------------------- + +// control ids +enum +{ + ChoicePage_Reset = wxID_HIGHEST, + ChoicePage_Add, + ChoicePage_AddText, + ChoicePage_AddSeveral, + ChoicePage_AddMany, + ChoicePage_Clear, + ChoicePage_Change, + ChoicePage_ChangeText, + ChoicePage_Delete, + ChoicePage_DeleteText, + ChoicePage_DeleteSel, + ChoicePage_Choice, + ChoicePage_ContainerTests +}; + +// ---------------------------------------------------------------------------- +// ChoiceWidgetsPage +// ---------------------------------------------------------------------------- + +class ChoiceWidgetsPage : public ItemContainerWidgetsPage +{ +public: + ChoiceWidgetsPage(WidgetsBookCtrl *book, wxImageList *imaglist); + + virtual wxControl *GetWidget() const { return m_choice; } + virtual wxItemContainer* GetContainer() const { return m_choice; } + virtual void RecreateWidget() { CreateChoice(); } + + // lazy creation of the content + virtual void CreateContent(); + +protected: + // event handlers + void OnButtonReset(wxCommandEvent& event); + void OnButtonChange(wxCommandEvent& event); + void OnButtonDelete(wxCommandEvent& event); + void OnButtonDeleteSel(wxCommandEvent& event); + void OnButtonClear(wxCommandEvent& event); + void OnButtonAdd(wxCommandEvent& event); + void OnButtonAddSeveral(wxCommandEvent& event); + void OnButtonAddMany(wxCommandEvent& event); + + void OnChoice(wxCommandEvent& event); + + void OnCheckOrRadioBox(wxCommandEvent& event); + + void OnUpdateUIAddSeveral(wxUpdateUIEvent& event); + void OnUpdateUIClearButton(wxUpdateUIEvent& event); + void OnUpdateUIDeleteButton(wxUpdateUIEvent& event); + void OnUpdateUIDeleteSelButton(wxUpdateUIEvent& event); + void OnUpdateUIResetButton(wxUpdateUIEvent& event); + + // reset the choice parameters + void Reset(); + + // (re)create the choice + void CreateChoice(); + + // should it be sorted? + bool m_sorted; + + // the controls + // ------------ + + // the checkboxes + wxCheckBox *m_chkSort; + + // the choice itself and the sizer it is in +#ifdef __WXWINCE__ + wxChoiceBase +#else + wxChoice +#endif + *m_choice; + + wxSizer *m_sizerChoice; + + // the text entries for "Add/change string" and "Delete" buttons + wxTextCtrl *m_textAdd, + *m_textChange, + *m_textDelete; + +private: + DECLARE_EVENT_TABLE() + DECLARE_WIDGETS_PAGE(ChoiceWidgetsPage) +}; + +// ---------------------------------------------------------------------------- +// event tables +// ---------------------------------------------------------------------------- + +BEGIN_EVENT_TABLE(ChoiceWidgetsPage, WidgetsPage) + EVT_BUTTON(ChoicePage_Reset, ChoiceWidgetsPage::OnButtonReset) + EVT_BUTTON(ChoicePage_Change, ChoiceWidgetsPage::OnButtonChange) + EVT_BUTTON(ChoicePage_Delete, ChoiceWidgetsPage::OnButtonDelete) + EVT_BUTTON(ChoicePage_DeleteSel, ChoiceWidgetsPage::OnButtonDeleteSel) + EVT_BUTTON(ChoicePage_Clear, ChoiceWidgetsPage::OnButtonClear) + EVT_BUTTON(ChoicePage_Add, ChoiceWidgetsPage::OnButtonAdd) + EVT_BUTTON(ChoicePage_AddSeveral, ChoiceWidgetsPage::OnButtonAddSeveral) + EVT_BUTTON(ChoicePage_AddMany, ChoiceWidgetsPage::OnButtonAddMany) + EVT_BUTTON(ChoicePage_ContainerTests, ItemContainerWidgetsPage::OnButtonTestItemContainer) + + EVT_TEXT_ENTER(ChoicePage_AddText, ChoiceWidgetsPage::OnButtonAdd) + EVT_TEXT_ENTER(ChoicePage_DeleteText, ChoiceWidgetsPage::OnButtonDelete) + + EVT_UPDATE_UI(ChoicePage_Reset, ChoiceWidgetsPage::OnUpdateUIResetButton) + EVT_UPDATE_UI(ChoicePage_AddSeveral, ChoiceWidgetsPage::OnUpdateUIAddSeveral) + EVT_UPDATE_UI(ChoicePage_Clear, ChoiceWidgetsPage::OnUpdateUIClearButton) + EVT_UPDATE_UI(ChoicePage_DeleteText, ChoiceWidgetsPage::OnUpdateUIClearButton) + EVT_UPDATE_UI(ChoicePage_Delete, ChoiceWidgetsPage::OnUpdateUIDeleteButton) + EVT_UPDATE_UI(ChoicePage_Change, ChoiceWidgetsPage::OnUpdateUIDeleteSelButton) + EVT_UPDATE_UI(ChoicePage_ChangeText, ChoiceWidgetsPage::OnUpdateUIDeleteSelButton) + EVT_UPDATE_UI(ChoicePage_DeleteSel, ChoiceWidgetsPage::OnUpdateUIDeleteSelButton) + + EVT_CHOICE(ChoicePage_Choice, ChoiceWidgetsPage::OnChoice) + + EVT_CHECKBOX(wxID_ANY, ChoiceWidgetsPage::OnCheckOrRadioBox) + EVT_RADIOBOX(wxID_ANY, ChoiceWidgetsPage::OnCheckOrRadioBox) +END_EVENT_TABLE() + +// ============================================================================ +// implementation +// ============================================================================ + +#if defined(__WXUNIVERSAL__) + #define FAMILY_CTRLS UNIVERSAL_CTRLS +#else + #define FAMILY_CTRLS NATIVE_CTRLS +#endif + +IMPLEMENT_WIDGETS_PAGE(ChoiceWidgetsPage, _T("Choice"), + FAMILY_CTRLS | WITH_ITEMS_CTRLS + ); + +ChoiceWidgetsPage::ChoiceWidgetsPage(WidgetsBookCtrl *book, + wxImageList *imaglist) + : ItemContainerWidgetsPage(book, imaglist, choice_xpm) +{ + // init everything + + m_chkSort = (wxCheckBox *)NULL; + + m_choice = NULL; + m_sizerChoice = (wxSizer *)NULL; + +} + +void ChoiceWidgetsPage::CreateContent() +{ + /* + What we create here is a frame having 3 panes: style pane is the + leftmost one, in the middle the pane with buttons allowing to perform + miscellaneous choice operations and the pane containing the choice + itself to the right + */ + wxSizer *sizerTop = new wxBoxSizer(wxHORIZONTAL); + + // left pane + wxStaticBox *box = new wxStaticBox(this, wxID_ANY, + _T("&Set choice parameters")); + wxSizer *sizerLeft = new wxStaticBoxSizer(box, wxVERTICAL); + + static const wxString modes[] = + { + _T("single"), + _T("extended"), + _T("multiple"), + }; + + m_chkSort = CreateCheckBoxAndAddToSizer(sizerLeft, _T("&Sort items")); + + wxButton *btn = new wxButton(this, ChoicePage_Reset, _T("&Reset")); + sizerLeft->Add(btn, 0, wxALIGN_CENTRE_HORIZONTAL | wxALL, 15); + + // middle pane + wxStaticBox *box2 = new wxStaticBox(this, wxID_ANY, + _T("&Change choice contents")); + wxSizer *sizerMiddle = new wxStaticBoxSizer(box2, wxVERTICAL); + + wxSizer *sizerRow = new wxBoxSizer(wxHORIZONTAL); + btn = new wxButton(this, ChoicePage_Add, _T("&Add this string")); + m_textAdd = new wxTextCtrl(this, ChoicePage_AddText, _T("test item 0")); + sizerRow->Add(btn, 0, wxRIGHT, 5); + sizerRow->Add(m_textAdd, 1, wxLEFT, 5); + sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5); + + btn = new wxButton(this, ChoicePage_AddSeveral, _T("&Insert a few strings")); + sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5); + + btn = new wxButton(this, ChoicePage_AddMany, _T("Add &many strings")); + sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5); + + sizerRow = new wxBoxSizer(wxHORIZONTAL); + btn = new wxButton(this, ChoicePage_Change, _T("C&hange current")); + m_textChange = new wxTextCtrl(this, ChoicePage_ChangeText, wxEmptyString); + sizerRow->Add(btn, 0, wxRIGHT, 5); + sizerRow->Add(m_textChange, 1, wxLEFT, 5); + sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5); + + sizerRow = new wxBoxSizer(wxHORIZONTAL); + btn = new wxButton(this, ChoicePage_Delete, _T("&Delete this item")); + m_textDelete = new wxTextCtrl(this, ChoicePage_DeleteText, wxEmptyString); + sizerRow->Add(btn, 0, wxRIGHT, 5); + sizerRow->Add(m_textDelete, 1, wxLEFT, 5); + sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5); + + btn = new wxButton(this, ChoicePage_DeleteSel, _T("Delete &selection")); + sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5); + + btn = new wxButton(this, ChoicePage_Clear, _T("&Clear")); + sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5); + + btn = new wxButton(this, ChoicePage_ContainerTests, _T("Run &tests")); + sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5); + + // right pane + wxSizer *sizerRight = new wxBoxSizer(wxVERTICAL); + m_choice = new wxChoice(this, ChoicePage_Choice); + sizerRight->Add(m_choice, 1, wxGROW | wxALL, 5); + sizerRight->SetMinSize(150, 0); + m_sizerChoice = sizerRight; // save it to modify it later + + // the 3 panes panes compose the window + sizerTop->Add(sizerLeft, 0, wxGROW | (wxALL & ~wxLEFT), 10); + sizerTop->Add(sizerMiddle, 1, wxGROW | wxALL, 10); + sizerTop->Add(sizerRight, 1, wxGROW | (wxALL & ~wxRIGHT), 10); + + // final initializations + Reset(); + + SetSizer(sizerTop); +} + +// ---------------------------------------------------------------------------- +// operations +// ---------------------------------------------------------------------------- + +void ChoiceWidgetsPage::Reset() +{ + m_chkSort->SetValue(false); +} + +void ChoiceWidgetsPage::CreateChoice() +{ + int flags = ms_defaultFlags; + + if ( m_chkSort->GetValue() ) + flags |= wxCB_SORT; + + wxArrayString items; + if ( m_choice ) + { + int count = m_choice->GetCount(); + for ( int n = 0; n < count; n++ ) + { + items.Add(m_choice->GetString(n)); + } + + m_sizerChoice->Detach( m_choice ); + delete m_choice; + } + + m_choice = new wxChoice(this, ChoicePage_Choice, + wxDefaultPosition, wxDefaultSize, + 0, NULL, + flags); + + m_choice->Set(items); + m_sizerChoice->Add(m_choice, 1, wxGROW | wxALL, 5); + m_sizerChoice->Layout(); +} + +// ---------------------------------------------------------------------------- +// event handlers +// ---------------------------------------------------------------------------- + +void ChoiceWidgetsPage::OnButtonReset(wxCommandEvent& WXUNUSED(event)) +{ + Reset(); + + CreateChoice(); +} + +void ChoiceWidgetsPage::OnButtonChange(wxCommandEvent& WXUNUSED(event)) +{ + int selection = m_choice->GetSelection(); + if(selection != wxNOT_FOUND) + { + m_choice->SetString(selection, m_textChange->GetValue()); + } +} + +void ChoiceWidgetsPage::OnButtonDelete(wxCommandEvent& WXUNUSED(event)) +{ + unsigned long n; + if ( !m_textDelete->GetValue().ToULong(&n) || + (n >= (unsigned)m_choice->GetCount()) ) + { + return; + } + + m_choice->Delete(n); +} + +void ChoiceWidgetsPage::OnButtonDeleteSel(wxCommandEvent& WXUNUSED(event)) +{ + int selection = m_choice->GetSelection(); + if(selection != wxNOT_FOUND) + { + m_choice->Delete(selection); + } +} + +void ChoiceWidgetsPage::OnButtonClear(wxCommandEvent& WXUNUSED(event)) +{ + m_choice->Clear(); +} + +void ChoiceWidgetsPage::OnButtonAdd(wxCommandEvent& WXUNUSED(event)) +{ + static unsigned int s_item = 0; + + wxString s = m_textAdd->GetValue(); + if ( !m_textAdd->IsModified() ) + { + // update the default string + m_textAdd->SetValue(wxString::Format(_T("test item %u"), ++s_item)); + } + + m_choice->Append(s); +} + +void ChoiceWidgetsPage::OnButtonAddMany(wxCommandEvent& WXUNUSED(event)) +{ + // "many" means 1000 here + wxArrayString strings; + for ( unsigned int n = 0; n < 1000; n++ ) + { + strings.Add(wxString::Format(_T("item #%u"), n)); + } + m_choice->Append(strings); +} + +void ChoiceWidgetsPage::OnButtonAddSeveral(wxCommandEvent& WXUNUSED(event)) +{ + wxArrayString items; + items.Add(_T("First")); + items.Add(_T("another one")); + items.Add(_T("and the last (very very very very very very very very very very long) one")); + m_choice->Insert(items, 0); +} + +void ChoiceWidgetsPage::OnUpdateUIResetButton(wxUpdateUIEvent& event) +{ + event.Enable( m_chkSort->GetValue() ); +} + +void ChoiceWidgetsPage::OnUpdateUIDeleteButton(wxUpdateUIEvent& event) +{ + unsigned long n; + event.Enable(m_textDelete->GetValue().ToULong(&n) && + (n < (unsigned)m_choice->GetCount())); +} + +void ChoiceWidgetsPage::OnUpdateUIDeleteSelButton(wxUpdateUIEvent& event) +{ + wxArrayInt selections; + event.Enable(m_choice->GetSelection() != wxNOT_FOUND); +} + +void ChoiceWidgetsPage::OnUpdateUIClearButton(wxUpdateUIEvent& event) +{ + event.Enable(m_choice->GetCount() != 0); +} + +void ChoiceWidgetsPage::OnUpdateUIAddSeveral(wxUpdateUIEvent& event) +{ + event.Enable(!m_choice->HasFlag(wxCB_SORT)); +} + +void ChoiceWidgetsPage::OnChoice(wxCommandEvent& event) +{ + long sel = event.GetSelection(); + m_textDelete->SetValue(wxString::Format(_T("%ld"), sel)); + + if (event.IsSelection()) + wxLogMessage(_T("Choice item %ld selected"), sel); + else + wxLogMessage(_T("Choice item %ld deselected"), sel); +} + +void ChoiceWidgetsPage::OnCheckOrRadioBox(wxCommandEvent& WXUNUSED(event)) +{ + CreateChoice(); +} + +#endif // wxUSE_CHOICE diff --git a/samples/widgets/combobox.cpp b/samples/widgets/combobox.cpp index bb565684bc..6518ddd09f 100644 --- a/samples/widgets/combobox.cpp +++ b/samples/widgets/combobox.cpp @@ -41,6 +41,7 @@ #include "wx/sizer.h" +#include "itemcontainer.h" #include "widgets.h" #if 1 #include "icons/combobox.xpm" @@ -70,7 +71,8 @@ enum ComboPage_DeleteSel, ComboPage_SetValue, ComboPage_SetValueText, - ComboPage_Combo + ComboPage_Combo, + ComboPage_ContainerTests }; // kinds of comboboxes @@ -85,12 +87,13 @@ enum // ComboboxWidgetsPage // ---------------------------------------------------------------------------- -class ComboboxWidgetsPage : public WidgetsPage +class ComboboxWidgetsPage : public ItemContainerWidgetsPage { public: ComboboxWidgetsPage(WidgetsBookCtrl *book, wxImageList *imaglist); virtual wxControl *GetWidget() const { return m_combobox; } + virtual wxItemContainer* GetContainer() const { return m_combobox; } virtual void RecreateWidget() { CreateCombo(); } // lazy creation of the content @@ -175,6 +178,7 @@ BEGIN_EVENT_TABLE(ComboboxWidgetsPage, WidgetsPage) EVT_BUTTON(ComboPage_AddMany, ComboboxWidgetsPage::OnButtonAddMany) EVT_BUTTON(ComboPage_SetValue, ComboboxWidgetsPage::OnButtonSetValue) EVT_BUTTON(ComboPage_SetCurrent, ComboboxWidgetsPage::OnButtonSetCurrent) + EVT_BUTTON(ComboPage_ContainerTests, ItemContainerWidgetsPage::OnButtonTestItemContainer) EVT_TEXT_ENTER(ComboPage_InsertText, ComboboxWidgetsPage::OnButtonInsert) EVT_TEXT_ENTER(ComboPage_AddText, ComboboxWidgetsPage::OnButtonAdd) @@ -217,7 +221,7 @@ IMPLEMENT_WIDGETS_PAGE(ComboboxWidgetsPage, _T("Combobox"), ComboboxWidgetsPage::ComboboxWidgetsPage(WidgetsBookCtrl *book, wxImageList *imaglist) - : WidgetsPage(book, imaglist, combobox_xpm) + : ItemContainerWidgetsPage(book, imaglist, combobox_xpm) { // init everything m_chkSort = @@ -331,6 +335,9 @@ void ComboboxWidgetsPage::CreateContent() &m_textSetValue); sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5); + btn = new wxButton(this, ComboPage_ContainerTests, _T("Run &tests")); + sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5); + // right pane diff --git a/samples/widgets/icons/choice.xpm b/samples/widgets/icons/choice.xpm new file mode 100644 index 0000000000..c46aaf5dba --- /dev/null +++ b/samples/widgets/icons/choice.xpm @@ -0,0 +1,27 @@ +/* XPM */ +static char * choice_xpm[] = { +/* width height ncolors chars_per_pixel */ +"16 16 5 1", +/* colors */ +" s None c None", +". c #000000", +"+ c #c0c0c0", +"@ c #808080", +"# c #ffffff", +/* pixels */ +"@@@@@@@@@@@@@@@@", +"@..............@", +"@.########+++++@", +"@.########.....@", +"@.########+...+@", +"@.########++.++@", +"@.+++++++++++++@", +"@@@@@@@@@@@@@@@@", +" ##############", +" ..............", +" .#########+.+.", +" .#########....", +" .#########+++.", +" .#########....", +" .#########+.+.", +" .............."}; diff --git a/samples/widgets/itemcontainer.cpp b/samples/widgets/itemcontainer.cpp new file mode 100644 index 0000000000..c46a738d08 --- /dev/null +++ b/samples/widgets/itemcontainer.cpp @@ -0,0 +1,288 @@ +///////////////////////////////////////////////////////////////////////////// +// 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; + + DECLARE_NO_COPY_CLASS(TrackedClientData) +}; + +// ============================================================================ +// implementation +// ============================================================================ + +ItemContainerWidgetsPage::ItemContainerWidgetsPage(WidgetsBookCtrl *book, + wxImageList *image_list, + char* icon[]) +: WidgetsPage(book, image_list, icon), m_trackedDataObjects(0) +{ + m_items.Add(_T("This")); + m_items.Add(_T("is")); + m_items.Add(_T("a")); + m_items.Add(_T("List")); + m_items.Add(_T("of")); + m_items.Add(_T("strings")); + 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 ) + { + wxString message = _T("Bug in managing wxClientData: "); + if ( m_trackedDataObjects > 0 ) + message << m_trackedDataObjects << _T(" lost objects"); + else + message << (-m_trackedDataObjects) << _T(" extra deletes"); + wxFAIL_MSG(message); + return false; + } + + return true; +} + +void ItemContainerWidgetsPage::StartTest(const wxString& label) +{ + m_container->Clear(); + wxLogMessage(_T("Test - %s:"), label.c_str()); +} + +void ItemContainerWidgetsPage::EndTest(const wxArrayString& items) +{ + const unsigned count = m_container->GetCount(); + + bool ok = count == items.GetCount(); + if ( !ok ) + { + wxFAIL_MSG(_T("Item count does not match.")); + } + else + { + for ( unsigned i = 0; i < count; ++i ) + { + wxString str = m_container->GetString(i); + if ( str != items[i] ) + { + wxFAIL_MSG(wxString::Format( + _T("Wrong string \"%s\" at position %d (expected \"%s\")"), + 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(); + + wxLogMessage(_T("...%s"), ok ? _T("passed") : _T("failed")); +} + +wxString +ItemContainerWidgetsPage::DumpContainerData(const wxArrayString& expected) const +{ + wxString str; + str << _T("Current content:\n"); + + unsigned i; + for ( i = 0; i < m_container->GetCount(); ++i ) + { + str << _T(" - ") << m_container->GetString(i) << _T(" ["); + 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; + } + str << _T("]\n"); + } + + str << _T("Expected content:\n"); + for ( i = 0; i < expected.GetCount(); ++i ) + { + const wxString& item = expected[i]; + str << _T(" - ") << item << _T("["); + for( unsigned j = 0; j < m_items.GetCount(); ++j ) + { + if ( m_items[j] == item ) + str << j; + } + str << _T("]\n"); + } + + return str; +} + +bool ItemContainerWidgetsPage::VerifyClientData(wxUIntPtr i, const wxString& str) +{ + if ( i > m_items.GetCount() || m_items[i] != str ) + { + wxLogMessage(_T("Client data for '%s' does not match."), str.c_str()); + return false; + } + + return true; +} + +void ItemContainerWidgetsPage::OnButtonTestItemContainer(wxCommandEvent&) +{ + m_container = GetContainer(); + wxASSERT_MSG(m_container, _T("Widget must have a test widget")); + + wxLogMessage(_T("wxItemContainer test for %s, %s:"), + GetWidget()->GetClassInfo()->GetClassName(), + (m_container->IsSorted() ? "Sorted" : "Unsorted")); + + const wxArrayString + & expected_result = m_container->IsSorted() ? m_itemsSorted + : m_items; + + StartTest(_T("Append one item")); + wxString item = m_items[0]; + m_container->Append(item); + EndTest(wxArrayString(1, &item)); + + StartTest(_T("Append some items")); + m_container->Append(m_items); + EndTest(expected_result); + + StartTest(_T("Append some items with data objects")); + wxClientData **objects = new wxClientData *[m_items.GetCount()]; + for ( unsigned i = 0; i < m_items.GetCount(); ++i ) + objects[i] = CreateClientData(i); + m_container->Append(m_items, objects); + EndTest(expected_result); + delete[] objects; + + StartTest(_T("Append some items with data")); + void **data = new void *[m_items.GetCount()]; + for ( unsigned i = 0; i < m_items.GetCount(); ++i ) + data[i] = (void*)i; + m_container->Append(m_items, data); + EndTest(expected_result); + delete[] data; + + StartTest(_T("Append some items with data, one by one")); + for ( unsigned i = 0; i < m_items.GetCount(); ++i ) + m_container->Append(m_items[i], (void*)i); + EndTest(expected_result); + + StartTest(_T("Append some items with data objects, one by one")); + for ( unsigned i = 0; i < m_items.GetCount(); ++i ) + m_container->Append(m_items[i], CreateClientData(i)); + EndTest(expected_result); + + if ( !m_container->IsSorted() ) + { + StartTest(_T("Insert in reverse order with data, one by one")); + for ( unsigned i = m_items.GetCount(); i; --i ) + m_container->Insert(m_items[i - 1], 0, (void*)(i - 1)); + EndTest(expected_result); + } +} + diff --git a/samples/widgets/itemcontainer.h b/samples/widgets/itemcontainer.h new file mode 100644 index 0000000000..30d79ec558 --- /dev/null +++ b/samples/widgets/itemcontainer.h @@ -0,0 +1,53 @@ +///////////////////////////////////////////////////////////////////////////// +// Program: wxWidgets Widgets Sample +// Name: itemcontainer.h +// Purpose: Part of the widgets sample showing wxComboBox +// Created: 20.07.07 +// Id: $Id$ +// License: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_SAMPLE_WIDGETS_ITEMCONTAINER_H_ +#define _WX_SAMPLE_WIDGETS_ITEMCONTAINER_H_ + +// for compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#include "widgets.h" + +class ItemContainerWidgetsPage : public WidgetsPage +{ +public: + ItemContainerWidgetsPage(WidgetsBookCtrl *book, + wxImageList *image_list, + char* icon[]); + virtual ~ItemContainerWidgetsPage(); + + void OnButtonTestItemContainer(wxCommandEvent& event); + + virtual wxItemContainer* GetContainer() const = 0; + +private: + void StartTest(const wxString& label); + void EndTest(const wxArrayString& result); + + // Track client data in wxItemContainer instances + wxClientData* CreateClientData(int value); + void StartTrackingData(); + void StopTrackingData(); + friend class TrackedClientData; + + bool VerifyAllClientDataDestroyed(); + bool VerifyClientData(wxUIntPtr i, const wxString& str); + + wxString DumpContainerData(const wxArrayString& expected) const; + + wxArrayString m_items; + wxSortedArrayString m_itemsSorted; + int m_trackedDataObjects; + + // holds pointer to the widget being tested + wxItemContainer *m_container; +}; + +#endif // _WX_SAMPLE_WIDGETS_ITEMCONTAINER_H_ diff --git a/samples/widgets/listbox.cpp b/samples/widgets/listbox.cpp index a766ef441f..b92ae08e7d 100644 --- a/samples/widgets/listbox.cpp +++ b/samples/widgets/listbox.cpp @@ -44,6 +44,7 @@ #include "wx/checklst.h" +#include "itemcontainer.h" #include "widgets.h" #include "icons/listbox.xpm" @@ -66,19 +67,21 @@ enum ListboxPage_Delete, ListboxPage_DeleteText, ListboxPage_DeleteSel, - ListboxPage_Listbox + ListboxPage_Listbox, + ListboxPage_ContainerTests }; // ---------------------------------------------------------------------------- // ListboxWidgetsPage // ---------------------------------------------------------------------------- -class ListboxWidgetsPage : public WidgetsPage +class ListboxWidgetsPage : public ItemContainerWidgetsPage { public: ListboxWidgetsPage(WidgetsBookCtrl *book, wxImageList *imaglist); virtual wxControl *GetWidget() const { return m_lbox; } + virtual wxItemContainer* GetContainer() const { return m_lbox; } virtual void RecreateWidget() { CreateLbox(); } // lazy creation of the content @@ -177,6 +180,7 @@ BEGIN_EVENT_TABLE(ListboxWidgetsPage, WidgetsPage) EVT_BUTTON(ListboxPage_Add, ListboxWidgetsPage::OnButtonAdd) EVT_BUTTON(ListboxPage_AddSeveral, ListboxWidgetsPage::OnButtonAddSeveral) EVT_BUTTON(ListboxPage_AddMany, ListboxWidgetsPage::OnButtonAddMany) + EVT_BUTTON(ListboxPage_ContainerTests, ItemContainerWidgetsPage::OnButtonTestItemContainer) EVT_TEXT_ENTER(ListboxPage_AddText, ListboxWidgetsPage::OnButtonAdd) EVT_TEXT_ENTER(ListboxPage_DeleteText, ListboxWidgetsPage::OnButtonDelete) @@ -214,7 +218,7 @@ IMPLEMENT_WIDGETS_PAGE(ListboxWidgetsPage, _T("Listbox"), ListboxWidgetsPage::ListboxWidgetsPage(WidgetsBookCtrl *book, wxImageList *imaglist) - : WidgetsPage(book, imaglist, listbox_xpm) + : ItemContainerWidgetsPage(book, imaglist, listbox_xpm) { // init everything m_radioSelMode = (wxRadioBox *)NULL; @@ -315,6 +319,9 @@ void ListboxWidgetsPage::CreateContent() btn = new wxButton(this, ListboxPage_Clear, _T("&Clear")); sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5); + btn = new wxButton(this, ListboxPage_ContainerTests, _T("Run &tests")); + sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5); + // right pane wxSizer *sizerRight = new wxBoxSizer(wxVERTICAL); m_lbox = new wxListBox(this, ListboxPage_Listbox, diff --git a/samples/widgets/makefile.bcc b/samples/widgets/makefile.bcc index 84c9e650f1..66a930a6ec 100644 --- a/samples/widgets/makefile.bcc +++ b/samples/widgets/makefile.bcc @@ -1,6 +1,6 @@ # ========================================================================= # This makefile was generated by -# Bakefile 0.2.1 (http://bakefile.sourceforge.net) +# Bakefile 0.2.2 (http://bakefile.sourceforge.net) # Do not modify, all changes will be overwritten! # ========================================================================= @@ -22,9 +22,10 @@ BCCDIR = $(MAKEDIR)\.. ### Variables: ### WX_RELEASE_NODOT = 29 +COMPILER_PREFIX = bcc OBJS = \ - bcc_$(PORTNAME)$(WXUNIVNAME)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WXDLLFLAG)$(CFG) -LIBDIRNAME = .\..\..\lib\bcc_$(LIBTYPE_SUFFIX)$(CFG) + $(COMPILER_PREFIX)_$(PORTNAME)$(WXUNIVNAME)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WXDLLFLAG)$(CFG) +LIBDIRNAME = .\..\..\lib\$(COMPILER_PREFIX)_$(LIBTYPE_SUFFIX)$(CFG) SETUPHDIR = \ $(LIBDIRNAME)\$(PORTNAME)$(WXUNIVNAME)$(WXUNICODEFLAG)$(WXDEBUGFLAG) WIDGETS_CXXFLAGS = $(__RUNTIME_LIBS_7) -I$(BCCDIR)\include $(__DEBUGINFO) \ @@ -37,6 +38,7 @@ WIDGETS_OBJECTS = \ $(OBJS)\widgets_bmpcombobox.obj \ $(OBJS)\widgets_button.obj \ $(OBJS)\widgets_checkbox.obj \ + $(OBJS)\widgets_choice.obj \ $(OBJS)\widgets_clrpicker.obj \ $(OBJS)\widgets_combobox.obj \ $(OBJS)\widgets_datepick.obj \ @@ -46,6 +48,7 @@ WIDGETS_OBJECTS = \ $(OBJS)\widgets_fontpicker.obj \ $(OBJS)\widgets_gauge.obj \ $(OBJS)\widgets_hyperlnk.obj \ + $(OBJS)\widgets_itemcontainer.obj \ $(OBJS)\widgets_listbox.obj \ $(OBJS)\widgets_notebook.obj \ $(OBJS)\widgets_odcombobox.obj \ @@ -269,6 +272,9 @@ $(OBJS)\widgets_button.obj: .\button.cpp $(OBJS)\widgets_checkbox.obj: .\checkbox.cpp $(CXX) -q -c -P -o$@ $(WIDGETS_CXXFLAGS) $** +$(OBJS)\widgets_choice.obj: .\choice.cpp + $(CXX) -q -c -P -o$@ $(WIDGETS_CXXFLAGS) $** + $(OBJS)\widgets_clrpicker.obj: .\clrpicker.cpp $(CXX) -q -c -P -o$@ $(WIDGETS_CXXFLAGS) $** @@ -296,6 +302,9 @@ $(OBJS)\widgets_gauge.obj: .\gauge.cpp $(OBJS)\widgets_hyperlnk.obj: .\hyperlnk.cpp $(CXX) -q -c -P -o$@ $(WIDGETS_CXXFLAGS) $** +$(OBJS)\widgets_itemcontainer.obj: .\itemcontainer.cpp + $(CXX) -q -c -P -o$@ $(WIDGETS_CXXFLAGS) $** + $(OBJS)\widgets_listbox.obj: .\listbox.cpp $(CXX) -q -c -P -o$@ $(WIDGETS_CXXFLAGS) $** @@ -330,5 +339,5 @@ $(OBJS)\widgets_widgets.obj: .\widgets.cpp $(CXX) -q -c -P -o$@ $(WIDGETS_CXXFLAGS) $** $(OBJS)\widgets_sample.res: .\..\sample.rc - brcc32 -32 -r -fo$@ -i$(BCCDIR)\include -d__WXMSW__ $(__WXUNIV_DEFINE_p_1) $(__DEBUG_DEFINE_p_1) $(__EXCEPTIONS_DEFINE_p_1) $(__RTTI_DEFINE_p_1) $(__THREAD_DEFINE_p_1) $(__UNICODE_DEFINE_p_1) $(__MSLU_DEFINE_p_1) $(__GFXCTX_DEFINE_p_1) -i$(SETUPHDIR) -i.\..\..\include -i. $(__DLLFLAG_p_1) -i.\..\..\samples -dNOPCH $** + brcc32 -32 -r -fo$@ -i$(BCCDIR)\include -d__WXMSW__ $(__WXUNIV_DEFINE_p_1) $(__DEBUG_DEFINE_p_1) $(__EXCEPTIONS_DEFINE_p_1) $(__RTTI_DEFINE_p_1) $(__THREAD_DEFINE_p_1) $(__UNICODE_DEFINE_p_1) $(__MSLU_DEFINE_p_1) $(__GFXCTX_DEFINE_p_1) -i$(SETUPHDIR) -i.\..\..\include -i. $(__DLLFLAG_p_1) -i.\..\..\samples -dNOPCH $** diff --git a/samples/widgets/makefile.gcc b/samples/widgets/makefile.gcc index 53aba1b639..9401c9c275 100644 --- a/samples/widgets/makefile.gcc +++ b/samples/widgets/makefile.gcc @@ -1,6 +1,6 @@ # ========================================================================= # This makefile was generated by -# Bakefile 0.2.1 (http://bakefile.sourceforge.net) +# Bakefile 0.2.2 (http://bakefile.sourceforge.net) # Do not modify, all changes will be overwritten! # ========================================================================= @@ -14,9 +14,10 @@ include ../../build/msw/config.gcc CPPDEPS = -MT$@ -MF$@.d -MD WX_RELEASE_NODOT = 29 +COMPILER_PREFIX = gcc OBJS = \ - gcc_$(PORTNAME)$(WXUNIVNAME)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WXDLLFLAG)$(CFG) -LIBDIRNAME = .\..\..\lib\gcc_$(LIBTYPE_SUFFIX)$(CFG) + $(COMPILER_PREFIX)_$(PORTNAME)$(WXUNIVNAME)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WXDLLFLAG)$(CFG) +LIBDIRNAME = .\..\..\lib\$(COMPILER_PREFIX)_$(LIBTYPE_SUFFIX)$(CFG) SETUPHDIR = \ $(LIBDIRNAME)\$(PORTNAME)$(WXUNIVNAME)$(WXUNICODEFLAG)$(WXDEBUGFLAG) WIDGETS_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZEFLAG_2) $(__THREADSFLAG) \ @@ -30,6 +31,7 @@ WIDGETS_OBJECTS = \ $(OBJS)\widgets_bmpcombobox.o \ $(OBJS)\widgets_button.o \ $(OBJS)\widgets_checkbox.o \ + $(OBJS)\widgets_choice.o \ $(OBJS)\widgets_clrpicker.o \ $(OBJS)\widgets_combobox.o \ $(OBJS)\widgets_datepick.o \ @@ -39,6 +41,7 @@ WIDGETS_OBJECTS = \ $(OBJS)\widgets_fontpicker.o \ $(OBJS)\widgets_gauge.o \ $(OBJS)\widgets_hyperlnk.o \ + $(OBJS)\widgets_itemcontainer.o \ $(OBJS)\widgets_listbox.o \ $(OBJS)\widgets_notebook.o \ $(OBJS)\widgets_odcombobox.o \ @@ -262,6 +265,9 @@ $(OBJS)\widgets_button.o: ./button.cpp $(OBJS)\widgets_checkbox.o: ./checkbox.cpp $(CXX) -c -o $@ $(WIDGETS_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\widgets_choice.o: ./choice.cpp + $(CXX) -c -o $@ $(WIDGETS_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\widgets_clrpicker.o: ./clrpicker.cpp $(CXX) -c -o $@ $(WIDGETS_CXXFLAGS) $(CPPDEPS) $< @@ -289,6 +295,9 @@ $(OBJS)\widgets_gauge.o: ./gauge.cpp $(OBJS)\widgets_hyperlnk.o: ./hyperlnk.cpp $(CXX) -c -o $@ $(WIDGETS_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\widgets_itemcontainer.o: ./itemcontainer.cpp + $(CXX) -c -o $@ $(WIDGETS_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\widgets_listbox.o: ./listbox.cpp $(CXX) -c -o $@ $(WIDGETS_CXXFLAGS) $(CPPDEPS) $< @@ -323,7 +332,7 @@ $(OBJS)\widgets_widgets.o: ./widgets.cpp $(CXX) -c -o $@ $(WIDGETS_CXXFLAGS) $(CPPDEPS) $< $(OBJS)\widgets_sample_rc.o: ./../sample.rc - windres --use-temp-file -i$< -o$@ --define __WXMSW__ $(__WXUNIV_DEFINE_p_1) $(__DEBUG_DEFINE_p_1) $(__EXCEPTIONS_DEFINE_p_1) $(__RTTI_DEFINE_p_1) $(__THREAD_DEFINE_p_1) $(__UNICODE_DEFINE_p_1) $(__MSLU_DEFINE_p_1) $(__GFXCTX_DEFINE_p_1) --include-dir $(SETUPHDIR) --include-dir ./../../include --include-dir . $(__DLLFLAG_p_1) --include-dir ./../../samples --define NOPCH + windres --use-temp-file -i$< -o$@ --define __WXMSW__ $(__WXUNIV_DEFINE_p_1) $(__DEBUG_DEFINE_p_1) $(__EXCEPTIONS_DEFINE_p_1) $(__RTTI_DEFINE_p_1) $(__THREAD_DEFINE_p_1) $(__UNICODE_DEFINE_p_1) $(__MSLU_DEFINE_p_1) $(__GFXCTX_DEFINE_p_1) --include-dir $(SETUPHDIR) --include-dir ./../../include --include-dir . $(__DLLFLAG_p_1) --include-dir ./../../samples --define NOPCH .PHONY: all clean diff --git a/samples/widgets/makefile.unx b/samples/widgets/makefile.unx index 5d1572e1b2..5a2096c8d0 100644 --- a/samples/widgets/makefile.unx +++ b/samples/widgets/makefile.unx @@ -1,6 +1,6 @@ # ========================================================================= # This makefile was generated by -# Bakefile 0.2.1 (http://bakefile.sourceforge.net) +# Bakefile 0.2.2 (http://bakefile.sourceforge.net) # Do not modify, all changes will be overwritten! # ========================================================================= @@ -11,34 +11,34 @@ # ------------------------------------------------------------------------- # C++ compiler -CXX = g++ +CXX := g++ # Standard flags for C++ -CXXFLAGS = +CXXFLAGS := # Standard preprocessor flags (common for CC and CXX) -CPPFLAGS = +CPPFLAGS := # Standard linker flags -LDFLAGS = +LDFLAGS := # Location and arguments of wx-config script -WX_CONFIG = wx-config +WX_CONFIG := wx-config -# Port of the wx library to build against [gtk1,gtk2,msw,x11,motif,mgl,mac,$(shell $(WX_CONFIG) --selected-config | cut -d '-' -f 1)] -WX_PORT = $(shell $(WX_CONFIG) --selected-config | cut -d '-' -f 1) +# Port of the wx library to build against [gtk1,gtk2,msw,x11,motif,mgl,mac,dfb] +WX_PORT := $(shell $(WX_CONFIG) --selected-config | cut -d '-' -f 1) -# Use DLL build of wx library to use? [0,1,$(shell if test -z `$(WX_CONFIG) --selected-config | cut -d '-' -f 5`; then echo 1; else echo 0; fi)] -WX_SHARED = $(shell if test -z `$(WX_CONFIG) --selected-config | cut -d '-' -f 5`; then echo 1; else echo 0; fi) +# Use DLL build of wx library to use? [0,1] +WX_SHARED := $(shell if test -z `$(WX_CONFIG) --selected-config | cut -d '-' -f 5`; then echo 1; else echo 0; fi) -# Compile Unicode build of wxWidgets? [0,1,$(shell $(WX_CONFIG) --selected-config | cut -d '-' -f 2 | sed 's/unicode/1/;s/ansi/0/')] -WX_UNICODE = $(shell $(WX_CONFIG) --selected-config | cut -d '-' -f 2 | sed 's/unicode/1/;s/ansi/0/') +# Compile Unicode build of wxWidgets? [0,1] +WX_UNICODE := $(shell $(WX_CONFIG) --selected-config | cut -d '-' -f 2 | sed 's/unicode/1/;s/ansi/0/') -# Use debug build of wxWidgets (define __WXDEBUG__)? [0,1,$(shell $(WX_CONFIG) --selected-config | cut -d '-' -f 3 | sed 's/debug/1/;s/release/0/')] -WX_DEBUG = $(shell $(WX_CONFIG) --selected-config | cut -d '-' -f 3 | sed 's/debug/1/;s/release/0/') +# Use debug build of wxWidgets (define __WXDEBUG__)? [0,1] +WX_DEBUG := $(shell $(WX_CONFIG) --selected-config | cut -d '-' -f 3 | sed 's/debug/1/;s/release/0/') # Version of the wx library to build against. -WX_VERSION = $(shell $(WX_CONFIG) --selected-config | sed -e 's/.*-\([0-9]*\)\.\([0-9]*\)$$/\1\2/') +WX_VERSION := $(shell $(WX_CONFIG) --selected-config | sed -e 's/.*-\([0-9]*\)\.\([0-9]*\)$$/\1\2/') @@ -60,6 +60,7 @@ WIDGETS_OBJECTS = \ widgets_bmpcombobox.o \ widgets_button.o \ widgets_checkbox.o \ + widgets_choice.o \ widgets_clrpicker.o \ widgets_combobox.o \ widgets_datepick.o \ @@ -69,6 +70,7 @@ WIDGETS_OBJECTS = \ widgets_fontpicker.o \ widgets_gauge.o \ widgets_hyperlnk.o \ + widgets_itemcontainer.o \ widgets_listbox.o \ widgets_notebook.o \ widgets_odcombobox.o \ @@ -131,6 +133,9 @@ widgets_button.o: ./button.cpp widgets_checkbox.o: ./checkbox.cpp $(CXX) -c -o $@ $(WIDGETS_CXXFLAGS) $(CPPDEPS) $< +widgets_choice.o: ./choice.cpp + $(CXX) -c -o $@ $(WIDGETS_CXXFLAGS) $(CPPDEPS) $< + widgets_clrpicker.o: ./clrpicker.cpp $(CXX) -c -o $@ $(WIDGETS_CXXFLAGS) $(CPPDEPS) $< @@ -158,6 +163,9 @@ widgets_gauge.o: ./gauge.cpp widgets_hyperlnk.o: ./hyperlnk.cpp $(CXX) -c -o $@ $(WIDGETS_CXXFLAGS) $(CPPDEPS) $< +widgets_itemcontainer.o: ./itemcontainer.cpp + $(CXX) -c -o $@ $(WIDGETS_CXXFLAGS) $(CPPDEPS) $< + widgets_listbox.o: ./listbox.cpp $(CXX) -c -o $@ $(WIDGETS_CXXFLAGS) $(CPPDEPS) $< diff --git a/samples/widgets/makefile.vc b/samples/widgets/makefile.vc index c16d810af5..bebfdcf199 100644 --- a/samples/widgets/makefile.vc +++ b/samples/widgets/makefile.vc @@ -1,6 +1,6 @@ # ========================================================================= # This makefile was generated by -# Bakefile 0.2.1 (http://bakefile.sourceforge.net) +# Bakefile 0.2.2 (http://bakefile.sourceforge.net) # Do not modify, all changes will be overwritten! # ========================================================================= @@ -13,9 +13,11 @@ ### Variables: ### WX_RELEASE_NODOT = 29 +COMPILER_PREFIX = vc OBJS = \ - vc_$(PORTNAME)$(WXUNIVNAME)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WXDLLFLAG)$(CFG)$(DIR_SUFFIX_CPU) -LIBDIRNAME = .\..\..\lib\vc$(DIR_SUFFIX_CPU)_$(LIBTYPE_SUFFIX)$(CFG) + $(COMPILER_PREFIX)_$(PORTNAME)$(WXUNIVNAME)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WXDLLFLAG)$(CFG)$(DIR_SUFFIX_CPU) +LIBDIRNAME = \ + .\..\..\lib\$(COMPILER_PREFIX)$(DIR_SUFFIX_CPU)_$(LIBTYPE_SUFFIX)$(CFG) SETUPHDIR = \ $(LIBDIRNAME)\$(PORTNAME)$(WXUNIVNAME)$(WXUNICODEFLAG)$(WXDEBUGFLAG) WIDGETS_CXXFLAGS = /M$(__RUNTIME_LIBS_8)$(__DEBUGRUNTIME_3) /DWIN32 \ @@ -30,6 +32,7 @@ WIDGETS_OBJECTS = \ $(OBJS)\widgets_bmpcombobox.obj \ $(OBJS)\widgets_button.obj \ $(OBJS)\widgets_checkbox.obj \ + $(OBJS)\widgets_choice.obj \ $(OBJS)\widgets_clrpicker.obj \ $(OBJS)\widgets_combobox.obj \ $(OBJS)\widgets_datepick.obj \ @@ -39,6 +42,7 @@ WIDGETS_OBJECTS = \ $(OBJS)\widgets_fontpicker.obj \ $(OBJS)\widgets_gauge.obj \ $(OBJS)\widgets_hyperlnk.obj \ + $(OBJS)\widgets_itemcontainer.obj \ $(OBJS)\widgets_listbox.obj \ $(OBJS)\widgets_notebook.obj \ $(OBJS)\widgets_odcombobox.obj \ @@ -344,6 +348,9 @@ $(OBJS)\widgets_button.obj: .\button.cpp $(OBJS)\widgets_checkbox.obj: .\checkbox.cpp $(CXX) /c /nologo /TP /Fo$@ $(WIDGETS_CXXFLAGS) $** +$(OBJS)\widgets_choice.obj: .\choice.cpp + $(CXX) /c /nologo /TP /Fo$@ $(WIDGETS_CXXFLAGS) $** + $(OBJS)\widgets_clrpicker.obj: .\clrpicker.cpp $(CXX) /c /nologo /TP /Fo$@ $(WIDGETS_CXXFLAGS) $** @@ -371,6 +378,9 @@ $(OBJS)\widgets_gauge.obj: .\gauge.cpp $(OBJS)\widgets_hyperlnk.obj: .\hyperlnk.cpp $(CXX) /c /nologo /TP /Fo$@ $(WIDGETS_CXXFLAGS) $** +$(OBJS)\widgets_itemcontainer.obj: .\itemcontainer.cpp + $(CXX) /c /nologo /TP /Fo$@ $(WIDGETS_CXXFLAGS) $** + $(OBJS)\widgets_listbox.obj: .\listbox.cpp $(CXX) /c /nologo /TP /Fo$@ $(WIDGETS_CXXFLAGS) $** diff --git a/samples/widgets/makefile.wat b/samples/widgets/makefile.wat index 1c54cf7930..189195cd06 100644 --- a/samples/widgets/makefile.wat +++ b/samples/widgets/makefile.wat @@ -1,6 +1,6 @@ # ========================================================================= # This makefile was generated by -# Bakefile 0.2.1 (http://bakefile.sourceforge.net) +# Bakefile 0.2.2 (http://bakefile.sourceforge.net) # Do not modify, all changes will be overwritten! # ========================================================================= @@ -225,9 +225,10 @@ __DLLFLAG_p = -dWXUSINGDLL ### Variables: ### WX_RELEASE_NODOT = 29 +COMPILER_PREFIX = wat OBJS = & - wat_$(PORTNAME)$(WXUNIVNAME)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WXDLLFLAG)$(CFG) -LIBDIRNAME = .\..\..\lib\wat_$(LIBTYPE_SUFFIX)$(CFG) + $(COMPILER_PREFIX)_$(PORTNAME)$(WXUNIVNAME)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WXDLLFLAG)$(CFG) +LIBDIRNAME = .\..\..\lib\$(COMPILER_PREFIX)_$(LIBTYPE_SUFFIX)$(CFG) SETUPHDIR = & $(LIBDIRNAME)\$(PORTNAME)$(WXUNIVNAME)$(WXUNICODEFLAG)$(WXDEBUGFLAG) WIDGETS_CXXFLAGS = $(__DEBUGINFO_0) $(__OPTIMIZEFLAG_2) $(__THREADSFLAG_5) & @@ -241,6 +242,7 @@ WIDGETS_OBJECTS = & $(OBJS)\widgets_bmpcombobox.obj & $(OBJS)\widgets_button.obj & $(OBJS)\widgets_checkbox.obj & + $(OBJS)\widgets_choice.obj & $(OBJS)\widgets_clrpicker.obj & $(OBJS)\widgets_combobox.obj & $(OBJS)\widgets_datepick.obj & @@ -250,6 +252,7 @@ WIDGETS_OBJECTS = & $(OBJS)\widgets_fontpicker.obj & $(OBJS)\widgets_gauge.obj & $(OBJS)\widgets_hyperlnk.obj & + $(OBJS)\widgets_itemcontainer.obj & $(OBJS)\widgets_listbox.obj & $(OBJS)\widgets_notebook.obj & $(OBJS)\widgets_odcombobox.obj & @@ -300,6 +303,9 @@ $(OBJS)\widgets_button.obj : .AUTODEPEND .\button.cpp $(OBJS)\widgets_checkbox.obj : .AUTODEPEND .\checkbox.cpp $(CXX) -bt=nt -zq -fo=$^@ $(WIDGETS_CXXFLAGS) $< +$(OBJS)\widgets_choice.obj : .AUTODEPEND .\choice.cpp + $(CXX) -bt=nt -zq -fo=$^@ $(WIDGETS_CXXFLAGS) $< + $(OBJS)\widgets_clrpicker.obj : .AUTODEPEND .\clrpicker.cpp $(CXX) -bt=nt -zq -fo=$^@ $(WIDGETS_CXXFLAGS) $< @@ -327,6 +333,9 @@ $(OBJS)\widgets_gauge.obj : .AUTODEPEND .\gauge.cpp $(OBJS)\widgets_hyperlnk.obj : .AUTODEPEND .\hyperlnk.cpp $(CXX) -bt=nt -zq -fo=$^@ $(WIDGETS_CXXFLAGS) $< +$(OBJS)\widgets_itemcontainer.obj : .AUTODEPEND .\itemcontainer.cpp + $(CXX) -bt=nt -zq -fo=$^@ $(WIDGETS_CXXFLAGS) $< + $(OBJS)\widgets_listbox.obj : .AUTODEPEND .\listbox.cpp $(CXX) -bt=nt -zq -fo=$^@ $(WIDGETS_CXXFLAGS) $< @@ -361,5 +370,5 @@ $(OBJS)\widgets_widgets.obj : .AUTODEPEND .\widgets.cpp $(CXX) -bt=nt -zq -fo=$^@ $(WIDGETS_CXXFLAGS) $< $(OBJS)\widgets_sample.res : .AUTODEPEND .\..\sample.rc - wrc -q -ad -bt=nt -r -fo=$^@ -d__WXMSW__ $(__WXUNIV_DEFINE_p) $(__DEBUG_DEFINE_p) $(__EXCEPTIONS_DEFINE_p) $(__RTTI_DEFINE_p) $(__THREAD_DEFINE_p) $(__UNICODE_DEFINE_p) $(__GFXCTX_DEFINE_p) -i=$(SETUPHDIR) -i=.\..\..\include -i=. $(__DLLFLAG_p) -i=.\..\..\samples -dNOPCH $< + wrc -q -ad -bt=nt -r -fo=$^@ -d__WXMSW__ $(__WXUNIV_DEFINE_p) $(__DEBUG_DEFINE_p) $(__EXCEPTIONS_DEFINE_p) $(__RTTI_DEFINE_p) $(__THREAD_DEFINE_p) $(__UNICODE_DEFINE_p) $(__GFXCTX_DEFINE_p) -i=$(SETUPHDIR) -i=.\..\..\include -i=. $(__DLLFLAG_p) -i=.\..\..\samples -dNOPCH $< diff --git a/samples/widgets/odcombobox.cpp b/samples/widgets/odcombobox.cpp index a20d439a43..b5201e3e3f 100644 --- a/samples/widgets/odcombobox.cpp +++ b/samples/widgets/odcombobox.cpp @@ -45,6 +45,7 @@ #include "wx/odcombo.h" +#include "itemcontainer.h" #include "widgets.h" #include "icons/odcombobox.xpm" @@ -76,7 +77,8 @@ enum ODComboPage_Delete, ODComboPage_DeleteText, ODComboPage_DeleteSel, - ODComboPage_Combo + ODComboPage_Combo, + ODComboPage_ContainerTests }; @@ -84,12 +86,13 @@ enum // ODComboboxWidgetsPage // ---------------------------------------------------------------------------- -class ODComboboxWidgetsPage : public WidgetsPage +class ODComboboxWidgetsPage : public ItemContainerWidgetsPage { public: ODComboboxWidgetsPage(WidgetsBookCtrl *book, wxImageList *imaglist); virtual wxControl *GetWidget() const { return m_combobox; } + virtual wxItemContainer* GetContainer() const { return m_combobox; } virtual void RecreateWidget() { CreateCombo(); } // lazy creation of the content @@ -188,6 +191,7 @@ BEGIN_EVENT_TABLE(ODComboboxWidgetsPage, WidgetsPage) EVT_BUTTON(ODComboPage_Add, ODComboboxWidgetsPage::OnButtonAdd) EVT_BUTTON(ODComboPage_AddSeveral, ODComboboxWidgetsPage::OnButtonAddSeveral) EVT_BUTTON(ODComboPage_AddMany, ODComboboxWidgetsPage::OnButtonAddMany) + EVT_BUTTON(ODComboPage_ContainerTests, ItemContainerWidgetsPage::OnButtonTestItemContainer) EVT_TEXT_ENTER(ODComboPage_InsertText, ODComboboxWidgetsPage::OnButtonInsert) EVT_TEXT_ENTER(ODComboPage_AddText, ODComboboxWidgetsPage::OnButtonAdd) @@ -296,7 +300,7 @@ IMPLEMENT_WIDGETS_PAGE(ODComboboxWidgetsPage, _T("OwnerDrawnCombobox"), ODComboboxWidgetsPage::ODComboboxWidgetsPage(WidgetsBookCtrl *book, wxImageList *imaglist) - : WidgetsPage(book, imaglist, odcombobox_xpm) + : ItemContainerWidgetsPage(book, imaglist, odcombobox_xpm) { // init everything m_chkSort = @@ -394,6 +398,9 @@ void ODComboboxWidgetsPage::CreateContent() _T("&Change combobox contents")); wxSizer *sizerMiddle = new wxStaticBoxSizer(box2, wxVERTICAL); + btn = new wxButton(this, ODComboPage_ContainerTests, _T("Run &tests")); + sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5); + sizerRow = CreateSizerWithTextAndLabel(_T("Current selection"), ODComboPage_CurText, &text); diff --git a/samples/widgets/widgets.bkl b/samples/widgets/widgets.bkl index 2d1768b779..229fa20740 100644 --- a/samples/widgets/widgets.bkl +++ b/samples/widgets/widgets.bkl @@ -9,6 +9,7 @@ bmpcombobox.cpp button.cpp checkbox.cpp + choice.cpp clrpicker.cpp combobox.cpp datepick.cpp @@ -18,6 +19,7 @@ fontpicker.cpp gauge.cpp hyperlnk.cpp + itemcontainer.cpp listbox.cpp notebook.cpp odcombobox.cpp diff --git a/samples/widgets/widgets.dsp b/samples/widgets/widgets.dsp index 3d309eb1e3..77a805177c 100644 --- a/samples/widgets/widgets.dsp +++ b/samples/widgets/widgets.dsp @@ -480,6 +480,10 @@ SOURCE=.\checkbox.cpp # End Source File # Begin Source File +SOURCE=.\choice.cpp +# End Source File +# Begin Source File + SOURCE=.\clrpicker.cpp # End Source File # Begin Source File @@ -516,6 +520,10 @@ SOURCE=.\hyperlnk.cpp # End Source File # Begin Source File +SOURCE=.\itemcontainer.cpp +# End Source File +# Begin Source File + SOURCE=.\listbox.cpp # End Source File # Begin Source File diff --git a/src/cocoa/choice.mm b/src/cocoa/choice.mm index 0da0563835..dbc2ce597f 100644 --- a/src/cocoa/choice.mm +++ b/src/cocoa/choice.mm @@ -108,16 +108,7 @@ wxChoice::~wxChoice() { DisassociateNSMenu([(NSPopUpButton*)m_cocoaNSView menu]); - if(m_sortedStrings) - m_sortedStrings->Clear(); - delete m_sortedStrings; - - if(HasClientObjectData()) - { - for(unsigned int i=0; i < m_itemsClientData.GetCount(); i++) - delete (wxClientData*)m_itemsClientData.Item(i); - } - m_itemsClientData.Clear(); + Clear(); } void wxChoice::CocoaNotification_menuDidSendAction(WX_NSNotification notification) @@ -134,25 +125,18 @@ void wxChoice::CocoaNotification_menuDidSendAction(WX_NSNotification notificatio GetEventHandler()->ProcessEvent(event); } -void wxChoice::Clear() +void wxChoice::DoClear() { if(m_sortedStrings) m_sortedStrings->Clear(); - if(HasClientObjectData()) - { - for(unsigned int i=0; i < m_itemsClientData.GetCount(); i++) - delete (wxClientData*)m_itemsClientData.Item(i); - } m_itemsClientData.Clear(); [(NSPopUpButton*)m_cocoaNSView removeAllItems]; } -void wxChoice::Delete(unsigned int n) +void wxChoice::DoDeleteOneItem(unsigned int n) { if(m_sortedStrings) m_sortedStrings->RemoveAt(n); - if(HasClientObjectData()) - delete (wxClientData*)m_itemsClientData.Item(n); m_itemsClientData.RemoveAt(n); [(NSPopUpButton*)m_cocoaNSView removeItemAtIndex:n]; } @@ -186,57 +170,35 @@ int wxChoice::GetSelection() const return [(NSPopUpButton*)m_cocoaNSView indexOfSelectedItem]; } -int wxChoice::DoAppend(const wxString& title) +int wxChoice::DoInsertItems(const wxArrayStringsAdapter & items, + unsigned int pos, + void **clientData, wxClientDataType type) { - wxAutoNSAutoreleasePool pool; NSMenu *nsmenu = [(NSPopUpButton*)m_cocoaNSView menu]; - NSMenuItem *item; - if(m_sortedStrings) - { - int sortedIndex = m_sortedStrings->Add(title); - item = [nsmenu insertItemWithTitle: - wxNSStringWithWxString(title) - action: nil keyEquivalent:@"" atIndex:sortedIndex]; - m_itemsClientData.Insert(NULL, sortedIndex); - } - else - { - item = [nsmenu addItemWithTitle:wxNSStringWithWxString(title) - action: nil keyEquivalent:@""]; - m_itemsClientData.Add(NULL); - } - return [nsmenu indexOfItem:item]; -} + NSMenuItem *item = NULL; -int wxChoice::DoInsert(const wxString& title, unsigned int pos) -{ - if(m_sortedStrings) - return DoAppend(title); - NSMenu *nsmenu = [(NSPopUpButton*)m_cocoaNSView menu]; - NSMenuItem *item = [nsmenu insertItemWithTitle:wxNSStringWithWxString(title) - action: nil keyEquivalent:@"" atIndex:pos]; - m_itemsClientData.Insert(NULL, pos); + unsigned int numItems = items.GetCount(); + for ( unsigned int i = 0; i < numItems; ++i, ++pos ) + { + const wxString& str = items[i]; + int idx = m_sortedStrings ? m_sortedStrings->Add(str) : pos; + + item = [nsmenu insertItemWithTitle:wxNSStringWithWxString(str) + action: nil keyEquivalent:@"" atIndex:idx]; + m_itemsClientData.Insert(NULL, idx); + AssignNewItemClientData(idx, clientData, i, type); + } return [nsmenu indexOfItem:item]; } void wxChoice::DoSetItemClientData(unsigned int n, void *data) { - m_itemsClientData.Item(n) = data; + m_itemsClientData[n] = data; } void* wxChoice::DoGetItemClientData(unsigned int n) const { - return m_itemsClientData.Item(n); -} - -void wxChoice::DoSetItemClientObject(unsigned int n, wxClientData *data) -{ - m_itemsClientData.Item(n) = data; -} - -wxClientData* wxChoice::DoGetItemClientObject(unsigned int n) const -{ - return (wxClientData*)m_itemsClientData.Item(n); + return m_itemsClientData[n]; } void wxChoice::SetSelection(int n) @@ -245,4 +207,4 @@ void wxChoice::SetSelection(int n) [(NSPopUpButton*)m_cocoaNSView selectItemAtIndex:n]; } -#endif +#endif // wxUSE_CHOICE diff --git a/src/cocoa/combobox.mm b/src/cocoa/combobox.mm index 4e016fb200..041fd382c5 100644 --- a/src/cocoa/combobox.mm +++ b/src/cocoa/combobox.mm @@ -206,8 +206,7 @@ bool wxComboBox::Create(wxWindow *parent, wxWindowID winid, m_parent->CocoaAddChild(this); SetInitialFrameRect(pos,size); - for(int i = 0; i < n; ++i) - wxComboBox::DoAppend(choices[i]); + wxComboBox::Append(n, choices); [GetNSComboBox() setCompletes:true]; //autocomplete :) @@ -246,13 +245,13 @@ wxString wxComboBox::GetStringSelection() return wxStringWithNSString([GetNSComboBox() objectValueOfSelectedItem]); } -void wxComboBox::Clear() +void wxComboBox::DoClear() { [GetNSComboBox() removeAllItems]; m_Datas.Clear(); } -void wxComboBox::Delete(unsigned int n) +void wxComboBox::DoDeleteOneItem(unsigned int n) { [GetNSComboBox() removeItemAtIndex:n]; m_Datas.RemoveAt(n); @@ -288,20 +287,20 @@ int wxComboBox::GetSelection() const return [GetNSComboBox() indexOfSelectedItem]; } -int wxComboBox::DoAppend(const wxString& szItem) +int wxComboBox::DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, + wxClientDataType type) { - m_Datas.Add(NULL); wxAutoNSAutoreleasePool pool; - [GetNSComboBox() addItemWithObjectValue:wxNSStringWithWxString(szItem)]; - return [GetNSComboBox() numberOfItems]; -} - -int wxComboBox::DoInsert(const wxString& szItem, unsigned int nIndex) -{ - m_Datas.Insert(NULL, nIndex); - wxAutoNSAutoreleasePool pool; - [GetNSComboBox() insertItemWithObjectValue:wxNSStringWithWxString(szItem) atIndex:nIndex]; - return (int)nIndex; + const unsigned int numITems = items.GetCount(); + for ( unsigned int i = 0; i < numITems; ++i, ++pos ) + { + [GetNSComboBox() insertItemWithObjectValue:wxNSStringWithWxString(items[i]) atIndex:(pos)]; + m_Datas.Insert(NULL, pos); + AssignNewItemClientData(pos, clientData, i, type); + } + return pos - 1; } void wxComboBox::DoSetItemClientData(unsigned int nIndex, void* pData) @@ -314,14 +313,4 @@ void* wxComboBox::DoGetItemClientData(unsigned int nIndex) const return m_Datas[nIndex]; } -void wxComboBox::DoSetItemClientObject(unsigned int nIndex, wxClientData* pClientData) -{ - m_Datas[nIndex] = (void*) pClientData; -} - -wxClientData* wxComboBox::DoGetItemClientObject(unsigned int nIndex) const -{ - return (wxClientData*) m_Datas[nIndex]; -} - -#endif //wxUSE_COMBOBOX +#endif // wxUSE_COMBOBOX diff --git a/src/cocoa/listbox.mm b/src/cocoa/listbox.mm index c24e9b9439..1b9a228a34 100644 --- a/src/cocoa/listbox.mm +++ b/src/cocoa/listbox.mm @@ -169,33 +169,21 @@ int wxListBox::GetSelections(wxArrayInt& aSelections) const return [GetNSTableView() numberOfSelectedRows]; } -void wxListBox::DoInsertItems(const wxArrayString& items, unsigned int pos) +int wxListBox::DoInsertItems(const wxArrayStringsAdapter & items, unsigned int pos, void **clientData, wxClientDataType type) { wxAutoNSAutoreleasePool pool; - for(int i=int(items.GetCount())-1; i >= 0; i--) + const unsigned int numItems = items.GetCount(); + for ( unsigned int i = 0; i < numItems; ++i, ++pos ) { [m_cocoaItems insertObject: wxNSStringWithWxString(items[i]) atIndex: pos]; - m_itemClientData.Insert(NULL,pos); + m_itemClientData.Insert(NULL, pos); + AssignNewItemClientData(pos, clientData, i, type); } - [GetNSTableView() reloadData]; -} -void wxListBox::DoSetItems(const wxArrayString& items, void **clientData) -{ - wxAutoNSAutoreleasePool pool; - - // Remove everything - [m_cocoaItems removeAllObjects]; - m_itemClientData.Clear(); - // Provide the data - for(unsigned int i=0; i < items.GetCount(); i++) - { - [m_cocoaItems addObject: wxNSStringWithWxString(items[i])]; - m_itemClientData.Add(clientData[i]); - } [GetNSTableView() reloadData]; + return pos - 1; } void wxListBox::DoSetFirstItem(int n) @@ -210,14 +198,14 @@ void wxListBox::DoSetFirstItem(int n) // pure virtuals from wxItemContainer // deleting items -void wxListBox::Clear() +void wxListBox::DoClear() { [m_cocoaItems removeAllObjects]; m_itemClientData.Clear(); [GetNSTableView() reloadData]; } -void wxListBox::Delete(unsigned int n) +void wxListBox::DoDeleteOneItem(unsigned int n) { [m_cocoaItems removeObjectAtIndex:n]; m_itemClientData.RemoveAt(n); @@ -256,15 +244,6 @@ int wxListBox::GetSelection() const return [GetNSTableView() selectedRow]; } -int wxListBox::DoAppend(const wxString& item) -{ - wxAutoNSAutoreleasePool pool; - [m_cocoaItems addObject:wxNSStringWithWxString(item)]; - [GetNSTableView() reloadData]; - m_itemClientData.Add(NULL); - return [m_cocoaItems count]; -} - void wxListBox::DoSetItemClientData(unsigned int n, void* clientData) { m_itemClientData[n] = clientData; @@ -275,14 +254,4 @@ void* wxListBox::DoGetItemClientData(unsigned int n) const return m_itemClientData[n]; } -void wxListBox::DoSetItemClientObject(unsigned int n, wxClientData* clientData) -{ - m_itemClientData[n] = (void*) clientData; -} - -wxClientData* wxListBox::DoGetItemClientObject(unsigned int n) const -{ - return (wxClientData*) m_itemClientData[n]; -} - -#endif +#endif // wxUSE_LISTBOX diff --git a/src/common/ctrlsub.cpp b/src/common/ctrlsub.cpp index c94e8f2ca3..ec05cae146 100644 --- a/src/common/ctrlsub.cpp +++ b/src/common/ctrlsub.cpp @@ -90,93 +90,175 @@ wxItemContainer::~wxItemContainer() } // ---------------------------------------------------------------------------- -// appending items +// deleting items // ---------------------------------------------------------------------------- -void wxItemContainer::Append(const wxArrayString& strings) +void wxItemContainer::Clear() { - const size_t count = strings.GetCount(); - for ( size_t n = 0; n < count; n++ ) + if ( HasClientObjectData() ) { - Append(strings[n]); + const unsigned count = GetCount(); + for ( unsigned i = 0; i < count; ++i ) + ResetItemClientObject(i); + } + + m_clientDataItemsType = wxClientData_None; + + DoClear(); +} + +void wxItemContainer::Delete(unsigned int pos) +{ + wxCHECK_RET( pos < GetCount(), _T("invalid index") ); + + if ( HasClientObjectData() ) + ResetItemClientObject(pos); + + DoDeleteOneItem(pos); + + if ( IsEmpty() ) + { + m_clientDataItemsType = wxClientData_None; } } -int wxItemContainer::Insert(const wxString& item, unsigned int pos, void *clientData) +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- + +int wxItemContainer::DoInsertItemsInLoop(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, + wxClientDataType type) { - int n = DoInsert(item, pos); - if ( n != wxNOT_FOUND ) - SetClientData(n, clientData); + int n = wxNOT_FOUND; + + const unsigned int count = items.GetCount(); + for ( unsigned int i = 0; i < count; ++i ) + { + n = DoInsertOneItem(items[i], pos++); + if ( n == wxNOT_FOUND ) + break; + + AssignNewItemClientData(n, clientData, i, type); + } return n; } -int wxItemContainer::Insert(const wxString& item, unsigned int pos, wxClientData *clientData) +int +wxItemContainer::DoInsertOneItem(const wxString& WXUNUSED(item), + unsigned int WXUNUSED(pos)) { - int n = DoInsert(item, pos); - if ( n != wxNOT_FOUND ) - SetClientObject(n, clientData); + wxFAIL_MSG( _T("Must be overridden if DoInsertItemsInLoop() is used") ); - return n; + return wxNOT_FOUND; } + // ---------------------------------------------------------------------------- // client data // ---------------------------------------------------------------------------- void wxItemContainer::SetClientObject(unsigned int n, wxClientData *data) { - wxASSERT_MSG( m_clientDataItemsType != wxClientData_Void, + wxASSERT_MSG( m_clientDataItemsType == wxClientData_Object || + m_clientDataItemsType == wxClientData_None, wxT("can't have both object and void client data") ); - // when we call SetClientObject() for the first time, m_clientDataItemsType - // is still wxClientData_None and so calling DoGetItemClientObject() would - // fail (in addition to being useless) - don't do it if ( m_clientDataItemsType == wxClientData_Object ) { - wxClientData *clientDataOld = DoGetItemClientObject(n); + wxClientData * clientDataOld + = wx_static_cast(wxClientData *, DoGetItemClientData(n)); if ( clientDataOld ) delete clientDataOld; } else // m_clientDataItemsType == wxClientData_None { // now we have object client data + DoInitItemClientData(); + m_clientDataItemsType = wxClientData_Object; } - DoSetItemClientObject(n, data); + DoSetItemClientData(n, data); } wxClientData *wxItemContainer::GetClientObject(unsigned int n) const { - wxASSERT_MSG( m_clientDataItemsType == wxClientData_Object, + wxCHECK_MSG( m_clientDataItemsType == wxClientData_Object, NULL, wxT("this window doesn't have object client data") ); - return DoGetItemClientObject(n); + return wx_static_cast(wxClientData *, DoGetItemClientData(n)); } void wxItemContainer::SetClientData(unsigned int n, void *data) { - wxASSERT_MSG( m_clientDataItemsType != wxClientData_Object, + if ( m_clientDataItemsType == wxClientData_None ) + { + DoInitItemClientData(); + m_clientDataItemsType = wxClientData_Void; + } + + wxASSERT_MSG( m_clientDataItemsType == wxClientData_Void, wxT("can't have both object and void client data") ); DoSetItemClientData(n, data); - m_clientDataItemsType = wxClientData_Void; } void *wxItemContainer::GetClientData(unsigned int n) const { - wxASSERT_MSG( m_clientDataItemsType == wxClientData_Void, + wxCHECK_MSG( m_clientDataItemsType == wxClientData_Void, NULL, wxT("this window doesn't have void client data") ); return DoGetItemClientData(n); } +void wxItemContainer::AssignNewItemClientData(unsigned int pos, + void **clientData, + unsigned int n, + wxClientDataType type) +{ + switch ( type ) + { + case wxClientData_Object: + SetClientObject + ( + pos, + (wx_reinterpret_cast(wxClientData **, clientData))[n] + ); + break; + + case wxClientData_Void: + SetClientData(pos, clientData[n]); + break; + + default: + wxFAIL_MSG( _T("unknown client data type") ); + // fall through + + case wxClientData_None: + // nothing to do + break; + } +} + +void wxItemContainer::ResetItemClientObject(unsigned int n) +{ + wxClientData * const data = GetClientObject(n); + if ( data ) + { + delete data; + DoSetItemClientData(n, NULL); + } +} + // ============================================================================ // wxControlWithItems implementation // ============================================================================ -void wxControlWithItems::InitCommandEventWithItems(wxCommandEvent& event, int n) +void +wxControlWithItemsBase::InitCommandEventWithItems(wxCommandEvent& event, int n) { InitCommandEvent(event); @@ -189,9 +271,4 @@ void wxControlWithItems::InitCommandEventWithItems(wxCommandEvent& event, int n) } } -wxControlWithItems::~wxControlWithItems() -{ - // this destructor is required for Darwin -} - #endif // wxUSE_CONTROLS diff --git a/src/common/lboxcmn.cpp b/src/common/lboxcmn.cpp index 218ba8a71a..2d764f33bf 100644 --- a/src/common/lboxcmn.cpp +++ b/src/common/lboxcmn.cpp @@ -42,33 +42,6 @@ wxListBoxBase::~wxListBoxBase() // this destructor is required for Darwin } -// ---------------------------------------------------------------------------- -// adding items -// ---------------------------------------------------------------------------- - -void wxListBoxBase::InsertItems(unsigned int nItems, const wxString *items, unsigned int pos) -{ - wxArrayString aItems; - for ( unsigned int n = 0; n < nItems; n++ ) - { - aItems.Add(items[n]); - } - - DoInsertItems(aItems, pos); -} - - -void wxListBoxBase::Set(int nItems, const wxString* items, void **clientData) -{ - wxArrayString aItems; - for ( int n = 0; n < nItems; n++ ) - { - aItems.Add(items[n]); - } - - DoSetItems(aItems, clientData); -} - // ---------------------------------------------------------------------------- // selection // ---------------------------------------------------------------------------- diff --git a/src/generic/bmpcboxg.cpp b/src/generic/bmpcboxg.cpp index 6aec2b629e..a9b1eb0a3e 100644 --- a/src/generic/bmpcboxg.cpp +++ b/src/generic/bmpcboxg.cpp @@ -176,23 +176,86 @@ wxBitmap wxBitmapComboBox::GetItemBitmap(unsigned int n) const return *GetBitmapPtr(n); } +int wxBitmapComboBox::DoInsertItems(const wxArrayStringsAdapter & items, + unsigned int pos, + void **clientData, wxClientDataType type) +{ + const unsigned int numItems = items.GetCount(); + const unsigned int countNew = GetCount() + numItems; + + m_bitmaps.Alloc(countNew); + + for ( unsigned int i = 0; i < numItems; ++i ) + { + m_bitmaps.Insert(new wxBitmap(wxNullBitmap), pos + i); + } + + const int index = wxOwnerDrawnComboBox::DoInsertItems(items, pos, + clientData, type); + + if ( index == wxNOT_FOUND ) + { + for ( int i = countNew - GetCount(); i > 0; --i ) + { + wxBitmap *bmp = GetBitmapPtr(pos); + m_bitmaps.RemoveAt(pos); + delete bmp; + } + } + return index; +} + +int wxBitmapComboBox::Append(const wxString& item, const wxBitmap& bitmap) +{ + const int n = wxOwnerDrawnComboBox::Append(item); + if(n != wxNOT_FOUND) + SetItemBitmap(n, bitmap); + return n; +} + +int wxBitmapComboBox::Append(const wxString& item, const wxBitmap& bitmap, + void *clientData) +{ + const int n = wxOwnerDrawnComboBox::Append(item, clientData); + if(n != wxNOT_FOUND) + SetItemBitmap(n, bitmap); + return n; +} + +int wxBitmapComboBox::Append(const wxString& item, const wxBitmap& bitmap, + wxClientData *clientData) +{ + const int n = wxOwnerDrawnComboBox::Append(item, clientData); + if(n != wxNOT_FOUND) + SetItemBitmap(n, bitmap); + return n; +} + +int wxBitmapComboBox::Insert(const wxString& item, + const wxBitmap& bitmap, + unsigned int pos) +{ + const int n = wxOwnerDrawnComboBox::Insert(item, pos); + if(n != wxNOT_FOUND) + SetItemBitmap(n, bitmap); + return n; +} + int wxBitmapComboBox::Insert(const wxString& item, const wxBitmap& bitmap, unsigned int pos, void *clientData) { - int n = DoInsertWithImage(item, bitmap, pos); - if ( n != wxNOT_FOUND ) - SetClientData(n, clientData); - + const int n = wxOwnerDrawnComboBox::Insert(item, pos, clientData); + if(n != wxNOT_FOUND) + SetItemBitmap(n, bitmap); return n; } int wxBitmapComboBox::Insert(const wxString& item, const wxBitmap& bitmap, unsigned int pos, wxClientData *clientData) { - int n = DoInsertWithImage(item, bitmap, pos); - if ( n != wxNOT_FOUND ) - SetClientObject(n, clientData); - + const int n = wxOwnerDrawnComboBox::Insert(item, pos, clientData); + if(n != wxNOT_FOUND) + SetItemBitmap(n, bitmap); return n; } @@ -227,67 +290,9 @@ bool wxBitmapComboBox::OnAddBitmap(const wxBitmap& bitmap) return true; } -bool wxBitmapComboBox::DoInsertBitmap(const wxBitmap& bitmap, unsigned int pos) +void wxBitmapComboBox::DoClear() { - if ( !OnAddBitmap(bitmap) ) - return false; - - // NB: We must try to set the image before DoInsert or - // DoAppend because OnMeasureItem might be called - // before it returns. - m_bitmaps.Insert( new wxBitmap(bitmap), pos); - - return true; -} - -int wxBitmapComboBox::DoAppendWithImage(const wxString& item, const wxBitmap& image) -{ - unsigned int pos = m_bitmaps.size(); - - if ( !DoInsertBitmap(image, pos) ) - return wxNOT_FOUND; - - int index = wxOwnerDrawnComboBox::DoAppend(item); - - if ( index < 0 ) - index = m_bitmaps.size(); - - // Need to re-check the index incase DoAppend sorted - if ( (unsigned int) index != pos ) - { - wxBitmap* bmp = GetBitmapPtr(pos); - m_bitmaps.RemoveAt(pos); - m_bitmaps.Insert(bmp, index); - } - - return index; -} - -int wxBitmapComboBox::DoInsertWithImage(const wxString& item, - const wxBitmap& image, - unsigned int pos) -{ - wxCHECK_MSG( IsValidInsert(pos), wxNOT_FOUND, wxT("invalid item index") ); - - if ( !DoInsertBitmap(image, pos) ) - return wxNOT_FOUND; - - return wxOwnerDrawnComboBox::DoInsert(item, pos); -} - -int wxBitmapComboBox::DoAppend(const wxString& item) -{ - return DoAppendWithImage(item, wxNullBitmap); -} - -int wxBitmapComboBox::DoInsert(const wxString& item, unsigned int pos) -{ - return DoInsertWithImage(item, wxNullBitmap, pos); -} - -void wxBitmapComboBox::Clear() -{ - wxOwnerDrawnComboBox::Clear(); + wxOwnerDrawnComboBox::DoClear(); unsigned int i; @@ -302,9 +307,9 @@ void wxBitmapComboBox::Clear() DetermineIndent(); } -void wxBitmapComboBox::Delete(unsigned int n) +void wxBitmapComboBox::DoDeleteOneItem(unsigned int n) { - wxOwnerDrawnComboBox::Delete(n); + wxOwnerDrawnComboBox::DoDeleteOneItem(n); delete GetBitmapPtr(n); m_bitmaps.RemoveAt(n); } diff --git a/src/generic/htmllbox.cpp b/src/generic/htmllbox.cpp index 22e2722cec..fb819ab3e6 100644 --- a/src/generic/htmllbox.cpp +++ b/src/generic/htmllbox.cpp @@ -562,19 +562,19 @@ bool wxSimpleHtmlListBox::Create(wxWindow *parent, wxWindowID id, #if wxUSE_VALIDATORS SetValidator(validator); #endif - for (int i=0; iGetSelection(); } -int wxOwnerDrawnComboBox::DoAppend(const wxString& item) -{ - EnsurePopupControl(); - wxASSERT(m_popupInterface); - - return GetVListBoxComboPopup()->Append(item); -} - -int wxOwnerDrawnComboBox::DoInsert(const wxString& item, unsigned int pos) +int wxOwnerDrawnComboBox::DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, + wxClientDataType type) { EnsurePopupControl(); - wxCHECK_MSG(!(GetWindowStyle() & wxCB_SORT), -1, wxT("can't insert into sorted list")); - wxCHECK_MSG(IsValidInsert(pos), -1, wxT("invalid index")); + const unsigned int count = items.GetCount(); + for( unsigned int i = 0; i < count; ++i, ++pos ) + { + GetVListBoxComboPopup()->Insert(items[i], pos); + AssignNewItemClientData(pos, clientData, i, type); + } - GetVListBoxComboPopup()->Insert(item,pos); - - return pos; + return pos - 1; } void wxOwnerDrawnComboBox::DoSetItemClientData(unsigned int n, void* clientData) @@ -1041,16 +1039,6 @@ void* wxOwnerDrawnComboBox::DoGetItemClientData(unsigned int n) const return GetVListBoxComboPopup()->GetItemClientData(n); } -void wxOwnerDrawnComboBox::DoSetItemClientObject(unsigned int n, wxClientData* clientData) -{ - DoSetItemClientData(n, (void*) clientData); -} - -wxClientData* wxOwnerDrawnComboBox::DoGetItemClientObject(unsigned int n) const -{ - return (wxClientData*) DoGetItemClientData(n); -} - // ---------------------------------------------------------------------------- // wxOwnerDrawnComboBox item drawing and measuring default implementations // ---------------------------------------------------------------------------- diff --git a/src/gtk/choice.cpp b/src/gtk/choice.cpp index 69ca481174..7dfecca77a 100644 --- a/src/gtk/choice.cpp +++ b/src/gtk/choice.cpp @@ -103,9 +103,9 @@ bool wxChoice::Create( wxWindow *parent, wxWindowID id, m_widget = gtk_option_menu_new(); - if ( style & wxCB_SORT ) + if ( IsSorted() ) { - // if our m_strings != NULL, DoAppend() will check for it and insert + // if our m_strings != NULL, Append() will check for it and insert // items in the correct order m_strings = new wxSortedArrayString; } @@ -137,79 +137,46 @@ wxChoice::~wxChoice() delete m_strings; } -int wxChoice::DoAppend( const wxString &item ) +int wxChoice::DoInsertItems(const wxArrayStringsAdapter & items, + unsigned int pos, + void **clientData, wxClientDataType type) { wxCHECK_MSG( m_widget != NULL, -1, wxT("invalid choice control") ); - GtkWidget *menu = gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) ); - - return GtkAddHelper(menu, GetCount(), item); -} - -int wxChoice::DoInsert(const wxString &item, unsigned int pos) -{ - wxCHECK_MSG( m_widget != NULL, -1, wxT("invalid choice control") ); - wxCHECK_MSG( IsValidInsert(pos), -1, wxT("invalid index")); - - if (pos == GetCount()) - return DoAppend(item); + const unsigned int count = items.GetCount(); GtkWidget *menu = gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) ); + for ( unsigned int i = 0; i < count; ++i, ++pos ) + { + int n = GtkAddHelper(menu, pos, items[i]); + if ( n == wxNOT_FOUND ) + return n; + + AssignNewItemClientData(n, clientData, i, type); + } + // if the item to insert is at or before the selection, and the selection is valid if (((int)pos <= m_selection_hack) && (m_selection_hack != wxNOT_FOUND)) { - // move the selection forward one - m_selection_hack++; + // move the selection forward + m_selection_hack += count; } - return GtkAddHelper(menu, pos, item); + return pos - 1; } void wxChoice::DoSetItemClientData(unsigned int n, void* clientData) { - wxCHECK_RET( m_widget != NULL, wxT("invalid choice control") ); - - wxList::compatibility_iterator node = m_clientList.Item( n ); - wxCHECK_RET( node, wxT("invalid index in wxChoice::DoSetItemClientData") ); - - node->SetData( (wxObject*) clientData ); + m_clientData[n] = clientData; } void* wxChoice::DoGetItemClientData(unsigned int n) const { - wxCHECK_MSG( m_widget != NULL, NULL, wxT("invalid choice control") ); - - wxList::compatibility_iterator node = m_clientList.Item( n ); - wxCHECK_MSG( node, NULL, wxT("invalid index in wxChoice::DoGetItemClientData") ); - - return node->GetData(); + return m_clientData[n]; } -void wxChoice::DoSetItemClientObject(unsigned int n, wxClientData* clientData) -{ - wxCHECK_RET( m_widget != NULL, wxT("invalid choice control") ); - - wxList::compatibility_iterator node = m_clientList.Item( n ); - wxCHECK_RET( node, wxT("invalid index in wxChoice::DoSetItemClientObject") ); - - // wxItemContainer already deletes data for us - - node->SetData( (wxObject*) clientData ); -} - -wxClientData* wxChoice::DoGetItemClientObject(unsigned int n) const -{ - wxCHECK_MSG( m_widget != NULL, (wxClientData*) NULL, wxT("invalid choice control") ); - - wxList::compatibility_iterator node = m_clientList.Item( n ); - wxCHECK_MSG( node, (wxClientData *)NULL, - wxT("invalid index in wxChoice::DoGetItemClientObject") ); - - return (wxClientData*) node->GetData(); -} - -void wxChoice::Clear() +void wxChoice::DoClear() { wxCHECK_RET( m_widget != NULL, wxT("invalid choice") ); @@ -217,19 +184,7 @@ void wxChoice::Clear() GtkWidget *menu = gtk_menu_new(); gtk_option_menu_set_menu( GTK_OPTION_MENU(m_widget), menu ); - if ( HasClientObjectData() ) - { - // destroy the data (due to Robert's idea of using wxList - // and not wxList we can't just say - // m_clientList.DeleteContents(true) - this would crash! - wxList::compatibility_iterator node = m_clientList.GetFirst(); - while ( node ) - { - delete (wxClientData *)node->GetData(); - node = node->GetNext(); - } - } - m_clientList.Clear(); + m_clientData.Clear(); if ( m_strings ) m_strings->Clear(); @@ -238,16 +193,11 @@ void wxChoice::Clear() m_selection_hack = wxNOT_FOUND; } -void wxChoice::Delete(unsigned int n) +void wxChoice::DoDeleteOneItem(unsigned int n) { wxCHECK_RET( m_widget != NULL, wxT("invalid choice") ); wxCHECK_RET( IsValid(n), _T("invalid index in wxChoice::Delete") ); - // VZ: apparently GTK+ doesn't have a built-in function to do it (not even - // in 2.0), hence this dumb implementation -- still better than nothing - unsigned int i; - const unsigned int count = GetCount(); - // if the item to delete is before the selection, and the selection is valid if (((int)n < m_selection_hack) && (m_selection_hack != wxNOT_FOUND)) { @@ -260,56 +210,30 @@ void wxChoice::Delete(unsigned int n) m_selection_hack = wxNOT_FOUND; } - const bool hasClientData = m_clientDataItemsType != wxClientData_None; - const bool hasObjectData = m_clientDataItemsType == wxClientData_Object; - - wxList::compatibility_iterator node = m_clientList.GetFirst(); + // VZ: apparently GTK+ doesn't have a built-in function to do it (not even + // in 2.0), hence this dumb implementation -- still better than nothing + const unsigned int count = GetCount(); wxArrayString items; wxArrayPtrVoid itemsData; items.Alloc(count); - for ( i = 0; i < count; i++ ) + itemsData.Alloc(count); + for ( unsigned i = 0; i < count; i++ ) { if ( i != n ) { items.Add(GetString(i)); - if ( hasClientData ) - { - // also save the client data - itemsData.Add(node->GetData()); - } - } - else // need to delete the client object too - { - if ( hasObjectData ) - { - delete (wxClientData *)node->GetData(); - } - } - - if ( hasClientData ) - { - node = node->GetNext(); + itemsData.Add(m_clientData[i]); } } - if ( hasObjectData ) - { - // prevent Clear() from destroying all client data - m_clientDataItemsType = wxClientData_None; - } + wxChoice::DoClear(); - Clear(); - - for ( i = 0; i < count - 1; i++ ) - { - Append(items[i]); - - if ( hasObjectData ) - SetClientObject(i, (wxClientData *)itemsData[i]); - else if ( hasClientData ) - SetClientData(i, itemsData[i]); - } + void ** const data = &itemsData[0]; + if ( HasClientObjectData() ) + Append(items, wx_reinterpret_cast(wxClientData **, data)); + else + Append(items, data); } int wxChoice::FindString( const wxString &string, bool bCase ) const @@ -482,47 +406,24 @@ void wxChoice::DoApplyWidgetStyle(GtkRcStyle *style) int wxChoice::GtkAddHelper(GtkWidget *menu, unsigned int pos, const wxString& item) { - wxCHECK_MSG(pos<=m_clientList.GetCount(), -1, wxT("invalid index")); + wxCHECK_MSG(pos<=m_clientData.GetCount(), -1, wxT("invalid index")); GtkWidget *menu_item = gtk_menu_item_new_with_label( wxGTK_CONV( item ) ); - unsigned int index; if ( m_strings ) { // sorted control, need to insert at the correct index - index = m_strings->Add(item); - - gtk_menu_shell_insert( GTK_MENU_SHELL(menu), menu_item, index ); - - if ( index ) - { - m_clientList.Insert( m_clientList.Item(index - 1), - (wxObject*) NULL ); - } - else - { - m_clientList.Insert( (wxObject*) NULL ); - } + pos = m_strings->Add(item); } + + // don't call wxChoice::GetCount() from here because it doesn't work + // if we're called from ctor (and GtkMenuShell is still NULL) + if (pos == m_clientData.GetCount()) + gtk_menu_shell_append( GTK_MENU_SHELL(menu), menu_item ); else - { - // don't call wxChoice::GetCount() from here because it doesn't work - // if we're called from ctor (and GtkMenuShell is still NULL) + gtk_menu_shell_insert( GTK_MENU_SHELL(menu), menu_item, pos ); - // normal control, just append - if (pos == m_clientList.GetCount()) - { - gtk_menu_shell_append( GTK_MENU_SHELL(menu), menu_item ); - m_clientList.Append( (wxObject*) NULL ); - index = m_clientList.GetCount() - 1; - } - else - { - gtk_menu_shell_insert( GTK_MENU_SHELL(menu), menu_item, pos ); - m_clientList.Insert( pos, (wxObject*) NULL ); - index = pos; - } - } + m_clientData.Insert( NULL, pos ); if (GTK_WIDGET_REALIZED(m_widget)) { @@ -545,7 +446,7 @@ int wxChoice::GtkAddHelper(GtkWidget *menu, unsigned int pos, const wxString& it gtk_widget_show( menu_item ); // return the index of the item in the control - return index; + return pos; } wxSize wxChoice::DoGetBestSize() const diff --git a/src/gtk/combobox.cpp b/src/gtk/combobox.cpp index 56acb50640..91207fc70a 100644 --- a/src/gtk/combobox.cpp +++ b/src/gtk/combobox.cpp @@ -241,6 +241,7 @@ bool wxComboBox::Create( wxWindow *parent, wxWindowID id, const wxString& value, long style, const wxValidator& validator, const wxString& name ) { + m_strings = NULL; m_ignoreNextUpdate = false; m_prevSelection = 0; @@ -251,21 +252,15 @@ bool wxComboBox::Create( wxWindow *parent, wxWindowID id, const wxString& value, return false; } + if(HasFlag(wxCB_SORT)) + m_strings = new wxSortedArrayString(); + #ifdef __WXGTK24__ if (!gtk_check_version(2,4,0)) { m_widget = gtk_combo_box_entry_new_text(); - GtkComboBox* combobox = GTK_COMBO_BOX( m_widget ); gtk_entry_set_editable( GTK_ENTRY( GTK_BIN(m_widget)->child ), TRUE ); - - for (int i = 0; i < n; i++) - { - gtk_combo_box_append_text( combobox, wxGTK_CONV( choices[i] ) ); - - m_clientDataList.Append( (wxObject*)NULL ); - m_clientObjectList.Append( (wxObject*)NULL ); - } } else #endif @@ -288,22 +283,9 @@ bool wxComboBox::Create( wxWindow *parent, wxWindowID id, const wxString& value, if (style & wxNO_BORDER) g_object_set (combo->entry, "has-frame", FALSE, NULL ); - - GtkWidget *list = combo->list; - - for (int i = 0; i < n; i++) - { - GtkWidget *list_item = gtk_list_item_new_with_label( wxGTK_CONV( choices[i] ) ); - - m_clientDataList.Append( (wxObject*)NULL ); - m_clientObjectList.Append( (wxObject*)NULL ); - - gtk_container_add( GTK_CONTAINER(list), list_item ); - - gtk_widget_show( list_item ); - } } + Append(n, choices); m_parent->DoAddChild( this ); @@ -372,16 +354,9 @@ bool wxComboBox::Create( wxWindow *parent, wxWindowID id, const wxString& value, wxComboBox::~wxComboBox() { - wxList::compatibility_iterator node = m_clientObjectList.GetFirst(); - while (node) - { - wxClientData *cd = (wxClientData*)node->GetData(); - if (cd) delete cd; - node = node->GetNext(); - } - m_clientObjectList.Clear(); + Clear(); - m_clientDataList.Clear(); + delete m_strings; } void wxComboBox::SetFocus() @@ -395,15 +370,36 @@ void wxComboBox::SetFocus() gtk_widget_grab_focus( m_focusWidget ); } -int wxComboBox::DoAppend( const wxString &item ) +int wxComboBox::DoInsertItems(const wxArrayStringsAdapter & items, + unsigned int pos, + void **clientData, wxClientDataType type) { wxCHECK_MSG( m_widget != NULL, -1, wxT("invalid combobox") ); + wxASSERT_MSG( !IsSorted() || (pos == GetCount()), + _T("In a sorted combobox data could only be appended")); + + const int count = items.GetCount(); + + int n = wxNOT_FOUND; + #ifdef __WXGTK24__ if (!gtk_check_version(2,4,0)) { GtkComboBox* combobox = GTK_COMBO_BOX( m_widget ); - gtk_combo_box_append_text( combobox, wxGTK_CONV( item ) ); + for( int i = 0; i < count; ++i ) + { + n = pos + i; + // If sorted, use this wxSortedArrayStrings to determine + // the right insertion point + if(m_strings) + n = m_strings->Add(items[i]); + + gtk_combo_box_insert_text( combobox, n, wxGTK_CONV( items[i] ) ); + + m_clientData.Insert( NULL, n ); + AssignNewItemClientData(n, clientData, i, type); + } } else #endif @@ -411,141 +407,54 @@ int wxComboBox::DoAppend( const wxString &item ) DisableEvents(); GtkWidget *list = GTK_COMBO(m_widget)->list; - GtkWidget *list_item = gtk_list_item_new_with_label( wxGTK_CONV( item ) ); - - gtk_container_add( GTK_CONTAINER(list), list_item ); - - if (GTK_WIDGET_REALIZED(m_widget)) + for( int i = 0; i < count; ++i ) { - gtk_widget_realize( list_item ); - gtk_widget_realize( GTK_BIN(list_item)->child ); - } + n = pos + i; + // If sorted, use this wxSortedArrayStrings to determine + // the right insertion point + if(m_strings) + n = m_strings->Add(items[i]); - // Apply current widget style to the new list_item - GtkRcStyle *style = CreateWidgetStyle(); - if (style) - { - gtk_widget_modify_style(list_item, style); - GtkBin *bin = GTK_BIN( list_item ); - GtkWidget *label = bin->child; - gtk_widget_modify_style( label, style ); - gtk_rc_style_unref( style ); - } + GtkWidget *list_item = gtk_list_item_new_with_label( wxGTK_CONV( items[i] ) ); - gtk_widget_show( list_item ); + // TODO construct a list with all items and call gtk_list_insert_items once? + GList *gitem_list = g_list_alloc (); + gitem_list->data = list_item; + gtk_list_insert_items( GTK_LIST (list), gitem_list, n ); + + m_clientData.Insert( NULL, n ); + AssignNewItemClientData(n, clientData, i, type); + + if (GTK_WIDGET_REALIZED(m_widget)) + { + gtk_widget_realize( list_item ); + gtk_widget_realize( GTK_BIN(list_item)->child ); + + ApplyWidgetStyle(); + } + + gtk_widget_show( list_item ); + } EnableEvents(); } - const unsigned int count = GetCount(); - - if ( m_clientDataList.GetCount() < count ) - m_clientDataList.Append( (wxObject*) NULL ); - if ( m_clientObjectList.GetCount() < count ) - m_clientObjectList.Append( (wxObject*) NULL ); - InvalidateBestSize(); - return count - 1; -} - -int wxComboBox::DoInsert(const wxString &item, unsigned int pos) -{ - wxCHECK_MSG( !(GetWindowStyle() & wxCB_SORT), -1, - wxT("can't insert into sorted list")); - - wxCHECK_MSG( m_widget != NULL, -1, wxT("invalid combobox") ); - wxCHECK_MSG( IsValidInsert(pos), -1, wxT("invalid index") ); - - unsigned int count = GetCount(); - - if (pos == count) - return Append(item); - -#ifdef __WXGTK24__ - if (!gtk_check_version(2,4,0)) - { - GtkComboBox* combobox = GTK_COMBO_BOX( m_widget ); - gtk_combo_box_insert_text( combobox, pos, wxGTK_CONV( item ) ); - } - else -#endif - { - DisableEvents(); - - GtkWidget *list = GTK_COMBO(m_widget)->list; - GtkWidget *list_item = gtk_list_item_new_with_label( wxGTK_CONV( item ) ); - - GList *gitem_list = g_list_alloc (); - gitem_list->data = list_item; - gtk_list_insert_items( GTK_LIST (list), gitem_list, pos ); - - if (GTK_WIDGET_REALIZED(m_widget)) - { - gtk_widget_realize( list_item ); - gtk_widget_realize( GTK_BIN(list_item)->child ); - - ApplyWidgetStyle(); - } - - gtk_widget_show( list_item ); - - EnableEvents(); - } - - count = GetCount(); - - if ( m_clientDataList.GetCount() < count ) - m_clientDataList.Insert( pos, (wxObject*) NULL ); - if ( m_clientObjectList.GetCount() < count ) - m_clientObjectList.Insert( pos, (wxObject*) NULL ); - - InvalidateBestSize(); - - return pos; + return n; } void wxComboBox::DoSetItemClientData(unsigned int n, void* clientData) { - wxCHECK_RET( m_widget != NULL, wxT("invalid combobox") ); - - wxList::compatibility_iterator node = m_clientDataList.Item( n ); - if (!node) return; - - node->SetData( (wxObject*) clientData ); + m_clientData[n] = clientData; } void* wxComboBox::DoGetItemClientData(unsigned int n) const { - wxCHECK_MSG( m_widget != NULL, NULL, wxT("invalid combobox") ); - - wxList::compatibility_iterator node = m_clientDataList.Item( n ); - - return node ? node->GetData() : NULL; + return m_clientData[n]; } -void wxComboBox::DoSetItemClientObject(unsigned int n, wxClientData* clientData) -{ - wxCHECK_RET( m_widget != NULL, wxT("invalid combobox") ); - - wxList::compatibility_iterator node = m_clientObjectList.Item( n ); - if (!node) return; - - // wxItemContainer already deletes data for us - - node->SetData( (wxObject*) clientData ); -} - -wxClientData* wxComboBox::DoGetItemClientObject(unsigned int n) const -{ - wxCHECK_MSG( m_widget != NULL, (wxClientData*)NULL, wxT("invalid combobox") ); - - wxList::compatibility_iterator node = m_clientObjectList.Item( n ); - - return node ? (wxClientData*) node->GetData() : NULL; -} - -void wxComboBox::Clear() +void wxComboBox::DoClear() { wxCHECK_RET( m_widget != NULL, wxT("invalid combobox") ); @@ -566,23 +475,17 @@ void wxComboBox::Clear() gtk_list_clear_items( GTK_LIST(list), 0, GetCount() ); } - wxList::compatibility_iterator node = m_clientObjectList.GetFirst(); - while (node) - { - wxClientData *cd = (wxClientData*)node->GetData(); - delete cd; - node = node->GetNext(); - } - m_clientObjectList.Clear(); + m_clientData.Clear(); - m_clientDataList.Clear(); + if(m_strings) + m_strings->Clear(); EnableEvents(); InvalidateBestSize(); } -void wxComboBox::Delete(unsigned int n) +void wxComboBox::DoDeleteOneItem(unsigned int n) { wxCHECK_RET( m_widget != NULL, wxT("invalid combobox") ); @@ -616,17 +519,9 @@ void wxComboBox::Delete(unsigned int n) EnableEvents(); } - wxList::compatibility_iterator node = m_clientObjectList.Item( n ); - if (node) - { - wxClientData *cd = (wxClientData*)node->GetData(); - if (cd) delete cd; - m_clientObjectList.Erase( node ); - } - - node = m_clientDataList.Item( n ); - if (node) - m_clientDataList.Erase( node ); + m_clientData.RemoveAt( n ); + if(m_strings) + m_strings->RemoveAt( n ); InvalidateBestSize(); } @@ -946,7 +841,7 @@ void wxComboBox::SetValue( const wxString& value ) wxString tmp; if (!value.IsNull()) tmp = value; - + DisableEvents(); gtk_entry_set_text( entry, wxGTK_CONV( tmp ) ); EnableEvents(); diff --git a/src/gtk/listbox.cpp b/src/gtk/listbox.cpp index 15c70a351d..3517dd9f71 100644 --- a/src/gtk/listbox.cpp +++ b/src/gtk/listbox.cpp @@ -205,6 +205,7 @@ static void gtk_tree_entry_destroy_cb(GtkTreeEntry* entry, //----------------------------------------------------------------------------- // Sorting callback (standard CmpNoCase return value) //----------------------------------------------------------------------------- +#include extern "C" { static gint gtk_listbox_sort_callback(GtkTreeModel *model, @@ -228,8 +229,8 @@ static gint gtk_listbox_sort_callback(GtkTreeModel *model, //We compare collate keys here instead of calling g_utf8_collate //as it is rather slow (and even the docs reccommend this) - int ret = strcasecmp(gtk_tree_entry_get_collate_key(entry), - gtk_tree_entry_get_collate_key(entry2)); + int ret = strcmp(gtk_tree_entry_get_collate_key(entry), + gtk_tree_entry_get_collate_key(entry2)); g_object_unref (entry); g_object_unref (entry2); @@ -258,8 +259,8 @@ static gboolean gtk_listbox_searchequal_callback(GtkTreeModel* model, wxCHECK_MSG(entry, 0, wxT("Could not get entry")); wxGtkString keycollatekey(g_utf8_collate_key(key, -1)); - int ret = strcasecmp(keycollatekey, - gtk_tree_entry_get_collate_key(entry)); + int ret = strcmp(keycollatekey, + gtk_tree_entry_get_collate_key(entry)); g_object_unref (entry); @@ -396,7 +397,7 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id, gtk_tree_selection_set_mode( selection, mode ); // Handle sortable stuff - if(style & wxLB_SORT) + if(HasFlag(wxLB_SORT)) { // Setup sorting in ascending (wx) order gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(m_liststore), @@ -418,7 +419,7 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id, gtk_widget_show( GTK_WIDGET(m_treeview) ); m_focusWidget = GTK_WIDGET(m_treeview); - wxListBox::DoInsertItems(wxArrayString(n, choices), 0); // insert initial items + Append(n, choices); // insert initial items // generate dclick events g_signal_connect_after(m_treeview, "row-activated", @@ -443,35 +444,30 @@ wxListBox::~wxListBox() // adding items // ---------------------------------------------------------------------------- -void wxListBox::GtkInsertItems(const wxArrayString& items, - void** clientData, unsigned int pos) +int wxListBox::DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, + wxClientDataType type) { - wxCHECK_RET( m_treeview != NULL, wxT("invalid listbox") ); + wxCHECK_MSG( m_treeview != NULL, wxNOT_FOUND, wxT("invalid listbox") ); InvalidateBestSize(); - // Create and set column ids and GValues - - unsigned int nNum = items.GetCount(); - unsigned int nCurCount = wxListBox::GetCount(); - wxASSERT_MSG(pos <= nCurCount, wxT("Invalid index passed to wxListBox")); - GtkTreeIter* pIter = NULL; // append by default GtkTreeIter iter; - if (pos != nCurCount) + if ( pos != GetCount() ) { - wxCHECK_RET( GtkGetIteratorFor(pos, &iter), + wxCHECK_MSG( GtkGetIteratorFor(pos, &iter), wxNOT_FOUND, wxT("internal wxListBox error in insertion") ); pIter = &iter; } - for (unsigned int i = 0; i < nNum; ++i) + const unsigned int numItems = items.GetCount(); + for ( unsigned int i = 0; i < numItems; ++i ) { - wxString label = items[i]; - GtkTreeEntry* entry = gtk_tree_entry_new(); - gtk_tree_entry_set_label(entry, wxGTK_CONV(label)); + gtk_tree_entry_set_label(entry, wxGTK_CONV(items[i])); gtk_tree_entry_set_destroy_func(entry, (GtkTreeEntryDestroy)gtk_tree_entry_destroy_cb, this); @@ -486,49 +482,18 @@ void wxListBox::GtkInsertItems(const wxArrayString& items, g_object_unref (entry); } -} -void wxListBox::DoInsertItems(const wxArrayString& items, unsigned int pos) -{ - wxCHECK_RET( IsValidInsert(pos), wxT("invalid index in wxListBox::InsertItems") ); + if ( !HasClientData() ) + m_clientDataItemsType = type; - GtkInsertItems(items, NULL, pos); -} - -int wxListBox::DoAppend( const wxString& item ) -{ - wxCHECK_MSG( m_treeview != NULL, -1, wxT("invalid listbox") ); - - InvalidateBestSize(); - - GtkTreeEntry* entry = gtk_tree_entry_new(); - gtk_tree_entry_set_label( entry, wxGTK_CONV(item) ); - gtk_tree_entry_set_destroy_func(entry, - (GtkTreeEntryDestroy)gtk_tree_entry_destroy_cb, - this); - - GtkTreeIter itercur; - gtk_list_store_insert_before( m_liststore, &itercur, NULL ); - - GtkSetItem(itercur, entry); - - g_object_unref (entry); - - return GtkGetIndexFor(itercur); -} - -void wxListBox::DoSetItems( const wxArrayString& items, - void **clientData) -{ - Clear(); - GtkInsertItems(items, clientData, 0); + return pos + numItems - 1; } // ---------------------------------------------------------------------------- // deleting items // ---------------------------------------------------------------------------- -void wxListBox::Clear() +void wxListBox::DoClear() { wxCHECK_RET( m_treeview != NULL, wxT("invalid listbox") ); @@ -537,7 +502,7 @@ void wxListBox::Clear() gtk_list_store_clear( m_liststore ); /* well, THAT was easy :) */ } -void wxListBox::Delete(unsigned int n) +void wxListBox::DoDeleteOneItem(unsigned int n) { wxCHECK_RET( m_treeview != NULL, wxT("invalid listbox") ); @@ -632,11 +597,6 @@ void* wxListBox::DoGetItemClientData(unsigned int n) const return userdata; } -wxClientData* wxListBox::DoGetItemClientObject(unsigned int n) const -{ - return (wxClientData*) wxListBox::DoGetItemClientData(n); -} - void wxListBox::DoSetItemClientData(unsigned int n, void* clientData) { wxCHECK_RET( IsValid(n), @@ -649,12 +609,6 @@ void wxListBox::DoSetItemClientData(unsigned int n, void* clientData) g_object_unref (entry); } -void wxListBox::DoSetItemClientObject(unsigned int n, wxClientData* clientData) -{ - // wxItemContainer already deletes data for us - wxListBox::DoSetItemClientData(n, (void*) clientData); -} - // ---------------------------------------------------------------------------- // string list access // ---------------------------------------------------------------------------- diff --git a/src/gtk1/choice.cpp b/src/gtk1/choice.cpp index 9b03f45cfe..adf1d04101 100644 --- a/src/gtk1/choice.cpp +++ b/src/gtk1/choice.cpp @@ -126,7 +126,7 @@ bool wxChoice::Create( wxWindow *parent, wxWindowID id, if ( style & wxCB_SORT ) { - // if our m_strings != NULL, DoAppend() will check for it and insert + // if our m_strings != NULL, Append() will check for it and insert // items in the correct order m_strings = new wxSortedArrayString; } @@ -158,33 +158,33 @@ wxChoice::~wxChoice() delete m_strings; } -int wxChoice::DoAppend( const wxString &item ) +int wxChoice::DoInsertItems(const wxArrayStringsAdapter & items, + unsigned int pos, + void **clientData, wxClientDataType type) { wxCHECK_MSG( m_widget != NULL, -1, wxT("invalid choice control") ); - GtkWidget *menu = gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) ); - - return GtkAddHelper(menu, GetCount(), item); -} - -int wxChoice::DoInsert( const wxString &item, unsigned int pos ) -{ - wxCHECK_MSG( m_widget != NULL, -1, wxT("invalid choice control") ); - wxCHECK_MSG( IsValidInsert(pos), -1, wxT("invalid index")); - - if (pos == GetCount()) - return DoAppend(item); + const unsigned int count = items.GetCount(); GtkWidget *menu = gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) ); + for ( unsigned int i = 0; i < count; ++i, ++pos ) + { + int n = GtkAddHelper(menu, pos, items[i]); + if ( n == wxNOT_FOUND ) + return n; + + AssignNewItemClientData(n, clientData, i, type); + } + // if the item to insert is at or before the selection, and the selection is valid if (((int)pos <= m_selection_hack) && (m_selection_hack != wxNOT_FOUND)) { - // move the selection forward one - m_selection_hack++; + // move the selection forward + m_selection_hack += count; } - return GtkAddHelper(menu, pos, item); + return pos - 1; } void wxChoice::DoSetItemClientData(unsigned int n, void* clientData) @@ -207,30 +207,7 @@ void* wxChoice::DoGetItemClientData(unsigned int n) const return node->GetData(); } -void wxChoice::DoSetItemClientObject(unsigned int n, wxClientData* clientData) -{ - wxCHECK_RET( m_widget != NULL, wxT("invalid choice control") ); - - wxList::compatibility_iterator node = m_clientList.Item( n ); - wxCHECK_RET( node, wxT("invalid index in wxChoice::DoSetItemClientObject") ); - - // wxItemContainer already deletes data for us - - node->SetData( (wxObject*) clientData ); -} - -wxClientData* wxChoice::DoGetItemClientObject(unsigned int n) const -{ - wxCHECK_MSG( m_widget != NULL, (wxClientData*) NULL, wxT("invalid choice control") ); - - wxList::compatibility_iterator node = m_clientList.Item( n ); - wxCHECK_MSG( node, (wxClientData *)NULL, - wxT("invalid index in wxChoice::DoGetItemClientObject") ); - - return (wxClientData*) node->GetData(); -} - -void wxChoice::Clear() +void wxChoice::DoClear() { wxCHECK_RET( m_widget != NULL, wxT("invalid choice") ); @@ -238,18 +215,6 @@ void wxChoice::Clear() GtkWidget *menu = gtk_menu_new(); gtk_option_menu_set_menu( GTK_OPTION_MENU(m_widget), menu ); - if ( HasClientObjectData() ) - { - // destroy the data (due to Robert's idea of using wxList - // and not wxList we can't just say - // m_clientList.DeleteContents(true) - this would crash! - wxList::compatibility_iterator node = m_clientList.GetFirst(); - while ( node ) - { - delete (wxClientData *)node->GetData(); - node = node->GetNext(); - } - } m_clientList.Clear(); if ( m_strings ) @@ -259,15 +224,10 @@ void wxChoice::Clear() m_selection_hack = wxNOT_FOUND; } -void wxChoice::Delete(unsigned int n) +void wxChoice::DoDeleteOneItem(unsigned int n) { wxCHECK_RET( m_widget != NULL, wxT("invalid choice") ); - // VZ: apparently GTK+ doesn't have a built-in function to do it (not even - // in 2.0), hence this dumb implementation -- still better than nothing - unsigned int i; - unsigned int count = GetCount(); - wxCHECK_RET( IsValid(n), _T("invalid index in wxChoice::Delete") ); // if the item to delete is before the selection, and the selection is valid @@ -282,56 +242,31 @@ void wxChoice::Delete(unsigned int n) m_selection_hack = wxNOT_FOUND; } - const bool hasClientData = m_clientDataItemsType != wxClientData_None; - const bool hasObjectData = m_clientDataItemsType == wxClientData_Object; + // VZ: apparently GTK+ doesn't have a built-in function to do it (not even + // in 2.0), hence this dumb implementation -- still better than nothing + const unsigned int count = GetCount(); wxList::compatibility_iterator node = m_clientList.GetFirst(); wxArrayString items; wxArrayPtrVoid itemsData; items.Alloc(count); - for ( i = 0; i < count; i++ ) + for ( unsigned i = 0; i < count; i++, node = node->GetNext() ) { if ( i != n ) { items.Add(GetString(i)); - if ( hasClientData ) - { - // also save the client data - itemsData.Add(node->GetData()); - } - } - else // need to delete the client object too - { - if ( hasObjectData ) - { - delete (wxClientData *)node->GetData(); - } - } - - if ( hasClientData ) - { - node = node->GetNext(); + itemsData.Add(node->GetData()); } } - if ( hasObjectData ) - { - // prevent Clear() from destroying all client data - m_clientDataItemsType = wxClientData_None; - } + wxChoice::DoClear(); - Clear(); - - for ( i = 0; i < count - 1; i++ ) - { - Append(items[i]); - - if ( hasObjectData ) - SetClientObject(i, (wxClientData *)itemsData[i]); - else if ( hasClientData ) - SetClientData(i, itemsData[i]); - } + void ** const data = &itemsData[0]; + if ( HasClientObjectData() ) + Append(items, wx_reinterpret_cast(wxClientData **, data)); + else + Append(items, data); } int wxChoice::FindString( const wxString &string, bool bCase ) const diff --git a/src/gtk1/combobox.cpp b/src/gtk1/combobox.cpp index 3e519a1bc0..d6f65e2af7 100644 --- a/src/gtk1/combobox.cpp +++ b/src/gtk1/combobox.cpp @@ -317,7 +317,10 @@ void wxComboBox::SetFocus() gtk_widget_grab_focus( m_focusWidget ); } -int wxComboBox::DoAppend( const wxString &item ) +int wxComboBox::DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, + wxClientDataType type) { wxCHECK_MSG( m_widget != NULL, -1, wxT("invalid combobox") ); @@ -325,87 +328,58 @@ int wxComboBox::DoAppend( const wxString &item ) GtkWidget *list = GTK_COMBO(m_widget)->list; - GtkWidget *list_item = gtk_list_item_new_with_label( wxGTK_CONV( item ) ); - - gtk_container_add( GTK_CONTAINER(list), list_item ); - - if (GTK_WIDGET_REALIZED(m_widget)) - { - gtk_widget_realize( list_item ); - gtk_widget_realize( GTK_BIN(list_item)->child ); - } - - // Apply current widget style to the new list_item GtkRcStyle *style = CreateWidgetStyle(); - if (style) + + const unsigned int count = items.GetCount(); + for( unsigned int i = 0; i < count; ++i, ++pos ) { - gtk_widget_modify_style( GTK_WIDGET( list_item ), style ); - GtkBin *bin = GTK_BIN( list_item ); - GtkWidget *label = GTK_WIDGET( bin->child ); - gtk_widget_modify_style( label, style ); + GtkWidget * + list_item = gtk_list_item_new_with_label( wxGTK_CONV( items[i] ) ); + + if ( pos == GetCount() ) + { + gtk_container_add( GTK_CONTAINER(list), list_item ); + } + else // insert, not append + { + GList *gitem_list = g_list_alloc (); + gitem_list->data = list_item; + gtk_list_insert_items( GTK_LIST (list), gitem_list, pos ); + } + + if (GTK_WIDGET_REALIZED(m_widget)) + { + gtk_widget_realize( list_item ); + gtk_widget_realize( GTK_BIN(list_item)->child ); + + if (style) + { + gtk_widget_modify_style( GTK_WIDGET( list_item ), style ); + GtkBin *bin = GTK_BIN( list_item ); + GtkWidget *label = GTK_WIDGET( bin->child ); + gtk_widget_modify_style( label, style ); + } + + } + + gtk_widget_show( list_item ); + + if ( m_clientDataList.GetCount() < GetCount() ) + m_clientDataList.Insert( pos, (wxObject*) NULL ); + if ( m_clientObjectList.GetCount() < GetCount() ) + m_clientObjectList.Insert( pos, (wxObject*) NULL ); + + AssignNewItemClientData(pos, clientData, i, type); + } + + if ( style ) gtk_rc_style_unref( style ); - } - - gtk_widget_show( list_item ); - - const unsigned int count = GetCount(); - - if ( m_clientDataList.GetCount() < count ) - m_clientDataList.Append( (wxObject*) NULL ); - if ( m_clientObjectList.GetCount() < count ) - m_clientObjectList.Append( (wxObject*) NULL ); EnableEvents(); InvalidateBestSize(); - return count - 1; -} - -int wxComboBox::DoInsert( const wxString &item, unsigned int pos ) -{ - wxCHECK_MSG( !(GetWindowStyle() & wxCB_SORT), -1, - wxT("can't insert into sorted list")); - - wxCHECK_MSG( m_widget != NULL, -1, wxT("invalid combobox") ); - - wxCHECK_MSG( IsValidInsert(pos), -1, wxT("invalid index") ); - - if (pos == GetCount()) - return Append(item); - - DisableEvents(); - - GtkWidget *list = GTK_COMBO(m_widget)->list; - - GtkWidget *list_item = gtk_list_item_new_with_label( wxGTK_CONV( item ) ); - - GList *gitem_list = g_list_alloc (); - gitem_list->data = list_item; - gtk_list_insert_items( GTK_LIST (list), gitem_list, pos ); - - if (GTK_WIDGET_REALIZED(m_widget)) - { - gtk_widget_realize( list_item ); - gtk_widget_realize( GTK_BIN(list_item)->child ); - - ApplyWidgetStyle(); - } - - gtk_widget_show( list_item ); - - const unsigned int count = GetCount(); - - if ( m_clientDataList.GetCount() < count ) - m_clientDataList.Insert( pos, (wxObject*) NULL ); - if ( m_clientObjectList.GetCount() < count ) - m_clientObjectList.Insert( pos, (wxObject*) NULL ); - - EnableEvents(); - - InvalidateBestSize(); - - return pos; + return pos - 1; } void wxComboBox::DoSetItemClientData(unsigned int n, void* clientData) @@ -427,28 +401,7 @@ void* wxComboBox::DoGetItemClientData(unsigned int n) const return node ? node->GetData() : NULL; } -void wxComboBox::DoSetItemClientObject(unsigned int n, wxClientData* clientData) -{ - wxCHECK_RET( m_widget != NULL, wxT("invalid combobox") ); - - wxList::compatibility_iterator node = m_clientObjectList.Item( n ); - if (!node) return; - - // wxItemContainer already deletes data for us - - node->SetData( (wxObject*) clientData ); -} - -wxClientData* wxComboBox::DoGetItemClientObject(unsigned int n) const -{ - wxCHECK_MSG( m_widget != NULL, (wxClientData*)NULL, wxT("invalid combobox") ); - - wxList::compatibility_iterator node = m_clientObjectList.Item( n ); - - return node ? (wxClientData*) node->GetData() : NULL; -} - -void wxComboBox::Clear() +void wxComboBox::DoClear() { wxCHECK_RET( m_widget != NULL, wxT("invalid combobox") ); @@ -457,13 +410,6 @@ void wxComboBox::Clear() GtkWidget *list = GTK_COMBO(m_widget)->list; gtk_list_clear_items( GTK_LIST(list), 0, (int)GetCount() ); - wxList::compatibility_iterator node = m_clientObjectList.GetFirst(); - while (node) - { - wxClientData *cd = (wxClientData*)node->GetData(); - if (cd) delete cd; - node = node->GetNext(); - } m_clientObjectList.Clear(); m_clientDataList.Clear(); @@ -473,7 +419,7 @@ void wxComboBox::Clear() InvalidateBestSize(); } -void wxComboBox::Delete(unsigned int n) +void wxComboBox::DoDeleteOneItem(unsigned int n) { wxCHECK_RET( m_widget != NULL, wxT("invalid combobox") ); @@ -496,8 +442,6 @@ void wxComboBox::Delete(unsigned int n) wxList::compatibility_iterator node = m_clientObjectList.Item( n ); if (node) { - wxClientData *cd = (wxClientData*)node->GetData(); - if (cd) delete cd; m_clientObjectList.Erase( node ); } diff --git a/src/gtk1/listbox.cpp b/src/gtk1/listbox.cpp index 2cf833d0ac..93815ed498 100644 --- a/src/gtk1/listbox.cpp +++ b/src/gtk1/listbox.cpp @@ -541,7 +541,7 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id, if ( style & wxLB_SORT ) { - // this will change DoAppend() behaviour + // this will change Append() behaviour m_strings = new wxSortedArrayString; } else @@ -549,11 +549,7 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id, m_strings = (wxSortedArrayString *)NULL; } - for (int i = 0; i < n; i++) - { - // add one by one - DoAppend(choices[i]); - } + Append(n, choices); m_parent->DoAddChild( this ); @@ -577,101 +573,44 @@ wxListBox::~wxListBox() // adding items // ---------------------------------------------------------------------------- -void wxListBox::DoInsertItems(const wxArrayString& items, unsigned int pos) +int wxListBox::DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, + wxClientDataType type) { - wxCHECK_RET( m_list != NULL, wxT("invalid listbox") ); + wxCHECK_MSG( m_list != NULL, wxNOT_FOUND, wxT("invalid listbox") ); - // VZ: notice that InsertItems knows nothing about sorting, so calling it - // from outside (and not from our own Append) is likely to break - // everything + const unsigned count = GetCount(); + wxCHECK_MSG( pos <= count, wxNOT_FOUND, + wxT("invalid index in wxListBox::InsertItems") ); // code elsewhere supposes we have as many items in m_clientList as items // in the listbox - wxASSERT_MSG( m_clientList.GetCount() == GetCount(), - wxT("bug in client data management") ); + wxASSERT_MSG( m_clientList.GetCount() == count, + wxT("bug in client data management") ); InvalidateBestSize(); - GList *children = m_list->children; - unsigned int length = g_list_length(children); + const unsigned numItems = items.GetCount(); - wxCHECK_RET( pos <= length, wxT("invalid index in wxListBox::InsertItems") ); - - unsigned int nItems = items.GetCount(); - int index; - - if (m_strings) + for ( unsigned int n = 0; n < numItems; ++n, ++pos ) { - for (unsigned int n = 0; n < nItems; n++) - { - index = m_strings->Add( items[n] ); + const wxString& item = items[n]; - if (index != (int)GetCount()) - { - GtkAddItem( items[n], index ); - wxList::compatibility_iterator node = m_clientList.Item( index ); - m_clientList.Insert( node, (wxObject*) NULL ); - } - else - { - GtkAddItem( items[n] ); - m_clientList.Append( (wxObject*) NULL ); - } - } - } - else - { - if (pos == length) - { - for ( unsigned int n = 0; n < nItems; n++ ) - { - GtkAddItem( items[n] ); + const unsigned idx = m_strings ? m_strings->Add(item) + : pos; - m_clientList.Append((wxObject *)NULL); - } - } - else - { - wxList::compatibility_iterator node = m_clientList.Item( pos ); - for ( unsigned int n = 0; n < nItems; n++ ) - { - GtkAddItem( items[n], pos+n ); + GtkAddItem(item, idx == GetCount() ? -1 : idx); - m_clientList.Insert( node, (wxObject *)NULL ); - } - } + m_clientList.Insert(idx, NULL); + + AssignNewItemClientData(idx, clientData, n, type); } wxASSERT_MSG( m_clientList.GetCount() == GetCount(), wxT("bug in client data management") ); -} -int wxListBox::DoAppend( const wxString& item ) -{ - InvalidateBestSize(); - - if (m_strings) - { - // need to determine the index - int index = m_strings->Add( item ); - - // only if not at the end anyway - if (index != (int)GetCount()) - { - GtkAddItem( item, index ); - - wxList::compatibility_iterator node = m_clientList.Item( index ); - m_clientList.Insert( node, (wxObject *)NULL ); - - return index; - } - } - - GtkAddItem(item); - - m_clientList.Append((wxObject *)NULL); - - return GetCount() - 1; + return pos - 1; } void wxListBox::GtkAddItem( const wxString &item, int pos ) @@ -752,28 +691,11 @@ void wxListBox::GtkAddItem( const wxString &item, int pos ) } } -void wxListBox::DoSetItems( const wxArrayString& items, - void **clientData) -{ - Clear(); - - DoInsertItems(items, 0); - - if ( clientData ) - { - unsigned int count = items.GetCount(); - for ( unsigned int n = 0; n < count; n++ ) - { - SetClientData(n, clientData[n]); - } - } -} - // ---------------------------------------------------------------------------- // deleting items // ---------------------------------------------------------------------------- -void wxListBox::Clear() +void wxListBox::DoClear() { wxCHECK_RET( m_list != NULL, wxT("invalid listbox") ); @@ -785,25 +707,13 @@ void wxListBox::Clear() GTK_LIST(m_list)->last_focus_child = NULL; } - if ( HasClientObjectData() ) - { - // destroy the data (due to Robert's idea of using wxList - // and not wxList we can't just say - // m_clientList.DeleteContents(true) - this would crash! - wxList::compatibility_iterator node = m_clientList.GetFirst(); - while ( node ) - { - delete (wxClientData *)node->GetData(); - node = node->GetNext(); - } - } m_clientList.Clear(); if ( m_strings ) m_strings->Clear(); } -void wxListBox::Delete(unsigned int n) +void wxListBox::DoDeleteOneItem(unsigned int n) { wxCHECK_RET( m_list != NULL, wxT("invalid listbox") ); @@ -818,12 +728,6 @@ void wxListBox::Delete(unsigned int n) wxList::compatibility_iterator node = m_clientList.Item( n ); if ( node ) { - if ( m_clientDataItemsType == wxClientData_Object ) - { - wxClientData *cd = (wxClientData*)node->GetData(); - delete cd; - } - m_clientList.Erase( node ); } @@ -855,29 +759,6 @@ void* wxListBox::DoGetItemClientData(unsigned int n) const return node->GetData(); } -void wxListBox::DoSetItemClientObject(unsigned int n, wxClientData* clientData) -{ - wxCHECK_RET( m_widget != NULL, wxT("invalid listbox control") ); - - wxList::compatibility_iterator node = m_clientList.Item( n ); - wxCHECK_RET( node, wxT("invalid index in wxListBox::DoSetItemClientObject") ); - - // wxItemContainer already deletes data for us - - node->SetData( (wxObject*) clientData ); -} - -wxClientData* wxListBox::DoGetItemClientObject(unsigned int n) const -{ - wxCHECK_MSG( m_widget != NULL, (wxClientData*) NULL, wxT("invalid listbox control") ); - - wxList::compatibility_iterator node = m_clientList.Item( n ); - wxCHECK_MSG( node, (wxClientData *)NULL, - wxT("invalid index in wxListBox::DoGetItemClientObject") ); - - return (wxClientData*) node->GetData(); -} - // ---------------------------------------------------------------------------- // string list access // ---------------------------------------------------------------------------- diff --git a/src/mac/carbon/choice.cpp b/src/mac/carbon/choice.cpp index b0ba01d97d..13a5f77c37 100644 --- a/src/mac/carbon/choice.cpp +++ b/src/mac/carbon/choice.cpp @@ -50,11 +50,14 @@ bool wxChoice::Create(wxWindow *parent, const wxValidator& validator, const wxString& name ) { - wxCArrayString chs( choices ); - return Create( - parent, id, pos, size, chs.GetCount(), chs.GetStrings(), + parent, id, pos, size, 0, NULL, style, validator, name ); + + Append( choices ); + + if ( !choices.empty() ) + SetSelection( 0 ); } bool wxChoice::Create(wxWindow *parent, @@ -91,10 +94,7 @@ bool wxChoice::Create(wxWindow *parent, m_strings = wxArrayString( 1 ); #endif - for ( int i = 0; i < n; i++ ) - { - Append( choices[i] ); - } + Append(n, choices); // Set the first item as being selected if (n > 0) @@ -109,54 +109,45 @@ bool wxChoice::Create(wxWindow *parent, // ---------------------------------------------------------------------------- // adding/deleting items to/from the list // ---------------------------------------------------------------------------- -int wxChoice::DoAppend( const wxString& item ) + +int wxChoice::DoInsertItems(const wxArrayStringsAdapter & items, + unsigned int pos, + void **clientData, wxClientDataType type) { + const unsigned int numItems = items.GetCount(); + for( unsigned int i = 0; i < numItems; ++i, ++pos ) + { + unsigned int idx; + #if wxUSE_STL - wxArrayString::iterator insertPoint; - unsigned int index; + if ( IsSorted() ) + { + wxArrayString::iterator + insertPoint = std::lower_bound( m_strings.begin(), m_strings.end(), items[i] ); + idx = insertPoint - m_strings.begin(); + m_strings.insert( insertPoint, items[i] ); + } + else +#endif // wxUSE_STL + { + idx = pos; + m_strings.Insert( items[i], idx ); + } - if (GetWindowStyle() & wxCB_SORT) - { - insertPoint = std::lower_bound( m_strings.begin(), m_strings.end(), item ); - index = insertPoint - m_strings.begin(); - } - else - { - insertPoint = m_strings.end(); - index = m_strings.size(); + UMAInsertMenuItem(MAC_WXHMENU( m_macPopUpMenuHandle ), + items[i], + m_font.GetEncoding(), + idx); + m_datas.Insert( NULL, idx ); + AssignNewItemClientData(idx, clientData, i, type); } - m_strings.insert( insertPoint, item ); -#else - unsigned int index = m_strings.Add( item ); -#endif - - m_datas.Insert( NULL , index ); - UMAInsertMenuItem( MAC_WXHMENU( m_macPopUpMenuHandle ), item, m_font.GetEncoding(), index ); - DoSetItemClientData( index, NULL ); m_peer->SetMaximum( GetCount() ); - return index; + return pos - 1; } -int wxChoice::DoInsert( const wxString& item, unsigned int pos ) -{ - wxCHECK_MSG( !(GetWindowStyle() & wxCB_SORT), -1, wxT("wxChoice::DoInsert: can't insert into sorted list") ); - wxCHECK_MSG( IsValidInsert(pos), -1, wxT("wxChoice::DoInsert: invalid index") ); - - if (pos == GetCount()) - return DoAppend( item ); - - UMAInsertMenuItem( MAC_WXHMENU( m_macPopUpMenuHandle ), item, m_font.GetEncoding(), pos ); - m_strings.Insert( item, pos ); - m_datas.Insert( NULL, pos ); - DoSetItemClientData( pos, NULL ); - m_peer->SetMaximum( GetCount() ); - - return pos; -} - -void wxChoice::Delete(unsigned int n) +void wxChoice::DoDeleteOneItem(unsigned int n) { wxCHECK_RET( IsValid(n) , wxT("wxChoice::Delete: invalid index") ); @@ -169,9 +160,8 @@ void wxChoice::Delete(unsigned int n) m_peer->SetMaximum( GetCount() ) ; } -void wxChoice::Clear() +void wxChoice::DoClear() { - FreeData(); for ( unsigned int i = 0 ; i < GetCount() ; i++ ) { ::DeleteMenuItem( MAC_WXHMENU(m_macPopUpMenuHandle) , 1 ) ; @@ -182,18 +172,6 @@ void wxChoice::Clear() m_peer->SetMaximum( 0 ) ; } -void wxChoice::FreeData() -{ - if ( HasClientObjectData() ) - { - unsigned int count = GetCount(); - for ( unsigned int n = 0; n < count; n++ ) - { - delete GetClientObject( n ); - } - } -} - // ---------------------------------------------------------------------------- // selection // ---------------------------------------------------------------------------- @@ -220,7 +198,7 @@ int wxChoice::FindString( const wxString& s, bool bCase ) const { #if !wxUSE_STL // Avoid assert for non-default args passed to sorted array Index - if ( HasFlag(wxCB_SORT) ) + if ( IsSorted() ) bCase = true; #endif @@ -261,16 +239,6 @@ void * wxChoice::DoGetItemClientData(unsigned int n) const return (void *)m_datas[n]; } -void wxChoice::DoSetItemClientObject(unsigned int n, wxClientData* clientData) -{ - DoSetItemClientData(n, clientData); -} - -wxClientData* wxChoice::DoGetItemClientObject(unsigned int n) const -{ - return (wxClientData*)DoGetItemClientData( n ) ; -} - wxInt32 wxChoice::MacControlHit( WXEVENTHANDLERREF WXUNUSED(handler) , WXEVENTREF WXUNUSED(event) ) { wxCommandEvent event( wxEVT_COMMAND_CHOICE_SELECTED, m_windowId ); diff --git a/src/mac/carbon/combobox.cpp b/src/mac/carbon/combobox.cpp index eaf09763e2..1241f98b12 100644 --- a/src/mac/carbon/combobox.cpp +++ b/src/mac/carbon/combobox.cpp @@ -230,9 +230,6 @@ END_EVENT_TABLE() wxComboBox::~wxComboBox() { - // delete client objects - FreeData(); - // delete the controls now, don't leave them alive even though they would // still be eventually deleted by our parent - but it will be too late, the // user code expects them to be gone now @@ -347,10 +344,8 @@ bool wxComboBox::Create(wxWindow *parent, const wxValidator& validator, const wxString& name) { - wxCArrayString chs( choices ); - - return Create( parent, id, value, pos, size, chs.GetCount(), - chs.GetStrings(), style, validator, name ); + return Create( parent, id, value, pos, size, 0, NULL, + style, validator, name ); } bool wxComboBox::Create(wxWindow *parent, @@ -388,10 +383,7 @@ bool wxComboBox::Create(wxWindow *parent, DoSetSize(pos.x, pos.y, csize.x, csize.y); - for ( int i = 0 ; i < n ; i++ ) - { - m_choice->DoAppend( choices[ i ] ); - } + Append( n, choices ); // Needed because it is a wxControlWithItems SetInitialSize(size); @@ -510,59 +502,48 @@ void wxComboBox::SetSelection(long from, long to) m_text->SetSelection(from,to); } -int wxComboBox::DoAppend(const wxString& item) +int wxComboBox::DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, + wxClientDataType type) { - return m_choice->DoAppend( item ) ; -} + // wxItemContainer should probably be doing it itself but usually this is + // not necessary as the derived class DoInsertItems() calls + // AssignNewItemClientData() which initializes m_clientDataItemsType + // correctly; however as we just forward everything to wxChoice, we need to + // do it ourselves + // + // also notice that we never use wxClientData_Object with wxChoice as we + // don't want it to delete the data -- we will + int rc = m_choice->DoInsertItems(items, pos, clientData, + clientData ? wxClientData_Void + : wxClientData_None) ; + if ( rc != wxNOT_FOUND ) + { + if ( !HasClientData() && type != wxClientData_None ) + m_clientDataItemsType = type; + } -int wxComboBox::DoInsert(const wxString& item, unsigned int pos) -{ - return m_choice->DoInsert( item , pos ) ; + return rc; } void wxComboBox::DoSetItemClientData(unsigned int n, void* clientData) { - return m_choice->DoSetItemClientData( n , clientData ) ; + return m_choice->SetClientData( n , clientData ) ; } void* wxComboBox::DoGetItemClientData(unsigned int n) const { - return m_choice->DoGetItemClientData( n ) ; + return m_choice->GetClientData( n ) ; } -void wxComboBox::DoSetItemClientObject(unsigned int n, wxClientData* clientData) +void wxComboBox::DoDeleteOneItem(unsigned int n) { - return m_choice->DoSetItemClientObject(n, clientData); -} - -wxClientData* wxComboBox::DoGetItemClientObject(unsigned int n) const -{ - return m_choice->DoGetItemClientObject( n ) ; -} - -void wxComboBox::FreeData() -{ - if ( HasClientObjectData() ) - { - unsigned int count = GetCount(); - for ( unsigned int n = 0; n < count; n++ ) - { - SetClientObject( n, NULL ); - } - } -} - -void wxComboBox::Delete(unsigned int n) -{ - // force client object deletion - if( HasClientObjectData() ) - SetClientObject( n, NULL ); m_choice->Delete( n ); } -void wxComboBox::Clear() +void wxComboBox::DoClear() { - FreeData(); m_choice->Clear(); } diff --git a/src/mac/carbon/combobxc.cpp b/src/mac/carbon/combobxc.cpp index 9a63c93e70..670cbf7b6d 100644 --- a/src/mac/carbon/combobxc.cpp +++ b/src/mac/carbon/combobxc.cpp @@ -216,9 +216,6 @@ END_EVENT_TABLE() wxComboBox::~wxComboBox() { - // delete client objects - FreeData(); - // delete the controls now, don't leave them alive even though they would // still be eventually deleted by our parent - but it will be too late, the // user code expects them to be gone now @@ -386,10 +383,7 @@ bool wxComboBox::Create(wxWindow *parent, wxWindowID id, MacPostControlCreate(pos,size); - for ( int i = 0; i < n; i++ ) - { - DoAppend( choices[ i ] ); - } + Append( choices[ i ] ); HIViewSetVisible( m_peer->GetControlRef(), true ); SetSelection(0); @@ -416,10 +410,7 @@ bool wxComboBox::Create(wxWindow *parent, wxWindowID id, DoSetSize(pos.x, pos.y, csize.x, csize.y); - for ( int i = 0; i < n; i++ ) - { - m_choice->DoAppend( choices[ i ] ); - } + m_choice->Append( n, choices ); SetInitialSize(csize); // Needed because it is a wxControlWithItems #endif @@ -545,28 +536,26 @@ void wxComboBox::SetSelection(long from, long to) // TODO } -int wxComboBox::DoAppend(const wxString& item) +int wxComboBox::DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, wxClientDataType type) { #if USE_HICOMBOBOX - CFIndex outIndex; - HIComboBoxAppendTextItem( m_peer->GetControlRef(), wxMacCFStringHolder( item, m_font.GetEncoding() ), &outIndex ); - //SetControl32BitMaximum( m_peer->GetControlRef(), GetCount() ); - return (int) outIndex; -#else - return m_choice->DoAppend( item ); -#endif -} - -int wxComboBox::DoInsert(const wxString& item, unsigned int pos) -{ -#if USE_HICOMBOBOX - HIComboBoxInsertTextItemAtIndex( m_peer->GetControlRef(), (CFIndex)pos, wxMacCFStringHolder(item, m_font.GetEncoding()) ); + const unsigned int count = items.GetCount(); + for ( unsigned int i = 0; i < count; ++i, ++pos ) + { + HIComboBoxInsertTextItemAtIndex(m_peer->GetControlRef(), + (CFIndex)pos, + wxMacCFStringHolder(items[i], + m_font.GetEncoding())); + AssignNewItemClientData(pos, clientData, i, type); + } //SetControl32BitMaximum( m_peer->GetControlRef(), GetCount() ); - return pos; + return pos - 1; #else - return m_choice->DoInsert( item , pos ); + return m_choice->DoInsertItems( items, pos, clientData, type ); #endif } @@ -588,36 +577,6 @@ void* wxComboBox::DoGetItemClientData(unsigned int n) const #endif } -void wxComboBox::DoSetItemClientObject(unsigned int n, wxClientData* clientData) -{ -#if USE_HICOMBOBOX - return; //TODO -#else - return m_choice->DoSetItemClientObject( n , clientData ); -#endif -} - -wxClientData* wxComboBox::DoGetItemClientObject(unsigned int n) const -{ -#if USE_HICOMBOBOX - return NULL; -#else - return m_choice->DoGetItemClientObject( n ); -#endif -} - -void wxComboBox::FreeData() -{ - if (HasClientObjectData()) - { - unsigned int count = GetCount(); - for ( unsigned int n = 0; n < count; n++ ) - { - SetClientObject( n, NULL ); - } - } -} - unsigned int wxComboBox::GetCount() const { #if USE_HICOMBOBOX return (unsigned int) HIComboBoxGetItemCount( m_peer->GetControlRef() ); @@ -626,21 +585,17 @@ unsigned int wxComboBox::GetCount() const { #endif } -void wxComboBox::Delete(unsigned int n) +void wxComboBox::DoDeleteOneItem(unsigned int n) { #if USE_HICOMBOBOX HIComboBoxRemoveItemAtIndex( m_peer->GetControlRef(), (CFIndex)n ); #else - // force client object deletion - if( HasClientObjectData() ) - SetClientObject( n, NULL ); m_choice->Delete( n ); #endif } -void wxComboBox::Clear() +void wxComboBox::DoClear() { - FreeData(); #if USE_HICOMBOBOX for ( CFIndex i = GetCount() - 1; i >= 0; ++ i ) verify_noerr( HIComboBoxRemoveItemAtIndex( m_peer->GetControlRef(), i ) ); diff --git a/src/mac/carbon/listbox.cpp b/src/mac/carbon/listbox.cpp index 54717cfb18..74efe70511 100644 --- a/src/mac/carbon/listbox.cpp +++ b/src/mac/carbon/listbox.cpp @@ -87,7 +87,7 @@ bool wxListBox::Create( MacPostControlCreate( pos, size ); - InsertItems( n, choices, 0 ); + Append(n, choices); // Needed because it is a wxControlWithItems SetInitialSize( size ); @@ -116,36 +116,29 @@ void wxListBox::EnsureVisible(int n) GetPeer()->MacScrollTo( n ); } -void wxListBox::Delete(unsigned int n) +void wxListBox::DoDeleteOneItem(unsigned int n) { wxCHECK_RET( IsValid(n), wxT("invalid index in wxListBox::Delete") ); GetPeer()->MacDelete( n ); } -int wxListBox::DoAppend(const wxString& item) +int wxListBox::DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, + wxClientDataType type) { InvalidateBestSize(); - return GetPeer()->MacAppend( item ); -} - -void wxListBox::DoSetItems(const wxArrayString& choices, void** clientData) -{ - Clear(); - - unsigned int n = choices.GetCount(); - - for ( size_t i = 0; i < n; ++i ) + GetPeer()->MacInsert( pos, items ); + const unsigned int count = items.GetCount(); + if ( clientData ) { - if ( clientData ) - { - Append( choices[i], clientData[i] ); - } - else - Append( choices[i] ); + for (unsigned int i = 0; i < count; ++i) + AssignNewItemClientData( pos + i, clientData, i, type ); } + return pos + count - 1; } int wxListBox::FindString(const wxString& s, bool bCase) const @@ -159,7 +152,7 @@ int wxListBox::FindString(const wxString& s, bool bCase) const return wxNOT_FOUND; } -void wxListBox::Clear() +void wxListBox::DoClear() { FreeData(); } @@ -188,22 +181,12 @@ void *wxListBox::DoGetItemClientData(unsigned int n) const return GetPeer()->MacGetClientData( n ); } -wxClientData *wxListBox::DoGetItemClientObject(unsigned int n) const -{ - return (wxClientData*)DoGetItemClientData( n ); -} - void wxListBox::DoSetItemClientData(unsigned int n, void *clientData) { wxCHECK_RET( IsValid(n), wxT("invalid index in wxListBox::SetClientData") ); GetPeer()->MacSetClientData( n , clientData); } -void wxListBox::DoSetItemClientObject(unsigned int n, wxClientData* clientData) -{ - DoSetItemClientData(n, clientData); -} - // Return number of selections and an array of selected integers int wxListBox::GetSelections(wxArrayInt& aSelections) const { @@ -223,15 +206,6 @@ wxString wxListBox::GetString(unsigned int n) const return GetPeer()->MacGetString(n); } -void wxListBox::DoInsertItems(const wxArrayString& items, unsigned int pos) -{ - wxCHECK_RET( IsValidInsert(pos), wxT("invalid index in wxListBox::InsertItems") ); - - InvalidateBestSize(); - - GetPeer()->MacInsert( pos, items ); -} - void wxListBox::SetString(unsigned int n, const wxString& s) { GetPeer()->MacSetString( n, s ); diff --git a/src/mac/carbon/utils.cpp b/src/mac/carbon/utils.cpp index 9afe0b6d5b..55848f5799 100644 --- a/src/mac/carbon/utils.cpp +++ b/src/mac/carbon/utils.cpp @@ -2020,36 +2020,9 @@ void wxMacDataItemBrowserControl::MacDelete( unsigned int n ) RemoveItem( wxMacDataBrowserRootContainer, item ); } -void wxMacDataItemBrowserControl::MacInsert( unsigned int n, const wxString& text, int column ) -{ - wxMacDataItem* newItem = CreateItem(); - newItem->SetLabel( text ); - if ( column != -1 ) - newItem->SetColumn( kMinColumnId + column ); - - if ( m_sortOrder == SortOrder_None ) - { - // increase the order of the lines to be shifted - unsigned int lines = MacGetCount(); - for ( unsigned int i = n; i < lines; ++i) - { - wxMacDataItem* iter = (wxMacDataItem*) GetItemFromLine(i); - iter->SetOrder( iter->GetOrder() + 1 ); - } - - SInt32 frontLineOrder = 0; - if ( n > 0 ) - { - wxMacDataItem* iter = (wxMacDataItem*) GetItemFromLine(n-1); - frontLineOrder = iter->GetOrder(); - } - newItem->SetOrder( frontLineOrder + 1 ); - } - - AddItem( wxMacDataBrowserRootContainer, newItem ); -} - -void wxMacDataItemBrowserControl::MacInsert( unsigned int n, const wxArrayString& items, int column ) +void wxMacDataItemBrowserControl::MacInsert( unsigned int n, + const wxArrayStringsAdapter& items, + int column ) { size_t itemsCount = items.GetCount(); if ( itemsCount == 0 ) diff --git a/src/motif/checklst.cpp b/src/motif/checklst.cpp index 0205216a2b..b0e22aaefe 100644 --- a/src/motif/checklst.cpp +++ b/src/motif/checklst.cpp @@ -51,15 +51,6 @@ static inline const wxString& Prefix(bool checked) static inline bool IsChecked(const wxString& s) { wxASSERT(s.length() >=4); return s[1] == checkChar; } -static void CopyStringsAddingPrefix(const wxArrayString& orig, - wxArrayString& copy) -{ - copy.Clear(); - - for(size_t i = 0; i < orig.GetCount(); ++i ) - copy.Add( Prefix(false) + orig[i] ); -} - // def ctor: use Create() to really create the control wxCheckListBox::wxCheckListBox() : wxCheckListBoxBase() { @@ -154,11 +145,6 @@ void wxCheckListBox::DoToggleItem( int n, int x ) } } -int wxCheckListBox::DoAppend(const wxString& item) -{ - return wxListBox::DoAppend( Prefix(false) + item ); -} - int wxCheckListBox::FindString(const wxString& s, bool bCase) const { int n1 = wxListBox::FindString(Prefix(false) + s, bCase); @@ -183,18 +169,16 @@ wxString wxCheckListBox::GetString(unsigned int n) const return wxListBox::GetString(n).substr(4); } -void wxCheckListBox::DoInsertItems(const wxArrayString& items, unsigned int pos) +int wxCheckListBox::DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, wxClientDataType type) { wxArrayString copy; - CopyStringsAddingPrefix(items, copy); - wxListBox::DoInsertItems(copy, pos); -} + copy.reserve(pos); + for ( size_t i = 0; i < items.GetCount(); ++i ) + copy.push_back( Prefix(false) + items[i] ); -void wxCheckListBox::DoSetItems(const wxArrayString& items, void **clientData) -{ - wxArrayString copy; - CopyStringsAddingPrefix(items, copy); - wxListBox::DoSetItems(copy, clientData); + return wxListBox::DoInsertItems(copy, pos, clientData, type); } #endif // wxUSE_CHECKLISTBOX diff --git a/src/motif/choice.cpp b/src/motif/choice.cpp index 6c7edaa117..bb1181f4fd 100644 --- a/src/motif/choice.cpp +++ b/src/motif/choice.cpp @@ -179,8 +179,6 @@ wxChoice::~wxChoice() m_mainWidget = (WXWidget) 0; m_buttonWidget = (WXWidget) 0; } - if ( HasClientObjectData() ) - m_clientDataDict.DestroyData(); } static inline wxChar* MYcopystring(const wxChar* s) @@ -189,72 +187,78 @@ static inline wxChar* MYcopystring(const wxChar* s) return wxStrcpy(copy, s); } -int wxChoice::DoInsert(const wxString& item, unsigned int pos) +// TODO auto-sorting is not supported by the code +int wxChoice::DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, wxClientDataType type) { #ifndef XmNpositionIndex wxCHECK_MSG( pos == GetCount(), -1, wxT("insert not implemented")); #endif - Widget w = XtVaCreateManagedWidget (GetLabelText(item), + + const unsigned int numItems = items.GetCount(); + AllocClientData(numItems); + for( unsigned int i = 0; i < numItems; ++i, ++pos ) + { + Widget w = XtVaCreateManagedWidget (GetLabelText(items[i]), #if wxUSE_GADGETS - xmPushButtonGadgetClass, (Widget) m_menuWidget, + xmPushButtonGadgetClass, (Widget) m_menuWidget, #else - xmPushButtonWidgetClass, (Widget) m_menuWidget, + xmPushButtonWidgetClass, (Widget) m_menuWidget, #endif #ifdef XmNpositionIndex - XmNpositionIndex, pos, + XmNpositionIndex, pos, #endif - NULL); - - wxDoChangeBackgroundColour((WXWidget) w, m_backgroundColour); - - if( m_font.Ok() ) - wxDoChangeFont( w, m_font ); - - m_widgetArray.Insert(w, pos); - - char mnem = wxFindMnemonic (item); - if (mnem != 0) - XtVaSetValues (w, XmNmnemonic, mnem, NULL); - - XtAddCallback (w, XmNactivateCallback, - (XtCallbackProc) wxChoiceCallback, - (XtPointer) this); - - if (m_noStrings == 0 && m_buttonWidget) - { - XtVaSetValues ((Widget) m_buttonWidget, XmNmenuHistory, w, NULL); - Widget label = XmOptionButtonGadget ((Widget) m_buttonWidget); - wxXmString text( item ); - XtVaSetValues (label, - XmNlabelString, text(), NULL); + + wxDoChangeBackgroundColour((WXWidget) w, m_backgroundColour); + + if( m_font.Ok() ) + wxDoChangeFont( w, m_font ); + + m_widgetArray.Insert(w, pos); + + char mnem = wxFindMnemonic (items[i]); + if (mnem != 0) + XtVaSetValues (w, XmNmnemonic, mnem, NULL); + + XtAddCallback (w, XmNactivateCallback, + (XtCallbackProc) wxChoiceCallback, + (XtPointer) this); + + if (m_noStrings == 0 && m_buttonWidget) + { + XtVaSetValues ((Widget) m_buttonWidget, XmNmenuHistory, w, NULL); + Widget label = XmOptionButtonGadget ((Widget) m_buttonWidget); + wxXmString text( items[i] ); + XtVaSetValues (label, + XmNlabelString, text(), + NULL); + } + // need to ditch wxStringList for wxArrayString + m_stringList.Insert(pos, MYcopystring(items[i])); + m_noStrings ++; + + InsertNewItemClientData(pos, clientData, i, type); } - // need to ditch wxStringList for wxArrayString - m_stringList.Insert(pos, MYcopystring(item)); - m_noStrings ++; - return pos; + return pos - 1; } -int wxChoice::DoAppend(const wxString& item) -{ - return DoInsert(item, GetCount()); -} - -void wxChoice::Delete(unsigned int n) +void wxChoice::DoDeleteOneItem(unsigned int n) { Widget w = (Widget)m_widgetArray[n]; XtRemoveCallback(w, XmNactivateCallback, (XtCallbackProc)wxChoiceCallback, (XtPointer)this); m_stringList.Erase(m_stringList.Item(n)); m_widgetArray.RemoveAt(size_t(n)); - m_clientDataDict.Delete(n, HasClientObjectData()); + wxChoiceBase::DoDeleteOneItem(n); XtDestroyWidget(w); m_noStrings--; } -void wxChoice::Clear() +void wxChoice::DoClear() { m_stringList.Clear (); unsigned int i; @@ -272,8 +276,7 @@ void wxChoice::Clear() XmNmenuHistory, (Widget) NULL, NULL); - if ( HasClientObjectData() ) - m_clientDataDict.DestroyData(); + wxChoiceBase::DoClear(); m_noStrings = 0; } @@ -502,27 +505,6 @@ unsigned int wxChoice::GetCount() const return m_noStrings; } -void wxChoice::DoSetItemClientData(unsigned int n, void* clientData) -{ - m_clientDataDict.Set(n, (wxClientData*)clientData, false); -} - -void* wxChoice::DoGetItemClientData(unsigned int n) const -{ - return (void*)m_clientDataDict.Get(n); -} - -void wxChoice::DoSetItemClientObject(unsigned int n, wxClientData* clientData) -{ - // don't delete, wxItemContainer does that for us - m_clientDataDict.Set(n, clientData, false); -} - -wxClientData* wxChoice::DoGetItemClientObject(unsigned int n) const -{ - return m_clientDataDict.Get(n); -} - void wxChoice::SetString(unsigned int WXUNUSED(n), const wxString& WXUNUSED(s)) { wxFAIL_MSG( wxT("wxChoice::SetString not implemented") ); diff --git a/src/motif/combobox.cpp b/src/motif/combobox.cpp index 313dde7628..4083a88ebd 100644 --- a/src/motif/combobox.cpp +++ b/src/motif/combobox.cpp @@ -111,8 +111,6 @@ wxComboBox::~wxComboBox() DetachWidget((Widget) m_mainWidget); // Removes event handlers XtDestroyWidget((Widget) m_mainWidget); m_mainWidget = (WXWidget) 0; - if ( HasClientObjectData() ) - m_clientDataDict.DestroyData(); } void wxComboBox::DoSetSize(int x, int y, @@ -151,34 +149,29 @@ void wxComboBox::SetString(unsigned int WXUNUSED(n), const wxString& WXUNUSED(s) wxFAIL_MSG( wxT("wxComboBox::SetString only implemented for Motif 2.0") ); } -int wxComboBox::DoAppend(const wxString& item) +// TODO auto-sorting is not supported by the code +int wxComboBox::DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, + wxClientDataType type) { - wxXmString str( item.c_str() ); - XmComboBoxAddItem((Widget) m_mainWidget, str(), 0); - m_stringList.Add(item); - m_noStrings ++; + const unsigned int numItems = items.GetCount(); - return GetCount() - 1; + AllocClientData(numItems); + for( unsigned int i = 0; i < numItems; ++i, ++pos ) + { + wxXmString str( items[i].c_str() ); + XmComboBoxAddItem((Widget) m_mainWidget, str(), GetMotifPosition(pos)); + wxChar* copy = wxStrcpy(new wxChar[items[i].length() + 1], items[i].c_str()); + m_stringList.Insert(pos, copy); + m_noStrings ++; + InsertNewItemClientData(pos, clientData, i, type); + } + + return pos - 1; } -int wxComboBox::DoInsert(const wxString& item, unsigned int pos) -{ - wxCHECK_MSG(!(GetWindowStyle() & wxCB_SORT), -1, wxT("can't insert into sorted list")); - wxCHECK_MSG(IsValidInsert(pos), -1, wxT("invalid index")); - - if (pos == GetCount()) - return DoAppend(item); - - wxXmString str( item.c_str() ); - XmComboBoxAddItem((Widget) m_mainWidget, str(), pos+1); - wxChar* copy = wxStrcpy(new wxChar[item.length() + 1], item.c_str()); - m_stringList.Insert(pos, copy); - m_noStrings ++; - - return pos; -} - -void wxComboBox::Delete(unsigned int n) +void wxComboBox::DoDeleteOneItem(unsigned int n) { XmComboBoxDeletePos((Widget) m_mainWidget, n+1); wxStringList::Node *node = m_stringList.Item(n); @@ -187,17 +180,16 @@ void wxComboBox::Delete(unsigned int n) delete[] node->GetData(); delete node; } - m_clientDataDict.Delete(n, HasClientObjectData()); + wxControlWithItems::DoDeleteOneItem(n); m_noStrings--; } -void wxComboBox::Clear() +void wxComboBox::DoClear() { XmComboBoxDeleteAllItems((Widget) m_mainWidget); m_stringList.Clear(); - if ( HasClientObjectData() ) - m_clientDataDict.DestroyData(); + wxControlWithItems::DoClear(); m_noStrings = 0; } diff --git a/src/motif/combobox_native.cpp b/src/motif/combobox_native.cpp index 0caced91fd..959b1581ae 100644 --- a/src/motif/combobox_native.cpp +++ b/src/motif/combobox_native.cpp @@ -161,8 +161,6 @@ wxComboBox::~wxComboBox() DetachWidget((Widget) m_mainWidget); // Removes event handlers XtDestroyWidget((Widget) m_mainWidget); m_mainWidget = (WXWidget) 0; - if ( HasClientObjectData() ) - m_clientDataDict.DestroyData(); } void wxComboBox::DoSetSize(int x, int y, int width, int WXUNUSED(height), int sizeFlags) @@ -202,33 +200,28 @@ void wxComboBox::SetValue(const wxString& value) m_inSetValue = false; } -int wxComboBox::DoAppend(const wxString& item) +int wxComboBox::DoInsertItems(const wxArrayStringsAdapter & items, + unsigned int pos, + void **clientData, wxClientDataType type) { - wxXmString str( item.c_str() ); - XmComboBoxAddItem((Widget) m_mainWidget, str(), 0, False); - m_noStrings ++; + const unsigned int numItems = items.GetCount(); + + AllocClientData(numItems); + for ( unsigned int i = 0; i < numItems; ++i, ++pos ) + { + wxXmString str( items[i].c_str() ); + XmComboBoxAddItem((Widget) m_mainWidget, str(), + GetMotifPosition(pos), False); + m_noStrings ++; + InsertNewItemClientData(pos, clientData, i, type); + } + AdjustDropDownListSize(); - return GetCount() - 1; + return pos - 1; } -int wxComboBox::DoInsert(const wxString& item, unsigned int pos) -{ - wxCHECK_MSG(!(GetWindowStyle() & wxCB_SORT), -1, wxT("can't insert into sorted list")); - wxCHECK_MSG(IsValidInsert(pos), -1, wxT("invalid index")); - - if (pos == GetCount()) - return DoAppend(item); - - wxXmString str( item.c_str() ); - XmComboBoxAddItem((Widget) m_mainWidget, str(), pos+1, False); - m_noStrings ++; - AdjustDropDownListSize(); - - return GetCount() - 1; -} - -void wxComboBox::Delete(unsigned int n) +void wxComboBox::DoDeleteOneItem(unsigned int n) { #ifdef LESSTIF_VERSION XmListDeletePos (GetXmList(this), n + 1); @@ -236,13 +229,13 @@ void wxComboBox::Delete(unsigned int n) XmComboBoxDeletePos((Widget) m_mainWidget, n+1); #endif - m_clientDataDict.Delete(n, HasClientObjectData()); + wxControlWithItems::DoDeleteOneItem(n); m_noStrings--; AdjustDropDownListSize(); } -void wxComboBox::Clear() +void wxComboBox::DoClear() { #ifdef LESSTIF_VERSION XmListDeleteAllItems (GetXmList(this)); @@ -253,8 +246,7 @@ void wxComboBox::Clear() } #endif - if ( HasClientObjectData() ) - m_clientDataDict.DestroyData(); + wxControlWithItems::DoClear(); m_noStrings = 0; AdjustDropDownListSize(); } diff --git a/src/motif/listbox.cpp b/src/motif/listbox.cpp index fc729fba27..d20f37dfcb 100644 --- a/src/motif/listbox.cpp +++ b/src/motif/listbox.cpp @@ -171,12 +171,6 @@ bool wxListBox::Create(wxWindow *parent, wxWindowID id, style, validator, name); } -wxListBox::~wxListBox() -{ - if( HasClientObjectData() ) - m_clientDataDict.DestroyData(); -} - void wxListBox::SetSelectionPolicy() { Widget listBox = (Widget)m_mainWidget; @@ -208,63 +202,16 @@ void wxListBox::DoSetFirstItem( int N ) XmListSetPos ((Widget) m_mainWidget, N + 1); } -void wxListBox::Delete(unsigned int n) +void wxListBox::DoDeleteOneItem(unsigned int n) { Widget listBox = (Widget) m_mainWidget; XmListDeletePos (listBox, n + 1); - m_clientDataDict.Delete(n, HasClientObjectData()); + wxListBoxBase::DoDeleteOneItem(n); m_noItems --; } -int wxListBox::DoAppend(const wxString& item) -{ - Widget listBox = (Widget) m_mainWidget; - - int n; - XtVaGetValues (listBox, XmNitemCount, &n, NULL); - wxXmString text( item ); - // XmListAddItem(listBox, text, n + 1); - XmListAddItemUnselected (listBox, text(), 0); - - // It seems that if the list is cleared, we must re-ask for - // selection policy!! - SetSelectionPolicy(); - - m_noItems ++; - - return GetCount() - 1; -} - -void wxListBox::DoSetItems(const wxArrayString& items, void** clientData) -{ - Widget listBox = (Widget) m_mainWidget; - - if( HasClientObjectData() ) - m_clientDataDict.DestroyData(); - - XmString *text = new XmString[items.GetCount()]; - unsigned int i; - for (i = 0; i < items.GetCount(); ++i) - text[i] = wxStringToXmString (items[i]); - - if ( clientData ) - for (i = 0; i < items.GetCount(); ++i) - m_clientDataDict.Set(i, (wxClientData*)clientData[i], false); - - XmListAddItems (listBox, text, items.GetCount(), 0); - for (i = 0; i < items.GetCount(); i++) - XmStringFree (text[i]); - delete[] text; - - // It seems that if the list is cleared, we must re-ask for - // selection policy!! - SetSelectionPolicy(); - - m_noItems = items.GetCount(); -} - int wxDoFindStringInList(Widget w, const wxString& s) { wxXmString str( s ); @@ -290,20 +237,19 @@ int wxListBox::FindString(const wxString& s, bool WXUNUSED(bCase)) const return wxDoFindStringInList( (Widget)m_mainWidget, s ); } -void wxListBox::Clear() +void wxListBox::DoClear() { - if (m_noItems <= 0) + if (!m_noItems) return; wxSizeKeeper sk( this ); Widget listBox = (Widget) m_mainWidget; XmListDeleteAllItems (listBox); - if( HasClientObjectData() ) - m_clientDataDict.DestroyData(); sk.Restore(); + wxListBoxBase::DoClear(); m_noItems = 0; } @@ -364,26 +310,6 @@ bool wxListBox::IsSelected(int N) const return false; } -void wxListBox::DoSetItemClientObject(unsigned int n, wxClientData* clientData) -{ - m_clientDataDict.Set(n, clientData, false); -} - -wxClientData* wxListBox::DoGetItemClientObject(unsigned int n) const -{ - return m_clientDataDict.Get(n); -} - -void *wxListBox::DoGetItemClientData(unsigned int n) const -{ - return (void*)m_clientDataDict.Get(n); -} - -void wxListBox::DoSetItemClientData(unsigned int n, void *Client_data) -{ - m_clientDataDict.Set(n, (wxClientData*)Client_data, false); -} - // Return number of selections and an array of selected integers int wxListBox::GetSelections(wxArrayInt& aSelections) const { @@ -456,36 +382,43 @@ wxString wxListBox::GetString(unsigned int n) const return wxDoGetStringInList( (Widget)m_mainWidget, n ); } -void wxListBox::DoInsertItems(const wxArrayString& items, unsigned int pos) +int wxListBox::DoInsertItems(const wxArrayStringsAdapter & items, + unsigned int pos, + void **clientData, wxClientDataType type) { Widget listBox = (Widget) m_mainWidget; - XmString *text = new XmString[items.GetCount()]; + const unsigned int numItems = items.GetCount(); + + XmString *text = new XmString[numItems]; unsigned int i; - // Steve Hammes: Motif 1.1 compatibility - // #if XmVersion > 1100 - // Corrected by Sergey Krasnov from Steve Hammes' code #if XmVersion > 1001 - for (i = 0; i < items.GetCount(); i++) - text[i] = wxStringToXmString(items[i]); - XmListAddItemsUnselected(listBox, text, items.GetCount(), pos+1); -#else - for (i = 0; i < items.GetCount(); i++) + for (i = 0; i < numItems; i++) { text[i] = wxStringToXmString(items[i]); - // Another Sergey correction - XmListAddItemUnselected(listBox, text[i], pos+i+1); + } + XmListAddItemsUnselected(listBox, text, numItems, GetMotifPosition(pos)); + InsertNewItemsClientData(pos, numItems, clientData, type); +#else + AllocClientData(numItems); + + unsigned int idx = pos; + for ( i = 0; i < numItems; i++, idx++ ) + { + text[i] = wxStringToXmString(items[i]); + XmListAddItemUnselected(listBox, text[i], GetMotifPosition(idx)); + InsertNewItemClientData(idx, clientData, i, type); } #endif - for (i = 0; i < items.GetCount(); i++) + for (i = 0; i < numItems; i++) XmStringFree(text[i]); delete[] text; - // It seems that if the list is cleared, we must re-ask for - // selection policy!! + m_noItems += numItems; + SetSelectionPolicy(); - m_noItems += items.GetCount(); + return pos + numItems - 1; } void wxListBox::SetString(unsigned int n, const wxString& s) diff --git a/src/msw/choice.cpp b/src/msw/choice.cpp index 4af53089a6..4d834267cd 100644 --- a/src/msw/choice.cpp +++ b/src/msw/choice.cpp @@ -211,63 +211,56 @@ WXDWORD wxChoice::MSWGetStyle(long style, WXDWORD *exstyle) const wxChoice::~wxChoice() { - Free(); + Clear(); } // ---------------------------------------------------------------------------- // adding/deleting items to/from the list // ---------------------------------------------------------------------------- -int wxChoice::DoAppend(const wxString& item) +int wxChoice::DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, wxClientDataType type) { - int n = (int)SendMessage(GetHwnd(), CB_ADDSTRING, 0, - (LPARAM)item.wx_str()); - if ( n == CB_ERR ) + MSWAllocStorage(items, CB_INITSTORAGE); + + const bool append = pos == GetCount(); + + // use CB_ADDSTRING when appending at the end to make sure the control is + // resorted if it has wxCB_SORT style + const unsigned msg = append ? CB_ADDSTRING : CB_INSERTSTRING; + + if ( append ) + pos = 0; + + int n = wxNOT_FOUND; + const unsigned numItems = items.GetCount(); + for ( unsigned i = 0; i < numItems; ++i ) { - wxLogLastError(wxT("SendMessage(CB_ADDSTRING)")); - } - else // ok - { - // we need to refresh our size in order to have enough space for the - // newly added items - if ( !IsFrozen() ) - UpdateVisibleHeight(); + n = MSWInsertOrAppendItem(pos, items[i], msg); + if ( n == wxNOT_FOUND ) + return n; + + if ( !append ) + pos++; + + AssignNewItemClientData(n, clientData, i, type); } + // we need to refresh our size in order to have enough space for the + // newly added items + if ( !IsFrozen() ) + UpdateVisibleHeight(); + InvalidateBestSize(); + return n; } -int wxChoice::DoInsert(const wxString& item, unsigned int pos) -{ - wxCHECK_MSG(!(GetWindowStyle() & wxCB_SORT), -1, wxT("can't insert into sorted list")); - wxCHECK_MSG(IsValidInsert(pos), -1, wxT("invalid index")); - - int n = (int)SendMessage(GetHwnd(), CB_INSERTSTRING, pos, - (LPARAM)item.wx_str()); - if ( n == CB_ERR ) - { - wxLogLastError(wxT("SendMessage(CB_INSERTSTRING)")); - } - else // ok - { - if ( !IsFrozen() ) - UpdateVisibleHeight(); - } - - InvalidateBestSize(); - return n; -} - -void wxChoice::Delete(unsigned int n) +void wxChoice::DoDeleteOneItem(unsigned int n) { wxCHECK_RET( IsValid(n), wxT("invalid item index in wxChoice::Delete") ); - if ( HasClientObjectData() ) - { - delete GetClientObject(n); - } - SendMessage(GetHwnd(), CB_DELETESTRING, n, 0); if ( !IsFrozen() ) @@ -276,10 +269,8 @@ void wxChoice::Delete(unsigned int n) InvalidateBestSize(); } -void wxChoice::Clear() +void wxChoice::DoClear() { - Free(); - SendMessage(GetHwnd(), CB_RESETCONTENT, 0, 0); if ( !IsFrozen() ) @@ -288,18 +279,6 @@ void wxChoice::Clear() InvalidateBestSize(); } -void wxChoice::Free() -{ - if ( HasClientObjectData() ) - { - unsigned int count = GetCount(); - for ( unsigned int n = 0; n < count; n++ ) - { - delete GetClientObject(n); - } - } -} - // ---------------------------------------------------------------------------- // selection // ---------------------------------------------------------------------------- @@ -456,16 +435,6 @@ void* wxChoice::DoGetItemClientData(unsigned int n) const return (void *)rc; } -void wxChoice::DoSetItemClientObject(unsigned int n, wxClientData* clientData) -{ - DoSetItemClientData(n, clientData); -} - -wxClientData* wxChoice::DoGetItemClientObject(unsigned int n) const -{ - return (wxClientData *)DoGetItemClientData(n); -} - // ---------------------------------------------------------------------------- // wxMSW specific helpers // ---------------------------------------------------------------------------- diff --git a/src/msw/control.cpp b/src/msw/control.cpp index 030a55f704..2b4eb28cd8 100644 --- a/src/msw/control.cpp +++ b/src/msw/control.cpp @@ -35,6 +35,7 @@ #include "wx/dcclient.h" #include "wx/log.h" #include "wx/settings.h" + #include "wx/ctrlsub.h" #endif #if wxUSE_LISTCTRL @@ -433,6 +434,41 @@ WXHBRUSH wxControl::MSWControlColorDisabled(WXHDC pDC) GetHWND()); } +// ---------------------------------------------------------------------------- +// wxControlWithItems +// ---------------------------------------------------------------------------- + +void wxControlWithItems::MSWAllocStorage(const wxArrayStringsAdapter& items, + unsigned wm) +{ + const unsigned numItems = items.GetCount(); + unsigned long totalTextLength = numItems; // for trailing '\0' characters + for ( unsigned i = 0; i < numItems; ++i ) + { + totalTextLength += items[i].length(); + } + + if ( SendMessage(MSWGetItemsHWND(), wm, numItems, + (LPARAM)totalTextLength*sizeof(wxChar)) == LB_ERRSPACE ) + { + wxLogLastError(wxT("SendMessage(XX_INITSTORAGE)")); + } +} + +int wxControlWithItems::MSWInsertOrAppendItem(unsigned pos, + const wxString& item, + unsigned wm) +{ + LRESULT n = SendMessage(MSWGetItemsHWND(), wm, pos, (LPARAM)item.wx_str()); + if ( n == CB_ERR || n == CB_ERRSPACE ) + { + wxLogLastError(wxT("SendMessage(XX_ADD/INSERTSTRING)")); + return wxNOT_FOUND; + } + + return n; +} + // --------------------------------------------------------------------------- // global functions // --------------------------------------------------------------------------- diff --git a/src/msw/datectrl.cpp b/src/msw/datectrl.cpp index d6a4315352..58a3b435c2 100644 --- a/src/msw/datectrl.cpp +++ b/src/msw/datectrl.cpp @@ -263,6 +263,8 @@ void wxDatePickerCtrl::SetValue(const wxDateTime& dt) m_date.ResetTime(); } +#include + wxDateTime wxDatePickerCtrl::GetValue() const { #ifdef __WXDEBUG__ diff --git a/src/msw/dir.cpp b/src/msw/dir.cpp index ae9d7ddb9b..5525d72a61 100644 --- a/src/msw/dir.cpp +++ b/src/msw/dir.cpp @@ -201,7 +201,7 @@ bool wxDirData::Read(wxString *filename) if ( err != ERROR_FILE_NOT_FOUND && err != ERROR_NO_MORE_FILES ) { - wxLogSysError(err, wxString(_("Can not enumerate files in directory '%s'")), + wxLogSysError(err, _("Can not enumerate files in directory '%s'"), m_dirname.c_str()); } #endif // __WIN32__ diff --git a/src/msw/listbox.cpp b/src/msw/listbox.cpp index 698d03d610..3f85f6bbb7 100644 --- a/src/msw/listbox.cpp +++ b/src/msw/listbox.cpp @@ -256,93 +256,17 @@ void wxListBox::DoSetFirstItem(int N) SendMessage(GetHwnd(), LB_SETTOPINDEX, (WPARAM)N, (LPARAM)0); } -void wxListBox::Delete(unsigned int n) +void wxListBox::DoDeleteOneItem(unsigned int n) { wxCHECK_RET( IsValid(n), wxT("invalid index in wxListBox::Delete") ); - // for owner drawn objects, the data is used for storing wxOwnerDrawn - // pointers and we shouldn't touch it -#if !wxUSE_OWNER_DRAWN - if ( !(m_windowStyle & wxLB_OWNERDRAW) ) -#endif // !wxUSE_OWNER_DRAWN - if ( HasClientObjectData() ) - { - delete GetClientObject(n); - } - SendMessage(GetHwnd(), LB_DELETESTRING, n, 0); m_noItems--; SetHorizontalExtent(wxEmptyString); } -int wxListBox::DoAppend(const wxString& item) -{ - int index = ListBox_AddString(GetHwnd(), item.wx_str()); - m_noItems++; - -#if wxUSE_OWNER_DRAWN - if ( m_windowStyle & wxLB_OWNERDRAW ) { - wxOwnerDrawn *pNewItem = CreateLboxItem(index); // dummy argument - pNewItem->SetName(item); - m_aItems.Insert(pNewItem, index); - ListBox_SetItemData(GetHwnd(), index, pNewItem); - pNewItem->SetFont(GetFont()); - } -#endif // wxUSE_OWNER_DRAWN - - SetHorizontalExtent(item); - - return index; -} - -void wxListBox::DoSetItems(const wxArrayString& choices, void** clientData) -{ - // avoid flicker - but don't need to do this for a hidden listbox - bool hideAndShow = IsShown(); - if ( hideAndShow ) - { - ShowWindow(GetHwnd(), SW_HIDE); - } - - ListBox_ResetContent(GetHwnd()); - - m_noItems = choices.GetCount(); - unsigned int i; - for (i = 0; i < m_noItems; i++) - { - ListBox_AddString(GetHwnd(), choices[i].wx_str()); - if ( clientData ) - { - SetClientData(i, clientData[i]); - } - } - -#if wxUSE_OWNER_DRAWN - if ( m_windowStyle & wxLB_OWNERDRAW ) { - // first delete old items - WX_CLEAR_ARRAY(m_aItems); - - // then create new ones - for ( unsigned int ui = 0; ui < m_noItems; ui++ ) { - wxOwnerDrawn *pNewItem = CreateLboxItem(ui); - pNewItem->SetName(choices[ui]); - m_aItems.Add(pNewItem); - ListBox_SetItemData(GetHwnd(), ui, pNewItem); - } - } -#endif // wxUSE_OWNER_DRAWN - - SetHorizontalExtent(); - - if ( hideAndShow ) - { - // show the listbox back if we hid it - ShowWindow(GetHwnd(), SW_SHOW); - } -} - int wxListBox::FindString(const wxString& s, bool bCase) const { // back to base class search for not native search type @@ -356,7 +280,7 @@ int wxListBox::FindString(const wxString& s, bool bCase) const return pos; } -void wxListBox::Clear() +void wxListBox::DoClear() { Free(); @@ -373,15 +297,7 @@ void wxListBox::Free() { WX_CLEAR_ARRAY(m_aItems); } - else #endif // wxUSE_OWNER_DRAWN - if ( HasClientObjectData() ) - { - for ( unsigned int n = 0; n < m_noItems; n++ ) - { - delete GetClientObject(n); - } - } } void wxListBox::DoSetSelection(int N, bool select) @@ -407,11 +323,6 @@ bool wxListBox::IsSelected(int N) const return SendMessage(GetHwnd(), LB_GETSEL, N, 0) == 0 ? false : true; } -wxClientData* wxListBox::DoGetItemClientObject(unsigned int n) const -{ - return (wxClientData *)DoGetItemClientData(n); -} - void *wxListBox::DoGetItemClientData(unsigned int n) const { wxCHECK_MSG( IsValid(n), NULL, @@ -420,11 +331,6 @@ void *wxListBox::DoGetItemClientData(unsigned int n) const return (void *)SendMessage(GetHwnd(), LB_GETITEMDATA, n, 0); } -void wxListBox::DoSetItemClientObject(unsigned int n, wxClientData* clientData) -{ - DoSetItemClientData(n, clientData); -} - void wxListBox::DoSetItemClientData(unsigned int n, void *clientData) { wxCHECK_RET( IsValid(n), @@ -511,35 +417,53 @@ wxString wxListBox::GetString(unsigned int n) const return result; } -void -wxListBox::DoInsertItems(const wxArrayString& items, unsigned int pos) +int wxListBox::DoInsertItems(const wxArrayStringsAdapter & items, + unsigned int pos, + void **clientData, + wxClientDataType type) { - wxCHECK_RET( IsValidInsert(pos), - wxT("invalid index in wxListBox::InsertItems") ); + MSWAllocStorage(items, LB_INITSTORAGE); - unsigned int nItems = items.GetCount(); - for ( unsigned int i = 0; i < nItems; i++ ) + const bool append = pos == GetCount(); + + // we must use CB_ADDSTRING when appending as only it works correctly for + // the sorted controls + const unsigned msg = append ? LB_ADDSTRING : LB_INSERTSTRING; + + if ( append ) + pos = 0; + + int n = wxNOT_FOUND; + + const unsigned int numItems = items.GetCount(); + for ( unsigned int i = 0; i < numItems; i++ ) { - int idx = ListBox_InsertString(GetHwnd(), i + pos, items[i].wx_str()); + n = MSWInsertOrAppendItem(pos, items[i], msg); + if ( n == wxNOT_FOUND ) + return n; + + if ( !append ) + pos++; + + ++m_noItems; #if wxUSE_OWNER_DRAWN - if ( m_windowStyle & wxLB_OWNERDRAW ) + if ( HasFlag(wxLB_OWNERDRAW) ) { - wxOwnerDrawn *pNewItem = CreateLboxItem(idx); + wxOwnerDrawn *pNewItem = CreateLboxItem(n); pNewItem->SetName(items[i]); pNewItem->SetFont(GetFont()); - m_aItems.Insert(pNewItem, idx); + m_aItems.Insert(pNewItem, n); - ListBox_SetItemData(GetHwnd(), idx, pNewItem); + ListBox_SetItemData(GetHwnd(), n, pNewItem); } -#else - wxUnusedVar(idx); #endif // wxUSE_OWNER_DRAWN + AssignNewItemClientData(n, clientData, i, type); } - m_noItems += nItems; - SetHorizontalExtent(); + + return n; } int wxListBox::DoListHitTest(const wxPoint& point) const diff --git a/src/msw/wince/checklst.cpp b/src/msw/wince/checklst.cpp index 7f14ed6c63..d5f5274921 100644 --- a/src/msw/wince/checklst.cpp +++ b/src/msw/wince/checklst.cpp @@ -152,7 +152,7 @@ void wxCheckListBox::OnSize(wxSizeEvent& event) // misc overloaded methods // ----------------------- -void wxCheckListBox::Delete(unsigned int n) +void wxCheckListBox::DoDeleteOneItem(unsigned int n) { wxCHECK_RET( IsValid( n ), _T("invalid index in wxCheckListBox::Delete") ); @@ -258,44 +258,35 @@ void wxCheckListBox::SetString(unsigned int n, const wxString& s) delete [] buf; } -int wxCheckListBox::DoAppend(const wxString& item) -{ - int n = (int)GetCount(); - LVITEM newItem; - wxZeroMemory(newItem); - newItem.iItem = n; - int ret = ListView_InsertItem( (HWND)GetHWND(), & newItem ); - wxCHECK_MSG( n == ret , -1, _T("Item not added") ); - SetString( ret , item ); - m_itemsClientData.Insert(NULL, ret); - return ret; -} - void* wxCheckListBox::DoGetItemClientData(unsigned int n) const { return m_itemsClientData.Item(n); } -wxClientData* wxCheckListBox::DoGetItemClientObject(unsigned int n) const +int wxCheckListBox::DoInsertItems(const wxArrayStringsAdapter & items, + unsigned int pos, + void **clientData, wxClientDataType type) { - return (wxClientData *)DoGetItemClientData(n); -} + ListView_SetItemCount( GetHwnd(), GetCount() + count ); -void wxCheckListBox::DoInsertItems(const wxArrayString& items, unsigned int pos) -{ - wxCHECK_RET( IsValidInsert( pos ), - wxT("invalid index in wxListBox::InsertItems") ); + const unsigned int count = items.GetCount(); - for( unsigned int i = 0; i < items.GetCount(); i++ ) + int n = wxNOT_FOUND; + + for( unsigned int i = 0; i < count; i++ ) { LVITEM newItem; wxZeroMemory(newItem); - newItem.iItem = i+pos; - int ret = ListView_InsertItem( (HWND)GetHWND(), & newItem ); - wxASSERT_MSG( int(i+pos) == ret , _T("Item not added") ); - SetString( ret , items[i] ); - m_itemsClientData.Insert(NULL, ret); + newItem.iItem = pos + i; + n = ListView_InsertItem( (HWND)GetHWND(), & newItem ); + wxCHECK_MSG( n != -1, -1, _T("Item not added") ); + SetString( n, items[i] ); + m_itemsClientData.Insert(NULL, n); + + AssignNewItemClientData(n, clientData, i, type); } + + return n; } void wxCheckListBox::DoSetFirstItem(int n) @@ -314,23 +305,6 @@ void wxCheckListBox::DoSetItemClientData(unsigned int n, void* clientData) m_itemsClientData.Item(n) = clientData; } -void wxCheckListBox::DoSetItemClientObject(unsigned int n, wxClientData* clientData) -{ - DoSetItemClientData(n, clientData); -} - -void wxCheckListBox::DoSetItems(const wxArrayString& items, void **clientData) -{ - ListView_SetItemCount( GetHwnd(), GetCount() + items.GetCount() ); - - for( unsigned int i = 0; i < items.GetCount(); i++ ) - { - int pos = Append(items[i]); - if( pos >= 0 && clientData ) - DoSetItemClientData(pos, clientData[i]); - } -} - void wxCheckListBox::DoSetSelection(int n, bool select) { ListView_SetItemState(GetHwnd(), n, select ? LVIS_SELECTED : 0, LVIS_SELECTED); diff --git a/src/msw/wince/choicece.cpp b/src/msw/wince/choicece.cpp index 40f7dc8120..0966c4276a 100644 --- a/src/msw/wince/choicece.cpp +++ b/src/msw/wince/choicece.cpp @@ -325,70 +325,52 @@ bool wxChoice::MSWCommand(WXUINT param, WXWORD WXUNUSED(id)) wxChoice::~wxChoice() { - Free(); + Clear(); } // ---------------------------------------------------------------------------- // adding/deleting items to/from the list // ---------------------------------------------------------------------------- -int wxChoice::DoAppend(const wxString& item) +int wxChoice::DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, + wxClientDataType type) { - int n = (int)::SendMessage(GetBuddyHwnd(), LB_ADDSTRING, 0, (LPARAM)item.c_str()); + MSWAllocStorage(items, LB_INITSTORAGE); - if ( n == LB_ERR ) + const bool append = pos == GetCount(); + const unsigned msg = append ? LB_ADDSTRING : LB_INSERTSTRING; + if ( append ) + pos = 0; + + int n = wxNOT_FOUND; + + const unsigned int numItems = items.GetCount(); + for ( unsigned int i = 0; i < numItems; ++i ) { - wxLogLastError(wxT("SendMessage(LB_ADDSTRING)")); + n = MSWInsertOrAppendItem(pos, items[i], msg); + if ( !append ) + pos++; + + AssignNewItemClientData(n, clientData, i, type); } return n; } -int wxChoice::DoInsert(const wxString& item, unsigned int pos) -{ - wxCHECK_MSG(!(GetWindowStyle() & wxCB_SORT), -1, wxT("can't insert into choice")); - wxCHECK_MSG(IsValidInsert(pos), -1, wxT("invalid index")); - - int n = (int)::SendMessage(GetBuddyHwnd(), LB_INSERTSTRING, pos, (LPARAM)item.c_str()); - if ( n == LB_ERR ) - { - wxLogLastError(wxT("SendMessage(LB_INSERTSTRING)")); - } - - return n; -} - -void wxChoice::Delete(unsigned int n) +void wxChoice::DoDeleteOneItem(unsigned int n) { wxCHECK_RET( IsValid(n), wxT("invalid item index in wxChoice::Delete") ); - if ( HasClientObjectData() ) - { - delete GetClientObject(n); - } - ::SendMessage(GetBuddyHwnd(), LB_DELETESTRING, n, 0); } -void wxChoice::Clear() +void wxChoice::DoClear() { - Free(); - ::SendMessage(GetBuddyHwnd(), LB_RESETCONTENT, 0, 0); } -void wxChoice::Free() -{ - if ( HasClientObjectData() ) - { - unsigned int count = GetCount(); - for ( unsigned int n = 0; n < count; n++ ) - { - delete GetClientObject(n); - } - } -} - // ---------------------------------------------------------------------------- // selection // ---------------------------------------------------------------------------- @@ -502,16 +484,6 @@ void* wxChoice::DoGetItemClientData(unsigned int n) const return (void *)rc; } -void wxChoice::DoSetItemClientObject(unsigned int n, wxClientData* clientData) -{ - DoSetItemClientData(n, clientData); -} - -wxClientData* wxChoice::DoGetItemClientObject(unsigned int n) const -{ - return (wxClientData *)DoGetItemClientData(n); -} - // ---------------------------------------------------------------------------- // size calculations // ---------------------------------------------------------------------------- diff --git a/src/os2/checklst.cpp b/src/os2/checklst.cpp index 8491b44200..c32fc84787 100644 --- a/src/os2/checklst.cpp +++ b/src/os2/checklst.cpp @@ -284,10 +284,13 @@ void wxCheckListBox::Delete(unsigned int n) m_aItems.RemoveAt(n); } // end of wxCheckListBox::Delete -void wxCheckListBox::DoInsertItems(const wxArrayString& items, unsigned int pos) +int wxCheckListBox::DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, + wxClientDataType type) { // pos is validated in wxListBox - wxListBox::DoInsertItems( items, pos ); + int result = wxListBox::DoInsertItems( items, pos, clientData, type ); unsigned int n = items.GetCount(); for (unsigned int i = 0; i < n; i++) { @@ -301,7 +304,8 @@ void wxCheckListBox::DoInsertItems(const wxArrayString& items, unsigned int pos) MPFROMP(pNewItem) ); } -} // end of wxCheckListBox::InsertItems + return result; +} // end of wxCheckListBox::DoInsertItems bool wxCheckListBox::SetFont ( const wxFont& rFont ) { diff --git a/src/os2/choice.cpp b/src/os2/choice.cpp index 59e63f9275..e91486c6d7 100644 --- a/src/os2/choice.cpp +++ b/src/os2/choice.cpp @@ -114,69 +114,62 @@ bool wxChoice::Create( wxChoice::~wxChoice() { - Free(); + Clear(); } // ---------------------------------------------------------------------------- // adding/deleting items to/from the list // ---------------------------------------------------------------------------- -int wxChoice::DoAppend( - const wxString& rsItem -) +int wxChoice::DoInsertItems(const wxArrayStringsAdapter& items + , unsigned int pos + , void **clientData + , wxClientDataType type + ) { - int nIndex; + int nIndex = wxNOT_FOUND; LONG nIndexType = 0; - if (m_windowStyle & wxCB_SORT) + bool incrementPos = false; + if ( IsSorted() ) nIndexType = LIT_SORTASCENDING; - else + else if (pos == GetCount()) nIndexType = LIT_END; - nIndex = (int)::WinSendMsg( GetHwnd() - ,LM_INSERTITEM - ,(MPARAM)nIndexType - ,(MPARAM)rsItem.wx_str() - ); - return nIndex; -} // end of wxChoice::DoAppend - -int wxChoice::DoInsert( const wxString& rsItem, unsigned int pos ) -{ - wxCHECK_MSG(!(GetWindowStyle() & wxCB_SORT), -1, wxT("can't insert into sorted list")); - wxCHECK_MSG(IsValidInsert(pos), -1, wxT("invalid index")); - - if (pos == GetCount()) - return DoAppend(rsItem); - - int nIndex; - LONG nIndexType = 0; - - if (m_windowStyle & wxCB_SORT) - nIndexType = LIT_SORTASCENDING; else + { nIndexType = pos; - nIndex = (int)::WinSendMsg( GetHwnd() - ,LM_INSERTITEM - ,(MPARAM)nIndexType - ,(MPARAM)rsItem.wx_str() - ); - return nIndex; -} // end of wxChoice::DoInsert + incrementPos = true; + } -void wxChoice::Delete(unsigned int n) + const unsigned int count = items.GetCount(); + for( unsigned int i = 0; i < count; ++i ) + { + nIndex = (int)::WinSendMsg( GetHwnd() + ,LM_INSERTITEM + ,(MPARAM)nIndexType + ,(MPARAM)items[i].wx_str() + ); + if (nIndex < 0) + { + nIndex = wxNOT_FOUND; + break; + } + AssignNewItemClientData(nIndex, clientData, i, type); + + if (incrementPos) + ++nIndexType; + } + return nIndex; +} // end of wxChoice::DoInsertAppendItemsWithData + +void wxChoice::DoDeleteOneItem(unsigned int n) { wxCHECK_RET( IsValid(n), wxT("invalid item index in wxChoice::Delete") ); - if ( HasClientObjectData() ) - { - delete GetClientObject(n); - } - ::WinSendMsg(GetHwnd(), LM_DELETEITEM, (MPARAM)n, (MPARAM)0); } // end of wxChoice::Delete -void wxChoice::Clear() +void wxChoice::DoClear() { - Free(); ::WinSendMsg(GetHwnd(), LM_DELETEALL, (MPARAM)0, (MPARAM)0); } // end of wxChoice::Clear @@ -277,16 +270,6 @@ void* wxChoice::DoGetItemClientData(unsigned int n) const return((void*)rc); } // end of wxChoice::DoGetItemClientData -void wxChoice::DoSetItemClientObject(unsigned int n, wxClientData* pClientData) -{ - DoSetItemClientData(n, pClientData); -} // end of wxChoice::DoSetItemClientObject - -wxClientData* wxChoice::DoGetItemClientObject(unsigned int n) const -{ - return (wxClientData *)DoGetItemClientData(n); -} // end of wxChoice::DoGetItemClientObject - // ---------------------------------------------------------------------------- // wxOS2 specific helpers // ---------------------------------------------------------------------------- @@ -399,17 +382,4 @@ bool wxChoice::OS2Command( return true; } // end of wxChoice::OS2Command -void wxChoice::Free() -{ - if (HasClientObjectData()) - { - const unsigned int nCount = GetCount(); - - for (unsigned int n = 0; n < nCount; n++) - { - delete GetClientObject(n); - } - } -} // end of wxChoice::Free - #endif // wxUSE_CHOICE diff --git a/src/os2/listbox.cpp b/src/os2/listbox.cpp index aaca7eabcb..3755c4109e 100644 --- a/src/os2/listbox.cpp +++ b/src/os2/listbox.cpp @@ -252,7 +252,7 @@ void wxListBox::DoSetFirstItem(int N) ::WinSendMsg(GetHwnd(), LM_SETTOPINDEX, MPFROMLONG(N), (MPARAM)0); } // end of wxListBox::DoSetFirstItem -void wxListBox::Delete(unsigned int n) +void wxListBox::DoDeleteOneItem(unsigned int n) { wxCHECK_RET( IsValid(n), wxT("invalid index in wxListBox::Delete") ); @@ -260,102 +260,67 @@ void wxListBox::Delete(unsigned int n) #if wxUSE_OWNER_DRAWN delete m_aItems[n]; m_aItems.RemoveAt(n); -#else // !wxUSE_OWNER_DRAWN - if (HasClientObjectData()) - { - delete GetClientObject(n); - } #endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN ::WinSendMsg(GetHwnd(), LM_DELETEITEM, (MPARAM)n, (MPARAM)0); m_nNumItems--; } // end of wxListBox::DoSetFirstItem -int wxListBox::DoAppend(const wxString& rsItem) +int wxListBox::DoInsertItems(const wxArrayStringsAdapter & items, + unsigned int pos, + void **clientData, + wxClientDataType type) { long lIndex = 0; LONG lIndexType = 0; + bool incrementPos = false; - if (m_windowStyle & wxLB_SORT) + if (IsSorted()) lIndexType = LIT_SORTASCENDING; - else + else if (pos == GetCount()) lIndexType = LIT_END; + else + { + lIndexType = (LONG)pos; + incrementPos = true; + } - lIndex = (long)::WinSendMsg(GetHwnd(), LM_INSERTITEM, (MPARAM)lIndexType, (MPARAM)rsItem.wx_str()); - m_nNumItems++; + int n = wxNOT_FOUND; + + unsigned int count = items.GetCount(); + for (unsigned int i = 0; i < count; i++) + { + n = (int)::WinSendMsg(GetHwnd(), LM_INSERTITEM, (MPARAM)lIndexType, (MPARAM)items[i].wx_str()); + if (n < 0) + { + wxLogLastError(_T("WinSendMsg(LM_INSERTITEM)")); + n = wxNOT_FOUND; + break; + } + ++m_nNumItems; #if wxUSE_OWNER_DRAWN - if (m_windowStyle & wxLB_OWNERDRAW) - { - wxOwnerDrawn* pNewItem = CreateItem(lIndex); // dummy argument - wxScreenDC vDc; - - - pNewItem->SetName(rsItem); - m_aItems.Insert(pNewItem, lIndex); - ::WinSendMsg(GetHwnd(), LM_SETITEMHANDLE, (MPARAM)lIndex, MPFROMP(pNewItem)); - pNewItem->SetFont(GetFont()); - } + if (HasFlag(wxLB_OWNERDRAW)) + { + wxOwnerDrawn* pNewItem = CreateItem(n); // dummy argument + wxScreenDC vDc; // FIXME: is it really needed here? + + pNewItem->SetName(items[i]); + m_aItems.Insert(pNewItem, n); + ::WinSendMsg(GetHwnd(), LM_SETITEMHANDLE, (MPARAM)n, MPFROMP(pNewItem)); + pNewItem->SetFont(GetFont()); + } #endif - return (int)lIndex; -} // end of wxListBox::DoAppend + AssignNewItemClientData(n, clientData, i, type); -void wxListBox::DoSetItems( const wxArrayString& raChoices, - void** ppClientData ) -{ - BOOL bHideAndShow = IsShown(); - LONG lIndexType = 0; - - if (bHideAndShow) - { - ::WinShowWindow(GetHwnd(), FALSE); - } - ::WinSendMsg(GetHwnd(), LM_DELETEALL, (MPARAM)0, (MPARAM)0); - m_nNumItems = raChoices.GetCount(); - for (unsigned int i = 0; i < m_nNumItems; i++) - { - if (m_windowStyle & wxLB_SORT) - lIndexType = LIT_SORTASCENDING; - else - lIndexType = LIT_END; - ::WinSendMsg(GetHwnd(), LM_INSERTITEM, (MPARAM)lIndexType, (MPARAM)raChoices[i].wx_str()); - - if (ppClientData) - { -#if wxUSE_OWNER_DRAWN - wxASSERT_MSG(ppClientData[i] == NULL, - wxT("Can't use client data with owner-drawn listboxes")); -#else // !wxUSE_OWNER_DRAWN - ::WinSendMsg(WinUtil_GetHwnd(), LM_SETITEMHANDLE, MPFROMLONG(lCount), MPFROMP(ppClientData[i])); -#endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN - } + if (incrementPos) + ++lIndexType; } -#if wxUSE_OWNER_DRAWN - if ( m_windowStyle & wxLB_OWNERDRAW ) - { - // - // First delete old items - // - WX_CLEAR_ARRAY(m_aItems); + return n; +} // end of wxListBox::DoInsertAppendItemsWithData - // - // Then create new ones - // - for (unsigned int ui = 0; ui < m_nNumItems; ui++) - { - wxOwnerDrawn* pNewItem = CreateItem(ui); - - pNewItem->SetName(raChoices[ui]); - m_aItems.Add(pNewItem); - ::WinSendMsg(GetHwnd(), LM_SETITEMHANDLE, MPFROMLONG(ui), MPFROMP(pNewItem)); - } - } -#endif // wxUSE_OWNER_DRAWN - ::WinShowWindow(GetHwnd(), TRUE); -} // end of wxListBox::DoSetItems - -void wxListBox::Clear() +void wxListBox::DoClear() { #if wxUSE_OWNER_DRAWN unsigned int lUiCount = m_aItems.Count(); @@ -366,15 +331,7 @@ void wxListBox::Clear() } m_aItems.Clear(); -#else // !wxUSE_OWNER_DRAWN - if (HasClientObjectData()) - { - for (unsigned int n = 0; n < m_lNumItems; n++) - { - delete GetClientObject(n); - } - } -#endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN +#endif // wxUSE_OWNER_DRAWN ::WinSendMsg(GetHwnd(), LM_DELETEALL, (MPARAM)0, (MPARAM)0); m_nNumItems = 0; @@ -414,11 +371,6 @@ bool wxListBox::IsSelected( int N ) const return (lItem == (LONG)N && lItem != LIT_NONE); } // end of wxListBox::IsSelected -wxClientData* wxListBox::DoGetItemClientObject(unsigned int n) const -{ - return (wxClientData *)DoGetItemClientData(n); -} - void* wxListBox::DoGetItemClientData(unsigned int n) const { wxCHECK_MSG( IsValid(n), NULL, @@ -427,11 +379,6 @@ void* wxListBox::DoGetItemClientData(unsigned int n) const return((void *)::WinSendMsg(GetHwnd(), LM_QUERYITEMHANDLE, MPFROMLONG(n), (MPARAM)0)); } // end of wxListBox::DoGetItemClientData -void wxListBox::DoSetItemClientObject(unsigned int n, wxClientData* pClientData) -{ - DoSetItemClientData(n, pClientData); -} // end of wxListBox::DoSetItemClientObject - void wxListBox::DoSetItemClientData(unsigned int n, void* pClientData) { wxCHECK_RET( IsValid(n), @@ -551,34 +498,6 @@ wxString wxListBox::GetString(unsigned int n) const return sResult; } // end of wxListBox::GetString -void wxListBox::DoInsertItems(const wxArrayString& asItems, unsigned int nPos) -{ - wxCHECK_RET( IsValidInsert(nPos), - wxT("invalid index in wxListBox::InsertItems") ); - - unsigned int nItems = asItems.GetCount(); - - for (unsigned int i = 0; i < nItems; i++) - { - int nIndex = (int)::WinSendMsg( GetHwnd(), - LM_INSERTITEM, - MPFROMLONG((LONG)(i + nPos)), - (MPARAM)asItems[i].wx_str() ); - - wxOwnerDrawn* pNewItem = CreateItem(nIndex); - - pNewItem->SetName(asItems[i]); - pNewItem->SetFont(GetFont()); - m_aItems.Insert(pNewItem, nIndex); - ::WinSendMsg( GetHwnd() - ,LM_SETITEMHANDLE - ,(MPARAM)((LONG)nIndex) - ,MPFROMP(pNewItem) - ); - m_nNumItems += nItems; - } -} // end of wxListBox::DoInsertItems - void wxListBox::SetString(unsigned int n, const wxString& rsString) { wxCHECK_RET( IsValid(n), diff --git a/src/palmos/choice.cpp b/src/palmos/choice.cpp index d9ba679dd6..c6c100fc0a 100644 --- a/src/palmos/choice.cpp +++ b/src/palmos/choice.cpp @@ -150,21 +150,19 @@ wxChoice::~wxChoice() // adding/deleting items to/from the list // ---------------------------------------------------------------------------- -int wxChoice::DoAppend(const wxString& item) +int wxChoice::DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, + wxClientDataType type) { return 0; } -int wxChoice::DoInsert(const wxString& item, unsigned int pos) -{ - return 0; -} - -void wxChoice::Delete(unsigned int n) +void wxChoice::DoDeleteOneItem(unsigned int n) { } -void wxChoice::Clear() +void wxChoice::DoClear() { } @@ -216,15 +214,6 @@ void* wxChoice::DoGetItemClientData(unsigned int n) const return (void *)NULL; } -void wxChoice::DoSetItemClientObject(unsigned int n, wxClientData* clientData ) -{ -} - -wxClientData* wxChoice::DoGetItemClientObject(unsigned int n) const -{ - return (wxClientData *)DoGetItemClientData(n); -} - // ---------------------------------------------------------------------------- // wxMSW specific helpers // ---------------------------------------------------------------------------- diff --git a/src/palmos/listbox.cpp b/src/palmos/listbox.cpp index eb61926a48..de22719ab6 100644 --- a/src/palmos/listbox.cpp +++ b/src/palmos/listbox.cpp @@ -177,20 +177,11 @@ void wxListBox::DoSetFirstItem(int N) { } -void wxListBox::Delete(unsigned int n) +void wxListBox::DoDeleteOneItem(unsigned int n) { } -int wxListBox::DoAppend(const wxString& item) -{ - return 0; -} - -void wxListBox::DoSetItems(const wxArrayString& choices, void** clientData) -{ -} - -void wxListBox::Clear() +void wxListBox::DoClear() { } @@ -207,20 +198,11 @@ bool wxListBox::IsSelected(int N) const return false; } -wxClientData* wxListBox::DoGetItemClientObject(unsigned int n) const -{ - return (wxClientData *)DoGetItemClientData(n); -} - void *wxListBox::DoGetItemClientData(unsigned int n) const { return (void *)NULL; } -void wxListBox::DoSetItemClientObject(unsigned int n, wxClientData* clientData) -{ -} - void wxListBox::DoSetItemClientData(unsigned int n, void *clientData) { } @@ -243,11 +225,13 @@ wxString wxListBox::GetString(unsigned int n) const return wxEmptyString; } -void -wxListBox::DoInsertItems(const wxArrayString& items, unsigned int pos) +int wxListBox::DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, + wxClientDataType type) { + return 0; } - void wxListBox::SetString(unsigned int n, const wxString& s) { } diff --git a/src/univ/checklst.cpp b/src/univ/checklst.cpp index 95e1af791d..3a85960386 100644 --- a/src/univ/checklst.cpp +++ b/src/univ/checklst.cpp @@ -146,46 +146,16 @@ void wxCheckListBox::Check(unsigned int item, bool check) // methods forwarded to wxListBox // ---------------------------------------------------------------------------- -void wxCheckListBox::Delete(unsigned int n) +void wxCheckListBox::DoDeleteOneItem(unsigned int n) { - wxCHECK_RET( IsValid(n), _T("invalid index in wxListBox::Delete") ); - - wxListBox::Delete(n); + wxListBox::DoDeleteOneItem(n); m_checks.RemoveAt(n); } -int wxCheckListBox::DoAppend(const wxString& item) +void wxCheckListBox::OnItemInserted(unsigned int pos) { - int pos = wxListBox::DoAppend(item); - - // the item is initially unchecked m_checks.Insert(false, pos); - - return pos; -} - -void wxCheckListBox::DoInsertItems(const wxArrayString& items, unsigned int pos) -{ - wxListBox::DoInsertItems(items, pos); - - unsigned int count = items.GetCount(); - for ( unsigned int n = 0; n < count; n++ ) - { - m_checks.Insert(false, pos + n); - } -} - -void wxCheckListBox::DoSetItems(const wxArrayString& items, void **clientData) -{ - // call it first as it does DoClear() - wxListBox::DoSetItems(items, clientData); - - unsigned int count = items.GetCount(); - for ( unsigned int n = 0; n < count; n++ ) - { - m_checks.Add(false); - } } void wxCheckListBox::DoClear() diff --git a/src/univ/combobox.cpp b/src/univ/combobox.cpp index f347cfe1b9..1ca6ffd795 100644 --- a/src/univ/combobox.cpp +++ b/src/univ/combobox.cpp @@ -344,13 +344,13 @@ void wxComboBox::SetEditable(bool editable) // wxComboBox methods forwarded to wxListBox // ---------------------------------------------------------------------------- -void wxComboBox::Clear() +void wxComboBox::DoClear() { GetLBox()->Clear(); if ( GetTextCtrl() ) GetTextCtrl()->SetValue(wxEmptyString); } -void wxComboBox::Delete(unsigned int n) +void wxComboBox::DoDeleteOneItem(unsigned int n) { wxCHECK_RET( IsValid(n), _T("invalid index in wxComboBox::Delete") ); @@ -410,21 +410,11 @@ int wxComboBox::GetSelection() const #endif } -int wxComboBox::DoAppend(const wxString& item) +int wxComboBox::DoInsertItems(const wxArrayStringsAdapter & items, + unsigned int pos, + void **clientData, wxClientDataType type) { - return GetLBox()->Append(item); -} - -int wxComboBox::DoInsert(const wxString& item, unsigned int pos) -{ - wxCHECK_MSG(!(GetWindowStyle() & wxCB_SORT), -1, wxT("can't insert into sorted list")); - wxCHECK_MSG(IsValidInsert(pos), -1, wxT("invalid index")); - - if (pos == GetCount()) - return DoAppend(item); - - GetLBox()->Insert(item, pos); - return pos; + return GetLBox()->DoInsertItems(items, pos, clientData, type); } void wxComboBox::DoSetItemClientData(unsigned int n, void* clientData) @@ -437,16 +427,6 @@ void *wxComboBox::DoGetItemClientData(unsigned int n) const return GetLBox()->GetClientData(n); } -void wxComboBox::DoSetItemClientObject(unsigned int n, wxClientData* clientData) -{ - GetLBox()->SetClientObject(n, clientData); -} - -wxClientData* wxComboBox::DoGetItemClientObject(unsigned int n) const -{ - return GetLBox()->GetClientObject(n); -} - bool wxComboBox::IsEditable() const { return GetTextCtrl() != NULL && (!HasFlag(wxCB_READONLY) || GetTextCtrl()->IsEditable() ); diff --git a/src/univ/listbox.cpp b/src/univ/listbox.cpp index 7aaa9953f3..7c1ca6dcca 100644 --- a/src/univ/listbox.cpp +++ b/src/univ/listbox.cpp @@ -192,7 +192,7 @@ bool wxListBox::Create(wxWindow *parent, validator, name) ) return false; - m_strings = new wxArrayString; + m_strings = IsSorted() ? new wxArrayString : new wxSortedArrayString; Set(n, choices); @@ -217,67 +217,25 @@ wxListBox::~wxListBox() // adding/inserting strings // ---------------------------------------------------------------------------- -int wxCMPFUNC_CONV wxListBoxSortNoCase(wxString* s1, wxString* s2) +int wxListBox::DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, + wxClientDataType type) { - return s1->CmpNoCase(*s2); -} + int idx = wxNOT_FOUND; -int wxListBox::DoAppendOnly(const wxString& item) -{ - unsigned int index; - - if ( IsSorted() ) + const unsigned int numItems = items.GetCount(); + for ( unsigned int i = 0; i < numItems; ++i ) { - m_strings->Add(item); - m_strings->Sort(wxListBoxSortNoCase); - index = m_strings->Index(item); - } - else - { - index = m_strings->GetCount(); - m_strings->Add(item); - } + const wxString& item = items[i]; + idx = IsSorted() ? m_strings->Add(item) + : (m_strings->Insert(item, pos), pos++); - return index; -} + m_itemsClientData.Insert(NULL, idx); + AssignNewItemClientData(idx, clientData, i, type); -int wxListBox::DoAppend(const wxString& item) -{ - size_t index = DoAppendOnly( item ); - - m_itemsClientData.Insert(NULL, index); - - m_updateScrollbarY = true; - - if ( HasHorzScrollbar() ) - { - // has the max width increased? - wxCoord width; - GetTextExtent(item, &width, NULL); - if ( width > m_maxWidth ) - { - m_maxWidth = width; - m_maxWidthItem = index; - m_updateScrollbarX = true; - } - } - - RefreshFromItemToEnd(index); - - return index; -} - -void wxListBox::DoInsertItems(const wxArrayString& items, unsigned int pos) -{ - // the position of the item being added to a sorted listbox can't be - // specified - wxCHECK_RET( !IsSorted(), _T("can't insert items into sorted listbox") ); - - unsigned int count = items.GetCount(); - for ( unsigned int n = 0; n < count; n++ ) - { - m_strings->Insert(items[n], pos + n); - m_itemsClientData.Insert(NULL, pos + n); + // call the wxCheckListBox hook + OnItemInserted(idx); } // the number of items has changed so we might have to show the scrollbar @@ -291,29 +249,8 @@ void wxListBox::DoInsertItems(const wxArrayString& items, unsigned int pos) // note that we have to refresh all the items after the ones we inserted, // not just these items RefreshFromItemToEnd(pos); -} -void wxListBox::DoSetItems(const wxArrayString& items, void **clientData) -{ - DoClear(); - - unsigned int count = items.GetCount(); - if ( !count ) - return; - - m_strings->Alloc(count); - - m_itemsClientData.Alloc(count); - for ( unsigned int n = 0; n < count; n++ ) - { - unsigned int index = DoAppendOnly(items[n]); - - m_itemsClientData.Insert(clientData ? clientData[n] : NULL, index); - } - - m_updateScrollbarY = true; - - RefreshAll(); + return idx; } void wxListBox::SetString(unsigned int n, const wxString& s) @@ -355,24 +292,10 @@ void wxListBox::DoClear() { m_strings->Clear(); - if ( HasClientObjectData() ) - { - unsigned int count = m_itemsClientData.GetCount(); - for ( unsigned int n = 0; n < count; n++ ) - { - delete (wxClientData *) m_itemsClientData[n]; - } - } - m_itemsClientData.Clear(); m_selections.Clear(); m_current = -1; -} - -void wxListBox::Clear() -{ - DoClear(); m_updateScrollbarY = true; @@ -381,7 +304,7 @@ void wxListBox::Clear() RefreshAll(); } -void wxListBox::Delete(unsigned int n) +void wxListBox::DoDeleteOneItem(unsigned int n) { wxCHECK_RET( IsValid(n), _T("invalid index in wxListBox::Delete") ); @@ -392,11 +315,6 @@ void wxListBox::Delete(unsigned int n) m_strings->RemoveAt(n); - if ( HasClientObjectData() ) - { - delete (wxClientData *)m_itemsClientData[n]; - } - m_itemsClientData.RemoveAt(n); // when the item disappears we must not keep using its index @@ -458,16 +376,6 @@ void *wxListBox::DoGetItemClientData(unsigned int n) const return m_itemsClientData[n]; } -void wxListBox::DoSetItemClientObject(unsigned int n, wxClientData* clientData) -{ - m_itemsClientData[n] = clientData; -} - -wxClientData* wxListBox::DoGetItemClientObject(unsigned int n) const -{ - return (wxClientData *)m_itemsClientData[n]; -} - // ---------------------------------------------------------------------------- // selection // ----------------------------------------------------------------------------