]> git.saurik.com Git - wxWidgets.git/commitdiff
wxChoice and wxListBox GTK+ changes (wxChoice works, wxListBox still doesn't)
authorVadim Zeitlin <vadim@wxwidgets.org>
Fri, 22 Oct 1999 15:55:27 +0000 (15:55 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Fri, 22 Oct 1999 15:55:27 +0000 (15:55 +0000)
to support sorting, also compilation fixes in dataobj.cpp

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4140 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

20 files changed:
distrib/msw/tmake/filelist.txt
distrib/msw/tmake/g95.t
include/wx/gtk/listbox.h
include/wx/gtk1/listbox.h
include/wx/listbox.h
include/wx/msw/listbox.h
src/common/dobjcmn.cpp
src/common/lboxcmn.cpp [new file with mode: 0644]
src/gtk/choice.cpp
src/gtk/listbox.cpp
src/gtk1/choice.cpp
src/gtk1/listbox.cpp
src/msw/listbox.cpp
src/msw/makefile.b32
src/msw/makefile.bcc
src/msw/makefile.dos
src/msw/makefile.g95
src/msw/makefile.sc
src/msw/makefile.vc
src/msw/makefile.wat

index 77b2310bfb13c39844cc8ea1f286f5b70305df89..8dceb25bc8c6bfe231777e0b084b5eb3c6cf1c7a 100644 (file)
@@ -138,6 +138,7 @@ init.cpp    B
 intl.cpp       C       B
 ipcbase.cpp    C
 layout.cpp     C
+lboxcmn.cpp    C
 list.cpp       C       B
 log.cpp        C       B
 memory.cpp     C
index 0148b7e1131ad5df9f8ff71620ab1e1607249390..11705b2128ff3891fac7e4169a08518e4fea339b 100644 (file)
@@ -6,7 +6,6 @@
 #! Created: 14.07.99
 #! Version: $Id$
 #!#############################################################################
-
 #${
     #! include the code which parses filelist.txt file and initializes
     #! %wxCommon, %wxGeneric and %wxMSW hashes.
index 8b477fff3af28d79c1e9bd1699e1d355178e9e08..a13b937e0924473ed5b42c2586b2437ecca2206b 100644 (file)
 #pragma interface
 #endif
 
-#include "wx/defs.h"
-
-#if wxUSE_LISTBOX
-
-#include "wx/object.h"
 #include "wx/list.h"
-#include "wx/control.h"
-
-//-----------------------------------------------------------------------------
-// classes
-//-----------------------------------------------------------------------------
-
-class wxListBox;
-class wxArrayInt;
-
-//-----------------------------------------------------------------------------
-// global data
-//-----------------------------------------------------------------------------
-
-extern const char *wxListBoxNameStr;
 
 //-----------------------------------------------------------------------------
 // wxListBox
 //-----------------------------------------------------------------------------
 
-class wxListBox : public wxControl
+class wxListBox : public wxListBoxBase
 {
-DECLARE_DYNAMIC_CLASS(wxListBox)
-
 public:
+    // ctors and such
     wxListBox();
     wxListBox( wxWindow *parent, wxWindowID id,
             const wxPoint& pos = wxDefaultPosition,
@@ -69,49 +49,40 @@ public:
                 const wxValidator& validator = wxDefaultValidator,
                 const wxString& name = wxListBoxNameStr);
 
-    void Append( const wxString &item );
-    void Append( const wxString &item, void* clientData );
-    void Append( const wxString &item, wxClientData* clientData );
-
-    void InsertItems(int nItems, const wxString items[], int pos);
-
-    void SetClientData( int n, void* clientData );
-    void* GetClientData( int n );
-    void SetClientObject( int n, wxClientData* clientData );
-    wxClientData* GetClientObject( int n );
-
-    void SetClientObject( wxClientData *data )  { wxControl::SetClientObject( data ); }
-    wxClientData *GetClientObject() const       { return wxControl::GetClientObject(); }
-    void SetClientData( void *data )            { wxControl::SetClientData( data ); }
-    void *GetClientData() const                 { return wxControl::GetClientData(); }
-    
-    void Clear();
-    void Delete( int n );
-
-    void Deselect( int n );
-    int FindString( const wxString &item ) const;
-    int GetSelection() const;
-    int GetSelections( class wxArrayInt &) const;
-    wxString GetString( int n ) const;
-    wxString GetStringSelection() const;
-    int Number();
-    bool Selected( int n );
-    void Set( int n, const wxString *choices );
-    void SetFirstItem( int n );
-    void SetFirstItem( const wxString &item );
-    void SetSelection( int n, bool select = TRUE );
-    void SetString( int n, const wxString &string );
-    void SetStringSelection( const wxString &string, bool select = TRUE );
+    // implement base class pure virtuals
+    virtual void Clear();
+    virtual void Delete(int n);
+
+    virtual int GetCount() const;
+    virtual wxString GetString(int n) const;
+    virtual void SetString(int n, const wxString& s);
+    virtual int FindString(const wxString& s) const;
+
+    virtual bool IsSelected(int n) const;
+    virtual void SetSelection(int n, bool select = TRUE);
+    virtual int GetSelection() const;
+    virtual int GetSelections(wxArrayInt& aSelections) const;
+
+    virtual int DoAppend(const wxString& item);
+    virtual void DoInsertItems(const wxArrayString& items, int pos);
+    virtual void DoSetItems(const wxArrayString& items, void **clientData);
+
+    virtual void DoSetFirstItem(int n);
+
+    virtual void DoSetClientData(int n, void* clientData);
+    virtual void* DoGetClientData(int n) const;
+    virtual void DoSetClientObject(int n, wxClientData* clientData);
+    virtual wxClientData* DoGetClientObject(int n) const;
+
+    // implementation from now on
 
 #if wxUSE_DRAG_AND_DROP
     void SetDropTarget( wxDropTarget *dropTarget );
 #endif
 
-    // implementation
-
     void DisableEvents();
     void EnableEvents();
-    void AppendCommon( const wxString &item );
+    void AppendWithoutSorting( const wxString &item );
     int GetIndex( GtkWidget *item ) const;
     GtkWidget *GetConnectWidget();
     bool IsOwnGtkWindow( GdkWindow *window );
@@ -123,14 +94,18 @@ public:
 #endif // wxUSE_TOOLTIPS
 
     GtkList   *m_list;
-    wxList     m_clientDataList;
-    wxList     m_clientObjectList;
+    wxList     m_clientData;
 
 #if wxUSE_CHECKLISTBOX
     bool       m_hasCheckBoxes;
 #endif // wxUSE_CHECKLISTBOX
-};
 
-#endif
+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(wxListBox)
+};
 
 #endif // __GTKLISTBOXH__
index 8b477fff3af28d79c1e9bd1699e1d355178e9e08..a13b937e0924473ed5b42c2586b2437ecca2206b 100644 (file)
 #pragma interface
 #endif
 
-#include "wx/defs.h"
-
-#if wxUSE_LISTBOX
-
-#include "wx/object.h"
 #include "wx/list.h"
-#include "wx/control.h"
-
-//-----------------------------------------------------------------------------
-// classes
-//-----------------------------------------------------------------------------
-
-class wxListBox;
-class wxArrayInt;
-
-//-----------------------------------------------------------------------------
-// global data
-//-----------------------------------------------------------------------------
-
-extern const char *wxListBoxNameStr;
 
 //-----------------------------------------------------------------------------
 // wxListBox
 //-----------------------------------------------------------------------------
 
-class wxListBox : public wxControl
+class wxListBox : public wxListBoxBase
 {
-DECLARE_DYNAMIC_CLASS(wxListBox)
-
 public:
+    // ctors and such
     wxListBox();
     wxListBox( wxWindow *parent, wxWindowID id,
             const wxPoint& pos = wxDefaultPosition,
@@ -69,49 +49,40 @@ public:
                 const wxValidator& validator = wxDefaultValidator,
                 const wxString& name = wxListBoxNameStr);
 
-    void Append( const wxString &item );
-    void Append( const wxString &item, void* clientData );
-    void Append( const wxString &item, wxClientData* clientData );
-
-    void InsertItems(int nItems, const wxString items[], int pos);
-
-    void SetClientData( int n, void* clientData );
-    void* GetClientData( int n );
-    void SetClientObject( int n, wxClientData* clientData );
-    wxClientData* GetClientObject( int n );
-
-    void SetClientObject( wxClientData *data )  { wxControl::SetClientObject( data ); }
-    wxClientData *GetClientObject() const       { return wxControl::GetClientObject(); }
-    void SetClientData( void *data )            { wxControl::SetClientData( data ); }
-    void *GetClientData() const                 { return wxControl::GetClientData(); }
-    
-    void Clear();
-    void Delete( int n );
-
-    void Deselect( int n );
-    int FindString( const wxString &item ) const;
-    int GetSelection() const;
-    int GetSelections( class wxArrayInt &) const;
-    wxString GetString( int n ) const;
-    wxString GetStringSelection() const;
-    int Number();
-    bool Selected( int n );
-    void Set( int n, const wxString *choices );
-    void SetFirstItem( int n );
-    void SetFirstItem( const wxString &item );
-    void SetSelection( int n, bool select = TRUE );
-    void SetString( int n, const wxString &string );
-    void SetStringSelection( const wxString &string, bool select = TRUE );
+    // implement base class pure virtuals
+    virtual void Clear();
+    virtual void Delete(int n);
+
+    virtual int GetCount() const;
+    virtual wxString GetString(int n) const;
+    virtual void SetString(int n, const wxString& s);
+    virtual int FindString(const wxString& s) const;
+
+    virtual bool IsSelected(int n) const;
+    virtual void SetSelection(int n, bool select = TRUE);
+    virtual int GetSelection() const;
+    virtual int GetSelections(wxArrayInt& aSelections) const;
+
+    virtual int DoAppend(const wxString& item);
+    virtual void DoInsertItems(const wxArrayString& items, int pos);
+    virtual void DoSetItems(const wxArrayString& items, void **clientData);
+
+    virtual void DoSetFirstItem(int n);
+
+    virtual void DoSetClientData(int n, void* clientData);
+    virtual void* DoGetClientData(int n) const;
+    virtual void DoSetClientObject(int n, wxClientData* clientData);
+    virtual wxClientData* DoGetClientObject(int n) const;
+
+    // implementation from now on
 
 #if wxUSE_DRAG_AND_DROP
     void SetDropTarget( wxDropTarget *dropTarget );
 #endif
 
-    // implementation
-
     void DisableEvents();
     void EnableEvents();
-    void AppendCommon( const wxString &item );
+    void AppendWithoutSorting( const wxString &item );
     int GetIndex( GtkWidget *item ) const;
     GtkWidget *GetConnectWidget();
     bool IsOwnGtkWindow( GdkWindow *window );
@@ -123,14 +94,18 @@ public:
 #endif // wxUSE_TOOLTIPS
 
     GtkList   *m_list;
-    wxList     m_clientDataList;
-    wxList     m_clientObjectList;
+    wxList     m_clientData;
 
 #if wxUSE_CHECKLISTBOX
     bool       m_hasCheckBoxes;
 #endif // wxUSE_CHECKLISTBOX
-};
 
-#endif
+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(wxListBox)
+};
 
 #endif // __GTKLISTBOXH__
index c104dbeabda47b5c39190d2b72315f93131a8195..62aee761eb30959ad83d554356c86d3abef445ae 100644 (file)
+///////////////////////////////////////////////////////////////////////////////
+// Name:        wx/listbox.h
+// Purpose:     wxListBox class interface
+// Author:      Vadim Zeitlin
+// Modified by:
+// Created:     22.10.99
+// RCS-ID:      $Id$
+// Copyright:   (c) wxWindows team
+// Licence:    wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
 #ifndef _WX_LISTBOX_H_BASE_
 #define _WX_LISTBOX_H_BASE_
 
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+#ifdef __GNUG__
+    #pragma interface "listboxbase.h"
+#endif
+
+#include "wx/defs.h"
+
+#if wxUSE_LISTBOX
+
+#include "wx/control.h"         // base class
+
+// forward declarations are enough here
+class WXDLLEXPORT wxArrayInt;
+class WXDLLEXPORT wxArrayString;
+
+// ----------------------------------------------------------------------------
+// global data
+// ----------------------------------------------------------------------------
+
+WXDLLEXPORT_DATA(extern const wxChar*) wxListBoxNameStr;
+
+// ----------------------------------------------------------------------------
+// wxListBox interface is defined by the class wxListBoxBase
+// ----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxListBoxBase : public wxControl
+{
+public:
+    // ctor
+    wxListBoxBase() { m_clientDataItemsType = ClientData_None; }
+
+    // adding items
+    // ------------
+
+    void Append(const wxString& item)
+        { DoAppend(item); }
+    void Append(const wxString& item, void *clientData)
+        { int n = DoAppend(item); SetClientData(n, clientData); }
+    void Append(const wxString& item, wxClientData *clientData)
+        { int n = DoAppend(item); SetClientObject(n, clientData); }
+
+    void Insert(const wxString& item, int pos)
+        { DoInsert(item, pos); }
+    void Insert(const wxString& item, int pos, void *clientData)
+        { DoInsert(item, pos); SetClientData(pos, clientData); }
+    void Insert(const wxString& item, int pos, wxClientData *clientData)
+        { DoInsert(item, pos); SetClientObject(pos, clientData); }
+
+    void InsertItems(int nItems, const wxString *items, int pos);
+    void InsertItems(const wxArrayString& items, 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); }
+
+    // deleting items
+    // --------------
+
+    virtual void Clear() = 0;
+    virtual void Delete(int n) = 0;
+
+    // accessing strings
+    // -----------------
+
+    virtual int GetCount() const = 0;
+    virtual wxString GetString(int n) const = 0;
+    virtual void SetString(int n, const wxString& s) = 0;
+    virtual int FindString(const wxString& s) const = 0;
+
+    // selection
+    // ---------
+
+    virtual bool IsSelected(int n) const = 0;
+    virtual void SetSelection(int n, bool select = TRUE) = 0;
+    void Select(int n) { SetSelection(n, TRUE); }
+    void Deselect(int n) { SetSelection(n, FALSE); }
+
+    virtual int GetSelection() const = 0;
+    virtual int GetSelections(wxArrayInt& aSelections) const = 0;
+
+    bool SetStringSelection(const wxString& s, bool select = TRUE);
+    wxString GetStringSelection() const;
+
+    // misc
+    // ----
+
+    // client data stuff
+    void SetClientData( int n, void* clientData );
+    void* GetClientData( int n ) const;
+
+    void SetClientObject( int n, wxClientData* clientData );
+    wxClientData* GetClientObject( int n ) const;
+
+    // Set the specified item at the first visible item or scroll to max
+    // range.
+    void SetFirstItem(int n) { DoSetFirstItem(n); }
+    void SetFirstItem(const wxString& s);
+
+    // emulate selecting or deselecting (depending on event.GetExtraLong())
+    // the item event.GetInt() from the control
+    virtual void Command(wxCommandEvent &event);
+
+    // compatibility - these functions are deprecated, use the new ones
+    // instead
+    bool Selected(int n) const { return IsSelected(n); }
+    int Number() const { return GetCount(); }
+
+protected:
+    // NB: due to wxGTK implementation details, DoInsert() is implemented
+    //     using DoInsertItems() and not the other way round
+    void DoInsert(const wxString& item, int pos)
+        { InsertItems(1, &item, pos); }
+
+    // to be implemented in derived classes
+    virtual int DoAppend(const wxString& item) = 0;
+    virtual void DoInsertItems(const wxArrayString& items, int pos) = 0;
+    virtual void DoSetItems(const wxArrayString& items, void **clientData) = 0;
+
+    virtual void DoSetFirstItem(int n) = 0;
+
+    virtual void DoSetClientData(int n, void* clientData) = 0;
+    virtual void* DoGetClientData(int n) const = 0;
+    virtual void DoSetClientObject(int n, wxClientData* clientData) = 0;
+    virtual wxClientData* DoGetClientObject(int n) const = 0;
+
+    // the above pure virtuals hide these virtuals in wxWindowBase
+    virtual void DoSetClientData(void* clientData )
+        { wxWindowBase::DoSetClientData(clientData); };
+    virtual void* DoGetClientData() const
+        { return(wxWindowBase::DoGetClientData()); };
+    virtual void DoSetClientObject( wxClientData* clientData )
+        { wxWindowBase::DoSetClientObject(clientData); };
+    virtual wxClientData* DoGetClientObject() const
+        { return(wxWindowBase::DoGetClientObject()); };
+
+    // the type of the client data for the items
+    wxClientDataType m_clientDataItemsType;
+};
+
+// ----------------------------------------------------------------------------
+// include the platform-specific class declaration
+// ----------------------------------------------------------------------------
+
 #if defined(__WXMSW__)
