wxChoice and wxListBox GTK+ changes (wxChoice works, wxListBox still doesn't)

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
This commit is contained in:
Vadim Zeitlin
1999-10-22 15:55:27 +00:00
parent bd77da975b
commit 2ee3ee1bc8
20 changed files with 1152 additions and 908 deletions

View File

@@ -138,6 +138,7 @@ init.cpp B
intl.cpp C B intl.cpp C B
ipcbase.cpp C ipcbase.cpp C
layout.cpp C layout.cpp C
lboxcmn.cpp C
list.cpp C B list.cpp C B
log.cpp C B log.cpp C B
memory.cpp C memory.cpp C

View File

@@ -6,7 +6,6 @@
#! Created: 14.07.99 #! Created: 14.07.99
#! Version: $Id$ #! Version: $Id$
#!############################################################################# #!#############################################################################
#${ #${
#! include the code which parses filelist.txt file and initializes #! include the code which parses filelist.txt file and initializes
#! %wxCommon, %wxGeneric and %wxMSW hashes. #! %wxCommon, %wxGeneric and %wxMSW hashes.

View File

@@ -15,36 +15,16 @@
#pragma interface #pragma interface
#endif #endif
#include "wx/defs.h"
#if wxUSE_LISTBOX
#include "wx/object.h"
#include "wx/list.h" #include "wx/list.h"
#include "wx/control.h"
//-----------------------------------------------------------------------------
// classes
//-----------------------------------------------------------------------------
class wxListBox;
class wxArrayInt;
//-----------------------------------------------------------------------------
// global data
//-----------------------------------------------------------------------------
extern const char *wxListBoxNameStr;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// wxListBox // wxListBox
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
class wxListBox : public wxControl class wxListBox : public wxListBoxBase
{ {
DECLARE_DYNAMIC_CLASS(wxListBox)
public: public:
// ctors and such
wxListBox(); wxListBox();
wxListBox( wxWindow *parent, wxWindowID id, wxListBox( wxWindow *parent, wxWindowID id,
const wxPoint& pos = wxDefaultPosition, const wxPoint& pos = wxDefaultPosition,
@@ -69,49 +49,40 @@ public:
const wxValidator& validator = wxDefaultValidator, const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxListBoxNameStr); const wxString& name = wxListBoxNameStr);
void Append( const wxString &item ); // implement base class pure virtuals
void Append( const wxString &item, void* clientData ); virtual void Clear();
void Append( const wxString &item, wxClientData* clientData ); virtual void Delete(int n);
void InsertItems(int nItems, const wxString items[], int pos); 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;
void SetClientData( int n, void* clientData ); virtual bool IsSelected(int n) const;
void* GetClientData( int n ); virtual void SetSelection(int n, bool select = TRUE);
void SetClientObject( int n, wxClientData* clientData ); virtual int GetSelection() const;
wxClientData* GetClientObject( int n ); virtual int GetSelections(wxArrayInt& aSelections) const;
void SetClientObject( wxClientData *data ) { wxControl::SetClientObject( data ); } virtual int DoAppend(const wxString& item);
wxClientData *GetClientObject() const { return wxControl::GetClientObject(); } virtual void DoInsertItems(const wxArrayString& items, int pos);
void SetClientData( void *data ) { wxControl::SetClientData( data ); } virtual void DoSetItems(const wxArrayString& items, void **clientData);
void *GetClientData() const { return wxControl::GetClientData(); }
void Clear();
void Delete( int n );
void Deselect( int n ); virtual void DoSetFirstItem(int n);
int FindString( const wxString &item ) const;
int GetSelection() const; virtual void DoSetClientData(int n, void* clientData);
int GetSelections( class wxArrayInt &) const; virtual void* DoGetClientData(int n) const;
wxString GetString( int n ) const; virtual void DoSetClientObject(int n, wxClientData* clientData);
wxString GetStringSelection() const; virtual wxClientData* DoGetClientObject(int n) const;
int Number();
bool Selected( int n ); // implementation from now on
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 );
#if wxUSE_DRAG_AND_DROP #if wxUSE_DRAG_AND_DROP
void SetDropTarget( wxDropTarget *dropTarget ); void SetDropTarget( wxDropTarget *dropTarget );
#endif #endif
// implementation
void DisableEvents(); void DisableEvents();
void EnableEvents(); void EnableEvents();
void AppendCommon( const wxString &item ); void AppendWithoutSorting( const wxString &item );
int GetIndex( GtkWidget *item ) const; int GetIndex( GtkWidget *item ) const;
GtkWidget *GetConnectWidget(); GtkWidget *GetConnectWidget();
bool IsOwnGtkWindow( GdkWindow *window ); bool IsOwnGtkWindow( GdkWindow *window );
@@ -123,14 +94,18 @@ public:
#endif // wxUSE_TOOLTIPS #endif // wxUSE_TOOLTIPS
GtkList *m_list; GtkList *m_list;
wxList m_clientDataList; wxList m_clientData;
wxList m_clientObjectList;
#if wxUSE_CHECKLISTBOX #if wxUSE_CHECKLISTBOX
bool m_hasCheckBoxes; bool m_hasCheckBoxes;
#endif // wxUSE_CHECKLISTBOX #endif // wxUSE_CHECKLISTBOX
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
#endif // __GTKLISTBOXH__ #endif // __GTKLISTBOXH__

View File

@@ -15,36 +15,16 @@
#pragma interface #pragma interface
#endif #endif
#include "wx/defs.h"
#if wxUSE_LISTBOX
#include "wx/object.h"
#include "wx/list.h" #include "wx/list.h"
#include "wx/control.h"
//-----------------------------------------------------------------------------
// classes
//-----------------------------------------------------------------------------
class wxListBox;
class wxArrayInt;
//-----------------------------------------------------------------------------
// global data
//-----------------------------------------------------------------------------
extern const char *wxListBoxNameStr;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// wxListBox // wxListBox
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
class wxListBox : public wxControl class wxListBox : public wxListBoxBase
{ {
DECLARE_DYNAMIC_CLASS(wxListBox)
public: public:
// ctors and such
wxListBox(); wxListBox();
wxListBox( wxWindow *parent, wxWindowID id, wxListBox( wxWindow *parent, wxWindowID id,
const wxPoint& pos = wxDefaultPosition, const wxPoint& pos = wxDefaultPosition,
@@ -69,49 +49,40 @@ public:
const wxValidator& validator = wxDefaultValidator, const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxListBoxNameStr); const wxString& name = wxListBoxNameStr);
void Append( const wxString &item ); // implement base class pure virtuals
void Append( const wxString &item, void* clientData ); virtual void Clear();
void Append( const wxString &item, wxClientData* clientData ); virtual void Delete(int n);
void InsertItems(int nItems, const wxString items[], int pos); 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;
void SetClientData( int n, void* clientData ); virtual bool IsSelected(int n) const;
void* GetClientData( int n ); virtual void SetSelection(int n, bool select = TRUE);
void SetClientObject( int n, wxClientData* clientData ); virtual int GetSelection() const;
wxClientData* GetClientObject( int n ); virtual int GetSelections(wxArrayInt& aSelections) const;
void SetClientObject( wxClientData *data ) { wxControl::SetClientObject( data ); } virtual int DoAppend(const wxString& item);
wxClientData *GetClientObject() const { return wxControl::GetClientObject(); } virtual void DoInsertItems(const wxArrayString& items, int pos);
void SetClientData( void *data ) { wxControl::SetClientData( data ); } virtual void DoSetItems(const wxArrayString& items, void **clientData);
void *GetClientData() const { return wxControl::GetClientData(); }
void Clear();
void Delete( int n );
void Deselect( int n ); virtual void DoSetFirstItem(int n);
int FindString( const wxString &item ) const;
int GetSelection() const; virtual void DoSetClientData(int n, void* clientData);
int GetSelections( class wxArrayInt &) const; virtual void* DoGetClientData(int n) const;
wxString GetString( int n ) const; virtual void DoSetClientObject(int n, wxClientData* clientData);
wxString GetStringSelection() const; virtual wxClientData* DoGetClientObject(int n) const;
int Number();
bool Selected( int n ); // implementation from now on
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 );
#if wxUSE_DRAG_AND_DROP #if wxUSE_DRAG_AND_DROP
void SetDropTarget( wxDropTarget *dropTarget ); void SetDropTarget( wxDropTarget *dropTarget );
#endif #endif
// implementation
void DisableEvents(); void DisableEvents();
void EnableEvents(); void EnableEvents();
void AppendCommon( const wxString &item ); void AppendWithoutSorting( const wxString &item );
int GetIndex( GtkWidget *item ) const; int GetIndex( GtkWidget *item ) const;
GtkWidget *GetConnectWidget(); GtkWidget *GetConnectWidget();
bool IsOwnGtkWindow( GdkWindow *window ); bool IsOwnGtkWindow( GdkWindow *window );
@@ -123,14 +94,18 @@ public:
#endif // wxUSE_TOOLTIPS #endif // wxUSE_TOOLTIPS
GtkList *m_list; GtkList *m_list;
wxList m_clientDataList; wxList m_clientData;
wxList m_clientObjectList;
#if wxUSE_CHECKLISTBOX #if wxUSE_CHECKLISTBOX
bool m_hasCheckBoxes; bool m_hasCheckBoxes;
#endif // wxUSE_CHECKLISTBOX #endif // wxUSE_CHECKLISTBOX
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
#endif // __GTKLISTBOXH__ #endif // __GTKLISTBOXH__

View File

@@ -1,21 +1,181 @@
///////////////////////////////////////////////////////////////////////////////
// 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_ #ifndef _WX_LISTBOX_H_BASE_
#define _WX_LISTBOX_H_BASE_ #define _WX_LISTBOX_H_BASE_
#if defined(__WXMSW__) // ----------------------------------------------------------------------------
#include "wx/msw/listbox.h" // headers
#elif defined(__WXMOTIF__) // ----------------------------------------------------------------------------
#include "wx/motif/listbox.h"
#elif defined(__WXGTK__) #ifdef __GNUG__
#include "wx/gtk/listbox.h" #pragma interface "listboxbase.h"
#elif defined(__WXQT__)
#include "wx/qt/listbox.h"
#elif defined(__WXMAC__)
#include "wx/mac/listbox.h"
#elif defined(__WXPM__)
#include "wx/os2/listbox.h"
#elif defined(__WXSTUBS__)
#include "wx/stubs/listbox.h"
#endif #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"
#elif defined(__WXMOTIF__)
#include "wx/motif/listbox.h"
#elif defined(__WXGTK__)
#include "wx/gtk/listbox.h"
#elif defined(__WXQT__)
#include "wx/qt/listbox.h"
#elif defined(__WXMAC__)
#include "wx/mac/listbox.h"
#elif defined(__WXPM__)
#include "wx/os2/listbox.h"
#elif defined(__WXSTUBS__)
#include "wx/stubs/listbox.h"
#endif
#endif // wxUSE_LISTBOX
#endif #endif
// _WX_LISTBOX_H_BASE_ // _WX_LISTBOX_H_BASE_

View File

@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Name: listbox.h // Name: wx/msw/listbox.h
// Purpose: wxListBox class // Purpose: wxListBox class
// Author: Julian Smart // Author: Julian Smart
// Modified by: // Modified by:
@@ -16,9 +16,9 @@
#pragma interface "listbox.h" #pragma interface "listbox.h"
#endif #endif
#include "wx/control.h" // ----------------------------------------------------------------------------
// simple types
WXDLLEXPORT_DATA(extern const wxChar*) wxListBoxNameStr; // ----------------------------------------------------------------------------
#if wxUSE_OWNER_DRAWN #if wxUSE_OWNER_DRAWN
class WXDLLEXPORT wxOwnerDrawn; class WXDLLEXPORT wxOwnerDrawn;
@@ -27,20 +27,19 @@ WXDLLEXPORT_DATA(extern const wxChar*) wxListBoxNameStr;
#include <wx/dynarray.h> #include <wx/dynarray.h>
WX_DEFINE_EXPORTED_ARRAY(wxOwnerDrawn *, wxListBoxItemsArray); WX_DEFINE_EXPORTED_ARRAY(wxOwnerDrawn *, wxListBoxItemsArray);
#endif // wxUSE_OWNER_DRAWN
#endif
// forward decl for GetSelections() // forward decl for GetSelections()
class wxArrayInt; class wxArrayInt;
WXDLLEXPORT_DATA(extern const wxChar*) wxEmptyString; // ----------------------------------------------------------------------------
// List box control
// ----------------------------------------------------------------------------
// List box item class WXDLLEXPORT wxListBox : public wxListBoxBase
class WXDLLEXPORT wxListBox : public wxControl
{ {
DECLARE_DYNAMIC_CLASS(wxListBox)
public: public:
// ctors and such
wxListBox(); wxListBox();
wxListBox(wxWindow *parent, wxWindowID id, wxListBox(wxWindow *parent, wxWindowID id,
const wxPoint& pos = wxDefaultPosition, const wxPoint& pos = wxDefaultPosition,
@@ -54,17 +53,41 @@ public:
} }
bool Create(wxWindow *parent, wxWindowID id, bool Create(wxWindow *parent, wxWindowID id,
const wxPoint& pos = wxDefaultPosition, const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize, const wxSize& size = wxDefaultSize,
int n = 0, const wxString choices[] = NULL, int n = 0, const wxString choices[] = NULL,
long style = 0, long style = 0,
const wxValidator& validator = wxDefaultValidator, const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxListBoxNameStr); 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 #if wxUSE_OWNER_DRAWN
bool MSWOnMeasure(WXMEASUREITEMSTRUCT *item); bool MSWOnMeasure(WXMEASUREITEMSTRUCT *item);
bool MSWOnDraw(WXDRAWITEMSTRUCT *item); bool MSWOnDraw(WXDRAWITEMSTRUCT *item);
@@ -79,53 +102,24 @@ public:
int GetItemIndex(wxOwnerDrawn *item) const { return m_aItems.Index(item); } int GetItemIndex(wxOwnerDrawn *item) const { return m_aItems.Index(item); }
#endif // wxUSE_OWNER_DRAWN #endif // wxUSE_OWNER_DRAWN
virtual void Append(const wxString& item); // Windows-specific code to set the horizontal extent of the listbox, if
virtual void Append(const wxString& item, void *clientData); // necessary. If s is non-NULL, it's used to calculate the horizontal
virtual void Set(int n, const wxString* choices, void **clientData = NULL); // extent. Otherwise, all strings are used.
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.
virtual void SetHorizontalExtent(const wxString& s = wxEmptyString); virtual void SetHorizontalExtent(const wxString& s = wxEmptyString);
// Windows callbacks
virtual WXHBRUSH OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor, 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(); virtual void SetupColours();
protected: protected:
// do we have multiple selections?
bool HasMultipleSelection() const;
int m_noItems; int m_noItems;
int m_selected; int m_selected;
@@ -135,6 +129,9 @@ protected:
// control items // control items
wxListBoxItemsArray m_aItems; wxListBoxItemsArray m_aItems;
#endif #endif
private:
DECLARE_DYNAMIC_CLASS(wxListBox)
}; };
#endif #endif

View File

@@ -97,11 +97,7 @@ wxDataObjectComposite::GetPreferredFormat(Direction WXUNUSED(dir)) const
{ {
wxSimpleDataObjectList::Node *node = m_dataObjects.Item( m_preferred ); wxSimpleDataObjectList::Node *node = m_dataObjects.Item( m_preferred );
#ifdef __WXGTK__ wxCHECK_MSG( node, wxFormatInvalid, wxT("no preferred format") );
wxCHECK_MSG( node, wxDataFormat(wxDF_INVALID), wxT("no preferred format") );
#else
wxCHECK_MSG( node, wxDataFormat((unsigned short) wxDF_INVALID), wxT("no preferred format") );
#endif
wxDataObjectSimple* dataObj = node->GetData(); wxDataObjectSimple* dataObj = node->GetData();

151
src/common/lboxcmn.cpp Normal file
View File

@@ -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);
}

View File

@@ -127,7 +127,7 @@ wxChoice::~wxChoice()
int wxChoice::DoAppend( const wxString &item ) 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) ); 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 ) 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 ); wxNode *node = m_clientList.Nth( n );
wxCHECK_RET( node, wxT("invalid index in wxChoice::DoSetClientData") ); 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 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 ); wxNode *node = m_clientList.Nth( n );
wxCHECK_MSG( node, NULL, wxT("invalid index in wxChoice::DoGetClientData") ); 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 ) 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 ); wxNode *node = m_clientList.Nth( n );
wxCHECK_RET( node, wxT("invalid index in wxChoice::DoSetClientObject") ); 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 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 ); wxNode *node = m_clientList.Nth( n );
wxCHECK_MSG( node, (wxClientData *)NULL, wxCHECK_MSG( node, (wxClientData *)NULL,
@@ -186,17 +186,12 @@ void wxChoice::Clear()
GtkWidget *menu = gtk_menu_new(); GtkWidget *menu = gtk_menu_new();
gtk_option_menu_set_menu( GTK_OPTION_MENU(m_widget), menu ); gtk_option_menu_set_menu( GTK_OPTION_MENU(m_widget), menu );
if (m_clientDataItemsType == ClientData_Object) if ( m_clientDataItemsType == ClientData_Object )
{ m_clientList.DeleteContents(TRUE);
wxNode *node = m_clientList.First();
while (node)
{
wxClientData *cd = (wxClientData*)node->Data();
if (cd) delete cd;
node = node->Next();
}
}
m_clientList.Clear(); m_clientList.Clear();
if ( m_strings )
m_strings->Clear();
} }
void wxChoice::Delete( int WXUNUSED(n) ) void wxChoice::Delete( int WXUNUSED(n) )