-#include "wx/msw/listbox.h"
+    #include "wx/msw/listbox.h"
 #elif defined(__WXMOTIF__)
-#include "wx/motif/listbox.h"
+    #include "wx/motif/listbox.h"
 #elif defined(__WXGTK__)
-#include "wx/gtk/listbox.h"
+    #include "wx/gtk/listbox.h"
 #elif defined(__WXQT__)
-#include "wx/qt/listbox.h"
+    #include "wx/qt/listbox.h"
 #elif defined(__WXMAC__)
-#include "wx/mac/listbox.h"
+    #include "wx/mac/listbox.h"
 #elif defined(__WXPM__)
-#include "wx/os2/listbox.h"
+    #include "wx/os2/listbox.h"
 #elif defined(__WXSTUBS__)
-#include "wx/stubs/listbox.h"
+    #include "wx/stubs/listbox.h"
 #endif
 
+#endif // wxUSE_LISTBOX
+
 #endif
     // _WX_LISTBOX_H_BASE_
index 6d1d8c0ba6e89b2ccd69481b9e3f23b2a6d98989..93238f7792d8c66fc85a13c6d656c2d8655df999 100644 (file)
@@ -1,5 +1,5 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:        listbox.h
+// Name:        wx/msw/listbox.h
 // Purpose:     wxListBox class
 // Author:      Julian Smart
 // Modified by:
@@ -16,9 +16,9 @@
 #pragma interface "listbox.h"
 #endif
 
-#include "wx/control.h"
-
-WXDLLEXPORT_DATA(extern const wxChar*) wxListBoxNameStr;
+// ----------------------------------------------------------------------------
+// simple types
+// ----------------------------------------------------------------------------
 
 #if wxUSE_OWNER_DRAWN
   class WXDLLEXPORT wxOwnerDrawn;
@@ -27,20 +27,19 @@ WXDLLEXPORT_DATA(extern const wxChar*) wxListBoxNameStr;
   #include  <wx/dynarray.h>
 
   WX_DEFINE_EXPORTED_ARRAY(wxOwnerDrawn *, wxListBoxItemsArray);
-
-#endif
+#endif // wxUSE_OWNER_DRAWN
 
 // forward decl for GetSelections()
 class wxArrayInt;
 
-WXDLLEXPORT_DATA(extern const wxChar*) wxEmptyString;
+// ----------------------------------------------------------------------------
+// List box control
+// ----------------------------------------------------------------------------
 
-// List box item
-class WXDLLEXPORT wxListBox : public wxControl
+class WXDLLEXPORT wxListBox : public wxListBoxBase
 {
-    DECLARE_DYNAMIC_CLASS(wxListBox)
-
 public:
+    // ctors and such
     wxListBox();
     wxListBox(wxWindow *parent, wxWindowID id,
             const wxPoint& pos = wxDefaultPosition,
@@ -54,17 +53,41 @@ public:
     }
 
     bool Create(wxWindow *parent, wxWindowID id,
-            const wxPoint& pos = wxDefaultPosition,
-            const wxSize& size = wxDefaultSize,
-            int n = 0, const wxString choices[] = NULL,
-            long style = 0,
-            const wxValidator& validator = wxDefaultValidator,
-            const wxString& name = wxListBoxNameStr);
+                const wxPoint& pos = wxDefaultPosition,
+                const wxSize& size = wxDefaultSize,
+                int n = 0, const wxString choices[] = NULL,
+                long style = 0,
+                const wxValidator& validator = wxDefaultValidator,
+                const wxString& name = wxListBoxNameStr);
 
-    ~wxListBox();
+    virtual ~wxListBox();
 
-    bool MSWCommand(WXUINT param, WXWORD id);
+    // implement base class pure virtuals
+    virtual void Clear();
+    virtual void Delete(int n);
+
+    virtual int GetCount() const;
+    virtual wxString GetString(int n) const;
+    virtual void SetString(int n, const wxString& s);
+    virtual int FindString(const wxString& s) const;
+
+    virtual bool IsSelected(int n) const;
+    virtual void SetSelection(int n, bool select = TRUE);
+    virtual int GetSelection() const;
+    virtual int GetSelections(wxArrayInt& aSelections) const;
+
+    virtual int DoAppend(const wxString& item);
+    virtual void DoInsertItems(const wxArrayString& items, int pos);
+    virtual void DoSetItems(const wxArrayString& items, void **clientData);
 
+    virtual void DoSetFirstItem(int n);
+
+    virtual void DoSetClientData(int n, void* clientData);
+    virtual void* DoGetClientData(int n) const;
+    virtual void DoSetClientObject(int n, wxClientData* clientData);
+    virtual wxClientData* DoGetClientObject(int n) const;
+
+    // wxCheckListBox support
 #if wxUSE_OWNER_DRAWN
     bool MSWOnMeasure(WXMEASUREITEMSTRUCT *item);
     bool MSWOnDraw(WXDRAWITEMSTRUCT *item);
@@ -79,53 +102,24 @@ public:
     int GetItemIndex(wxOwnerDrawn *item) const { return m_aItems.Index(item); }
 #endif // wxUSE_OWNER_DRAWN
 
-    virtual void Append(const wxString& item);
-    virtual void Append(const wxString& item, void *clientData);
-    virtual void Set(int n, const wxString* choices, void **clientData = NULL);
-    virtual int FindString(const wxString& s) const ;
-    virtual void Clear();
-    virtual void SetSelection(int n, bool select = TRUE);
-
-    virtual void Deselect(int n);
-
-    // For single choice list item only
-    virtual int GetSelection() const ;
-    virtual void Delete(int n);
-    virtual void *GetClientData(int n) const ;
-    virtual void SetClientData(int n, void *clientData);
-    virtual void SetString(int n, const wxString& s);
-
-    // For single or multiple choice list item
-    virtual int GetSelections(wxArrayInt& aSelections) const;
-    virtual bool Selected(int n) const ;
-    virtual wxString GetString(int n) const ;
-
-    // Set the specified item at the first visible item
-    // or scroll to max range.
-    virtual void SetFirstItem(int n) ;
-    virtual void SetFirstItem(const wxString& s) ;
-
-    virtual void InsertItems(int nItems, const wxString items[], int pos);
-
-    virtual wxString GetStringSelection() const ;
-    virtual bool SetStringSelection(const wxString& s, bool flag = TRUE);
-    virtual int Number() const ;
-
-    void Command(wxCommandEvent& event);
-
-    // Windows-specific code to set the horizontal extent of
-    // the listbox, if necessary. If s is non-NULL, it's
-    // used to calculate the horizontal extent.
-    // Otherwise, all strings are used.
+    // Windows-specific code to set the horizontal extent of the listbox, if
+    // necessary. If s is non-NULL, it's used to calculate the horizontal
+    // extent. Otherwise, all strings are used.
     virtual void SetHorizontalExtent(const wxString& s = wxEmptyString);
 
+    // Windows callbacks
     virtual WXHBRUSH OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor,
-            WXUINT message, WXWPARAM wParam, WXLPARAM lParam);
+                                WXUINT message,
+                                WXWPARAM wParam, WXLPARAM lParam);
+
+    bool MSWCommand(WXUINT param, WXWORD id);
 
-    virtual long MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
     virtual void SetupColours();
 
 protected:
+    // do we have multiple selections?
+    bool HasMultipleSelection() const;
+
     int m_noItems;
     int m_selected;
 
@@ -135,6 +129,9 @@ protected:
     // control items
     wxListBoxItemsArray m_aItems;
 #endif
+
+private:
+    DECLARE_DYNAMIC_CLASS(wxListBox)
 };
 
 #endif
index de267315e2f88598b3fc49076743d3aa76916d52..6a40f0b1d9926938111dabdd65a2b180e8c71a4f 100644 (file)
@@ -97,11 +97,7 @@ wxDataObjectComposite::GetPreferredFormat(Direction WXUNUSED(dir)) const
 {
     wxSimpleDataObjectList::Node *node = m_dataObjects.Item( m_preferred );
 
-#ifdef __WXGTK__
-    wxCHECK_MSG( node, wxDataFormat(wxDF_INVALID), wxT("no preferred format") );
-#else
-    wxCHECK_MSG( node, wxDataFormat((unsigned short) wxDF_INVALID), wxT("no preferred format") );
-#endif
+    wxCHECK_MSG( node, wxFormatInvalid, wxT("no preferred format") );
 
     wxDataObjectSimple* dataObj = node->GetData();
 
diff --git a/src/common/lboxcmn.cpp b/src/common/lboxcmn.cpp
new file mode 100644 (file)
index 0000000..8525ef8
--- /dev/null
@@ -0,0 +1,151 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name:        common/lboxcmn.cpp
+// Purpose:     wxListBox class methods common to all platforms
+// Author:      Vadim Zeitlin
+// Modified by:
+// Created:     22.10.99
+// RCS-ID:      $Id$
+// Copyright:   (c) wxWindows team
+// Licence:    wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+#ifdef __GNUG__
+    #pragma implementation "listboxbase.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+    #include "wx/listbox.h"
+#endif
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// adding items
+// ----------------------------------------------------------------------------
+
+void wxListBoxBase::InsertItems(int nItems, const wxString *items, int pos)
+{
+    wxArrayString aItems;
+    for ( 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
+// ----------------------------------------------------------------------------
+
+wxString wxListBoxBase::GetStringSelection () const
+{
+    wxString s;
+    int sel = GetSelection();
+    if ( sel != -1 )
+        s = GetString(sel);
+
+    return s;
+}
+
+bool wxListBoxBase::SetStringSelection(const wxString& s, bool select)
+{
+    int sel = FindString(s);
+    wxCHECK_MSG( sel != -1, FALSE,
+                 wxT("invalid string in wxListBox::SetStringSelection") );
+
+    SetSelection(sel, select);
+
+    return TRUE;
+}
+
+// ----------------------------------------------------------------------------
+// client data
+// ----------------------------------------------------------------------------
+
+void wxListBoxBase::SetClientObject(int n, wxClientData *data)
+{
+    wxASSERT_MSG( m_clientDataItemsType != ClientData_Void,
+                  wxT("can't have both object and void client data") );
+
+    wxClientData *clientDataOld = DoGetClientObject(n);
+    if ( clientDataOld )
+        delete clientDataOld;
+
+    DoSetClientObject(n, data);
+    m_clientDataItemsType = ClientData_Object;
+}
+
+wxClientData *wxListBoxBase::GetClientObject(int n) const
+{
+    wxASSERT_MSG( m_clientDataItemsType == ClientData_Object,
+                  wxT("this window doesn't have object client data") );
+
+    return DoGetClientObject(n);
+}
+
+void wxListBoxBase::SetClientData(int n, void *data)
+{
+    wxASSERT_MSG( m_clientDataItemsType != ClientData_Object,
+                  wxT("can't have both object and void client data") );
+
+    DoSetClientData(n, data);
+    m_clientDataItemsType = ClientData_Void;
+}
+
+void *wxListBoxBase::GetClientData(int n) const
+{
+    wxASSERT_MSG( m_clientDataItemsType == ClientData_Void,
+                  wxT("this window doesn't have void client data") );
+
+    return DoGetClientData(n);
+}
+
+// ----------------------------------------------------------------------------
+// misc
+// ----------------------------------------------------------------------------
+
+void wxListBoxBase::SetFirstItem(const wxString& s)
+{
+    int n = FindString(s);
+
+    wxCHECK_RET( n != -1, wxT("invalid string in wxListBox::SetFirstItem") );
+
+    DoSetFirstItem(n);
+}
+
+void wxListBoxBase::Command(wxCommandEvent & event)
+{
+    SetSelection(event.m_commandInt, event.m_extraLong);
+    (void)ProcessEvent(event);
+}
+
index 44c8f53503bd68b31ebaa669f21fef8722c1793a..9e209bf95f216d270708019619bc326c96170075 100644 (file)
@@ -127,7 +127,7 @@ wxChoice::~wxChoice()
 
 int wxChoice::DoAppend( const wxString &item )
 {
-    wxCHECK_MSG( m_widget != NULL, -1, wxT("invalid choice") );
+    wxCHECK_MSG( m_widget != NULL, -1, wxT("invalid choice control") );
 
     GtkWidget *menu = gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) );
 
@@ -136,7 +136,7 @@ int wxChoice::DoAppend( const wxString &item )
 
 void wxChoice::DoSetClientData( int n, void* clientData )
 {
-    wxCHECK_RET( m_widget != NULL, wxT("invalid combobox") );
+    wxCHECK_RET( m_widget != NULL, wxT("invalid choice control") );
 
     wxNode *node = m_clientList.Nth( n );
     wxCHECK_RET( node, wxT("invalid index in wxChoice::DoSetClientData") );
@@ -146,7 +146,7 @@ void wxChoice::DoSetClientData( int n, void* clientData )
 
 void* wxChoice::DoGetClientData( int n ) const
 {
-    wxCHECK_MSG( m_widget != NULL, NULL, wxT("invalid combobox") );
+    wxCHECK_MSG( m_widget != NULL, NULL, wxT("invalid choice control") );
 
     wxNode *node = m_clientList.Nth( n );
     wxCHECK_MSG( node, NULL, wxT("invalid index in wxChoice::DoGetClientData") );
@@ -156,7 +156,7 @@ void* wxChoice::DoGetClientData( int n ) const
 
 void wxChoice::DoSetClientObject( int n, wxClientData* clientData )
 {
-    wxCHECK_RET( m_widget != NULL, wxT("invalid combobox") );
+    wxCHECK_RET( m_widget != NULL, wxT("invalid choice control") );
 
     wxNode *node = m_clientList.Nth( n );
     wxCHECK_RET( node, wxT("invalid index in wxChoice::DoSetClientObject") );
@@ -169,7 +169,7 @@ void wxChoice::DoSetClientObject( int n, wxClientData* clientData )
 
 wxClientData* wxChoice::DoGetClientObject( int n ) const
 {
-    wxCHECK_MSG( m_widget != NULL, (wxClientData*) NULL, wxT("invalid combobox") );
+    wxCHECK_MSG( m_widget != NULL, (wxClientData*) NULL, wxT("invalid choice control") );
 
     wxNode *node = m_clientList.Nth( n );
     wxCHECK_MSG( node, (wxClientData *)NULL,
@@ -186,17 +186,12 @@ void wxChoice::Clear()
     GtkWidget *menu = gtk_menu_new();
     gtk_option_menu_set_menu( GTK_OPTION_MENU(m_widget), menu );
 
-    if (m_clientDataItemsType == ClientData_Object)
-    {
-        wxNode *node = m_clientList.First();
-        while (node)
-        {
-            wxClientData *cd = (wxClientData*)node->Data();
-            if (cd) delete cd;
-            node = node->Next();
-        }
-    }
+    if ( m_clientDataItemsType == ClientData_Object )
+        m_clientList.DeleteContents(TRUE);
     m_clientList.Clear();
+
+    if ( m_strings )
+        m_strings->Clear();
 }
 
 void wxChoice::Delete( int WXUNUSED(n) )
index b4652068770b5345fb3f6dce4d1a1162bd505e23..c09dca49777236760bddb87e5af6cd93fcabdb16 100644 (file)
@@ -215,20 +215,20 @@ static void gtk_listitem_select_callback( GtkWidget *WXUNUSED(widget), wxListBox
     wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, listbox->GetId() );
 
     wxArrayInt aSelections;
-    int count = listbox->GetSelections(aSelections);
+    int n, count = listbox->GetSelections(aSelections);
     if ( count > 0 )
     {
-        event.m_commandInt = aSelections[0] ;
-        event.m_clientData = listbox->GetClientData( event.m_commandInt );
-        wxString str(listbox->GetString(event.m_commandInt));
-        if (!str.IsEmpty()) event.m_commandString = str;
+        n = aSelections[0];
+        event.m_clientData = listbox->m_clientData.Item(n);
+        event.m_commandString = listbox->GetString(n);
     }
     else
     {
-        event.m_commandInt = -1 ;
-        event.m_commandString.Empty();
+        n = -1;
     }
 
+    event.m_commandInt = n;
+
     event.SetEventObject( listbox );
 
     listbox->GetEventHandler()->ProcessEvent( event );
@@ -240,6 +240,10 @@ static void gtk_listitem_select_callback( GtkWidget *WXUNUSED(widget), wxListBox
 
 IMPLEMENT_DYNAMIC_CLASS(wxListBox,wxControl)
 
+// ----------------------------------------------------------------------------
+// construction
+// ----------------------------------------------------------------------------
+
 wxListBox::wxListBox()
 {
     m_list = (GtkList *) NULL;
@@ -251,7 +255,8 @@ wxListBox::wxListBox()
 bool wxListBox::Create( wxWindow *parent, wxWindowID id,
                         const wxPoint &pos, const wxSize &size,
                         int n, const wxString choices[],
-                        long style, const wxValidator& validator, const wxString &name )
+                        long style, const wxValidator& validator,
+                        const wxString &name )
 {
     m_needParent = TRUE;
     m_acceptsFocus = TRUE;
@@ -260,7 +265,7 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id,
         !CreateBase( parent, id, pos, size, style, validator, name ))
     {
         wxFAIL_MSG( wxT("wxListBox creation failed") );
-       return FALSE;
+        return FALSE;
     }
 
     m_widget = gtk_scrolled_window_new( (GtkAdjustment*) NULL, (GtkAdjustment*) NULL );
@@ -295,7 +300,7 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id,
     gtk_container_set_focus_vadjustment(
         GTK_CONTAINER(m_list),
         gtk_scrolled_window_get_vadjustment(
-           GTK_SCROLLED_WINDOW(m_widget)));
+            GTK_SCROLLED_WINDOW(m_widget)));
 
     gtk_widget_show( GTK_WIDGET(m_list) );
 
@@ -304,14 +309,21 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id,
     if (newSize.y == -1) newSize.y = 110;
     SetSize( newSize.x, newSize.y );
 
+    if ( style & wxLB_SORT )
+    {
+        // this will change DoAppend() behaviour
+        m_strings = new wxSortedArrayString;
+    }
+
     for (int i = 0; i < n; i++)
     {
-        m_clientDataList.Append( (wxObject*) NULL );
-        m_clientObjectList.Append( (wxObject*) NULL );
+        m_clientData.Append((wxObject *)NULL);
 
-        GtkWidget *list_item;
+        DoAppend(choices[i]);
 
+#if 0
         wxString str(choices[i]);
+
 #if wxUSE_CHECKLISTBOX
         if (m_hasCheckBoxes)
         {
@@ -319,7 +331,7 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id,
         }
 #endif // wxUSE_CHECKLISTBOX
 
-        list_item = gtk_list_item_new_with_label( str.mbc_str() );
+        GtkWidget *list_item = gtk_list_item_new_with_label( str.mbc_str() );
 
         gtk_container_add( GTK_CONTAINER(m_list), list_item );
 
@@ -353,6 +365,7 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id,
         ConnectWidget( list_item );
 
         gtk_widget_show( list_item );
+#endif // 0
     }
 
     m_parent->DoAddChild( this );
@@ -373,10 +386,15 @@ wxListBox::~wxListBox()
     Clear();
 }
 
-void wxListBox::InsertItems(int nItems, const wxString items[], int pos)
+void wxListBox::DoInsertItems(const wxArrayString& items, int pos)
 {
     wxCHECK_RET( m_list != NULL, wxT("invalid listbox") );
 
+    // code elsewhere supposes we have as many items in m_clientData as items
+    // in the listbox
+    wxASSERT_MSG( m_clientData.GetCount() == (size_t)GetCount(),
+                  wxT("bug in client data management") );
+
     GList *children = m_list->children;
     int length = g_list_length(children);
     wxCHECK_RET( pos <= length, wxT("invalid index in wxListBox::InsertItems") );
@@ -386,23 +404,37 @@ void wxListBox::InsertItems(int nItems, const wxString items[], int pos)
     //     all items after this position, then append these items and then
     //     reappend back the old ones.
 
-    // first detach the old items
-    int n; // loop var
+    // VZ: notice that InsertItems knows nothing about sorting, so calling it
+    //     from outside (and not from our own Append) is likely to break
+    //     everything
 
+    size_t nItems = items.GetCount();
+
+    size_t n; // loop var
+
+    // optimise for this trivial case
     if ( pos == length )
     {
         // no need to do anything complicated
         for ( n = 0; n < nItems; n++ )
         {
-            Append(items[n]);
+            AppendWithoutSorting(items[n]);
+
+            m_clientData.Append((wxObject *)NULL);
         }
 
+        wxASSERT_MSG( m_clientData.GetCount() == (size_t)GetCount(),
+                      wxT("bug in client data management") );
+
         return;
     }
 
+    // remove the old items
     wxArrayString deletedLabels;
     wxArrayPtrVoid deletedData;
-    wxArrayInt deletedChecks;   // only for check list boxes
+#if wxUSE_CHECKLISTBOX
+    wxArrayInt deletedChecks;
+#endif
 
     GList *child = g_list_nth( children, pos );
     for ( n = 0; child != NULL; n++, child = child->next )
@@ -415,31 +447,7 @@ void wxListBox::InsertItems(int nItems, const wxString items[], int pos)
         deletedLabels.Add(str);
 
         // save data
-        void *clientData = NULL;
-        wxNode *node = NULL;
-
-        if ( n < (int)m_clientObjectList.GetCount() )
-            node = m_clientObjectList.Nth( n );
-
-        if ( node )
-        {
-            clientData = node->GetData();
-            m_clientObjectList.DeleteNode( node );
-        }
-
-        if ( !clientData )
-        {
-            if ( n < (int)m_clientDataList.GetCount() )
-                node = m_clientDataList.Nth( n );
-
-            if ( node )
-            {
-                clientData = node->GetData();
-                node = m_clientDataList.Nth( n );
-            }
-        }
-
-        deletedData.Add(clientData);
+        deletedData.Add(m_clientData.Item(n));
 
 #if wxUSE_CHECKLISTBOX
         // save check state
@@ -450,21 +458,33 @@ void wxListBox::InsertItems(int nItems, const wxString items[], int pos)
 #endif // wxUSE_CHECKLISTBOX
     }
 
-    int nDeletedCount = n;
+    // don't delete contents, the data will be reappended soon
+    m_clientData.Clear();
+
+    size_t nDeletedCount = n;
 
     gtk_list_clear_items( m_list, pos, length );
 
     // now append the new items
     for ( n = 0; n < nItems; n++ )
     {
-        Append(items[n]);
+        AppendWithoutSorting(items[n]);
+
+        m_clientData.Append((wxObject *)NULL);
     }
 
     // and append the old items too
     pos += nItems;  // now the indices are shifter
     for ( n = 0; n < nDeletedCount; n++ )
     {
-        Append(deletedLabels[n], deletedData[n]);
+        AppendWithoutSorting(deletedLabels[n]);
+
+        m_clientData.Append((wxObject *)NULL);
+
+        if ( m_clientDataItemsType == ClientData_Object )
+            SetClientObject(n, (wxClientData *)deletedData[n]);
+        else if ( m_clientDataItemsType == ClientData_Void )
+            SetClientData(n, deletedData[n]);
 
 #if wxUSE_CHECKLISTBOX
         if ( m_hasCheckBoxes )
@@ -473,9 +493,35 @@ void wxListBox::InsertItems(int nItems, const wxString items[], int pos)
         }
 #endif // wxUSE_CHECKLISTBOX
     }
+
+    wxASSERT_MSG( m_clientData.GetCount() == (size_t)GetCount(),
+                  wxT("bug in client data management") );
+}
+
+int wxListBox::DoAppend( const wxString& item )
+{
+    int index;
+    if ( m_strings )
+    {
+        // need to determine the index
+        index = m_strings->Add(item);
+
+        InsertItems(1, &item, index);
+    }
+    else
+    {
+        // not sorted, just append
+        AppendWithoutSorting(item);
+
+        m_clientData.Append((wxObject *)NULL);
+
+        index = GetCount() - 1;
+    }
+
+    return index;
 }
 
-void wxListBox::AppendCommon( const wxString &item )
+void wxListBox::AppendWithoutSorting( const wxString &item )
 {
     wxCHECK_RET( m_list != NULL, wxT("invalid listbox") );
 
@@ -539,9 +585,9 @@ void wxListBox::AppendCommon( const wxString &item )
         }
 
 #if wxUSE_DRAG_AND_DROP
-#ifndef NEW_GTK_DND_CODE
+    #ifndef NEW_GTK_DND_CODE
         if (m_dropTarget) m_dropTarget->RegisterWidget( list_item );
-#endif
+    #endif
 #endif
 
 #if wxUSE_TOOLTIPS
@@ -550,69 +596,67 @@ void wxListBox::AppendCommon( const wxString &item )
     }
 }
 
-void wxListBox::Append( const wxString &item )
+void wxListBox::DoSetItems( const wxArrayString& items,
+                            void **clientData)
 {
-    m_clientDataList.Append( (wxObject*) NULL );
-    m_clientObjectList.Append( (wxObject*) NULL );
-
-    AppendCommon( item );
-}
+    Clear();
 
-void wxListBox::Append( const wxString &item, void *clientData )
-{
-    m_clientDataList.Append( (wxObject*) clientData );
-    m_clientObjectList.Append( (wxObject*) NULL );
+    DoInsertItems(items, 0);
 
-    AppendCommon( item );
+    if ( clientData )
+    {
+        size_t count = items.GetCount();
+        for ( size_t n = 0; n < count; n++ )
+        {
+            SetClientData(n, clientData[n]);
+        }
+    }
 }
 