View File

@@ -215,20 +215,20 @@ static void gtk_listitem_select_callback( GtkWidget *WXUNUSED(widget), wxListBox
wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, listbox->GetId() ); wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, listbox->GetId() );
wxArrayInt aSelections; wxArrayInt aSelections;
int count = listbox->GetSelections(aSelections); int n, count = listbox->GetSelections(aSelections);
if ( count > 0 ) if ( count > 0 )
{ {
event.m_commandInt = aSelections[0] ; n = aSelections[0];
event.m_clientData = listbox->GetClientData( event.m_commandInt ); event.m_clientData = listbox->m_clientData.Item(n);
wxString str(listbox->GetString(event.m_commandInt)); event.m_commandString = listbox->GetString(n);
if (!str.IsEmpty()) event.m_commandString = str;
} }
else else
{ {
event.m_commandInt = -1 ; n = -1;
event.m_commandString.Empty();
} }
event.m_commandInt = n;
event.SetEventObject( listbox ); event.SetEventObject( listbox );
listbox->GetEventHandler()->ProcessEvent( event ); listbox->GetEventHandler()->ProcessEvent( event );
@@ -240,6 +240,10 @@ static void gtk_listitem_select_callback( GtkWidget *WXUNUSED(widget), wxListBox
IMPLEMENT_DYNAMIC_CLASS(wxListBox,wxControl) IMPLEMENT_DYNAMIC_CLASS(wxListBox,wxControl)
// ----------------------------------------------------------------------------
// construction
// ----------------------------------------------------------------------------
wxListBox::wxListBox() wxListBox::wxListBox()
{ {
m_list = (GtkList *) NULL; m_list = (GtkList *) NULL;
@@ -251,7 +255,8 @@ wxListBox::wxListBox()
bool wxListBox::Create( wxWindow *parent, wxWindowID id, bool wxListBox::Create( wxWindow *parent, wxWindowID id,
const wxPoint &pos, const wxSize &size, const wxPoint &pos, const wxSize &size,
int n, const wxString choices[], 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_needParent = TRUE;
m_acceptsFocus = TRUE; m_acceptsFocus = TRUE;
@@ -260,7 +265,7 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id,
!CreateBase( parent, id, pos, size, style, validator, name )) !CreateBase( parent, id, pos, size, style, validator, name ))
{ {
wxFAIL_MSG( wxT("wxListBox creation failed") ); wxFAIL_MSG( wxT("wxListBox creation failed") );
return FALSE; return FALSE;
} }
m_widget = gtk_scrolled_window_new( (GtkAdjustment*) NULL, (GtkAdjustment*) NULL ); 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_set_focus_vadjustment(
GTK_CONTAINER(m_list), GTK_CONTAINER(m_list),
gtk_scrolled_window_get_vadjustment( gtk_scrolled_window_get_vadjustment(
GTK_SCROLLED_WINDOW(m_widget))); GTK_SCROLLED_WINDOW(m_widget)));
gtk_widget_show( GTK_WIDGET(m_list) ); 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; if (newSize.y == -1) newSize.y = 110;
SetSize( newSize.x, newSize.y ); 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++) for (int i = 0; i < n; i++)
{ {
m_clientDataList.Append( (wxObject*) NULL ); m_clientData.Append((wxObject *)NULL);
m_clientObjectList.Append( (wxObject*) NULL );
GtkWidget *list_item; DoAppend(choices[i]);
#if 0
wxString str(choices[i]); wxString str(choices[i]);
#if wxUSE_CHECKLISTBOX #if wxUSE_CHECKLISTBOX
if (m_hasCheckBoxes) if (m_hasCheckBoxes)
{ {
@@ -319,7 +331,7 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id,
} }
#endif // wxUSE_CHECKLISTBOX #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 ); gtk_container_add( GTK_CONTAINER(m_list), list_item );
@@ -353,6 +365,7 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id,
ConnectWidget( list_item ); ConnectWidget( list_item );
gtk_widget_show( list_item ); gtk_widget_show( list_item );
#endif // 0
} }
m_parent->DoAddChild( this ); m_parent->DoAddChild( this );
@@ -373,10 +386,15 @@ wxListBox::~wxListBox()
Clear(); 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") ); 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; GList *children = m_list->children;
int length = g_list_length(children); int length = g_list_length(children);
wxCHECK_RET( pos <= length, wxT("invalid index in wxListBox::InsertItems") ); 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 // all items after this position, then append these items and then
// reappend back the old ones. // reappend back the old ones.
// first detach the old items // VZ: notice that InsertItems knows nothing about sorting, so calling it
int n; // loop var // 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 ) if ( pos == length )
{ {
// no need to do anything complicated // no need to do anything complicated
for ( n = 0; n < nItems; n++ ) 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; return;
} }
// remove the old items
wxArrayString deletedLabels; wxArrayString deletedLabels;
wxArrayPtrVoid deletedData; wxArrayPtrVoid deletedData;
wxArrayInt deletedChecks; // only for check list boxes #if wxUSE_CHECKLISTBOX
wxArrayInt deletedChecks;
#endif
GList *child = g_list_nth( children, pos ); GList *child = g_list_nth( children, pos );
for ( n = 0; child != NULL; n++, child = child->next ) 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); deletedLabels.Add(str);
// save data // save data
void *clientData = NULL; deletedData.Add(m_clientData.Item(n));
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);
#if wxUSE_CHECKLISTBOX #if wxUSE_CHECKLISTBOX
// save check state // save check state
@@ -450,21 +458,33 @@ void wxListBox::InsertItems(int nItems, const wxString items[], int pos)
#endif // wxUSE_CHECKLISTBOX #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 ); gtk_list_clear_items( m_list, pos, length );
// now append the new items // now append the new items
for ( n = 0; n < nItems; n++ ) for ( n = 0; n < nItems; n++ )
{ {
Append(items[n]); AppendWithoutSorting(items[n]);
m_clientData.Append((wxObject *)NULL);
} }
// and append the old items too // and append the old items too
pos += nItems; // now the indices are shifter pos += nItems; // now the indices are shifter
for ( n = 0; n < nDeletedCount; n++ ) 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 wxUSE_CHECKLISTBOX
if ( m_hasCheckBoxes ) if ( m_hasCheckBoxes )
@@ -473,9 +493,35 @@ void wxListBox::InsertItems(int nItems, const wxString items[], int pos)
} }
#endif // wxUSE_CHECKLISTBOX #endif // wxUSE_CHECKLISTBOX
} }
wxASSERT_MSG( m_clientData.GetCount() == (size_t)GetCount(),
wxT("bug in client data management") );
} }
void wxListBox::AppendCommon( const wxString &item ) 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::AppendWithoutSorting( const wxString &item )
{ {
wxCHECK_RET( m_list != NULL, wxT("invalid listbox") ); wxCHECK_RET( m_list != NULL, wxT("invalid listbox") );
@@ -539,9 +585,9 @@ void wxListBox::AppendCommon( const wxString &item )
} }
#if wxUSE_DRAG_AND_DROP #if wxUSE_DRAG_AND_DROP
#ifndef NEW_GTK_DND_CODE #ifndef NEW_GTK_DND_CODE
if (m_dropTarget) m_dropTarget->RegisterWidget( list_item ); if (m_dropTarget) m_dropTarget->RegisterWidget( list_item );
#endif #endif
#endif #endif
#if wxUSE_TOOLTIPS #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 ); Clear();
m_clientObjectList.Append( (wxObject*) NULL );
AppendCommon( item ); DoInsertItems(items, 0);
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, void *clientData ) // ----------------------------------------------------------------------------
// client data
// ----------------------------------------------------------------------------
void wxListBox::DoSetClientData( int n, void* clientData )
{ {
m_clientDataList.Append( (wxObject*) clientData ); wxCHECK_RET( m_widget != NULL, wxT("invalid listbox control") );
m_clientObjectList.Append( (wxObject*) NULL );
AppendCommon( item ); wxNode *node = m_clientData.Nth( n );
} wxCHECK_RET( node, wxT("invalid index in wxListBox::DoSetClientData") );
void wxListBox::Append( const wxString &item, wxClientData *clientData )
{
m_clientObjectList.Append( (wxObject*) clientData );
m_clientDataList.Append( (wxObject*) NULL );
AppendCommon( item );
}
void wxListBox::SetClientData( int n, void* clientData )
{
wxCHECK_RET( m_widget != NULL, wxT("invalid combobox") );
wxNode *node = m_clientDataList.Nth( n );
if (!node) return;
node->SetData( (wxObject*) clientData ); 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 ); wxNode *node = m_clientData.Nth( n );
if (!node) return NULL; wxCHECK_MSG( node, NULL, wxT("invalid index in wxListBox::DoGetClientData") );
return node->Data(); 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 ); wxNode *node = m_clientData.Nth( n );
if (!node) return; wxCHECK_RET( node, wxT("invalid index in wxListBox::DoSetClientObject") );
wxClientData *cd = (wxClientData*) node->Data(); wxClientData *cd = (wxClientData*) node->Data();
if (cd) delete cd; delete cd;
node->SetData( (wxObject*) clientData ); 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 ); wxNode *node = m_clientData.Nth( n );
if (!node) return (wxClientData*) NULL; wxCHECK_MSG( node, (wxClientData *)NULL,
wxT("invalid index in wxListBox::DoGetClientObject") );
return (wxClientData*) node->Data(); return (wxClientData*) node->Data();
} }
@@ -623,16 +667,12 @@ void wxListBox::Clear()
gtk_list_clear_items( m_list, 0, Number() ); gtk_list_clear_items( m_list, 0, Number() );
wxNode *node = m_clientObjectList.First(); if ( m_clientDataItemsType == ClientData_Object )
while (node) m_clientData.DeleteContents(TRUE);
{ m_clientData.Clear();
wxClientData *cd = (wxClientData*)node->Data();
if (cd) delete cd;
node = node->Next();
}
m_clientObjectList.Clear();
m_clientDataList.Clear(); if ( m_strings )
m_strings->Clear();
} }
void wxListBox::Delete( int n ) void wxListBox::Delete( int n )
@@ -647,30 +687,84 @@ void wxListBox::Delete( int n )
gtk_list_remove_items( m_list, list ); gtk_list_remove_items( m_list, list );
g_list_free( list ); g_list_free( list );
wxNode *node = m_clientObjectList.Nth( n ); wxNode *node = m_clientData.Nth( n );
if (node) if ( node )
{ {
wxClientData *cd = (wxClientData*)node->Data(); if ( m_clientDataItemsType == ClientData_Object )
if (cd) delete cd; {
m_clientObjectList.DeleteNode( node ); wxClientData *cd = (wxClientData*)node->Data();
delete cd;
}
m_clientData.DeleteNode( node );
} }
node = m_clientDataList.Nth( n ); if ( m_strings )
if (node) m_strings->Remove(n);
{
m_clientDataList.DeleteNode( node );
}
} }
void wxListBox::Deselect( int n ) // ----------------------------------------------------------------------------
// string list access
// ----------------------------------------------------------------------------
void wxListBox::SetString( int n, const wxString &string )
{ {
wxCHECK_RET( m_list != NULL, wxT("invalid listbox") ); wxCHECK_RET( m_list != NULL, 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;
#if wxUSE_CHECKLISTBOX
if (m_hasCheckBoxes)
str += CHECKBOX_STRING;
#endif // wxUSE_CHECKLISTBOX
str += string;
EnableEvents(); gtk_label_set( label, str.mbc_str() );
}
else
{
wxFAIL_MSG(wxT("wrong listbox index"));
}
}
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("");
}
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 int wxListBox::FindString( const wxString &item ) const
@@ -693,11 +787,15 @@ int wxListBox::FindString( const wxString &item ) const
child = child->next; 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 int wxListBox::GetSelection() const
{ {
wxCHECK_MSG( m_list != NULL, -1, wxT("invalid listbox") ); wxCHECK_MSG( m_list != NULL, -1, wxT("invalid listbox") );
@@ -743,56 +841,7 @@ int wxListBox::GetSelections( wxArrayInt& aSelections ) const
return count; return count;
} }
wxString wxListBox::GetString( int n ) const bool wxListBox::IsSelected( 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 )
{ {
wxCHECK_MSG( m_list != NULL, FALSE, wxT("invalid listbox") ); wxCHECK_MSG( m_list != NULL, FALSE, wxT("invalid listbox") );
@@ -806,25 +855,12 @@ bool wxListBox::Selected( int n )
child = child->next; child = child->next;
} }
} }
wxFAIL_MSG(wxT("wrong listbox index")); wxFAIL_MSG(wxT("wrong listbox index"));
return FALSE; 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"));
}
void wxListBox::SetFirstItem( const wxString &WXUNUSED(item) )
{
wxFAIL_MSG(wxT("wxListBox::SetFirstItem not implemented"));
}
void wxListBox::SetSelection( int n, bool select ) void wxListBox::SetSelection( int n, bool select )
{ {
wxCHECK_RET( m_list != NULL, wxT("invalid listbox") ); wxCHECK_RET( m_list != NULL, wxT("invalid listbox") );
@@ -839,37 +875,14 @@ void wxListBox::SetSelection( int n, bool select )
EnableEvents(); EnableEvents();
} }
void wxListBox::SetString( int n, const wxString &string ) void wxListBox::DoSetFirstItem( int WXUNUSED(n) )
{ {
wxCHECK_RET( m_list != NULL, wxT("invalid listbox") ); wxFAIL_MSG(wxT("wxListBox::SetFirstItem not implemented"));
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"));
}
} }
void wxListBox::SetStringSelection( const wxString &string, bool select ) // ----------------------------------------------------------------------------
{ // helpers
wxCHECK_RET( m_list != NULL, wxT("invalid listbox") ); // ----------------------------------------------------------------------------
SetSelection( FindString(string), select );
}
int wxListBox::GetIndex( GtkWidget *item ) const int wxListBox::GetIndex( GtkWidget *item ) const
{ {
@@ -1020,22 +1033,22 @@ void wxListBox::OnInternalIdle()
if (GTK_WIDGET(m_list)->window && cursor.Ok()) if (GTK_WIDGET(m_list)->window && cursor.Ok())
{ {
/* I now set the cursor the anew in every OnInternalIdle call /* I now set the cursor the anew in every OnInternalIdle call
as setting the cursor in a parent window also effects the as setting the cursor in a parent window also effects the
windows above so that checking for the current cursor is windows above so that checking for the current cursor is
not possible. */ not possible. */
gdk_window_set_cursor( GTK_WIDGET(m_list)->window, cursor.GetCursor() ); gdk_window_set_cursor( GTK_WIDGET(m_list)->window, cursor.GetCursor() );
GList *child = m_list->children; GList *child = m_list->children;
while (child) while (child)
{ {
GtkBin *bin = GTK_BIN( child->data ); GtkBin *bin = GTK_BIN( child->data );
GtkWidget *label = GTK_WIDGET( bin->child ); GtkWidget *label = GTK_WIDGET( bin->child );
if (!label->window) if (!label->window)
break; break;
else else
gdk_window_set_cursor( label->window, cursor.GetCursor() ); gdk_window_set_cursor( label->window, cursor.GetCursor() );
child = child->next; child = child->next;
} }

View File

@@ -127,7 +127,7 @@ wxChoice::~wxChoice()
int wxChoice::DoAppend( const wxString &item ) 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) ); 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 ) 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 ); wxNode *node = m_clientList.Nth( n );
wxCHECK_RET( node, wxT("invalid index in wxChoice::DoSetClientData") ); 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 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 ); wxNode *node = m_clientList.Nth( n );
wxCHECK_MSG( node, NULL, wxT("invalid index in wxChoice::DoGetClientData") ); 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 ) 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 ); wxNode *node = m_clientList.Nth( n );
wxCHECK_RET( node, wxT("invalid index in wxChoice::DoSetClientObject") ); 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 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 ); wxNode *node = m_clientList.Nth( n );
wxCHECK_MSG( node, (wxClientData *)NULL, wxCHECK_MSG( node, (wxClientData *)NULL,
@@ -186,17 +186,12 @@ void wxChoice::Clear()
GtkWidget *menu = gtk_menu_new(); GtkWidget *menu = gtk_menu_new();
gtk_option_menu_set_menu( GTK_OPTION_MENU(m_widget), menu ); gtk_option_menu_set_menu( GTK_OPTION_MENU(m_widget), menu );
if (m_clientDataItemsType == ClientData_Object) if ( m_clientDataItemsType == ClientData_Object )
{ m_clientList.DeleteContents(TRUE);
wxNode *node = m_clientList.First();
while (node)
{
wxClientData *cd = (wxClientData*)node->Data();
if (cd) delete cd;
node = node->Next();
}
}
m_clientList.Clear(); m_clientList.Clear();
if ( m_strings )
m_strings->Clear();
} }
void wxChoice::Delete( int WXUNUSED(n) ) void wxChoice::Delete( int WXUNUSED(n) )