-void wxListBox::Append( const wxString &item, wxClientData *clientData )
-{
-    m_clientObjectList.Append( (wxObject*) clientData );
-    m_clientDataList.Append( (wxObject*) NULL );
+// ----------------------------------------------------------------------------
+// client data
+// ----------------------------------------------------------------------------
 
-    AppendCommon( item );
-}
-
-void wxListBox::SetClientData( int n, void* clientData )
+void wxListBox::DoSetClientData( int n, void* clientData )
 {
-    wxCHECK_RET( m_widget != NULL, wxT("invalid combobox") );
+    wxCHECK_RET( m_widget != NULL, wxT("invalid listbox control") );
 
-    wxNode *node = m_clientDataList.Nth( n );
-    if (!node) return;
+    wxNode *node = m_clientData.Nth( n );
+    wxCHECK_RET( node, wxT("invalid index in wxListBox::DoSetClientData") );
 
     node->SetData( (wxObject*) clientData );
 }
 
-void* wxListBox::GetClientData( int n )
+void* wxListBox::DoGetClientData( int n ) const
 {
-    wxCHECK_MSG( m_widget != NULL, NULL, wxT("invalid combobox") );
+    wxCHECK_MSG( m_widget != NULL, NULL, wxT("invalid listbox control") );
 
-    wxNode *node = m_clientDataList.Nth( n );
-    if (!node) return NULL;
+    wxNode *node = m_clientData.Nth( n );
+    wxCHECK_MSG( node, NULL, wxT("invalid index in wxListBox::DoGetClientData") );
 
     return node->Data();
 }
 
-void wxListBox::SetClientObject( int n, wxClientData* clientData )
+void wxListBox::DoSetClientObject( int n, wxClientData* clientData )
 {
-    wxCHECK_RET( m_widget != NULL, wxT("invalid combobox") );
+    wxCHECK_RET( m_widget != NULL, wxT("invalid listbox control") );
 
-    wxNode *node = m_clientObjectList.Nth( n );
-    if (!node) return;
+    wxNode *node = m_clientData.Nth( n );
+    wxCHECK_RET( node, wxT("invalid index in wxListBox::DoSetClientObject") );
 
     wxClientData *cd = (wxClientData*) node->Data();
-    if (cd) delete cd;
+    delete cd;
 
     node->SetData( (wxObject*) clientData );
 }
 
-wxClientData* wxListBox::GetClientObject( int n )
+wxClientData* wxListBox::DoGetClientObject( int n ) const
 {
-    wxCHECK_MSG( m_widget != NULL, (wxClientData*)NULL, wxT("invalid combobox") );
+    wxCHECK_MSG( m_widget != NULL, (wxClientData*) NULL, wxT("invalid listbox control") );
 
-    wxNode *node = m_clientObjectList.Nth( n );
-    if (!node) return (wxClientData*) NULL;
+    wxNode *node = m_clientData.Nth( n );
+    wxCHECK_MSG( node, (wxClientData *)NULL,
+                 wxT("invalid index in wxListBox::DoGetClientObject") );
 
     return (wxClientData*) node->Data();
 }
@@ -623,16 +667,12 @@ void wxListBox::Clear()
 
     gtk_list_clear_items( m_list, 0, Number() );
 
-    wxNode *node = m_clientObjectList.First();
-    while (node)
-    {
-        wxClientData *cd = (wxClientData*)node->Data();
-        if (cd) delete cd;
-        node = node->Next();
-    }
-    m_clientObjectList.Clear();
+    if ( m_clientDataItemsType == ClientData_Object )
+        m_clientData.DeleteContents(TRUE);
+    m_clientData.Clear();
 
-    m_clientDataList.Clear();
+    if ( m_strings )
+        m_strings->Clear();
 }
 
 void wxListBox::Delete( int n )
@@ -647,30 +687,84 @@ void wxListBox::Delete( int n )
     gtk_list_remove_items( m_list, list );
     g_list_free( list );
 
-    wxNode *node = m_clientObjectList.Nth( n );
-    if (node)
+    wxNode *node = m_clientData.Nth( n );
+    if ( node )
     {
-        wxClientData *cd = (wxClientData*)node->Data();
-        if (cd) delete cd;
-        m_clientObjectList.DeleteNode( node );
+        if ( m_clientDataItemsType == ClientData_Object )
+        {
+            wxClientData *cd = (wxClientData*)node->Data();
+            delete cd;
+        }
+
+        m_clientData.DeleteNode( node );
     }
 
-    node = m_clientDataList.Nth( n );
-    if (node)
+    if ( m_strings )
+        m_strings->Remove(n);
+}
+
+// ----------------------------------------------------------------------------
+// string list access
+// ----------------------------------------------------------------------------
+
+void wxListBox::SetString( int n, const wxString &string )
+{
+    wxCHECK_RET( m_list != NULL, wxT("invalid listbox") );
+
+    GList *child = g_list_nth( m_list->children, n );
+    if (child)
+    {
+        GtkBin *bin = GTK_BIN( child->data );
+        GtkLabel *label = GTK_LABEL( bin->child );
+
+        wxString str;
+#if wxUSE_CHECKLISTBOX
+        if (m_hasCheckBoxes)
+            str += CHECKBOX_STRING;
+#endif // wxUSE_CHECKLISTBOX
+        str += string;
+
+        gtk_label_set( label, str.mbc_str() );
+    }
+    else
     {
-        m_clientDataList.DeleteNode( node );
+        wxFAIL_MSG(wxT("wrong listbox index"));
     }
 }
 
-void wxListBox::Deselect( int n )
+wxString wxListBox::GetString( int n ) const
 {
-    wxCHECK_RET( m_list != NULL, wxT("invalid listbox") );
+    wxCHECK_MSG( m_list != NULL, wxT(""), wxT("invalid listbox") );
 
-    DisableEvents();
+    GList *child = g_list_nth( m_list->children, n );
+    if (child)
+    {
+        GtkBin *bin = GTK_BIN( child->data );
+        GtkLabel *label = GTK_LABEL( bin->child );
 
-    gtk_list_unselect_item( m_list, n );
+        wxString str = wxString(GET_REAL_LABEL(label->label),*wxConvCurrent);
 
-    EnableEvents();
+        return str;
+    }
+
+    wxFAIL_MSG(wxT("wrong listbox index"));
+
+    return wxT("");
+}
+
+int wxListBox::GetCount() const
+{
+    wxCHECK_MSG( m_list != NULL, -1, wxT("invalid listbox") );
+
+    GList *child = m_list->children;
+    int count = 0;
+    while (child)
+    {
+        count++;
+        child = child->next;
+    }
+
+    return count;
 }
 
 int wxListBox::FindString( const wxString &item ) const
@@ -693,11 +787,15 @@ int wxListBox::FindString( const wxString &item ) const
         child = child->next;
     }
 
-  // it's not an error if the string is not found -> no wxCHECK
+    // it's not an error if the string is not found -> no wxCHECK
 
-  return -1;
+    return wxNOT_FOUND;
 }
 
+// ----------------------------------------------------------------------------
+// selection
+// ----------------------------------------------------------------------------
+
 int wxListBox::GetSelection() const
 {
     wxCHECK_MSG( m_list != NULL, -1, wxT("invalid listbox") );
@@ -743,56 +841,7 @@ int wxListBox::GetSelections( wxArrayInt& aSelections ) const
     return count;
 }
 
-wxString wxListBox::GetString( int n ) const
-{
-    wxCHECK_MSG( m_list != NULL, wxT(""), wxT("invalid listbox") );
-
-    GList *child = g_list_nth( m_list->children, n );
-    if (child)
-    {
-        GtkBin *bin = GTK_BIN( child->data );
-        GtkLabel *label = GTK_LABEL( bin->child );
-
-        wxString str = wxString(GET_REAL_LABEL(label->label),*wxConvCurrent);
-
-        return str;
-    }
-
-    wxFAIL_MSG(wxT("wrong listbox index"));
-
-    return wxT("");
-}
-
-wxString wxListBox::GetStringSelection() const
-{
-    wxCHECK_MSG( m_list != NULL, wxT(""), wxT("invalid listbox") );
-
-    GList *selection = m_list->selection;
-    if (selection)
-    {
-        GtkBin *bin = GTK_BIN( selection->data );
-        GtkLabel *label = GTK_LABEL( bin->child );
-
-        wxString str = wxString(GET_REAL_LABEL(label->label),*wxConvCurrent);
-
-        return str;
-    }
-
-    wxFAIL_MSG(wxT("no listbox selection available"));
-    return wxT("");
-}
-
-int wxListBox::Number()
-{
-    wxCHECK_MSG( m_list != NULL, -1, wxT("invalid listbox") );
-
-    GList *child = m_list->children;
-    int count = 0;
-    while (child) { count++; child = child->next; }
-    return count;
-}
-
-bool wxListBox::Selected( int n )
+bool wxListBox::IsSelected( int n ) const
 {
     wxCHECK_MSG( m_list != NULL, FALSE, wxT("invalid listbox") );
 
@@ -806,23 +855,10 @@ bool wxListBox::Selected( int n )
             child = child->next;
         }
     }
-    wxFAIL_MSG(wxT("wrong listbox index"));
-    return FALSE;
-}
-
-void wxListBox::Set( int WXUNUSED(n), const wxString *WXUNUSED(choices) )
-{
-    wxFAIL_MSG(wxT("wxListBox::Set not implemented"));
-}
 
-void wxListBox::SetFirstItem( int WXUNUSED(n) )
-{
-    wxFAIL_MSG(wxT("wxListBox::SetFirstItem not implemented"));
-}
+    wxFAIL_MSG(wxT("wrong listbox index"));
 
-void wxListBox::SetFirstItem( const wxString &WXUNUSED(item) )
-{
-    wxFAIL_MSG(wxT("wxListBox::SetFirstItem not implemented"));
+    return FALSE;
 }
 
 void wxListBox::SetSelection( int n, bool select )
@@ -839,37 +875,14 @@ void wxListBox::SetSelection( int n, bool select )
     EnableEvents();
 }
 
-void wxListBox::SetString( int n, const wxString &string )
+void wxListBox::DoSetFirstItem( int WXUNUSED(n) )
 {
-    wxCHECK_RET( m_list != NULL, wxT("invalid listbox") );
-
-    GList *child = g_list_nth( m_list->children, n );
-    if (child)
-    {
-        GtkBin *bin = GTK_BIN( child->data );
-        GtkLabel *label = GTK_LABEL( bin->child );
-
-        wxString str;
-#if wxUSE_CHECKLISTBOX
-        if (m_hasCheckBoxes)
-            str += CHECKBOX_STRING;
-#endif // wxUSE_CHECKLISTBOX
-        str += string;
-
-        gtk_label_set( label, str.mbc_str() );
-    }
-    else
-    {
-        wxFAIL_MSG(wxT("wrong listbox index"));
-    }
+    wxFAIL_MSG(wxT("wxListBox::SetFirstItem not implemented"));
 }
 