View File

@@ -215,20 +215,20 @@ static void gtk_listitem_select_callback( GtkWidget *WXUNUSED(widget), wxListBox
wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, listbox->GetId() ); wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, listbox->GetId() );
wxArrayInt aSelections; wxArrayInt aSelections;
int count = listbox->GetSelections(aSelections); int n, count = listbox->GetSelections(aSelections);
if ( count > 0 ) if ( count > 0 )
{ {
event.m_commandInt = aSelections[0] ; n = aSelections[0];
event.m_clientData = listbox->GetClientData( event.m_commandInt ); event.m_clientData = listbox->m_clientData.Item(n);
wxString str(listbox->GetString(event.m_commandInt)); event.m_commandString = listbox->GetString(n);
if (!str.IsEmpty()) event.m_commandString = str;
} }
else else
{ {
event.m_commandInt = -1 ; n = -1;
event.m_commandString.Empty();
} }
event.m_commandInt = n;
event.SetEventObject( listbox ); event.SetEventObject( listbox );
listbox->GetEventHandler()->ProcessEvent( event ); listbox->GetEventHandler()->ProcessEvent( event );
@@ -240,6 +240,10 @@ static void gtk_listitem_select_callback( GtkWidget *WXUNUSED(widget), wxListBox
IMPLEMENT_DYNAMIC_CLASS(wxListBox,wxControl) IMPLEMENT_DYNAMIC_CLASS(wxListBox,wxControl)
// ----------------------------------------------------------------------------
// construction
// ----------------------------------------------------------------------------
wxListBox::wxListBox() wxListBox::wxListBox()
{ {
m_list = (GtkList *) NULL; m_list = (GtkList *) NULL;
@@ -251,7 +255,8 @@ wxListBox::wxListBox()
bool wxListBox::Create( wxWindow *parent, wxWindowID id, bool wxListBox::Create( wxWindow *parent, wxWindowID id,
const wxPoint &pos, const wxSize &size, const wxPoint &pos, const wxSize &size,
int n, const wxString choices[], 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_needParent = TRUE;
m_acceptsFocus = TRUE; m_acceptsFocus = TRUE;
@@ -260,7 +265,7 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id,
!CreateBase( parent, id, pos, size, style, validator, name )) !CreateBase( parent, id, pos, size, style, validator, name ))
{ {
wxFAIL_MSG( wxT("wxListBox creation failed") ); wxFAIL_MSG( wxT("wxListBox creation failed") );
return FALSE; return FALSE;
} }
m_widget = gtk_scrolled_window_new( (GtkAdjustment*) NULL, (GtkAdjustment*) NULL ); 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_set_focus_vadjustment(
GTK_CONTAINER(m_list), GTK_CONTAINER(m_list),
gtk_scrolled_window_get_vadjustment( gtk_scrolled_window_get_vadjustment(
GTK_SCROLLED_WINDOW(m_widget))); GTK_SCROLLED_WINDOW(m_widget)));
gtk_widget_show( GTK_WIDGET(m_list) ); 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; if (newSize.y == -1) newSize.y = 110;
SetSize( newSize.x, newSize.y ); 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++) for (int i = 0; i < n; i++)
{ {
m_clientDataList.Append( (wxObject*) NULL ); m_clientData.Append((wxObject *)NULL);
m_clientObjectList.Append( (wxObject*) NULL );
GtkWidget *list_item; DoAppend(choices[i]);
#if 0
wxString str(choices[i]); wxString str(choices[i]);
#if wxUSE_CHECKLISTBOX #if wxUSE_CHECKLISTBOX
if (m_hasCheckBoxes) if (m_hasCheckBoxes)
{ {
@@ -319,7 +331,7 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id,
} }
#endif // wxUSE_CHECKLISTBOX #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 ); gtk_container_add( GTK_CONTAINER(m_list), list_item );
@@ -353,6 +365,7 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id,
ConnectWidget( list_item ); ConnectWidget( list_item );
gtk_widget_show( list_item ); gtk_widget_show( list_item );
#endif // 0
} }
m_parent->DoAddChild( this ); m_parent->DoAddChild( this );
@@ -373,10 +386,15 @@ wxListBox::~wxListBox()
Clear(); 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") ); 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; GList *children = m_list->children;
int length = g_list_length(children); int length = g_list_length(children);
wxCHECK_RET( pos <= length, wxT("invalid index in wxListBox::InsertItems") ); 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 // all items after this position, then append these items and then
// reappend back the old ones. // reappend back the old ones.
// first detach the old items // VZ: notice that InsertItems knows nothing about sorting, so calling it
int n; // loop var // 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 ) if ( pos == length )
{ {
// no need to do anything complicated // no need to do anything complicated
for ( n = 0; n < nItems; n++ ) 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; return;
} }
// remove the old items
wxArrayString deletedLabels; wxArrayString deletedLabels;
wxArrayPtrVoid deletedData; wxArrayPtrVoid deletedData;
wxArrayInt deletedChecks; // only for check list boxes #if wxUSE_CHECKLISTBOX
wxArrayInt deletedChecks;
#endif
GList *child = g_list_nth( children, pos ); GList *child = g_list_nth( children, pos );
for ( n = 0; child != NULL; n++, child = child->next ) 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); deletedLabels.Add(str);
// save data // save data
void *clientData = NULL; deletedData.Add(m_clientData.Item(n));
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);
#if wxUSE_CHECKLISTBOX #if wxUSE_CHECKLISTBOX
// save check state // save check state
@@ -450,21 +458,33 @@ void wxListBox::InsertItems(int nItems, const wxString items[], int pos)
#endif // wxUSE_CHECKLISTBOX #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 ); gtk_list_clear_items( m_list, pos, length );
// now append the new items // now append the new items
for ( n = 0; n < nItems; n++ ) for ( n = 0; n < nItems; n++ )
{ {
Append(items[n]); AppendWithoutSorting(items[n]);
m_clientData.Append((wxObject *)NULL);
} }
// and append the old items too // and append the old items too
pos += nItems; // now the indices are shifter pos += nItems; // now the indices are shifter
for ( n = 0; n < nDeletedCount; n++ ) 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 wxUSE_CHECKLISTBOX
if ( m_hasCheckBoxes ) if ( m_hasCheckBoxes )
@@ -473,9 +493,35 @@ void wxListBox::InsertItems(int nItems, const wxString items[], int pos)
} }
#endif // wxUSE_CHECKLISTBOX #endif // wxUSE_CHECKLISTBOX
} }
wxASSERT_MSG( m_clientData.GetCount() == (size_t)GetCount(),
wxT("bug in client data management") );
} }
void wxListBox::AppendCommon( const wxString &item ) 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::AppendWithoutSorting( const wxString &item )
{ {
wxCHECK_RET( m_list != NULL, wxT("invalid listbox") ); wxCHECK_RET( m_list != NULL, wxT("invalid listbox") );
@@ -539,9 +585,9 @@ void wxListBox::AppendCommon( const wxString &item )
} }
#if wxUSE_DRAG_AND_DROP #if wxUSE_DRAG_AND_DROP
#ifndef NEW_GTK_DND_CODE #ifndef NEW_GTK_DND_CODE
if (m_dropTarget) m_dropTarget->RegisterWidget( list_item ); if (m_dropTarget) m_dropTarget->RegisterWidget( list_item );
#endif #endif
#endif #endif
#if wxUSE_TOOLTIPS #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 ); Clear();
m_clientObjectList.Append( (wxObject*) NULL );
AppendCommon( item ); DoInsertItems(items, 0);
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, void *clientData ) // ----------------------------------------------------------------------------
// client data
// ----------------------------------------------------------------------------
void wxListBox::DoSetClientData( int n, void* clientData )
{ {
m_clientDataList.Append( (wxObject*) clientData ); wxCHECK_RET( m_widget != NULL, wxT("invalid listbox control") );
m_clientObjectList.Append( (wxObject*) NULL );
AppendCommon( item ); wxNode *node = m_clientData.Nth( n );
} wxCHECK_RET( node, wxT("invalid index in wxListBox::DoSetClientData") );
void wxListBox::Append( const wxString &item, wxClientData *clientData )
{
m_clientObjectList.Append( (wxObject*) clientData );
m_clientDataList.Append( (wxObject*) NULL );
AppendCommon( item );
}
void wxListBox::SetClientData( int n, void* clientData )
{
wxCHECK_RET( m_widget != NULL, wxT("invalid combobox") );
wxNode *node = m_clientDataList.Nth( n );
if (!node) return;
node->SetData( (wxObject*) clientData ); 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 ); wxNode *node = m_clientData.Nth( n );
if (!node) return NULL; wxCHECK_MSG( node, NULL, wxT("invalid index in wxListBox::DoGetClientData") );
return node->Data(); 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 ); wxNode *node = m_clientData.Nth( n );
if (!node) return; wxCHECK_RET( node, wxT("invalid index in wxListBox::DoSetClientObject") );
wxClientData *cd = (wxClientData*) node->Data(); wxClientData *cd = (wxClientData*) node->Data();
if (cd) delete cd; delete cd;
node->SetData( (wxObject*) clientData ); 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 ); wxNode *node = m_clientData.Nth( n );
if (!node) return (wxClientData*) NULL; wxCHECK_MSG( node, (wxClientData *)NULL,
wxT("invalid index in wxListBox::DoGetClientObject") );
return (wxClientData*) node->Data(); return (wxClientData*) node->Data();
} }
@@ -623,16 +667,12 @@ void wxListBox::Clear()
gtk_list_clear_items( m_list, 0, Number() ); gtk_list_clear_items( m_list, 0, Number() );
wxNode *node = m_clientObjectList.First(); if ( m_clientDataItemsType == ClientData_Object )
while (node) m_clientData.DeleteContents(TRUE);
{ m_clientData.Clear();
wxClientData *cd = (wxClientData*)node->Data();
if (cd) delete cd;
node = node->Next();
}
m_clientObjectList.Clear();
m_clientDataList.Clear(); if ( m_strings )
m_strings->Clear();
} }
void wxListBox::Delete( int n ) void wxListBox::Delete( int n )
@@ -647,30 +687,84 @@ void wxListBox::Delete( int n )
gtk_list_remove_items( m_list, list ); gtk_list_remove_items( m_list, list );
g_list_free( list ); g_list_free( list );
wxNode *node = m_clientObjectList.Nth( n ); wxNode *node = m_clientData.Nth( n );
if (node) if ( node )
{ {
wxClientData *cd = (wxClientData*)node->Data(); if ( m_clientDataItemsType == ClientData_Object )
if (cd) delete cd; {
m_clientObjectList.DeleteNode( node ); wxClientData *cd = (wxClientData*)node->Data();
delete cd;
}
m_clientData.DeleteNode( node );
} }
node = m_clientDataList.Nth( n ); if ( m_strings )
if (node) m_strings->Remove(n);
{
m_clientDataList.DeleteNode( node );
}
} }
void wxListBox::Deselect( int n ) // ----------------------------------------------------------------------------
// string list access
// ----------------------------------------------------------------------------
void wxListBox::SetString( int n, const wxString &string )
{ {
wxCHECK_RET( m_list != NULL, wxT("invalid listbox") ); wxCHECK_RET( m_list != NULL, 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;
#if wxUSE_CHECKLISTBOX
if (m_hasCheckBoxes)
str += CHECKBOX_STRING;
#endif // wxUSE_CHECKLISTBOX
str += string;
EnableEvents(); gtk_label_set( label, str.mbc_str() );
}
else
{
wxFAIL_MSG(wxT("wrong listbox index"));
}
}
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("");
}
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 int wxListBox::FindString( const wxString &item ) const
@@ -693,11 +787,15 @@ int wxListBox::FindString( const wxString &item ) const
child = child->next; 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 int wxListBox::GetSelection() const
{ {
wxCHECK_MSG( m_list != NULL, -1, wxT("invalid listbox") ); wxCHECK_MSG( m_list != NULL, -1, wxT("invalid listbox") );
@@ -743,56 +841,7 @@ int wxListBox::GetSelections( wxArrayInt& aSelections ) const
return count; return count;
} }
wxString wxListBox::GetString( int n ) const bool wxListBox::IsSelected( 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 )
{ {
wxCHECK_MSG( m_list != NULL, FALSE, wxT("invalid listbox") ); wxCHECK_MSG( m_list != NULL, FALSE, wxT("invalid listbox") );
@@ -806,25 +855,12 @@ bool wxListBox::Selected( int n )
child = child->next; child = child->next;
} }
} }
wxFAIL_MSG(wxT("wrong listbox index")); wxFAIL_MSG(wxT("wrong listbox index"));
return FALSE; 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"));
}
void wxListBox::SetFirstItem( const wxString &WXUNUSED(item) )
{
wxFAIL_MSG(wxT("wxListBox::SetFirstItem not implemented"));
}
void wxListBox::SetSelection( int n, bool select ) void wxListBox::SetSelection( int n, bool select )
{ {
wxCHECK_RET( m_list != NULL, wxT("invalid listbox") ); wxCHECK_RET( m_list != NULL, wxT("invalid listbox") );
@@ -839,37 +875,14 @@ void wxListBox::SetSelection( int n, bool select )
EnableEvents(); EnableEvents();
} }
void wxListBox::SetString( int n, const wxString &string ) void wxListBox::DoSetFirstItem( int WXUNUSED(n) )
{ {
wxCHECK_RET( m_list != NULL, wxT("invalid listbox") ); wxFAIL_MSG(wxT("wxListBox::SetFirstItem not implemented"));
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"));
}
} }
void wxListBox::SetStringSelection( const wxString &string, bool select ) // ----------------------------------------------------------------------------
{ // helpers
wxCHECK_RET( m_list != NULL, wxT("invalid listbox") ); // ----------------------------------------------------------------------------
SetSelection( FindString(string), select );
}
int wxListBox::GetIndex( GtkWidget *item ) const int wxListBox::GetIndex( GtkWidget *item ) const
{ {
@@ -1020,22 +1033,22 @@ void wxListBox::OnInternalIdle()
if (GTK_WIDGET(m_list)->window && cursor.Ok()) if (GTK_WIDGET(m_list)->window && cursor.Ok())
{ {
/* I now set the cursor the anew in every OnInternalIdle call /* I now set the cursor the anew in every OnInternalIdle call
as setting the cursor in a parent window also effects the as setting the cursor in a parent window also effects the
windows above so that checking for the current cursor is windows above so that checking for the current cursor is
not possible. */ not possible. */
gdk_window_set_cursor( GTK_WIDGET(m_list)->window, cursor.GetCursor() ); gdk_window_set_cursor( GTK_WIDGET(m_list)->window, cursor.GetCursor() );
GList *child = m_list->children; GList *child = m_list->children;
while (child) while (child)
{ {
GtkBin *bin = GTK_BIN( child->data ); GtkBin *bin = GTK_BIN( child->data );
GtkWidget *label = GTK_WIDGET( bin->child ); GtkWidget *label = GTK_WIDGET( bin->child );
if (!label->window) if (!label->window)
break; break;
else else
gdk_window_set_cursor( label->window, cursor.GetCursor() ); gdk_window_set_cursor( label->window, cursor.GetCursor() );
child = child->next; child = child->next;
} }

View File

@@ -115,51 +115,11 @@ wxOwnerDrawn *wxListBox::CreateItem(size_t n)
// list box control implementation // list box control implementation
// ============================================================================ // ============================================================================
bool wxListBox::MSWCommand(WXUINT param, WXWORD WXUNUSED(id)) // ----------------------------------------------------------------------------
{ // creation
/* // ----------------------------------------------------------------------------
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();
}
event.SetEventObject( this ); // Listbox item
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
wxListBox::wxListBox() wxListBox::wxListBox()
{ {
m_noItems = 0; m_noItems = 0;
@@ -205,7 +165,7 @@ bool wxListBox::Create(wxWindow *parent,
wstyle |= LBS_EXTENDEDSEL; wstyle |= LBS_EXTENDEDSEL;
if (m_windowStyle & wxLB_ALWAYS_SB) if (m_windowStyle & wxLB_ALWAYS_SB)
wstyle |= LBS_DISABLENOSCROLL ; wstyle |= LBS_DISABLENOSCROLL;
if (m_windowStyle & wxLB_HSCROLL) if (m_windowStyle & wxLB_HSCROLL)
wstyle |= WS_HSCROLL; wstyle |= WS_HSCROLL;
if (m_windowStyle & wxLB_SORT) if (m_windowStyle & wxLB_SORT)
@@ -223,10 +183,10 @@ bool wxListBox::Create(wxWindow *parent,
wstyle |= LBS_NOINTEGRALHEIGHT; wstyle |= LBS_NOINTEGRALHEIGHT;
bool want3D; 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 // Even with extended styles, need to combine with WS_BORDER for them to
// for them to look right. // look right.
if ( want3D || wxStyleHasBorder(m_windowStyle) ) if ( want3D || wxStyleHasBorder(m_windowStyle) )
{ {
wstyle |= WS_BORDER; wstyle |= WS_BORDER;
@@ -284,20 +244,16 @@ void wxListBox::SetupColours()
SetForegroundColour(GetParent()->GetForegroundColour()); SetForegroundColour(GetParent()->GetForegroundColour());
} }
void wxListBox::SetFirstItem(int N) // ----------------------------------------------------------------------------
// implementation of wxListBoxBase methods
// ----------------------------------------------------------------------------
void wxListBox::DoSetFirstItem(int N)
{ {
wxCHECK_RET( N >= 0 && N < m_noItems, wxCHECK_RET( N >= 0 && N < m_noItems,
wxT("invalid index in wxListBox::SetFirstItem") ); wxT("invalid index in wxListBox::SetFirstItem") );
SendMessage(GetHwnd(),LB_SETTOPINDEX,(WPARAM)N,(LPARAM)0) ; SendMessage(GetHwnd(), LB_SETTOPINDEX, (WPARAM)N, (LPARAM)0);
}
void wxListBox::SetFirstItem(const wxString& s)
{
int N = FindString(s) ;
if ( N >= 0 )
SetFirstItem(N) ;
} }
void wxListBox::Delete(int N) void wxListBox::Delete(int N)
@@ -311,10 +267,10 @@ void wxListBox::Delete(int N)
SetHorizontalExtent(""); SetHorizontalExtent("");
} }
void wxListBox::Append(const wxString& item) int wxListBox::DoAppend(const wxString& item)
{ {
int index = ListBox_AddString(GetHwnd(), item); int index = ListBox_AddString(GetHwnd(), item);
m_noItems ++; m_noItems++;
#if wxUSE_OWNER_DRAWN #if wxUSE_OWNER_DRAWN
if ( m_windowStyle & wxLB_OWNERDRAW ) { if ( m_windowStyle & wxLB_OWNERDRAW ) {
@@ -326,39 +282,31 @@ void wxListBox::Append(const wxString& item)
#endif #endif
SetHorizontalExtent(item); SetHorizontalExtent(item);
return index;
} }
void wxListBox::Append(const wxString& item, void *Client_data) void wxListBox::DoSetItems(const wxArrayString& choices, void** clientData)
{
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);
}
void wxListBox::Set(int n, const wxString *choices, void** clientData)
{ {
ShowWindow(GetHwnd(), SW_HIDE); ShowWindow(GetHwnd(), SW_HIDE);
ListBox_ResetContent(GetHwnd()); ListBox_ResetContent(GetHwnd());
m_noItems = choices.GetCount();
int i; int i;
for (i = 0; i < n; i++) for (i = 0; i < m_noItems; i++)
{ {
ListBox_AddString(GetHwnd(), choices[i]); ListBox_AddString(GetHwnd(), choices[i]);
if ( clientData ) 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]); ListBox_SetItemData(GetHwnd(), i, clientData[i]);
#endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN
}
} }
m_noItems = n;
#if wxUSE_OWNER_DRAWN #if wxUSE_OWNER_DRAWN
if ( m_windowStyle & wxLB_OWNERDRAW ) { if ( m_windowStyle & wxLB_OWNERDRAW ) {
@@ -370,19 +318,17 @@ void wxListBox::Set(int n, const wxString *choices, void** clientData)
m_aItems.Empty(); m_aItems.Empty();
// then create new ones // 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); wxOwnerDrawn *pNewItem = CreateItem(ui);
pNewItem->SetName(choices[ui]); pNewItem->SetName(choices[ui]);
m_aItems.Add(pNewItem); m_aItems.Add(pNewItem);
ListBox_SetItemData(GetHwnd(), ui, 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); ShowWindow(GetHwnd(), SW_SHOW);
} }
@@ -390,7 +336,7 @@ int wxListBox::FindString(const wxString& s) const
{ {
int pos = ListBox_FindStringExact(GetHwnd(), (WPARAM)-1, s); int pos = ListBox_FindStringExact(GetHwnd(), (WPARAM)-1, s);
if (pos == LB_ERR) if (pos == LB_ERR)
return -1; return wxNOT_FOUND;
else else
return pos; return pos;
} }
@@ -409,7 +355,7 @@ void wxListBox::Clear()
#endif // wxUSE_OWNER_DRAWN #endif // wxUSE_OWNER_DRAWN
m_noItems = 0; m_noItems = 0;
ListBox_GetHorizontalExtent(GetHwnd()); SetHorizontalExtent();
} }
void wxListBox::SetSelection(int N, bool select) 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, wxCHECK_RET( N >= 0 && N < m_noItems,
wxT("invalid index in wxListBox::SetSelection") ); wxT("invalid index in wxListBox::SetSelection") );
if ((m_windowStyle & wxLB_MULTIPLE) || (m_windowStyle & wxLB_EXTENDED)) if ( HasMultipleSelection() )
{
SendMessage(GetHwnd(), LB_SETSEL, select, N); SendMessage(GetHwnd(), LB_SETSEL, select, N);
}
else else
{ {
int N1 = N; SendMessage(GetHwnd(), LB_SETCURSEL, select ? N : -1, 0);
if (!select)
N1 = -1;
SendMessage(GetHwnd(), LB_SETCURSEL, N1, 0);
} }
} }
bool wxListBox::Selected(int N) const bool wxListBox::IsSelected(int N) const
{ {
wxCHECK_MSG( N >= 0 && N < m_noItems, FALSE, wxCHECK_MSG( N >= 0 && N < m_noItems, FALSE,
wxT("invalid index in wxListBox::Selected") ); 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; 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, return (wxClientData *)DoGetClientData(n);
wxT("invalid index in wxListBox::Deselect") );
if ((m_windowStyle & wxLB_MULTIPLE) || (m_windowStyle & wxLB_EXTENDED))
SendMessage(GetHwnd(), LB_SETSEL, FALSE, 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") ); 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") ); 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")); 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 // Return number of selections and an array of selected integers
int wxListBox::GetSelections(wxArrayInt& aSelections) const int wxListBox::GetSelections(wxArrayInt& aSelections) const
{ {
aSelections.Empty(); aSelections.Empty();
if ((m_windowStyle & wxLB_MULTIPLE) || (m_windowStyle & wxLB_EXTENDED)) if ( HasMultipleSelection() )
{ {
int no_sel = ListBox_GetSelCount(GetHwnd()); int no_sel = ListBox_GetSelCount(GetHwnd());
if (no_sel != 0) { if (no_sel != 0) {
int *selections = new int[no_sel]; int *selections = new int[no_sel];
if ( ListBox_GetSelItems(GetHwnd(), no_sel, selections) == LB_ERR ) { int rc = ListBox_GetSelItems(GetHwnd(), no_sel, selections);
wxFAIL_MSG(wxT("This listbox can't have single-selection style!"));
} wxCHECK_MSG(rc != LB_ERR, -1, wxT("ListBox_GetSelItems failed"));
aSelections.Alloc(no_sel); aSelections.Alloc(no_sel);
for ( int n = 0; n < no_sel; n++ ) 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 // Get single selection, for single choice list items
int wxListBox::GetSelection() const int wxListBox::GetSelection() const
{ {
wxCHECK_MSG( !(m_windowStyle & wxLB_MULTIPLE) && wxCHECK_MSG( !HasMultipleSelection(),
!(m_windowStyle & wxLB_EXTENDED),
-1, -1,
wxT("GetSelection() can't be used with multiple-selection " wxT("GetSelection() can't be used with multiple-selection "
"listboxes, use GetSelections() instead.") ); "listboxes, use GetSelections() instead.") );
@@ -521,6 +480,70 @@ wxString wxListBox::GetString(int N) const
return result; 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 // 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. // necessary. If s is non-NULL, it's used to calculate the horizontal extent.
// Otherwise, all strings are used. // Otherwise, all strings are used.
@@ -531,7 +554,7 @@ void wxListBox::SetHorizontalExtent(const wxString& s)
return; return;
TEXTMETRIC lpTextMetric; TEXTMETRIC lpTextMetric;
if (s != wxT("")) if ( !s.IsEmpty() )
{ {
int existingExtent = (int)SendMessage(GetHwnd(), LB_GETHORIZONTALEXTENT, 0, 0L); int existingExtent = (int)SendMessage(GetHwnd(), LB_GETHORIZONTALEXTENT, 0, 0L);
HDC dc = GetWindowDC(GetHwnd()); HDC dc = GetWindowDC(GetHwnd());
@@ -550,7 +573,6 @@ void wxListBox::SetHorizontalExtent(const wxString& s)
ReleaseDC(GetHwnd(), dc); ReleaseDC(GetHwnd(), dc);
if (extentX > existingExtent) if (extentX > existingExtent)
SendMessage(GetHwnd(), LB_SETHORIZONTALEXTENT, LOWORD(extentX), 0L); SendMessage(GetHwnd(), LB_SETHORIZONTALEXTENT, LOWORD(extentX), 0L);
return;
} }
else 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() wxSize wxListBox::DoGetBestSize()
{ {
// find the widest string // find the widest string
@@ -682,26 +631,56 @@ wxSize wxListBox::DoGetBestSize()
return wxSize(wListbox, hListbox); 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. // callbacks
// 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 bool wxListBox::MSWCommand(WXUINT param, WXWORD WXUNUSED(id))
// by the actual window system, or a separate function, ProcessCommand)
void wxListBox::Command (wxCommandEvent & event)
{ {
if (event.m_extraLong) /*
SetSelection (event.m_commandInt); if (param == LBN_SELCANCEL)
else {
event.extraLong = FALSE;
}
*/
if (param == LBN_SELCHANGE)
{ {
Deselect (event.m_commandInt); wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, m_windowId);
return; 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, 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 wxUSE_CTL3D
if ( m_useCtl3D ) if ( m_useCtl3D )
@@ -727,10 +706,9 @@ WXHBRUSH wxListBox::OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor,
return (WXHBRUSH) backgroundBrush->GetResourceHandle(); return (WXHBRUSH) backgroundBrush->GetResourceHandle();
} }
long wxListBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) // ----------------------------------------------------------------------------
{ // wxCheckListBox support
return wxControl::MSWWindowProc(nMsg, wParam, lParam); // ----------------------------------------------------------------------------
}
#if wxUSE_OWNER_DRAWN #if wxUSE_OWNER_DRAWN

View 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! # DO NOT CHANGE THIS FILE, YOUR CHANGES WILL BE LOST! CHANGE B32.T!
# #
@@ -154,6 +154,7 @@ COMMONOBJS = \
$(MSWDIR)\intl.obj \ $(MSWDIR)\intl.obj \
$(MSWDIR)\ipcbase.obj \ $(MSWDIR)\ipcbase.obj \
$(MSWDIR)\layout.obj \ $(MSWDIR)\layout.obj \
$(MSWDIR)\lboxcmn.obj \
$(MSWDIR)\list.obj \ $(MSWDIR)\list.obj \
$(MSWDIR)\log.obj \ $(MSWDIR)\log.obj \
$(MSWDIR)\memory.obj \ $(MSWDIR)\memory.obj \
@@ -618,6 +619,8 @@ $(MSWDIR)\ipcbase.obj: $(COMMDIR)\ipcbase.$(SRCSUFF)
$(MSWDIR)\layout.obj: $(COMMDIR)\layout.$(SRCSUFF) $(MSWDIR)\layout.obj: $(COMMDIR)\layout.$(SRCSUFF)
$(MSWDIR)\lboxcmn.obj: $(COMMDIR)\lboxcmn.$(SRCSUFF)
$(MSWDIR)\list.obj: $(COMMDIR)\list.$(SRCSUFF) $(MSWDIR)\list.obj: $(COMMDIR)\list.$(SRCSUFF)
$(MSWDIR)\log.obj: $(COMMDIR)\log.$(SRCSUFF) $(MSWDIR)\log.obj: $(COMMDIR)\log.$(SRCSUFF)

View 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! # DO NOT CHANGE THIS FILE, YOUR CHANGES WILL BE LOST! CHANGE BCC.T!
# #
@@ -139,6 +139,7 @@ COMMONOBJS = \
$(MSWDIR)\intl.obj \ $(MSWDIR)\intl.obj \
$(MSWDIR)\ipcbase.obj \ $(MSWDIR)\ipcbase.obj \
$(MSWDIR)\layout.obj \ $(MSWDIR)\layout.obj \
$(MSWDIR)\lboxcmn.obj \
$(MSWDIR)\list.obj \ $(MSWDIR)\list.obj \
$(MSWDIR)\log.obj \ $(MSWDIR)\log.obj \
$(MSWDIR)\memory.obj \ $(MSWDIR)\memory.obj \
@@ -514,6 +515,8 @@ $(MSWDIR)\ipcbase.obj: $(COMMDIR)\ipcbase.$(SRCSUFF)
$(MSWDIR)\layout.obj: $(COMMDIR)\layout.$(SRCSUFF) $(MSWDIR)\layout.obj: $(COMMDIR)\layout.$(SRCSUFF)
$(MSWDIR)\lboxcmn.obj: $(COMMDIR)\lboxcmn.$(SRCSUFF)
$(MSWDIR)\list.obj: $(COMMDIR)\list.$(SRCSUFF) $(MSWDIR)\list.obj: $(COMMDIR)\list.$(SRCSUFF)
$(MSWDIR)\log.obj: $(COMMDIR)\log.$(SRCSUFF) $(MSWDIR)\log.obj: $(COMMDIR)\log.$(SRCSUFF)

View 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! # DO NOT CHANGE THIS FILE, YOUR CHANGES WILL BE LOST! CHANGE DOS.T!
# #
@@ -126,6 +126,7 @@ COMMONOBJS = \
$(COMMDIR)\intl.obj \ $(COMMDIR)\intl.obj \
$(COMMDIR)\ipcbase.obj \ $(COMMDIR)\ipcbase.obj \
$(COMMDIR)\layout.obj \ $(COMMDIR)\layout.obj \
$(COMMDIR)\lboxcmn.obj \
$(COMMDIR)\list.obj \ $(COMMDIR)\list.obj \
$(COMMDIR)\log.obj \ $(COMMDIR)\log.obj \
$(COMMDIR)\memory.obj \ $(COMMDIR)\memory.obj \
@@ -875,6 +876,11 @@ $(COMMDIR)/layout.obj: $*.$(SRCSUFF)
$(CPPFLAGS) /Fo$@ /c /Tp $*.$(SRCSUFF) $(CPPFLAGS) /Fo$@ /c /Tp $*.$(SRCSUFF)
<< <<
$(COMMDIR)/lboxcmn.obj: $*.$(SRCSUFF)
cl @<<
$(CPPFLAGS) /Fo$@ /c /Tp $*.$(SRCSUFF)
<<
$(COMMDIR)/list.obj: $*.$(SRCSUFF) $(COMMDIR)/list.obj: $*.$(SRCSUFF)
cl @<< cl @<<
$(CPPFLAGS) /Fo$@ /c /Tp $*.$(SRCSUFF) $(CPPFLAGS) /Fo$@ /c /Tp $*.$(SRCSUFF)

View File

@@ -1,5 +1,4 @@
# This file was automatically generated by tmake at 16:37, 1999/10/22
# This file was automatically generated by tmake at 12:32, 1999/10/22
# DO NOT CHANGE THIS FILE, YOUR CHANGES WILL BE LOST! CHANGE G95.T! # DO NOT CHANGE THIS FILE, YOUR CHANGES WILL BE LOST! CHANGE G95.T!
# #
@@ -105,6 +104,7 @@ COMMONOBJS = \
$(COMMDIR)/intl.$(OBJSUFF) \ $(COMMDIR)/intl.$(OBJSUFF) \
$(COMMDIR)/ipcbase.$(OBJSUFF) \ $(COMMDIR)/ipcbase.$(OBJSUFF) \
$(COMMDIR)/layout.$(OBJSUFF) \ $(COMMDIR)/layout.$(OBJSUFF) \
$(COMMDIR)/lboxcmn.$(OBJSUFF) \
$(COMMDIR)/list.$(OBJSUFF) \ $(COMMDIR)/list.$(OBJSUFF) \
$(COMMDIR)/log.$(OBJSUFF) \ $(COMMDIR)/log.$(OBJSUFF) \
$(COMMDIR)/memory.$(OBJSUFF) \ $(COMMDIR)/memory.$(OBJSUFF) \
@@ -258,15 +258,6 @@ MSWOBJS = \
$(MSWDIR)/window.$(OBJSUFF) \ $(MSWDIR)/window.$(OBJSUFF) \
$(MSWDIR)/xpmhand.$(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 = \ ZLIBOBJS = \
$(ZLIBDIR)/adler32.$(OBJSUFF) \ $(ZLIBDIR)/adler32.$(OBJSUFF) \
$(ZLIBDIR)/compress.$(OBJSUFF) \ $(ZLIBDIR)/compress.$(OBJSUFF) \
@@ -362,20 +353,7 @@ XPMOBJECTS = $(XPMDIR)/crbuffri.o\
$(XPMDIR)/wrffrp.o $(XPMDIR)/wrffri.o $(XPMDIR)/wrffrp.o $(XPMDIR)/wrffri.o
OBJECTS = $(MSWOBJS) $(COMMONOBJS) $(GENERICOBJS) $(HTMLOBJS) \ 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) $(JPEGOBJS) $(PNGOBJS) $(ZLIBOBJS) # $(XPMOBJECTS)
endif
else
OBJECTS = $(MSWOBJS) $(COMMONOBJS) $(GENERICOBJS) $(HTMLOBJS) \
$(JPEGOBJS) $(PNGOBJS) $(ZLIBOBJS) # $(XPMOBJECTS)
endif
all: $(OBJECTS) $(WXLIB) all: $(OBJECTS) $(WXLIB)
@@ -425,21 +403,21 @@ $(COMMDIR)/lex_yy.c: $(COMMDIR)/doslex.c
# mv y.tab.c $(COMMDIR)/y_tab.c # mv y.tab.c $(COMMDIR)/y_tab.c
clean: clean:
rm -f *.o -erase *.o
rm -f *.bak -erase *.bak
rm -f core -erase core
rm -f ..\common\y_tab.c -erase ..\common\y_tab.c
rm -f ..\common\lex_yy.c -erase ..\common\lex_yy.c
rm -f ..\common\*.o -erase ..\common\*.o
rm -f ..\common\*.bak -erase ..\common\*.bak
rm -f ..\generic\*.o -erase ..\generic\*.o
rm -f ..\generic\*.bak -erase ..\generic\*.bak
rm -f ..\html\*.o -erase ..\html\*.o
rm -f ..\png\*.o -erase ..\png\*.o
rm -f ..\png\*.bak -erase ..\png\*.bak
rm -f ..\zlib\*.o -erase ..\zlib\*.o
rm -f ..\zlib\*.bak -erase ..\zlib\*.bak
rm -f ..\jpeg\*.o -erase ..\jpeg\*.o
rm -f ..\..\lib\libwx.a -erase ..\..\lib\libwx.a
cleanall: clean cleanall: clean

View 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! # DO NOT CHANGE THIS FILE, YOUR CHANGES WILL BE LOST! CHANGE SC.T!
# Symantec C++ makefile for the msw objects # Symantec C++ makefile for the msw objects
@@ -93,6 +93,7 @@ COMMONOBJS = \
$(COMMDIR)\intl.obj \ $(COMMDIR)\intl.obj \
$(COMMDIR)\ipcbase.obj \ $(COMMDIR)\ipcbase.obj \
$(COMMDIR)\layout.obj \ $(COMMDIR)\layout.obj \
$(COMMDIR)\lboxcmn.obj \
$(COMMDIR)\list.obj \ $(COMMDIR)\list.obj \
$(COMMDIR)\log.obj \ $(COMMDIR)\log.obj \
$(COMMDIR)\memory.obj \ $(COMMDIR)\memory.obj \

View 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! # DO NOT CHANGE THIS FILE, YOUR CHANGES WILL BE LOST! CHANGE VC.T!
# File: makefile.vc # File: makefile.vc
@@ -171,6 +171,7 @@ COMMONOBJS = \
..\common\$D\intl.obj \ ..\common\$D\intl.obj \
..\common\$D\ipcbase.obj \ ..\common\$D\ipcbase.obj \
..\common\$D\layout.obj \ ..\common\$D\layout.obj \
..\common\$D\lboxcmn.obj \
..\common\$D\list.obj \ ..\common\$D\list.obj \
..\common\$D\log.obj \ ..\common\$D\log.obj \
..\common\$D\memory.obj \ ..\common\$D\memory.obj \

View 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! # DO NOT CHANGE THIS FILE, YOUR CHANGES WILL BE LOST! CHANGE WAT.T!
#!/binb/wmake.exe #!/binb/wmake.exe
@@ -119,6 +119,7 @@ COMMONOBJS = &
intl.obj & intl.obj &
ipcbase.obj & ipcbase.obj &
layout.obj & layout.obj &
lboxcmn.obj &
list.obj & list.obj &
log.obj & log.obj &
memory.obj & memory.obj &
@@ -692,6 +693,9 @@ ipcbase.obj: $(COMMDIR)\ipcbase.cpp
layout.obj: $(COMMDIR)\layout.cpp layout.obj: $(COMMDIR)\layout.cpp
*$(CCC) $(CPPFLAGS) $(IFLAGS) $< *$(CCC) $(CPPFLAGS) $(IFLAGS) $<
lboxcmn.obj: $(COMMDIR)\lboxcmn.cpp
*$(CCC) $(CPPFLAGS) $(IFLAGS) $<
list.obj: $(COMMDIR)\list.cpp list.obj: $(COMMDIR)\list.cpp
*$(CCC) $(CPPFLAGS) $(IFLAGS) $< *$(CCC) $(CPPFLAGS) $(IFLAGS) $<