-void wxListBox::SetStringSelection( const wxString &string, bool select )
-{
-    wxCHECK_RET( m_list != NULL, wxT("invalid listbox") );
-
-    SetSelection( FindString(string), select );
-}
+// ----------------------------------------------------------------------------
+// helpers
+// ----------------------------------------------------------------------------
 
 int wxListBox::GetIndex( GtkWidget *item ) const
 {
@@ -1020,22 +1033,22 @@ void wxListBox::OnInternalIdle()
     if (GTK_WIDGET(m_list)->window && cursor.Ok())
     {
         /* I now set the cursor the anew in every OnInternalIdle call
-          as setting the cursor in a parent window also effects the
-          windows above so that checking for the current cursor is
-          not possible. */
-          
-       gdk_window_set_cursor( GTK_WIDGET(m_list)->window, cursor.GetCursor() );
+           as setting the cursor in a parent window also effects the
+           windows above so that checking for the current cursor is
+           not possible. */
+           
+        gdk_window_set_cursor( GTK_WIDGET(m_list)->window, cursor.GetCursor() );
 
         GList *child = m_list->children;
         while (child)
         {
             GtkBin *bin = GTK_BIN( child->data );
             GtkWidget *label = GTK_WIDGET( bin->child );
-           
-           if (!label->window)
-               break;
-           else
-               gdk_window_set_cursor( label->window, cursor.GetCursor() );
+            
+            if (!label->window)
+                break;
+            else
+                gdk_window_set_cursor( label->window, cursor.GetCursor() );
 
             child = child->next;
         }
index 44c8f53503bd68b31ebaa669f21fef8722c1793a..9e209bf95f216d270708019619bc326c96170075 100644 (file)
@@ -127,7 +127,7 @@ wxChoice::~wxChoice()
 
 int wxChoice::DoAppend( const wxString &item )
 {
-    wxCHECK_MSG( m_widget != NULL, -1, wxT("invalid choice") );
+    wxCHECK_MSG( m_widget != NULL, -1, wxT("invalid choice control") );
 
     GtkWidget *menu = gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) );
 
@@ -136,7 +136,7 @@ int wxChoice::DoAppend( const wxString &item )
 
 void wxChoice::DoSetClientData( int n, void* clientData )
 {
-    wxCHECK_RET( m_widget != NULL, wxT("invalid combobox") );
+    wxCHECK_RET( m_widget != NULL, wxT("invalid choice control") );
 
     wxNode *node = m_clientList.Nth( n );
     wxCHECK_RET( node, wxT("invalid index in wxChoice::DoSetClientData") );
@@ -146,7 +146,7 @@ void wxChoice::DoSetClientData( int n, void* clientData )
 
 void* wxChoice::DoGetClientData( int n ) const
 {
-    wxCHECK_MSG( m_widget != NULL, NULL, wxT("invalid combobox") );
+    wxCHECK_MSG( m_widget != NULL, NULL, wxT("invalid choice control") );
 
     wxNode *node = m_clientList.Nth( n );
     wxCHECK_MSG( node, NULL, wxT("invalid index in wxChoice::DoGetClientData") );
@@ -156,7 +156,7 @@ void* wxChoice::DoGetClientData( int n ) const
 
 void wxChoice::DoSetClientObject( int n, wxClientData* clientData )
 {
-    wxCHECK_RET( m_widget != NULL, wxT("invalid combobox") );
+    wxCHECK_RET( m_widget != NULL, wxT("invalid choice control") );
 
     wxNode *node = m_clientList.Nth( n );
     wxCHECK_RET( node, wxT("invalid index in wxChoice::DoSetClientObject") );
@@ -169,7 +169,7 @@ void wxChoice::DoSetClientObject( int n, wxClientData* clientData )
 
 wxClientData* wxChoice::DoGetClientObject( int n ) const
 {
-    wxCHECK_MSG( m_widget != NULL, (wxClientData*) NULL, wxT("invalid combobox") );
+    wxCHECK_MSG( m_widget != NULL, (wxClientData*) NULL, wxT("invalid choice control") );
 
     wxNode *node = m_clientList.Nth( n );
     wxCHECK_MSG( node, (wxClientData *)NULL,
@@ -186,17 +186,12 @@ void wxChoice::Clear()
     GtkWidget *menu = gtk_menu_new();
     gtk_option_menu_set_menu( GTK_OPTION_MENU(m_widget), menu );
 
-    if (m_clientDataItemsType == ClientData_Object)
-    {
-        wxNode *node = m_clientList.First();
-        while (node)
-        {
-            wxClientData *cd = (wxClientData*)node->Data();
-            if (cd) delete cd;
-            node = node->Next();
-        }
-    }
+    if ( m_clientDataItemsType == ClientData_Object )
+        m_clientList.DeleteContents(TRUE);
     m_clientList.Clear();
+
+    if ( m_strings )
+        m_strings->Clear();
 }
 
 void wxChoice::Delete( int WXUNUSED(n) )
index b4652068770b5345fb3f6dce4d1a1162bd505e23..c09dca49777236760bddb87e5af6cd93fcabdb16 100644 (file)
@@ -215,20 +215,20 @@ static void gtk_listitem_select_callback( GtkWidget *WXUNUSED(widget), wxListBox
     wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, listbox->GetId() );
 
     wxArrayInt aSelections;
-    int count = listbox->GetSelections(aSelections);
+    int n, count = listbox->GetSelections(aSelections);
     if ( count > 0 )
     {
-        event.m_commandInt = aSelections[0] ;
-        event.m_clientData = listbox->GetClientData( event.m_commandInt );
-        wxString str(listbox->GetString(event.m_commandInt));
-        if (!str.IsEmpty()) event.m_commandString = str;
+        n = aSelections[0];
+        event.m_clientData = listbox->m_clientData.Item(n);
+        event.m_commandString = listbox->GetString(n);
     }
     else
     {
-        event.m_commandInt = -1 ;
-        event.m_commandString.Empty();
+        n = -1;
     }
 
+    event.m_commandInt = n;
+
     event.SetEventObject( listbox );
 
     listbox->GetEventHandler()->ProcessEvent( event );
@@ -240,6 +240,10 @@ static void gtk_listitem_select_callback( GtkWidget *WXUNUSED(widget), wxListBox
 
 IMPLEMENT_DYNAMIC_CLASS(wxListBox,wxControl)
 
+// ----------------------------------------------------------------------------
+// construction
+// ----------------------------------------------------------------------------
+
 wxListBox::wxListBox()
 {
     m_list = (GtkList *) NULL;
@@ -251,7 +255,8 @@ wxListBox::wxListBox()
 bool wxListBox::Create( wxWindow *parent, wxWindowID id,
                         const wxPoint &pos, const wxSize &size,
                         int n, const wxString choices[],
-                        long style, const wxValidator& validator, const wxString &name )
+                        long style, const wxValidator& validator,
+                        const wxString &name )
 {
     m_needParent = TRUE;
     m_acceptsFocus = TRUE;
@@ -260,7 +265,7 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id,
         !CreateBase( parent, id, pos, size, style, validator, name ))
     {
         wxFAIL_MSG( wxT("wxListBox creation failed") );
-       return FALSE;
+        return FALSE;
     }
 
     m_widget = gtk_scrolled_window_new( (GtkAdjustment*) NULL, (GtkAdjustment*) NULL );
@@ -295,7 +300,7 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id,
     gtk_container_set_focus_vadjustment(
         GTK_CONTAINER(m_list),
         gtk_scrolled_window_get_vadjustment(
-           GTK_SCROLLED_WINDOW(m_widget)));
+            GTK_SCROLLED_WINDOW(m_widget)));
 
     gtk_widget_show( GTK_WIDGET(m_list) );
 
@@ -304,14 +309,21 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id,
     if (newSize.y == -1) newSize.y = 110;
     SetSize( newSize.x, newSize.y );
 
+    if ( style & wxLB_SORT )
+    {
+        // this will change DoAppend() behaviour
+        m_strings = new wxSortedArrayString;
+    }
+
     for (int i = 0; i < n; i++)
     {
-        m_clientDataList.Append( (wxObject*) NULL );
-        m_clientObjectList.Append( (wxObject*) NULL );
+        m_clientData.Append((wxObject *)NULL);
 
-        GtkWidget *list_item;
+        DoAppend(choices[i]);
 
+#if 0
         wxString str(choices[i]);
+
 #if wxUSE_CHECKLISTBOX
         if (m_hasCheckBoxes)
         {
@@ -319,7 +331,7 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id,
         }
 #endif // wxUSE_CHECKLISTBOX
 
-        list_item = gtk_list_item_new_with_label( str.mbc_str() );
+        GtkWidget *list_item = gtk_list_item_new_with_label( str.mbc_str() );
 
         gtk_container_add( GTK_CONTAINER(m_list), list_item );
 
@@ -353,6 +365,7 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id,
         ConnectWidget( list_item );
 
         gtk_widget_show( list_item );
+#endif // 0
     }
 
     m_parent->DoAddChild( this );
@@ -373,10 +386,15 @@ wxListBox::~wxListBox()
     Clear();
 }
 
-void wxListBox::InsertItems(int nItems, const wxString items[], int pos)
+void wxListBox::DoInsertItems(const wxArrayString& items, int pos)
 {
     wxCHECK_RET( m_list != NULL, wxT("invalid listbox") );
 
+    // code elsewhere supposes we have as many items in m_clientData as items
+    // in the listbox
+    wxASSERT_MSG( m_clientData.GetCount() == (size_t)GetCount(),
+                  wxT("bug in client data management") );
+
     GList *children = m_list->children;
     int length = g_list_length(children);
     wxCHECK_RET( pos <= length, wxT("invalid index in wxListBox::InsertItems") );
@@ -386,23 +404,37 @@ void wxListBox::InsertItems(int nItems, const wxString items[], int pos)
     //     all items after this position, then append these items and then
     //     reappend back the old ones.
 
-    // first detach the old items
-    int n; // loop var
+    // VZ: notice that InsertItems knows nothing about sorting, so calling it
+    //     from outside (and not from our own Append) is likely to break
+    //     everything
 
+    size_t nItems = items.GetCount();
+
+    size_t n; // loop var
+
+    // optimise for this trivial case
     if ( pos == length )
     {
         // no need to do anything complicated
         for ( n = 0; n < nItems; n++ )
         {
-            Append(items[n]);
+            AppendWithoutSorting(items[n]);
+
+            m_clientData.Append((wxObject *)NULL);
         }
 
+        wxASSERT_MSG( m_clientData.GetCount() == (size_t)GetCount(),
+                      wxT("bug in client data management") );
+
         return;
     }
 
+    // remove the old items
     wxArrayString deletedLabels;
     wxArrayPtrVoid deletedData;
-    wxArrayInt deletedChecks;   // only for check list boxes
+#if wxUSE_CHECKLISTBOX
+    wxArrayInt deletedChecks;
+#endif
 
     GList *child = g_list_nth( children, pos );
     for ( n = 0; child != NULL; n++, child = child->next )
@@ -415,31 +447,7 @@ void wxListBox::InsertItems(int nItems, const wxString items[], int pos)
         deletedLabels.Add(str);
 
         // save data
-        void *clientData = NULL;
-        wxNode *node = NULL;
-
-        if ( n < (int)m_clientObjectList.GetCount() )
-            node = m_clientObjectList.Nth( n );
-
-        if ( node )
-        {
-            clientData = node->GetData();
-            m_clientObjectList.DeleteNode( node );
-        }
-
-        if ( !clientData )
-        {
-            if ( n < (int)m_clientDataList.GetCount() )
-                node = m_clientDataList.Nth( n );
-
-            if ( node )
-            {
-                clientData = node->GetData();
-                node = m_clientDataList.Nth( n );
-            }
-        }
-
-        deletedData.Add(clientData);
+        deletedData.Add(m_clientData.Item(n));
 
 #if wxUSE_CHECKLISTBOX
         // save check state
@@ -450,21 +458,33 @@ void wxListBox::InsertItems(int nItems, const wxString items[], int pos)
 #endif // wxUSE_CHECKLISTBOX
     }
 
-    int nDeletedCount = n;
+    // don't delete contents, the data will be reappended soon
+    m_clientData.Clear();
+
+    size_t nDeletedCount = n;
 
     gtk_list_clear_items( m_list, pos, length );
 
     // now append the new items
     for ( n = 0; n < nItems; n++ )
     {
-        Append(items[n]);
+        AppendWithoutSorting(items[n]);
+
+        m_clientData.Append((wxObject *)NULL);
     }
 
     // and append the old items too
     pos += nItems;  // now the indices are shifter
     for ( n = 0; n < nDeletedCount; n++ )
     {
-        Append(deletedLabels[n], deletedData[n]);
+        AppendWithoutSorting(deletedLabels[n]);
+
+        m_clientData.Append((wxObject *)NULL);
+
+        if ( m_clientDataItemsType == ClientData_Object )
+            SetClientObject(n, (wxClientData *)deletedData[n]);
+        else if ( m_clientDataItemsType == ClientData_Void )
+            SetClientData(n, deletedData[n]);
 
 #if wxUSE_CHECKLISTBOX
         if ( m_hasCheckBoxes )
@@ -473,9 +493,35 @@ void wxListBox::InsertItems(int nItems, const wxString items[], int pos)
         }
 #endif // wxUSE_CHECKLISTBOX
     }
+
+    wxASSERT_MSG( m_clientData.GetCount() == (size_t)GetCount(),
+                  wxT("bug in client data management") );
+}
+
+int wxListBox::DoAppend( const wxString& item )
+{
+    int index;
+    if ( m_strings )
+    {
+        // need to determine the index
+        index = m_strings->Add(item);
+
+        InsertItems(1, &item, index);
+    }
+    else
+    {
+        // not sorted, just append
+        AppendWithoutSorting(item);
+
+        m_clientData.Append((wxObject *)NULL);
+
+        index = GetCount() - 1;
+    }
+
+    return index;
 }
 
-void wxListBox::AppendCommon( const wxString &item )
+void wxListBox::AppendWithoutSorting( const wxString &item )
 {
     wxCHECK_RET( m_list != NULL, wxT("invalid listbox") );
 
@@ -539,9 +585,9 @@ void wxListBox::AppendCommon( const wxString &item )
         }
 
 #if wxUSE_DRAG_AND_DROP
-#ifndef NEW_GTK_DND_CODE
+    #ifndef NEW_GTK_DND_CODE
         if (m_dropTarget) m_dropTarget->RegisterWidget( list_item );
-#endif
+    #endif
 #endif
 
 #if wxUSE_TOOLTIPS
@@ -550,69 +596,67 @@ void wxListBox::AppendCommon( const wxString &item )
     }
 }
 
-void wxListBox::Append( const wxString &item )
+void wxListBox::DoSetItems( const wxArrayString& items,
+                            void **clientData)
 {
-    m_clientDataList.Append( (wxObject*) NULL );
-    m_clientObjectList.Append( (wxObject*) NULL );
-
-    AppendCommon( item );
-}
+    Clear();
 
-void wxListBox::Append( const wxString &item, void *clientData )
-{
-    m_clientDataList.Append( (wxObject*) clientData );
-    m_clientObjectList.Append( (wxObject*) NULL );
+    DoInsertItems(items, 0);
 
-    AppendCommon( item );
+    if ( clientData )
+    {
+        size_t count = items.GetCount();
+        for ( size_t n = 0; n < count; n++ )
+        {
+            SetClientData(n, clientData[n]);
+        }
+    }
 }
 
-void wxListBox::Append( const wxString &item, wxClientData *clientData )
-{
-    m_clientObjectList.Append( (wxObject*) clientData );
-    m_clientDataList.Append( (wxObject*) NULL );
+// ----------------------------------------------------------------------------
+// client data
+// ----------------------------------------------------------------------------
 
-    AppendCommon( item );
-}
-
-void wxListBox::SetClientData( int n, void* clientData )
+void wxListBox::DoSetClientData( int n, void* clientData )
 {
-    wxCHECK_RET( m_widget != NULL, wxT("invalid combobox") );
+    wxCHECK_RET( m_widget != NULL, wxT("invalid listbox control") );
 
-    wxNode *node = m_clientDataList.Nth( n );
-    if (!node) return;
+    wxNode *node = m_clientData.Nth( n );
+    wxCHECK_RET( node, wxT("invalid index in wxListBox::DoSetClientData") );
 
     node->SetData( (wxObject*) clientData );
 }
 
-void* wxListBox::GetClientData( int n )
+void* wxListBox::DoGetClientData( int n ) const
 {
-    wxCHECK_MSG( m_widget != NULL, NULL, wxT("invalid combobox") );
+    wxCHECK_MSG( m_widget != NULL, NULL, wxT("invalid listbox control") );
 
-    wxNode *node = m_clientDataList.Nth( n );
-    if (!node) return NULL;
+    wxNode *node = m_clientData.Nth( n );
+    wxCHECK_MSG( node, NULL, wxT("invalid index in wxListBox::DoGetClientData") );
 
     return node->Data();
 }
 
-void wxListBox::SetClientObject( int n, wxClientData* clientData )
+void wxListBox::DoSetClientObject( int n, wxClientData* clientData )
 {
-    wxCHECK_RET( m_widget != NULL, wxT("invalid combobox") );
+    wxCHECK_RET( m_widget != NULL, wxT("invalid listbox control") );
 
-    wxNode *node = m_clientObjectList.Nth( n );
-    if (!node) return;
+    wxNode *node = m_clientData.Nth( n );
+    wxCHECK_RET( node, wxT("invalid index in wxListBox::DoSetClientObject") );
 
     wxClientData *cd = (wxClientData*) node->Data();
-    if (cd) delete cd;
+    delete cd;
 
     node->SetData( (wxObject*) clientData );
 }
 
-wxClientData* wxListBox::GetClientObject( int n )
+wxClientData* wxListBox::DoGetClientObject( int n ) const
 {
-    wxCHECK_MSG( m_widget != NULL, (wxClientData*)NULL, wxT("invalid combobox") );
+    wxCHECK_MSG( m_widget != NULL, (wxClientData*) NULL, wxT("invalid listbox control") );
 
-    wxNode *node = m_clientObjectList.Nth( n );
-    if (!node) return (wxClientData*) NULL;
+    wxNode *node = m_clientData.Nth( n );
+    wxCHECK_MSG( node, (wxClientData *)NULL,
+                 wxT("invalid index in wxListBox::DoGetClientObject") );
 
     return (wxClientData*) node->Data();
 }
@@ -623,16 +667,12 @@ void wxListBox::Clear()
 
     gtk_list_clear_items( m_list, 0, Number() );
 
-    wxNode *node = m_clientObjectList.First();
-    while (node)
-    {
-        wxClientData *cd = (wxClientData*)node->Data();
-        if (cd) delete cd;
-        node = node->Next();
-    }
-    m_clientObjectList.Clear();
+    if ( m_clientDataItemsType == ClientData_Object )
+        m_clientData.DeleteContents(TRUE);
+    m_clientData.Clear();
 
-    m_clientDataList.Clear();
+    if ( m_strings )
+        m_strings->Clear();
 }
 
 void wxListBox::Delete( int n )
@@ -647,30 +687,84 @@ void wxListBox::Delete( int n )
     gtk_list_remove_items( m_list, list );
     g_list_free( list );
 
-    wxNode *node = m_clientObjectList.Nth( n );
-    if (node)
+    wxNode *node = m_clientData.Nth( n );
+    if ( node )
     {
-        wxClientData *cd = (wxClientData*)node->Data();
-        if (cd) delete cd;
-        m_clientObjectList.DeleteNode( node );
+        if ( m_clientDataItemsType == ClientData_Object )
+        {
+            wxClientData *cd = (wxClientData*)node->Data();
+            delete cd;
+        }
+
+        m_clientData.DeleteNode( node );
     }
 
-    node = m_clientDataList.Nth( n );
-    if (node)
+    if ( m_strings )
+        m_strings->Remove(n);
+}
+
+// ----------------------------------------------------------------------------
+// string list access
+// ----------------------------------------------------------------------------
+
+void wxListBox::SetString( int n, const wxString &string )
+{
+    wxCHECK_RET( m_list != NULL, wxT("invalid listbox") );
+
+    GList *child = g_list_nth( m_list->children, n );
+    if (child)
+    {
+        GtkBin *bin = GTK_BIN( child->data );
+        GtkLabel *label = GTK_LABEL( bin->child );
+
+        wxString str;
+#if wxUSE_CHECKLISTBOX
+        if (m_hasCheckBoxes)
+            str += CHECKBOX_STRING;
+#endif // wxUSE_CHECKLISTBOX
+        str += string;
+
+        gtk_label_set( label, str.mbc_str() );
+    }
+    else
     {
-        m_clientDataList.DeleteNode( node );
+        wxFAIL_MSG(wxT("wrong listbox index"));
     }
 }
 
-void wxListBox::Deselect( int n )
+wxString wxListBox::GetString( int n ) const
 {
-    wxCHECK_RET( m_list != NULL, wxT("invalid listbox") );
+    wxCHECK_MSG( m_list != NULL, wxT(""), wxT("invalid listbox") );
 
-    DisableEvents();
+    GList *child = g_list_nth( m_list->children, n );
+    if (child)
+    {
+        GtkBin *bin = GTK_BIN( child->data );
+        GtkLabel *label = GTK_LABEL( bin->child );
 
-    gtk_list_unselect_item( m_list, n );
+        wxString str = wxString(GET_REAL_LABEL(label->label),*wxConvCurrent);
 
-    EnableEvents();
+        return str;
+    }
+
+    wxFAIL_MSG(wxT("wrong listbox index"));
+
+    return wxT("");
+}
+
+int wxListBox::GetCount() const
+{
+    wxCHECK_MSG( m_list != NULL, -1, wxT("invalid listbox") );
+
+    GList *child = m_list->children;
+    int count = 0;
+    while (child)
+    {
+        count++;
+        child = child->next;
+    }
+
+    return count;
 }
 
 int wxListBox::FindString( const wxString &item ) const
@@ -693,11 +787,15 @@ int wxListBox::FindString( const wxString &item ) const
         child = child->next;
     }
 
-  // it's not an error if the string is not found -> no wxCHECK
+    // it's not an error if the string is not found -> no wxCHECK
 
-  return -1;
+    return wxNOT_FOUND;
 }
 
+// ----------------------------------------------------------------------------
+// selection
+// ----------------------------------------------------------------------------
+
 int wxListBox::GetSelection() const
 {
     wxCHECK_MSG( m_list != NULL, -1, wxT("invalid listbox") );
@@ -743,56 +841,7 @@ int wxListBox::GetSelections( wxArrayInt& aSelections ) const
     return count;
 }
 
-wxString wxListBox::GetString( int n ) const
-{
-    wxCHECK_MSG( m_list != NULL, wxT(""), wxT("invalid listbox") );
-
-    GList *child = g_list_nth( m_list->children, n );
-    if (child)
-    {
-        GtkBin *bin = GTK_BIN( child->data );
-        GtkLabel *label = GTK_LABEL( bin->child );
-
-        wxString str = wxString(GET_REAL_LABEL(label->label),*wxConvCurrent);
-
-        return str;
-    }
-
-    wxFAIL_MSG(wxT("wrong listbox index"));
-
-    return wxT("");
-}
-
-wxString wxListBox::GetStringSelection() const
-{
-    wxCHECK_MSG( m_list != NULL, wxT(""), wxT("invalid listbox") );
-
-    GList *selection = m_list->selection;
-    if (selection)
-    {
-        GtkBin *bin = GTK_BIN( selection->data );
-        GtkLabel *label = GTK_LABEL( bin->child );
-
-        wxString str = wxString(GET_REAL_LABEL(label->label),*wxConvCurrent);
-
-        return str;
-    }
-
-    wxFAIL_MSG(wxT("no listbox selection available"));
-    return wxT("");
-}
-
-int wxListBox::Number()
-{
-    wxCHECK_MSG( m_list != NULL, -1, wxT("invalid listbox") );
-
-    GList *child = m_list->children;
-    int count = 0;
-    while (child) { count++; child = child->next; }
-    return count;
-}
-
-bool wxListBox::Selected( int n )
+bool wxListBox::IsSelected( int n ) const
 {
     wxCHECK_MSG( m_list != NULL, FALSE, wxT("invalid listbox") );
 
@@ -806,23 +855,10 @@ bool wxListBox::Selected( int n )
             child = child->next;
         }
     }
-    wxFAIL_MSG(wxT("wrong listbox index"));
-    return FALSE;
-}
-
-void wxListBox::Set( int WXUNUSED(n), const wxString *WXUNUSED(choices) )
-{
-    wxFAIL_MSG(wxT("wxListBox::Set not implemented"));
-}
 
-void wxListBox::SetFirstItem( int WXUNUSED(n) )
-{
-    wxFAIL_MSG(wxT("wxListBox::SetFirstItem not implemented"));
-}
+    wxFAIL_MSG(wxT("wrong listbox index"));
 
-void wxListBox::SetFirstItem( const wxString &WXUNUSED(item) )
-{
-    wxFAIL_MSG(wxT("wxListBox::SetFirstItem not implemented"));
+    return FALSE;
 }
 
 void wxListBox::SetSelection( int n, bool select )
@@ -839,37 +875,14 @@ void wxListBox::SetSelection( int n, bool select )
     EnableEvents();
 }
 
-void wxListBox::SetString( int n, const wxString &string )
+void wxListBox::DoSetFirstItem( int WXUNUSED(n) )
 {
-    wxCHECK_RET( m_list != NULL, wxT("invalid listbox") );
-
-    GList *child = g_list_nth( m_list->children, n );
-    if (child)
-    {
-        GtkBin *bin = GTK_BIN( child->data );
-        GtkLabel *label = GTK_LABEL( bin->child );
-
-        wxString str;
-#if wxUSE_CHECKLISTBOX
-        if (m_hasCheckBoxes)
-            str += CHECKBOX_STRING;
-#endif // wxUSE_CHECKLISTBOX
-        str += string;
-
-        gtk_label_set( label, str.mbc_str() );
-    }
-    else
-    {
-        wxFAIL_MSG(wxT("wrong listbox index"));
-    }
+    wxFAIL_MSG(wxT("wxListBox::SetFirstItem not implemented"));
 }
 
-void wxListBox::SetStringSelection( const wxString &string, bool select )
-{
-    wxCHECK_RET( m_list != NULL, wxT("invalid listbox") );
-
-    SetSelection( FindString(string), select );
-}
+// ----------------------------------------------------------------------------
+// helpers
+// ----------------------------------------------------------------------------
 
 int wxListBox::GetIndex( GtkWidget *item ) const
 {
@@ -1020,22 +1033,22 @@ void wxListBox::OnInternalIdle()
     if (GTK_WIDGET(m_list)->window && cursor.Ok())
     {
         /* I now set the cursor the anew in every OnInternalIdle call
-          as setting the cursor in a parent window also effects the
-          windows above so that checking for the current cursor is
-          not possible. */
-          
-       gdk_window_set_cursor( GTK_WIDGET(m_list)->window, cursor.GetCursor() );
+           as setting the cursor in a parent window also effects the
+           windows above so that checking for the current cursor is
+           not possible. */
+           
+        gdk_window_set_cursor( GTK_WIDGET(m_list)->window, cursor.GetCursor() );
 
         GList *child = m_list->children;
         while (child)
         {
             GtkBin *bin = GTK_BIN( child->data );
             GtkWidget *label = GTK_WIDGET( bin->child );
-           
-           if (!label->window)
-               break;
-           else
-               gdk_window_set_cursor( label->window, cursor.GetCursor() );
+            
+            if (!label->window)
+                break;
+            else
+                gdk_window_set_cursor( label->window, cursor.GetCursor() );
 
             child = child->next;
         }
index 5374d816a7c72f05e96773ac201b06f061343df3..3d234296176f3057cbda48dc190fe8ba5b75ad43 100644 (file)
@@ -115,51 +115,11 @@ wxOwnerDrawn *wxListBox::CreateItem(size_t n)
 // list box control implementation
 // ============================================================================
 
-bool wxListBox::MSWCommand(WXUINT param, WXWORD WXUNUSED(id))
-{
-    /*
-       if (param == LBN_SELCANCEL)
-       {
-       event.extraLong = FALSE;
-       }
-     */
-    if (param == LBN_SELCHANGE)
-    {
-        wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, m_windowId);
-        wxArrayInt aSelections;
-        int count = GetSelections(aSelections);
-        if ( count > 0 )
-        {
-            event.m_commandInt = aSelections[0] ;
-            event.m_clientData = GetClientData(event.m_commandInt);
-            wxString str(GetString(event.m_commandInt));
-            if (str != wxT(""))
-            {
-               event.m_commandString = str;
-            }
-        }
-        else
-        {
-            event.m_commandInt = -1 ;
-            event.m_commandString.Empty();
-        }
+// ----------------------------------------------------------------------------
+// creation
+// ----------------------------------------------------------------------------
 
-        event.SetEventObject( this );
-        ProcessCommand(event);
-        return TRUE;
-    }
-    else if (param == LBN_DBLCLK)
-    {
-        wxCommandEvent event(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, m_windowId);
-        event.SetEventObject( this );
-        GetEventHandler()->ProcessEvent(event) ;
-        return TRUE;
-    }
-
-    return FALSE;
-}
-
-    // Listbox item
+// Listbox item
 wxListBox::wxListBox()
 {
     m_noItems = 0;
@@ -205,7 +165,7 @@ bool wxListBox::Create(wxWindow *parent,
         wstyle |= LBS_EXTENDEDSEL;
 
     if (m_windowStyle & wxLB_ALWAYS_SB)
-        wstyle |= LBS_DISABLENOSCROLL ;
+        wstyle |= LBS_DISABLENOSCROLL;
     if (m_windowStyle & wxLB_HSCROLL)
         wstyle |= WS_HSCROLL;
     if (m_windowStyle & wxLB_SORT)
@@ -223,10 +183,10 @@ bool wxListBox::Create(wxWindow *parent,
     wstyle |= LBS_NOINTEGRALHEIGHT;
 
     bool want3D;
-    WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D) ;
+    WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D);
 
-    // Even with extended styles, need to combine with WS_BORDER
-    // for them to look right.
+    // Even with extended styles, need to combine with WS_BORDER for them to
+    // look right.
     if ( want3D || wxStyleHasBorder(m_windowStyle) )
     {
         wstyle |= WS_BORDER;
@@ -284,20 +244,16 @@ void wxListBox::SetupColours()
     SetForegroundColour(GetParent()->GetForegroundColour());
 }
 
-void wxListBox::SetFirstItem(int N)
+// ----------------------------------------------------------------------------
+// implementation of wxListBoxBase methods
+// ----------------------------------------------------------------------------
+
+void wxListBox::DoSetFirstItem(int N)
 {
     wxCHECK_RET( N >= 0 && N < m_noItems,
                  wxT("invalid index in wxListBox::SetFirstItem") );
 
-    SendMessage(GetHwnd(),LB_SETTOPINDEX,(WPARAM)N,(LPARAM)0) ;
-}
-
-void wxListBox::SetFirstItem(const wxString& s)
-{
-    int N = FindString(s) ;
-
-    if ( N >= 0 )
-        SetFirstItem(N) ;
+    SendMessage(GetHwnd(), LB_SETTOPINDEX, (WPARAM)N, (LPARAM)0);
 }
 
 void wxListBox::Delete(int N)
@@ -311,10 +267,10 @@ void wxListBox::Delete(int N)
     SetHorizontalExtent("");
 }
 
-void wxListBox::Append(const wxString& item)
+int wxListBox::DoAppend(const wxString& item)
 {
     int index = ListBox_AddString(GetHwnd(), item);
-    m_noItems ++;
+    m_noItems++;
 
 #if wxUSE_OWNER_DRAWN
     if ( m_windowStyle & wxLB_OWNERDRAW ) {
@@ -326,39 +282,31 @@ void wxListBox::Append(const wxString& item)
 #endif
 
     SetHorizontalExtent(item);
-}
-
-void wxListBox::Append(const wxString& item, void *Client_data)
-{
-    int index = ListBox_AddString(GetHwnd(), item);
-    m_noItems ++;
-
-#if wxUSE_OWNER_DRAWN
-    if ( m_windowStyle & wxLB_OWNERDRAW ) {
-        // client data must be pointer to wxOwnerDrawn, otherwise we would crash
-        // in OnMeasure/OnDraw.
-        wxFAIL_MSG(wxT("Can't use client data with owner-drawn listboxes"));
-    }
-    else
-#endif
-
-    ListBox_SetItemData(GetHwnd(), index, Client_data);
 
-    SetHorizontalExtent(item);
+    return index;
 }
 
-void wxListBox::Set(int n, const wxString *choices, void** clientData)
+void wxListBox::DoSetItems(const wxArrayString& choices, void** clientData)
 {
     ShowWindow(GetHwnd(), SW_HIDE);
+
     ListBox_ResetContent(GetHwnd());
+
+    m_noItems = choices.GetCount();
     int i;
-    for (i = 0; i < n; i++)
+    for (i = 0; i < m_noItems; i++)
     {
         ListBox_AddString(GetHwnd(), choices[i]);
         if ( clientData )
+        {
+#if wxUSE_OWNER_DRAWN
+            wxASSERT_MSG(clientData[ui] == NULL,
+                         wxT("Can't use client data with owner-drawn listboxes"));
+#else // !wxUSE_OWNER_DRAWN
             ListBox_SetItemData(GetHwnd(), i, clientData[i]);
+#endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN
+        }
     }
-    m_noItems = n;
 
 #if wxUSE_OWNER_DRAWN
     if ( m_windowStyle & wxLB_OWNERDRAW ) {
@@ -370,19 +318,17 @@ void wxListBox::Set(int n, const wxString *choices, void** clientData)
         m_aItems.Empty();
 
         // then create new ones
-        for (ui = 0; ui < (size_t)n; ui++) {
+        for ( ui = 0; ui < (size_t)m_noItems; ui++ ) {
             wxOwnerDrawn *pNewItem = CreateItem(ui);
             pNewItem->SetName(choices[ui]);
             m_aItems.Add(pNewItem);
             ListBox_SetItemData(GetHwnd(), ui, pNewItem);
-
-            wxASSERT_MSG(clientData[ui] == NULL,
-                    wxT("Can't use client data with owner-drawn listboxes"));
         }
     }
-#endif
+#endif // wxUSE_OWNER_DRAWN
+
+    SetHorizontalExtent();
 
-    SetHorizontalExtent("");
     ShowWindow(GetHwnd(), SW_SHOW);
 }
 
@@ -390,7 +336,7 @@ int wxListBox::FindString(const wxString& s) const
 {
     int pos = ListBox_FindStringExact(GetHwnd(), (WPARAM)-1, s);
     if (pos == LB_ERR)
-        return -1;
+        return wxNOT_FOUND;
     else
         return pos;
 }
@@ -409,7 +355,7 @@ void wxListBox::Clear()
 #endif // wxUSE_OWNER_DRAWN
 
     m_noItems = 0;
-    ListBox_GetHorizontalExtent(GetHwnd());
+    SetHorizontalExtent();
 }
 
 void wxListBox::SetSelection(int N, bool select)
@@ -417,18 +363,17 @@ void wxListBox::SetSelection(int N, bool select)
     wxCHECK_RET( N >= 0 && N < m_noItems,
                  wxT("invalid index in wxListBox::SetSelection") );
 
-    if ((m_windowStyle & wxLB_MULTIPLE) || (m_windowStyle & wxLB_EXTENDED))
+    if ( HasMultipleSelection() )
+    {
         SendMessage(GetHwnd(), LB_SETSEL, select, N);
+    }
     else
     {
-        int N1 = N;
-        if (!select)
-            N1 = -1;
-        SendMessage(GetHwnd(), LB_SETCURSEL, N1, 0);
+        SendMessage(GetHwnd(), LB_SETCURSEL, select ? N : -1, 0);
     }
 }
 
-bool wxListBox::Selected(int N) const
+bool wxListBox::IsSelected(int N) const
 {
     wxCHECK_MSG( N >= 0 && N < m_noItems, FALSE,
                  wxT("invalid index in wxListBox::Selected") );
@@ -436,45 +381,60 @@ bool wxListBox::Selected(int N) const
     return SendMessage(GetHwnd(), LB_GETSEL, N, 0) == 0 ? FALSE : TRUE;
 }
 
-void wxListBox::Deselect(int N)
+wxClientData* wxListBox::DoGetClientObject(int n) const
 {
-    wxCHECK_RET( N >= 0 && N < m_noItems,
-                 wxT("invalid index in wxListBox::Deselect") );
-
-    if ((m_windowStyle & wxLB_MULTIPLE) || (m_windowStyle & wxLB_EXTENDED))
-        SendMessage(GetHwnd(), LB_SETSEL, FALSE, N);
+    return (wxClientData *)DoGetClientData(n);
 }
 
-void *wxListBox::GetClientData(int N) const
+void *wxListBox::DoGetClientData(int n) const
 {
-    wxCHECK_MSG( N >= 0 && N < m_noItems, NULL,
+    wxCHECK_MSG( n >= 0 && n < m_noItems, NULL,
                  wxT("invalid index in wxListBox::GetClientData") );
 
-    return (void *)SendMessage(GetHwnd(), LB_GETITEMDATA, N, 0);
+    return (void *)SendMessage(GetHwnd(), LB_GETITEMDATA, n, 0);
 }
 
-void wxListBox::SetClientData(int N, void *Client_data)
+void wxListBox::DoSetClientObject(int n, wxClientData* clientData)
 {
-    wxCHECK_RET( N >= 0 && N < m_noItems,
+    DoSetClientData(n, clientData);
+}
+
+void wxListBox::DoSetClientData(int n, void *clientData)
+{
+    wxCHECK_RET( n >= 0 && n < m_noItems,
                  wxT("invalid index in wxListBox::SetClientData") );
 
-    if ( ListBox_SetItemData(GetHwnd(), N, Client_data) == LB_ERR )
+#if wxUSE_OWNER_DRAWN
+    if ( m_windowStyle & wxLB_OWNERDRAW )
+    {
+        // client data must be pointer to wxOwnerDrawn, otherwise we would crash
+        // in OnMeasure/OnDraw.
+        wxFAIL_MSG(wxT("Can't use client data with owner-drawn listboxes"));
+    }
+#endif // wxUSE_OWNER_DRAWN
+
+    if ( ListBox_SetItemData(GetHwnd(), n, clientData) == LB_ERR )
         wxLogDebug(wxT("LB_SETITEMDATA failed"));
 }
 
+bool wxListBox::HasMultipleSelection() const
+{
+    return (m_windowStyle & wxLB_MULTIPLE) || (m_windowStyle & wxLB_EXTENDED);
+}
+
 // Return number of selections and an array of selected integers
 int wxListBox::GetSelections(wxArrayInt& aSelections) const
 {
     aSelections.Empty();
 
-    if ((m_windowStyle & wxLB_MULTIPLE) || (m_windowStyle & wxLB_EXTENDED))
+    if ( HasMultipleSelection() )
     {
         int no_sel = ListBox_GetSelCount(GetHwnd());
         if (no_sel != 0) {
             int *selections = new int[no_sel];
-            if ( ListBox_GetSelItems(GetHwnd(), no_sel, selections) == LB_ERR ) {
-                wxFAIL_MSG(wxT("This listbox can't have single-selection style!"));
-            }
+            int rc = ListBox_GetSelItems(GetHwnd(), no_sel, selections);
+
+            wxCHECK_MSG(rc != LB_ERR, -1, wxT("ListBox_GetSelItems failed"));
 
             aSelections.Alloc(no_sel);
             for ( int n = 0; n < no_sel; n++ )
@@ -496,8 +456,7 @@ int wxListBox::GetSelections(wxArrayInt& aSelections) const
 // Get single selection, for single choice list items
 int wxListBox::GetSelection() const
 {
-    wxCHECK_MSG( !(m_windowStyle & wxLB_MULTIPLE) &&
-                 !(m_windowStyle & wxLB_EXTENDED),
+    wxCHECK_MSG( !HasMultipleSelection(),
                  -1,
                  wxT("GetSelection() can't be used with multiple-selection "
                     "listboxes, use GetSelections() instead.") );
@@ -521,6 +480,70 @@ wxString wxListBox::GetString(int N) const
     return result;
 }
 
+void
+wxListBox::DoInsertItems(const wxArrayString& items, int pos)
+{
+    wxCHECK_RET( pos >= 0 && pos <= m_noItems,
+                 wxT("invalid index in wxListBox::InsertItems") );
+
+    int nItems = items.GetCount();
+    for ( int i = 0; i < nItems; i++ )
+        ListBox_InsertString(GetHwnd(), i + pos, items[i]);
+    m_noItems += nItems;
+
+    SetHorizontalExtent();
+}
+
+void wxListBox::SetString(int N, const wxString& s)
+{
+    wxCHECK_RET( N >= 0 && N < m_noItems,
+                 wxT("invalid index in wxListBox::SetString") );
+
+    // remember the state of the item
+    bool wasSelected = IsSelected(N);
+
+    void *oldData = NULL;
+    wxClientData *oldObjData = NULL;
+    if ( m_clientDataItemsType == ClientData_Void )
+        oldData = GetClientData(N);
+    else if ( m_clientDataItemsType == ClientData_Object )
+        oldObjData = GetClientObject(N);
+
+    // delete and recreate it
+    SendMessage(GetHwnd(), LB_DELETESTRING, N, 0);
+
+    int newN = N;
+    if ( N == m_noItems - 1 )
+        newN = -1;
+
+    ListBox_InsertString(GetHwnd(), newN, s);
+
+    // restore the client data
+    if ( oldData )
+        SetClientData(N, oldData);
+    else if ( oldObjData )
+        SetClientObject(N, oldObjData);
+
+    // we may have lost the selection
+    if ( wasSelected )
+        Select(N);
+
+#if wxUSE_OWNER_DRAWN
+    if ( m_windowStyle & wxLB_OWNERDRAW )
+        // update item's text
+        m_aItems[N]->SetName(s);
+#endif  //USE_OWNER_DRAWN
+}
+
+int wxListBox::GetCount() const
+{
+    return m_noItems;
+}
+
+// ----------------------------------------------------------------------------
+// helpers
+// ----------------------------------------------------------------------------
+
 // Windows-specific code to set the horizontal extent of the listbox, if
 // necessary. If s is non-NULL, it's used to calculate the horizontal extent.
 // Otherwise, all strings are used.
@@ -531,7 +554,7 @@ void wxListBox::SetHorizontalExtent(const wxString& s)
         return;
     TEXTMETRIC lpTextMetric;
 
-    if (s != wxT(""))
+    if ( !s.IsEmpty() )
     {
         int existingExtent = (int)SendMessage(GetHwnd(), LB_GETHORIZONTALEXTENT, 0, 0L);
         HDC dc = GetWindowDC(GetHwnd());
@@ -550,7 +573,6 @@ void wxListBox::SetHorizontalExtent(const wxString& s)
         ReleaseDC(GetHwnd(), dc);
         if (extentX > existingExtent)
             SendMessage(GetHwnd(), LB_SETHORIZONTALEXTENT, LOWORD(extentX), 0L);
-        return;
     }
     else
     {
@@ -580,79 +602,6 @@ void wxListBox::SetHorizontalExtent(const wxString& s)
     }
 }
 
-void
-wxListBox::InsertItems(int nItems, const wxString items[], int pos)
-{
-    wxCHECK_RET( pos >= 0 && pos <= m_noItems,
-                 wxT("invalid index in wxListBox::InsertItems") );
-
-    int i;
-    for (i = 0; i < nItems; i++)
-        ListBox_InsertString(GetHwnd(), i + pos, items[i]);
-    m_noItems += nItems;
-
-    SetHorizontalExtent(wxT(""));
-}
-
-void wxListBox::SetString(int N, const wxString& s)
-{
-    wxCHECK_RET( N >= 0 && N < m_noItems,
-                 wxT("invalid index in wxListBox::SetString") );
-
-    int sel = -1;
-    if (!(m_windowStyle & wxLB_MULTIPLE) && !(m_windowStyle & wxLB_EXTENDED))
-        sel = GetSelection();
-
-    void *oldData = wxListBox::GetClientData(N);
-
-    SendMessage(GetHwnd(), LB_DELETESTRING, N, 0);
-
-    int newN = N;
-    if (N == (m_noItems - 1))
-        newN = -1;
-
-    SendMessage(GetHwnd(), LB_INSERTSTRING, newN, (LPARAM) (const wxChar *)s);
-    if (oldData)
-        wxListBox::SetClientData(N, oldData);
-
-    // Selection may have changed
-    if (sel >= 0)
-        SetSelection(sel);
-
-#if       wxUSE_OWNER_DRAWN
-    if ( m_windowStyle & wxLB_OWNERDRAW )
-        // update item's text
-        m_aItems[N]->SetName(s);
-#endif  //USE_OWNER_DRAWN
-}
-
-int wxListBox::Number () const
-{
-    return m_noItems;
-}
-
-// For single selection items only
-wxString wxListBox::GetStringSelection () const
-{
-    int sel = GetSelection ();
-    if (sel > -1)
-        return this->GetString (sel);
-    else
-        return wxString("");
-}
-
-bool wxListBox::SetStringSelection (const wxString& s, bool flag)
-{
-    int sel = FindString (s);
-    if (sel > -1)
-    {
-        SetSelection (sel, flag);
-        return TRUE;
-    }
-    else
-        return FALSE;
-}
-
 wxSize wxListBox::DoGetBestSize()
 {
     // find the widest string
@@ -682,26 +631,56 @@ wxSize wxListBox::DoGetBestSize()
     return wxSize(wListbox, hListbox);
 }
 
-// Is this the right thing? Won't setselection generate a command
-// event too? No! It'll just generate a setselection event.
-// But we still can't have this being called whenever a real command
-// is generated, because it sets the selection, which will already
-// have been done! (Unless we have an optional argument for calling
-// by the actual window system, or a separate function, ProcessCommand)
-void wxListBox::Command (wxCommandEvent & event)
+// ----------------------------------------------------------------------------
+// callbacks
+// ----------------------------------------------------------------------------
+
+bool wxListBox::MSWCommand(WXUINT param, WXWORD WXUNUSED(id))
 {
-    if (event.m_extraLong)
-        SetSelection (event.m_commandInt);
-    else
+    /*
+       if (param == LBN_SELCANCEL)
+       {
+       event.extraLong = FALSE;
+       }
+     */
+    if (param == LBN_SELCHANGE)
     {
-        Deselect (event.m_commandInt);
-        return;
+        wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, m_windowId);
+        wxArrayInt aSelections;
+        int count = GetSelections(aSelections);
+        if ( count > 0 )
+        {
+            event.m_commandInt = aSelections[0];
+            event.m_clientData = GetClientData(event.m_commandInt);
+            wxString str(GetString(event.m_commandInt));
+            if (str != wxT(""))
+            {
+               event.m_commandString = str;
+            }
+        }
+        else
+        {
+            event.m_commandInt = -1;
+            event.m_commandString.Empty();
+        }
+
+        event.SetEventObject( this );
+        ProcessCommand(event);
+        return TRUE;
     }
-    ProcessCommand (event);
+    else if (param == LBN_DBLCLK)
+    {
+        wxCommandEvent event(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, m_windowId);
+        event.SetEventObject( this );
+        GetEventHandler()->ProcessEvent(event);
+        return TRUE;
+    }
+
+    return FALSE;
 }
 
 WXHBRUSH wxListBox::OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor,
-        WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
+                               WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
 {
 #if wxUSE_CTL3D
     if ( m_useCtl3D )
@@ -727,10 +706,9 @@ WXHBRUSH wxListBox::OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor,
     return (WXHBRUSH) backgroundBrush->GetResourceHandle();
 }
 
-long wxListBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
-{
-    return wxControl::MSWWindowProc(nMsg, wParam, lParam);
-}
+// ----------------------------------------------------------------------------
+// wxCheckListBox support
+// ----------------------------------------------------------------------------
 
 #if wxUSE_OWNER_DRAWN
 
index f513975da2904a52ad5c73e6402a6fe2f4636a22..dae062836b7708e735c01017cedbe16e903f18d1 100644 (file)
@@ -1,6 +1,6 @@
 
 
-# This file was automatically generated by tmake at 15:16, 1999/10/21
+# This file was automatically generated by tmake at 16:37, 1999/10/22
 # DO NOT CHANGE THIS FILE, YOUR CHANGES WILL BE LOST! CHANGE B32.T!
 
 #
@@ -154,6 +154,7 @@ COMMONOBJS = \
                $(MSWDIR)\intl.obj \
                $(MSWDIR)\ipcbase.obj \
                $(MSWDIR)\layout.obj \
+               $(MSWDIR)\lboxcmn.obj \
                $(MSWDIR)\list.obj \
                $(MSWDIR)\log.obj \
                $(MSWDIR)\memory.obj \
@@ -618,6 +619,8 @@ $(MSWDIR)\ipcbase.obj: $(COMMDIR)\ipcbase.$(SRCSUFF)
 
 $(MSWDIR)\layout.obj: $(COMMDIR)\layout.$(SRCSUFF)
 
+$(MSWDIR)\lboxcmn.obj: $(COMMDIR)\lboxcmn.$(SRCSUFF)
+
 $(MSWDIR)\list.obj: $(COMMDIR)\list.$(SRCSUFF)
 
 $(MSWDIR)\log.obj: $(COMMDIR)\log.$(SRCSUFF)
index 3ba8806867d82864a89e940f9c6cc70e73591cda..7e6ebc43c0c37835ef84ef529c3a3b32e8d88481 100644 (file)
@@ -1,6 +1,6 @@
 
 
-# This file was automatically generated by tmake at 15:16, 1999/10/21
+# This file was automatically generated by tmake at 16:37, 1999/10/22
 # DO NOT CHANGE THIS FILE, YOUR CHANGES WILL BE LOST! CHANGE BCC.T!
 
 #
@@ -139,6 +139,7 @@ COMMONOBJS = \
                $(MSWDIR)\intl.obj \
                $(MSWDIR)\ipcbase.obj \
                $(MSWDIR)\layout.obj \
+               $(MSWDIR)\lboxcmn.obj \
                $(MSWDIR)\list.obj \
                $(MSWDIR)\log.obj \
                $(MSWDIR)\memory.obj \
@@ -514,6 +515,8 @@ $(MSWDIR)\ipcbase.obj: $(COMMDIR)\ipcbase.$(SRCSUFF)
 
 $(MSWDIR)\layout.obj: $(COMMDIR)\layout.$(SRCSUFF)
 
+$(MSWDIR)\lboxcmn.obj: $(COMMDIR)\lboxcmn.$(SRCSUFF)
+
 $(MSWDIR)\list.obj: $(COMMDIR)\list.$(SRCSUFF)
 
 $(MSWDIR)\log.obj: $(COMMDIR)\log.$(SRCSUFF)
index c5ee8db1df2f1a0e23f97666bba42c10bb38ca63..07543540faf5502ea57196324d240f2d5931cc72 100644 (file)
@@ -1,6 +1,6 @@
 
 
-# This file was automatically generated by tmake at 15:16, 1999/10/21
+# This file was automatically generated by tmake at 16:37, 1999/10/22
 # DO NOT CHANGE THIS FILE, YOUR CHANGES WILL BE LOST! CHANGE DOS.T!
 
 #
@@ -126,6 +126,7 @@ COMMONOBJS = \
                $(COMMDIR)\intl.obj \
                $(COMMDIR)\ipcbase.obj \
                $(COMMDIR)\layout.obj \
+               $(COMMDIR)\lboxcmn.obj \
                $(COMMDIR)\list.obj \
                $(COMMDIR)\log.obj \
                $(COMMDIR)\memory.obj \
@@ -875,6 +876,11 @@ $(COMMDIR)/layout.obj:     $*.$(SRCSUFF)
 $(CPPFLAGS) /Fo$@ /c /Tp $*.$(SRCSUFF)
 <<
 
+$(COMMDIR)/lboxcmn.obj:     $*.$(SRCSUFF)
+        cl @<<
+$(CPPFLAGS) /Fo$@ /c /Tp $*.$(SRCSUFF)
+<<
+
 $(COMMDIR)/list.obj:     $*.$(SRCSUFF)
         cl @<<
 $(CPPFLAGS) /Fo$@ /c /Tp $*.$(SRCSUFF)
index e6f37e0f9595eb794aa27072c0a567bbff43bc11..d1288c154e16d5d9e4d6075fa2dcd006699c38be 100644 (file)
@@ -1,5 +1,4 @@
-
-# This file was automatically generated by tmake at 12:32, 1999/10/22
+# This file was automatically generated by tmake at 16:37, 1999/10/22
 # DO NOT CHANGE THIS FILE, YOUR CHANGES WILL BE LOST! CHANGE G95.T!
 
 #
@@ -105,6 +104,7 @@ COMMONOBJS  = \
                $(COMMDIR)/intl.$(OBJSUFF) \
                $(COMMDIR)/ipcbase.$(OBJSUFF) \
                $(COMMDIR)/layout.$(OBJSUFF) \
+               $(COMMDIR)/lboxcmn.$(OBJSUFF) \
                $(COMMDIR)/list.$(OBJSUFF) \
                $(COMMDIR)/log.$(OBJSUFF) \
                $(COMMDIR)/memory.$(OBJSUFF) \
@@ -258,15 +258,6 @@ MSWOBJS     = \
                $(MSWDIR)/window.$(OBJSUFF) \
                $(MSWDIR)/xpmhand.$(OBJSUFF)
 
-ADVANCEDOBJS     = \
-               $(COMMDIR)/odbc.$(OBJSUFF) \
-               $(MSWDIR)/ole/automtn.$(OBJSUFF) \
-               $(MSWDIR)/ole/dataobj.$(OBJSUFF) \
-               $(MSWDIR)/ole/dropsrc.$(OBJSUFF) \
-               $(MSWDIR)/ole/droptgt.$(OBJSUFF) \
-               $(MSWDIR)/ole/oleutils.$(OBJSUFF) \
-               $(MSWDIR)/ole/uuid.$(OBJSUFF)
-
 ZLIBOBJS    = \
                $(ZLIBDIR)/adler32.$(OBJSUFF) \
                $(ZLIBDIR)/compress.$(OBJSUFF) \
@@ -362,20 +353,7 @@ XPMOBJECTS =       $(XPMDIR)/crbuffri.o\
                $(XPMDIR)/wrffrp.o $(XPMDIR)/wrffri.o
 
 OBJECTS = $(MSWOBJS) $(COMMONOBJS) $(GENERICOBJS) $(HTMLOBJS) \
-         $(JPEGOBJS) $(PNGOBJS) $(ZLIBOBJS) # $(ADVANCEDOBJS) # $(XPMOBJECTS)
-
-ifeq ($(MINGW32),1)
-  ifeq ($(MINGW32VERSION),2.95)
-    OBJECTS = $(MSWOBJS) $(COMMONOBJS) $(GENERICOBJS) $(HTMLOBJS) \
-         $(JPEGOBJS) $(PNGOBJS) $(ZLIBOBJS) $(ADVANCEDOBJS) # $(XPMOBJECTS)   
-  else
-    OBJECTS = $(MSWOBJS) $(COMMONOBJS) $(GENERICOBJS) $(HTMLOBJS) \
-         $(JPEGOBJS) $(PNGOBJS) $(ZLIBOBJS) # $(XPMOBJECTS)
-  endif
-else
-  OBJECTS = $(MSWOBJS) $(COMMONOBJS) $(GENERICOBJS) $(HTMLOBJS) \
          $(JPEGOBJS) $(PNGOBJS) $(ZLIBOBJS) # $(XPMOBJECTS)
-endif
 
 all:    $(OBJECTS) $(WXLIB)
 
@@ -425,21 +403,21 @@ $(COMMDIR)/lex_yy.c:    $(COMMDIR)/doslex.c
 #      mv y.tab.c $(COMMDIR)/y_tab.c
 
 clean:
-       rm -f *.o
-       rm -f *.bak
-       rm -f core
-       rm -f ..\common\y_tab.c
-       rm -f ..\common\lex_yy.c
-       rm -f ..\common\*.o
-       rm -f ..\common\*.bak
-       rm -f ..\generic\*.o
-       rm -f ..\generic\*.bak
-       rm -f ..\html\*.o
-       rm -f ..\png\*.o
-       rm -f ..\png\*.bak
-       rm -f ..\zlib\*.o
-       rm -f ..\zlib\*.bak
-       rm -f ..\jpeg\*.o
-       rm -f ..\..\lib\libwx.a
+       -erase *.o
+       -erase *.bak
+       -erase core
+       -erase ..\common\y_tab.c
+       -erase ..\common\lex_yy.c
+       -erase ..\common\*.o
+       -erase ..\common\*.bak
+       -erase ..\generic\*.o
+       -erase ..\generic\*.bak
+       -erase ..\html\*.o
+       -erase ..\png\*.o
+       -erase ..\png\*.bak
+       -erase ..\zlib\*.o
+       -erase ..\zlib\*.bak
+       -erase ..\jpeg\*.o
+       -erase ..\..\lib\libwx.a
 
 cleanall: clean
index 6aa83c8d424af727380d2a0bd32c492fb46a937b..2fa756651271fadf73afe46b2ef2050348e078fe 100644 (file)
@@ -1,6 +1,6 @@
 
 
-# This file was automatically generated by tmake at 15:16, 1999/10/21
+# This file was automatically generated by tmake at 16:37, 1999/10/22
 # DO NOT CHANGE THIS FILE, YOUR CHANGES WILL BE LOST! CHANGE SC.T!
 
 # Symantec C++ makefile for the msw objects
@@ -93,6 +93,7 @@ COMMONOBJS = \
                $(COMMDIR)\intl.obj \
                $(COMMDIR)\ipcbase.obj \
                $(COMMDIR)\layout.obj \
+               $(COMMDIR)\lboxcmn.obj \
                $(COMMDIR)\list.obj \
                $(COMMDIR)\log.obj \
                $(COMMDIR)\memory.obj \
index 4758b1fe11f84633dd0e7d3ee2dce96179e2c228..3be0732d9eb4c6a29619c65cf1d293c07bdfefba 100644 (file)
@@ -1,4 +1,4 @@
-# This file was automatically generated by tmake at 15:16, 1999/10/21
+# This file was automatically generated by tmake at 16:37, 1999/10/22
 # DO NOT CHANGE THIS FILE, YOUR CHANGES WILL BE LOST! CHANGE VC.T!
 
 # File:     makefile.vc
@@ -171,6 +171,7 @@ COMMONOBJS = \
                ..\common\$D\intl.obj \
                ..\common\$D\ipcbase.obj \
                ..\common\$D\layout.obj \
+               ..\common\$D\lboxcmn.obj \
                ..\common\$D\list.obj \
                ..\common\$D\log.obj \
                ..\common\$D\memory.obj \
index 8fbe6d1467d2ff794528bd29e67673c9c04cdf7a..21a1e94d5920961e97980c929ca7150ae0645a97 100644 (file)
@@ -1,6 +1,6 @@
 
 
-# This file was automatically generated by tmake at 15:16, 1999/10/21
+# This file was automatically generated by tmake at 16:37, 1999/10/22
 # DO NOT CHANGE THIS FILE, YOUR CHANGES WILL BE LOST! CHANGE WAT.T!
 
 #!/binb/wmake.exe
@@ -119,6 +119,7 @@ COMMONOBJS = &
        intl.obj &
        ipcbase.obj &
        layout.obj &
+       lboxcmn.obj &
        list.obj &
        log.obj &
        memory.obj &
@@ -692,6 +693,9 @@ ipcbase.obj:     $(COMMDIR)\ipcbase.cpp
 layout.obj:     $(COMMDIR)\layout.cpp
   *$(CCC) $(CPPFLAGS) $(IFLAGS) $<
 
+lboxcmn.obj:     $(COMMDIR)\lboxcmn.cpp
+  *$(CCC) $(CPPFLAGS) $(IFLAGS) $<
+
 list.obj:     $(COMMDIR)\list.cpp
   *$(CCC) $(CPPFLAGS) $(IFLAGS) $<