diff --git a/docs/doxygen/overviews/propgrid.h b/docs/doxygen/overviews/propgrid.h index ba37bc48aa..c24203017b 100644 --- a/docs/doxygen/overviews/propgrid.h +++ b/docs/doxygen/overviews/propgrid.h @@ -296,8 +296,8 @@ You have to provide list of constant labels, and optionally relevant values @remarks -- Value wxPG_INVALID_VALUE (equals 2147483647 which usually equals INT_MAX) is not - allowed as value. +- Value wxPG_INVALID_VALUE (equals INT_MAX) is not allowed as list + item value. A very simple example: @@ -365,7 +365,6 @@ Here's extended example using values as well: long array_diet_ids[] = { 40, 45, 50 }; - // Value can be set from string as well pg->Append( new wxEnumProperty(wxT("Diet"), wxPG_LABEL, array_diet, @@ -394,45 +393,26 @@ Here's extended example using values as well: // Note: you can add even whole arrays to wxPGChoices - pg->Append( new wxEnumProperty(wxT("Diet"), + pg->Append( new wxEnumProperty(wxT("Primary Diet"), wxPG_LABEL, chs) ); // Add same choices to another property as well - this is efficient due // to reference counting - pg->Append( new wxEnumProperty(wxT("Diet 2"), + pg->Append( new wxEnumProperty(wxT("Secondary Diet"), wxPG_LABEL, chs) ); - @endcode - -If you later need to change choices used by a property, there is function -for that as well. - -@code - - // - // Example 1: Add one extra item - wxPGChoices& choices = pg->GetPropertyChoices(wxT("Diet")); - choices.Add(wxT("Custom"),55); - - // - // Example 2: Replace all the choices - wxPGChoices chs; - chs.Add(wxT(""),0); - pg->SetPropertyChoices(wxT("Diet"),chs); - @endcode -If you want to create your enum properties with simple (label,name,value) -constructor, then you need to create a new property class using one of the -supplied macro pairs. See @ref pgproperty_creating for details. +You can later change choices of property by using wxPGProperty::InsertChoice(), +wxPGProperty::DeleteChoice(), and wxPGProperty::SetChoices(). wxEditEnumProperty is works exactly like wxEnumProperty, except is uses non-readonly combobox as default editor, and value is stored as string when it is not any of the choices. -wxFlagsProperty is similar: +wxFlagsProperty has similar construction: @code @@ -454,8 +434,8 @@ wxFlagsProperty is similar: wxFlagsProperty can use wxPGChoices just the same way as wxEnumProperty (and also custom property classes can be created with similar macro pairs). Note: When changing "choices" (ie. flag labels) of wxFlagsProperty, -you will need to use SetPropertyChoices - otherwise they will not get updated -properly. +you will need to use wxPGProperty::SetChoices() to replace all choices +at once - otherwise they will not get updated properly. @section propgrid_advprops Specialized Properties @@ -839,7 +819,7 @@ each cell in the property grid. Use wxPropertyGridInterface::SetPropertyCell() o wxPGProperty::SetCell() for this purpose. In addition, it is possible to control these characteristics for -wxPGChoices list items. See wxPGChoices::Item() and wxPGChoiceEntry class +wxPGChoices list items. See wxPGChoices class reference for more info. @@ -1049,8 +1029,8 @@ unique (base) name. pg->SetPropertyAttribute(wxT("MyFlagsProperty"),wxPG_BOOL_USE_CHECKBOX,true,wxPG_RECURSE); @endcode - - Default item names for wxBoolProperty are [wxT("False"),wxT("True")]. This can be - changed using wxPropertyGrid::SetBoolChoices(trueChoice,falseChoice). + - Default item names for wxBoolProperty are ["False", "True"]. This can be + changed using wxPropertyGrid::SetBoolChoices(trueChoice, falseChoice). @subsection propgrid_textctrlupdates Updates from wxTextCtrl Based Editor diff --git a/include/wx/propgrid/advprops.h b/include/wx/propgrid/advprops.h index a3fb60dd83..a73c0d3c76 100644 --- a/include/wx/propgrid/advprops.h +++ b/include/wx/propgrid/advprops.h @@ -372,8 +372,6 @@ public: int argFlags = 0) const; WX_PG_DECLARE_EVENT_METHODS() - virtual int GetChoiceInfo( wxPGChoiceInfo* choiceinfo ); - wxArrayInt GetValueAsArrayInt() const { return m_choices.GetValuesForStrings(m_value.GetArrayString()); @@ -388,8 +386,6 @@ protected: wxArrayString m_valueAsStrings; // Value as array of strings - wxPGChoices m_choices; - // Cache displayed text since generating it is relatively complicated. wxString m_display; }; diff --git a/include/wx/propgrid/property.h b/include/wx/propgrid/property.h index 593de4b467..cd4ec9f2af 100644 --- a/include/wx/propgrid/property.h +++ b/include/wx/propgrid/property.h @@ -47,13 +47,6 @@ struct wxPGPaintData }; -// Structure for relaying choice/list info. -struct wxPGChoiceInfo -{ - wxPGChoices* m_choices; -}; - - #ifndef SWIG @@ -567,6 +560,383 @@ wxPG_PROP_CLASS_SPECIFIC_2 = 0x00100000 // ----------------------------------------------------------------------- +#ifndef SWIG + +/** @class wxPGChoiceEntry + Data of a single wxPGChoices choice. +*/ +class WXDLLIMPEXP_PROPGRID wxPGChoiceEntry : public wxPGCell +{ +public: + wxPGChoiceEntry(); + wxPGChoiceEntry( const wxPGChoiceEntry& entry ); + wxPGChoiceEntry( const wxString& label, + int value = wxPG_INVALID_VALUE ) + : wxPGCell(), m_value(value) + { + m_text = label; + } + + wxPGChoiceEntry( const wxString& label, + int value, + const wxBitmap& bitmap, + const wxColour& fgCol = wxNullColour, + const wxColour& bgCol = wxNullColour ) + : wxPGCell(label, bitmap, fgCol, bgCol), m_value(value) + { + } + + virtual ~wxPGChoiceEntry() + { + } + + void SetValue( int value ) { m_value = value; } + + int GetValue() const { return m_value; } + + bool HasValue() const { return (m_value != wxPG_INVALID_VALUE); } + +protected: + int m_value; +}; + + +typedef void* wxPGChoicesId; + +class WXDLLIMPEXP_PROPGRID wxPGChoicesData +{ + friend class wxPGChoices; +public: + // Constructor sets m_refCount to 1. + wxPGChoicesData(); + + void CopyDataFrom( wxPGChoicesData* data ); + + // Takes ownership of 'item' + void Insert( int index, wxPGChoiceEntry* item ) + { + wxArrayPtrVoid::iterator it; + if ( index == -1 ) + { + it = m_items.end(); + index = m_items.size(); + } + else + { + it = m_items.begin() + index; + } + + // Need to fix value? + if ( item->GetValue() == wxPG_INVALID_VALUE ) + item->SetValue(index); + + m_items.insert(it, item); + } + + // Delete all entries + void Clear(); + + size_t GetCount() const { return m_items.size(); } + + wxPGChoiceEntry* Item( unsigned int i ) const + { + wxCHECK_MSG( i < GetCount(), NULL, "invalid index" ); + + return (wxPGChoiceEntry*) m_items[i]; + } + + void DecRef() + { + m_refCount--; + wxASSERT( m_refCount >= 0 ); + if ( m_refCount == 0 ) + delete this; + } + +private: + wxArrayPtrVoid m_items; + + // So that multiple properties can use the same set + int m_refCount; + + virtual ~wxPGChoicesData(); +}; + +#define wxPGChoicesEmptyData ((wxPGChoicesData*)NULL) + +#endif // SWIG + +/** @class wxPGChoices + + Helper class for managing choices of wxPropertyGrid properties. + Each entry can have label, value, bitmap, text colour, and background + colour. + + @library{wxpropgrid} + @category{propgrid} +*/ +class WXDLLIMPEXP_PROPGRID wxPGChoices +{ +public: + typedef long ValArrItem; + + /** Default constructor. */ + wxPGChoices() + { + Init(); + } + + /** Copy constructor. */ + wxPGChoices( const wxPGChoices& a ) + { + if ( a.m_data != wxPGChoicesEmptyData ) + { + m_data = a.m_data; + m_data->m_refCount++; + } + } + + /** Constructor. */ + wxPGChoices( const wxChar** labels, const long* values = NULL ) + { + Init(); + Set(labels,values); + } + + /** Constructor. */ + wxPGChoices( const wxArrayString& labels, + const wxArrayInt& values = wxArrayInt() ) + { + Init(); + Set(labels,values); + } + + /** Simple interface constructor. */ + wxPGChoices( wxPGChoicesData* data ) + { + wxASSERT(data); + m_data = data; + data->m_refCount++; + } + + /** Destructor. */ + ~wxPGChoices() + { + Free(); + } + + /** + Adds to current. + + If did not have own copies, creates them now. If was empty, identical + to set except that creates copies. + */ + void Add( const wxChar** labels, const ValArrItem* values = NULL ); + + /** Version that works with wxArrayString. */ + void Add( const wxArrayString& arr, const ValArrItem* values = NULL ); + + /** Version that works with wxArrayString and wxArrayInt. */ + void Add( const wxArrayString& arr, const wxArrayInt& arrint ); + + /** Adds single item. */ + wxPGChoiceEntry& Add( const wxString& label, + int value = wxPG_INVALID_VALUE ); + + /** Adds a single item, with bitmap. */ + wxPGChoiceEntry& Add( const wxString& label, + const wxBitmap& bitmap, + int value = wxPG_INVALID_VALUE ); + + /** Adds a single item with full entry information. */ + wxPGChoiceEntry& Add( const wxPGChoiceEntry& entry ) + { + return Insert(entry, -1); + } + + /** Adds single item. */ + wxPGChoiceEntry& AddAsSorted( const wxString& label, + int value = wxPG_INVALID_VALUE ); + + void Assign( const wxPGChoices& a ) + { + AssignData(a.m_data); + } + + void AssignData( wxPGChoicesData* data ); + + /** Delete all choices. */ + void Clear() + { + if ( m_data != wxPGChoicesEmptyData ) + m_data->Clear(); + } + + void EnsureData() + { + if ( m_data == wxPGChoicesEmptyData ) + m_data = new wxPGChoicesData(); + } + + /** Gets a unsigned number identifying this list. */ + wxPGChoicesId GetId() const { return (wxPGChoicesId) m_data; }; + + const wxString& GetLabel( size_t ind ) const + { + return Item(ind).GetText(); + } + + size_t GetCount () const + { + if ( !m_data ) + return 0; + + return m_data->GetCount(); + } + + int GetValue( size_t ind ) const { return Item(ind).GetValue(); } + + /** Returns array of values matching the given strings. Unmatching strings + result in wxPG_INVALID_VALUE entry in array. + */ + wxArrayInt GetValuesForStrings( const wxArrayString& strings ) const; + + /** Returns array of indices matching given strings. Unmatching strings + are added to 'unmatched', if not NULL. + */ + wxArrayInt GetIndicesForStrings( const wxArrayString& strings, + wxArrayString* unmatched = NULL ) const; + + /** Returns true if choices in general are likely to have values + (depens on that all entries have values or none has) + */ + bool HasValues() const; + + bool HasValue( unsigned int i ) const + { return (i < m_data->GetCount()) && m_data->Item(i)->HasValue(); } + + int Index( const wxString& str ) const; + int Index( int val ) const; + + /** Inserts single item. */ + wxPGChoiceEntry& Insert( const wxString& label, + int index, + int value = wxPG_INVALID_VALUE ); + + /** Inserts a single item with full entry information. */ + wxPGChoiceEntry& Insert( const wxPGChoiceEntry& entry, int index ); + + /** Returns false if this is a constant empty set of choices, + which should not be modified. + */ + bool IsOk() const + { + return ( m_data != wxPGChoicesEmptyData ); + } + + const wxPGChoiceEntry& Item( unsigned int i ) const + { + wxASSERT( IsOk() ); + return *m_data->Item(i); + } + + wxPGChoiceEntry& Item( unsigned int i ) + { + wxASSERT( IsOk() ); + return *m_data->Item(i); + } + + /** Removes count items starting at position nIndex. */ + void RemoveAt(size_t nIndex, size_t count = 1); + +#ifndef SWIG + /** Does not create copies for itself. */ + void Set( const wxChar** labels, const long* values = NULL ) + { + Free(); + Add(labels,values); + } + + /** Version that works with wxArrayString. + TODO: Deprecate this. + */ + void Set( wxArrayString& arr, const long* values = (const long*) NULL ) + { + Free(); + Add(arr,values); + } +#endif // SWIG + + /** Version that works with wxArrayString and wxArrayInt. */ + void Set( const wxArrayString& labels, + const wxArrayInt& values = wxArrayInt() ) + { + Free(); + if ( &values ) + Add(labels,values); + else + Add(labels); + } + + // Creates exclusive copy of current choices + void SetExclusive() + { + if ( m_data->m_refCount != 1 ) + { + wxPGChoicesData* data = new wxPGChoicesData(); + data->CopyDataFrom(m_data); + Free(); + m_data = data; + } + } + + // Returns data, increases refcount. + wxPGChoicesData* GetData() + { + wxASSERT( m_data->m_refCount != 0xFFFFFFF ); + m_data->m_refCount++; + return m_data; + } + + // Returns plain data ptr - no refcounting stuff is done. + wxPGChoicesData* GetDataPtr() const { return m_data; } + + // Changes ownership of data to you. + wxPGChoicesData* ExtractData() + { + wxPGChoicesData* data = m_data; + m_data = wxPGChoicesEmptyData; + return data; + } + + wxArrayString GetLabels() const; + +#ifndef SWIG + void operator= (const wxPGChoices& a) + { + AssignData(a.m_data); + } + + wxPGChoiceEntry& operator[](unsigned int i) + { + return Item(i); + } + + const wxPGChoiceEntry& operator[](unsigned int i) const + { + return Item(i); + } + +protected: + wxPGChoicesData* m_data; + + void Init(); + void Free(); +#endif // !SWIG +}; + +// ----------------------------------------------------------------------- + /** @class wxPGProperty wxPGProperty is base class for all wxPropertyGrid properties. @@ -853,21 +1223,6 @@ public: */ virtual wxValidator* DoGetValidator () const; - /** - Returns current value's index to the choice control. - - May also return, through pointer arguments, strings that should be - inserted to that control. Irrelevant to classes which do not employ - wxPGEditor_Choice or similar. - - @remarks - - If returns NULL in choiceinfo.m_choices, then this class must be - derived from wxBaseEnumProperty. - - Must be able to cope situation where property's set of choices is - uninitialized. - */ - virtual int GetChoiceInfo( wxPGChoiceInfo* choiceinfo ); - /** Override to paint an image in front of the property value text or drop-down list item (but only if wxPGProperty::OnMeasureImage is @@ -923,6 +1278,14 @@ public: */ virtual wxPGCellRenderer* GetCellRenderer( int column ) const; + /** Returns which choice is currently selected. Only applies to properties + which have choices. + + Needs to reimplemented in derived class if property value does not + map directly to a choice. Integer as index, bool, and string usually do. + */ + virtual int GetChoiceSelection() const; + /** Refresh values of child properties. @@ -955,17 +1318,6 @@ public: */ virtual wxPGEditorDialogAdapter* GetEditorDialog() const; - /** - Adds entry to property's wxPGChoices and editor control (if it is - active). - - Returns index of item added. - */ - int AppendChoice( const wxString& label, int value = wxPG_INVALID_VALUE ) - { - return InsertChoice(label,-1,value); - } - /** Returns wxPGCell of given column, NULL if none. If valid object is returned, caller will gain its ownership. */ @@ -979,6 +1331,13 @@ public: return cell; } + /** Append a new choice to property's list of choices. + */ + int AddChoice( const wxString& label, int value = wxPG_INVALID_VALUE ) + { + return InsertChoice(label, wxNOT_FOUND, value); + } + /** Returns true if children of this property are component values (for instance, points size, face name, and is_underlined are component @@ -1028,11 +1387,12 @@ public: */ const wxString& GetBaseName() const { return m_name; } - wxPGChoices& GetChoices(); - - const wxPGChoices& GetChoices() const; - - const wxPGChoiceEntry* GetCurrentChoice() const; + /** Returns read-only reference to property's list of choices. + */ + const wxPGChoices& GetChoices() const + { + return m_choices; + } /** Returns coordinate to the top y of the property. Note that the position of scrollbars is not taken into account. @@ -1077,10 +1437,6 @@ public: return (wxPGCell*) m_cells[column]; } - unsigned int GetChoiceCount() const; - - wxString GetChoiceString( unsigned int index ); - /** Return number of displayed common values for this property. */ int GetDisplayedCommonValueCount() const; @@ -1171,15 +1527,9 @@ public: */ bool HasVisibleChildren() const; - /** - Adds entry to property's wxPGChoices and editor control (if it is - active). - - Returns index of item added. + /** Inserts a new choice to property's list of choices. */ - int InsertChoice( const wxString& label, - int index, - int value = wxPG_INVALID_VALUE ); + int InsertChoice( const wxString& label, int index, int value = wxPG_INVALID_VALUE ); /** Returns true if this property is actually a wxPropertyCategory. @@ -1341,10 +1691,6 @@ public: */ void SetCell( int column, wxPGCell* cellObj ); - /** Changes value of a property with choices, but only - works if the value type is long or string. */ - void SetChoiceSelection( int newValue, const wxPGChoiceInfo& choiceInfo ); - /** Sets common value selected for this property. -1 for none. */ void SetCommonValue( int commonValue ) @@ -1402,7 +1748,17 @@ public: /** If property has choices and they are not yet exclusive, new such copy of them will be created. */ - void SetChoicesExclusive(); + void SetChoicesExclusive() + { + m_choices.SetExclusive(); + } + + /** Sets selected choice and changes property value. + + Tries to retain value type, although currently if it is not string, + then it is forced to integer. + */ + void SetChoiceSelection( int newValue ); void SetExpanded( bool expanded ) { @@ -1501,8 +1857,12 @@ public: /** Sets new set of choices for property. */ - inline bool SetChoices( const wxArrayString& labels, - const wxArrayInt& values = wxArrayInt() ); + bool SetChoices( const wxArrayString& labels, + const wxArrayInt& values = wxArrayInt() ) + { + wxPGChoices chs(labels, values); + return SetChoices(chs); + } /** Set max length of text in text editor. */ @@ -1682,6 +2042,9 @@ protected: // Extended cell information wxArrayPtrVoid m_cells; + // Choices shown in drop-down list of editor control. + wxPGChoices m_choices; + // Help shown in statusbar or help box. wxString m_helpString; @@ -1813,390 +2176,6 @@ private: // ----------------------------------------------------------------------- -#ifndef SWIG - -/** @class wxPGChoiceEntry - Data of a single wxPGChoices choice. -*/ -class WXDLLIMPEXP_PROPGRID wxPGChoiceEntry : public wxPGCell -{ -public: - wxPGChoiceEntry(); - wxPGChoiceEntry( const wxPGChoiceEntry& entry ); - wxPGChoiceEntry( const wxString& label, - int value = wxPG_INVALID_VALUE ) - : wxPGCell(), m_value(value) - { - m_text = label; - } - - wxPGChoiceEntry( const wxString& label, - int value, - const wxBitmap& bitmap, - const wxColour& fgCol = wxNullColour, - const wxColour& bgCol = wxNullColour ) - : wxPGCell(label, bitmap, fgCol, bgCol), m_value(value) - { - } - - virtual ~wxPGChoiceEntry() - { - } - - void SetValue( int value ) { m_value = value; } - - int GetValue() const { return m_value; } - - bool HasValue() const { return (m_value != wxPG_INVALID_VALUE); } - -protected: - int m_value; -}; - - -typedef void* wxPGChoicesId; - -class WXDLLIMPEXP_PROPGRID wxPGChoicesData -{ - friend class wxPGChoices; -public: - // Constructor sets m_refCount to 1. - wxPGChoicesData(); - - void CopyDataFrom( wxPGChoicesData* data ); - - // Takes ownership of 'item' - void Insert( int index, wxPGChoiceEntry* item ) - { - wxArrayPtrVoid::iterator it; - if ( index == -1 ) - { - it = m_items.end(); - index = m_items.size(); - } - else - { - it = m_items.begin() + index; - } - - // Need to fix value? - if ( item->GetValue() == wxPG_INVALID_VALUE ) - item->SetValue(index); - - m_items.insert(it, item); - } - - // Delete all entries - void Clear(); - - size_t GetCount() const { return m_items.size(); } - - wxPGChoiceEntry* Item( unsigned int i ) const - { - wxCHECK_MSG( i < GetCount(), NULL, "invalid index" ); - - return (wxPGChoiceEntry*) m_items[i]; - } - - void DecRef() - { - m_refCount--; - wxASSERT( m_refCount >= 0 ); - if ( m_refCount == 0 ) - delete this; - } - -private: - wxArrayPtrVoid m_items; - - // So that multiple properties can use the same set - int m_refCount; - - virtual ~wxPGChoicesData(); -}; - -#define wxPGChoicesEmptyData ((wxPGChoicesData*)NULL) - -#endif // SWIG - - -/** @class wxPGChoices - - Helper class for managing choices of wxPropertyGrid properties. - Each entry can have label, value, bitmap, text colour, and background - colour. - - @library{wxpropgrid} - @category{propgrid} -*/ -class WXDLLIMPEXP_PROPGRID wxPGChoices -{ -public: - typedef long ValArrItem; - - /** Default constructor. */ - wxPGChoices() - { - Init(); - } - - /** Copy constructor. */ - wxPGChoices( const wxPGChoices& a ) - { - if ( a.m_data != wxPGChoicesEmptyData ) - { - m_data = a.m_data; - m_data->m_refCount++; - } - } - - /** Constructor. */ - wxPGChoices( const wxChar** labels, const long* values = NULL ) - { - Init(); - Set(labels,values); - } - - /** Constructor. */ - wxPGChoices( const wxArrayString& labels, - const wxArrayInt& values = wxArrayInt() ) - { - Init(); - Set(labels,values); - } - - /** Simple interface constructor. */ - wxPGChoices( wxPGChoicesData* data ) - { - wxASSERT(data); - m_data = data; - data->m_refCount++; - } - - /** Destructor. */ - ~wxPGChoices() - { - Free(); - } - - /** - Adds to current. - - If did not have own copies, creates them now. If was empty, identical - to set except that creates copies. - */ - void Add( const wxChar** labels, const ValArrItem* values = NULL ); - - /** Version that works with wxArrayString. */ - void Add( const wxArrayString& arr, const ValArrItem* values = NULL ); - - /** Version that works with wxArrayString and wxArrayInt. */ - void Add( const wxArrayString& arr, const wxArrayInt& arrint ); - - /** Adds single item. */ - wxPGChoiceEntry& Add( const wxString& label, - int value = wxPG_INVALID_VALUE ); - - /** Adds a single item, with bitmap. */ - wxPGChoiceEntry& Add( const wxString& label, - const wxBitmap& bitmap, - int value = wxPG_INVALID_VALUE ); - - /** Adds a single item with full entry information. */ - wxPGChoiceEntry& Add( const wxPGChoiceEntry& entry ) - { - return Insert(entry, -1); - } - - /** Adds single item. */ - wxPGChoiceEntry& AddAsSorted( const wxString& label, - int value = wxPG_INVALID_VALUE ); - - void Assign( const wxPGChoices& a ) - { - AssignData(a.m_data); - } - - void AssignData( wxPGChoicesData* data ); - - /** Delete all choices. */ - void Clear() - { - if ( m_data != wxPGChoicesEmptyData ) - m_data->Clear(); - } - - void EnsureData() - { - if ( m_data == wxPGChoicesEmptyData ) - m_data = new wxPGChoicesData(); - } - - /** Gets a unsigned number identifying this list. */ - wxPGChoicesId GetId() const { return (wxPGChoicesId) m_data; }; - - const wxString& GetLabel( size_t ind ) const - { - return Item(ind).GetText(); - } - - size_t GetCount () const - { - wxASSERT_MSG( m_data, "When checking if wxPGChoices is valid, " - "use IsOk() instead of GetCount()" ); - return m_data->GetCount(); - } - - int GetValue( size_t ind ) const { return Item(ind).GetValue(); } - - /** Returns array of values matching the given strings. Unmatching strings - result in wxPG_INVALID_VALUE entry in array. - */ - wxArrayInt GetValuesForStrings( const wxArrayString& strings ) const; - - /** Returns array of indices matching given strings. Unmatching strings - are added to 'unmatched', if not NULL. - */ - wxArrayInt GetIndicesForStrings( const wxArrayString& strings, - wxArrayString* unmatched = NULL ) const; - - /** Returns true if choices in general are likely to have values - (depens on that all entries have values or none has) - */ - bool HasValues() const; - - bool HasValue( unsigned int i ) const - { return (i < m_data->GetCount()) && m_data->Item(i)->HasValue(); } - - int Index( const wxString& str ) const; - int Index( int val ) const; - - /** Inserts single item. */ - wxPGChoiceEntry& Insert( const wxString& label, - int index, - int value = wxPG_INVALID_VALUE ); - - /** Inserts a single item with full entry information. */ - wxPGChoiceEntry& Insert( const wxPGChoiceEntry& entry, int index ); - - /** Returns false if this is a constant empty set of choices, - which should not be modified. - */ - bool IsOk() const - { - return ( m_data != wxPGChoicesEmptyData ); - } - - const wxPGChoiceEntry& Item( unsigned int i ) const - { - wxASSERT( IsOk() ); - return *m_data->Item(i); - } - - wxPGChoiceEntry& Item( unsigned int i ) - { - wxASSERT( IsOk() ); - return *m_data->Item(i); - } - - /** Removes count items starting at position nIndex. */ - void RemoveAt(size_t nIndex, size_t count = 1); - -#ifndef SWIG - /** Does not create copies for itself. */ - void Set( const wxChar** labels, const long* values = NULL ) - { - Free(); - Add(labels,values); - } - - /** Version that works with wxArrayString. - TODO: Deprecate this. - */ - void Set( wxArrayString& arr, const long* values = (const long*) NULL ) - { - Free(); - Add(arr,values); - } -#endif // SWIG - - /** Version that works with wxArrayString and wxArrayInt. */ - void Set( const wxArrayString& labels, - const wxArrayInt& values = wxArrayInt() ) - { - Free(); - if ( &values ) - Add(labels,values); - else - Add(labels); - } - - // Creates exclusive copy of current choices - void SetExclusive() - { - if ( m_data->m_refCount != 1 ) - { - wxPGChoicesData* data = new wxPGChoicesData(); - data->CopyDataFrom(m_data); - Free(); - m_data = data; - } - } - - // Returns data, increases refcount. - wxPGChoicesData* GetData() - { - wxASSERT( m_data->m_refCount != 0xFFFFFFF ); - m_data->m_refCount++; - return m_data; - } - - // Returns plain data ptr - no refcounting stuff is done. - wxPGChoicesData* GetDataPtr() const { return m_data; } - - // Changes ownership of data to you. - wxPGChoicesData* ExtractData() - { - wxPGChoicesData* data = m_data; - m_data = wxPGChoicesEmptyData; - return data; - } - - wxArrayString GetLabels() const; - -#ifndef SWIG - void operator= (const wxPGChoices& a) - { - AssignData(a.m_data); - } - - wxPGChoiceEntry& operator[](unsigned int i) - { - return Item(i); - } - - const wxPGChoiceEntry& operator[](unsigned int i) const - { - return Item(i); - } - -protected: - wxPGChoicesData* m_data; - - void Init(); - void Free(); -#endif // !SWIG -}; - -inline bool wxPGProperty::SetChoices( const wxArrayString& labels, - const wxArrayInt& values ) -{ - wxPGChoices chs(labels, values); - return SetChoices(chs); -} - -// ----------------------------------------------------------------------- - #endif // wxUSE_PROPGRID #endif // _WX_PROPGRID_PROPERTY_H_ diff --git a/include/wx/propgrid/propgridiface.h b/include/wx/propgrid/propgridiface.h index 60aeb2d72a..76aa1afa76 100644 --- a/include/wx/propgrid/propgridiface.h +++ b/include/wx/propgrid/propgridiface.h @@ -169,20 +169,6 @@ public: /** Destructor */ virtual ~wxPropertyGridInterface() { } - /** Adds choice to a property that can accept one. - @remarks - - If you need to make sure that you modify only the set of choices of - a single property (and not also choices of other properties with - initially identical set), call - wxPropertyGrid::SetPropertyChoicesPrivate. - - This usually only works for wxEnumProperty and derivatives - (wxFlagsProperty can get accept new items but its items may not get - updated). - */ - void AddPropertyChoice( wxPGPropArg id, - const wxString& label, - int value = wxPG_INVALID_VALUE ); - /** Appends property to the list. @@ -263,14 +249,6 @@ public: */ void DeleteProperty( wxPGPropArg id ); - /** Deletes choice from a property. - - If selected item is deleted, then the value is set to unspecified. - - See AddPropertyChoice for more details. - */ - void DeletePropertyChoice( wxPGPropArg id, int index ); - /** Disables property. */ bool DisableProperty( wxPGPropArg id ) { return EnableProperty(id,false); } @@ -463,12 +441,6 @@ public: wxPGProperty* GetPropertyByName( const wxString& name, const wxString& subname ) const; - /** Returns writable reference to property's list of choices (and relevant - values). If property does not have any choices, will return reference - to an invalid set of choices that will return false on IsOk call. - */ - wxPGChoices& GetPropertyChoices( wxPGPropArg id ); - /** Returns property's editor. */ const wxPGEditor* GetPropertyEditor( wxPGPropArg id ) const { @@ -762,15 +734,6 @@ public: return p->IsCategory(); } - /** Inserts choice to a property that can accept one. - - See AddPropertyChoice for more details. - */ - void InsertPropertyChoice( wxPGPropArg id, - const wxString& label, - int index, - int value = wxPG_INVALID_VALUE ); - /** Returns true if property is enabled. */ bool IsPropertyEnabled( wxPGPropArg id ) const { @@ -971,28 +934,6 @@ public: p->SetCell( column, new wxPGCell(text, bitmap, fgCol, bgCol) ); } - /** Set choices of a property to specified set of labels and values. - - @remarks - This operation clears the property value. - */ - void SetPropertyChoices( wxPGPropArg id, wxPGChoices& choices) - { - wxPG_PROP_ARG_CALL_PROLOG() - p->SetChoices(choices); - } - - - /** - If property's set of choices is shared, then calling this method - converts it to private. - */ - void SetPropertyChoicesExclusive( wxPGPropArg id ) - { - wxPG_PROP_ARG_CALL_PROLOG() - p->SetChoicesExclusive(); - } - #ifndef SWIG /** Sets client data (void*) of a property. @remarks diff --git a/include/wx/propgrid/props.h b/include/wx/propgrid/props.h index 7e4dcb9dd0..6e42c2813a 100644 --- a/include/wx/propgrid/props.h +++ b/include/wx/propgrid/props.h @@ -39,7 +39,6 @@ class wxArrayEditorDialog; #define WX_PG_DECLARE_CHOICE_METHODS() \ virtual bool IntToValue( wxVariant& variant, \ int number, int argFlags = 0 ) const; \ - virtual int GetChoiceInfo( wxPGChoiceInfo* choiceinfo ); #define WX_PG_DECLARE_EVENT_METHODS() \ virtual bool OnEvent( wxPropertyGrid* propgrid, \ @@ -640,6 +639,11 @@ public: // pvalue is never NULL - always set it. virtual const wxString* GetEntry( size_t index, int* pvalue ) const = 0; + // GetChoiceSelection needs to overridden since m_index is + // the true index, and various property classes derived from + // this take advantage of it. + virtual int GetChoiceSelection() const { return m_index; } + int GetValueForIndex( size_t index ) const { int v; @@ -718,15 +722,11 @@ public: virtual ~wxEnumProperty(); - virtual int GetChoiceInfo( wxPGChoiceInfo* choiceinfo ); virtual int GetIndexForValue( int value ) const; virtual const wxString* GetEntry( size_t index, int* pvalue ) const; size_t GetItemCount() const { return m_choices.GetCount(); } const wxPGChoices& GetChoices() const { return m_choices; } - -protected: - wxPGChoices m_choices; }; // ----------------------------------------------------------------------- @@ -817,8 +817,9 @@ public: wxVariant& childValue ) const; virtual void RefreshChildren(); - // this is necessary for conveying m_choices - virtual int GetChoiceInfo( wxPGChoiceInfo* choiceinfo ); + // GetChoiceSelection needs to overridden since m_choices is + // used and value is integer, but it is not index. + virtual int GetChoiceSelection() const { return wxNOT_FOUND; } // helpers size_t GetItemCount() const { return m_choices.GetCount(); } @@ -826,8 +827,6 @@ public: { return m_choices.GetLabel(ind); } protected: - wxPGChoices m_choices; - // Used to detect if choices have been changed wxPGChoicesData* m_oldChoicesData; diff --git a/interface/wx/propgrid/property.h b/interface/wx/propgrid/property.h index 593e0f62c8..59f37bdc1b 100644 --- a/interface/wx/propgrid/property.h +++ b/interface/wx/propgrid/property.h @@ -10,13 +10,6 @@ #define wxNullProperty ((wxPGProperty*)NULL) -// Structure for relaying choice/list info. -struct wxPGChoiceInfo -{ - wxPGChoices* m_choices; -}; - - /** @section propgrid_property_attributes wxPropertyGrid Property Attribute Identifiers wxPGProperty::SetAttribute() and @@ -257,7 +250,8 @@ struct wxPGChoiceInfo the flags as a text; a continous sequence of spaces, commas and semicolons is considered as a flag id separator. Note: When changing "choices" (ie. flag labels) of wxFlagsProperty, you - will need to use SetPropertyChoices - otherwise they will not get updated properly. + will need to use wxPGProperty::SetChoices() - otherwise they will not get updated + properly. @subsection wxArrayStringProperty @@ -634,17 +628,6 @@ public: */ virtual wxValidator* DoGetValidator () const; - /** Returns current value's index to the choice control. May also return, - through pointer arguments, strings that should be inserted to that control. - Irrelevant to classes which do not employ wxPGEditor_Choice or similar. - @remarks - - If returns NULL in choiceinfo.m_choices, then this class must be - derived from wxBaseEnumProperty. - - Must be able to cope situation where property's set of choices is - uninitialized. - */ - virtual int GetChoiceInfo( wxPGChoiceInfo* choiceinfo ); - /** Override to paint an image in front of the property value text or drop-down list item (but only if wxPGProperty::OnMeasureImage is overridden as well). @@ -682,7 +665,7 @@ public: int m_drawnWidth; // In a measure item call, set this to the height of item at m_choiceItem index - int m_drawnHeight; + int m_drawnHeight; }; @endcode @@ -706,6 +689,14 @@ public: */ virtual wxPGCellRenderer* GetCellRenderer( int column ) const; + /** Returns which choice is currently selected. Only applies to properties + which have choices. + + Needs to reimplemented in derived class if property value does not + map directly to a choice. Integer as index, bool, and string usually do. + */ + virtual int GetChoiceSelection() const; + /** Refresh values of child properties. Automatically called after value is set. */ virtual void RefreshChildren(); @@ -735,14 +726,6 @@ public: */ virtual wxPGEditorDialogAdapter* GetEditorDialog() const; - /** Adds entry to property's wxPGChoices and editor control (if it is active). - Returns index of item added. - */ - int AppendChoice( const wxString& label, int value = wxPG_INVALID_VALUE ) - { - return InsertChoice(label,-1,value); - } - /** Returns wxPGCell of given column, NULL if none. If valid object is returned, caller will gain its ownership. */ @@ -756,6 +739,20 @@ public: return cell; } + /** Append a new choice to property's list of choices. + + @param label + Label for added choice. + + @param value + Value for new choice. Do not specify if you wish this + to equal choice index. + + @return + Index to added choice. + */ + int AddChoice( const wxString& label, int value = wxPG_INVALID_VALUE ); + /** Returns true if children of this property are component values (for instance, points size, face name, and is_underlined are component values of a font). */ @@ -796,12 +793,10 @@ public: /** Returns property's base name (ie. parent's name is not added in any case) */ const wxString& GetBaseName() const { return m_name; } - wxPGChoices& GetChoices(); - + /** Returns read-only reference to property's list of choices. + */ const wxPGChoices& GetChoices() const; - const wxPGChoiceEntry* GetCurrentChoice() const; - /** Returns coordinate to the top y of the property. Note that the position of scrollbars is not taken into account. */ @@ -843,10 +838,6 @@ public: return (wxPGCell*) m_cells[column]; } - unsigned int GetChoiceCount() const; - - wxString GetChoiceString( unsigned int index ); - /** Return number of displayed common values for this property. */ int GetDisplayedCommonValueCount() const; @@ -937,8 +928,17 @@ public: */ bool HasVisibleChildren() const; - /** Adds entry to property's wxPGChoices and editor control (if it is active). - Returns index of item added. + /** Inserts a new choice to property's list of choices. + + @param label + Text for new choice + + @param index + Insertion position. Use wxNOT_FOUND to append. + + @param value + Value for new choice. Do not specify if you wish this + to equal choice index. */ int InsertChoice( const wxString& label, int index, int value = wxPG_INVALID_VALUE ); @@ -1086,9 +1086,17 @@ public: */ void SetCell( int column, wxPGCell* cellObj ); - /** Changes value of a property with choices, but only - works if the value type is long or string. */ - void SetChoiceSelection( int newValue, const wxPGChoiceInfo& choiceInfo ); + /** If property has choices and they are not yet exclusive, new such copy + of them will be created. + */ + void SetChoicesExclusive(); + + /** Sets selected choice and changes property value. + + Tries to retain value type, although currently if it is not string, + then it is forced to integer. + */ + void SetChoiceSelection( int newValue ); /** Sets common value selected for this property. -1 for none. */ @@ -1141,11 +1149,6 @@ public: */ void SetValueImage( wxBitmap& bmp ); - /** If property has choices and they are not yet exclusive, new such copy - of them will be created. - */ - void SetChoicesExclusive(); - void SetExpanded( bool expanded ) { if ( !expanded ) m_flags |= wxPG_PROP_COLLAPSED; @@ -1280,7 +1283,7 @@ public: /** Returns height of children, recursively, and by taking expanded/collapsed status into account. - + iMax is used when finding property y-positions. */ int GetChildrenHeight( int lh, int iMax = -1 ) const; diff --git a/interface/wx/propgrid/propgridiface.h b/interface/wx/propgrid/propgridiface.h index 8bc8442175..d5aabb60e8 100644 --- a/interface/wx/propgrid/propgridiface.h +++ b/interface/wx/propgrid/propgridiface.h @@ -26,16 +26,6 @@ public: /** Destructor */ virtual ~wxPropertyGridInterface() { } - /** Adds choice to a property that can accept one. - @remarks - - If you need to make sure that you modify only the set of choices of - a single property (and not also choices of other properties with initially - identical set), call wxPropertyGrid::SetPropertyChoicesPrivate. - - This usually only works for wxEnumProperty and derivatives (wxFlagsProperty - can get accept new items but its items may not get updated). - */ - void AddPropertyChoice( wxPGPropArg id, const wxString& label, int value = wxPG_INVALID_VALUE ); - /** Appends property to the list. wxPropertyGrid assumes ownership of the object. Becomes child of most recently added category. @remarks @@ -106,14 +96,6 @@ public: /** Deletes a property by id. If category is deleted, all children are automatically deleted as well. */ void DeleteProperty( wxPGPropArg id ); - /** Deletes choice from a property. - - If selected item is deleted, then the value is set to unspecified. - - See AddPropertyChoice for more details. - */ - void DeletePropertyChoice( wxPGPropArg id, int index ); - /** Disables property. */ bool DisableProperty( wxPGPropArg id ) { return EnableProperty(id,false); } @@ -286,12 +268,6 @@ public: */ wxPGProperty* GetPropertyByName( const wxString& name, const wxString& subname ) const; - /** Returns writable reference to property's list of choices (and relevant - values). If property does not have any choices, will return reference - to an invalid set of choices that will return false on IsOk call. - */ - wxPGChoices& GetPropertyChoices( wxPGPropArg id ); - /** Returns property's editor. */ const wxPGEditor* GetPropertyEditor( wxPGPropArg id ) const { @@ -534,12 +510,6 @@ public: return p->IsCategory(); } - /** Inserts choice to a property that can accept one. - - See AddPropertyChoice for more details. - */ - void InsertPropertyChoice( wxPGPropArg id, const wxString& label, int index, int value = wxPG_INVALID_VALUE ); - /** Returns true if property is enabled. */ bool IsPropertyEnabled( wxPGPropArg id ) const { @@ -707,27 +677,6 @@ public: p->SetCell( column, new wxPGCell(text, bitmap, fgCol, bgCol) ); } - /** Set choices of a property to specified set of labels and values. - - @remarks - This operation clears the property value. - */ - void SetPropertyChoices( wxPGPropArg id, wxPGChoices& choices) - { - wxPG_PROP_ARG_CALL_PROLOG() - p->SetChoices(choices); - } - - - /** If property's set of choices is shared, then calling this method converts - it to private. - */ - void SetPropertyChoicesExclusive( wxPGPropArg id ) - { - wxPG_PROP_ARG_CALL_PROLOG() - p->SetChoicesExclusive(); - } - /** Sets client data (void*) of a property. @remarks This untyped client data has to be deleted manually. diff --git a/samples/propgrid/propgrid.cpp b/samples/propgrid/propgrid.cpp index f44d23dab8..d6ab769b84 100644 --- a/samples/propgrid/propgrid.cpp +++ b/samples/propgrid/propgrid.cpp @@ -326,14 +326,6 @@ void wxAdvImageFileProperty::OnSetValue() m_index = -1; } -int wxAdvImageFileProperty::GetChoiceInfo( wxPGChoiceInfo* choiceinfo ) -{ - if ( choiceinfo ) - choiceinfo->m_choices = &ms_choices; - - return m_index; -} - bool wxAdvImageFileProperty::IntToValue( wxVariant& variant, int number, int WXUNUSED(argFlags) ) const { wxASSERT( number >= 0 ); @@ -1488,7 +1480,7 @@ void FormMain::PopulateWithExamples () wxPG_LABEL, soc, 240) ); - pg->AddPropertyChoice(wxT("EnumProperty 2"),wxT("Testing Extra"),360); + pg->GetProperty(wxT("EnumProperty 2"))->AddChoice(wxT("Testing Extra"), 360); // Add a second time to test that the caching works pg->Append( new wxEnumProperty(wxT("EnumProperty 3"),wxPG_LABEL, @@ -1503,8 +1495,9 @@ void FormMain::PopulateWithExamples () pg->Append( new wxEnumProperty(wxT("EnumProperty 5"),wxPG_LABEL, soc, 240 ) ); - pg->SetPropertyChoicesExclusive(wxT("EnumProperty 5")); - pg->AddPropertyChoice(wxT("EnumProperty 5"),wxT("5th only"),360); + pg->GetProperty(wxT("EnumProperty 5"))->SetChoicesExclusive(); + pg->GetProperty(wxT("EnumProperty 5"))->AddChoice(wxT("5th only"), 360); + pg->SetPropertyHelpString(wxT("EnumProperty 5"), wxT("Should have one extra item when compared to EnumProperty 4")); @@ -2495,8 +2488,7 @@ void FormMain::OnFitColumnsClick( wxCommandEvent& WXUNUSED(event) ) void FormMain::OnChangeFlagsPropItemsClick( wxCommandEvent& WXUNUSED(event) ) { - - wxPGProperty* id = m_pPropGridManager->GetPropertyByName(wxT("Window Styles")); + wxPGProperty* p = m_pPropGridManager->GetPropertyByName(wxT("Window Styles")); wxPGChoices newChoices; @@ -2505,9 +2497,7 @@ void FormMain::OnChangeFlagsPropItemsClick( wxCommandEvent& WXUNUSED(event) ) newChoices.Add(wxT("Safe"),0x4); newChoices.Add(wxT("Sleek"),0x8); - m_pPropGridManager->SetPropertyChoices(id,newChoices); - //m_pPropGridManager->ReplaceProperty(wxT("Window Styles"), - // wxFlagsProperty(wxT("Window Styles"),wxPG_LABEL,newChoices)); + p->SetChoices(newChoices); } // ----------------------------------------------------------------------- @@ -2892,14 +2882,14 @@ void FormMain::OnInsertChoice( wxCommandEvent& WXUNUSED(event) ) wxPropertyGrid* pg = m_pPropGridManager->GetGrid(); wxPGProperty* selected = pg->GetSelection(); - wxPGChoices& choices = pg->GetPropertyChoices(selected); + const wxPGChoices& choices = selected->GetChoices(); // Insert new choice to the center of list if ( choices.IsOk() ) { int pos = choices.GetCount() / 2; - pg->InsertPropertyChoice(selected,wxT("New Choice"),pos); + selected->InsertChoice(wxT("New Choice"), pos); } else { @@ -2914,14 +2904,14 @@ void FormMain::OnDeleteChoice( wxCommandEvent& WXUNUSED(event) ) wxPropertyGrid* pg = m_pPropGridManager->GetGrid(); wxPGProperty* selected = pg->GetSelection(); - wxPGChoices& choices = pg->GetPropertyChoices(selected); + const wxPGChoices& choices = selected->GetChoices(); // Deletes choice from the center of list if ( choices.IsOk() ) { int pos = choices.GetCount() / 2; - pg->DeletePropertyChoice(selected,pos); + selected->DeleteChoice(pos); } else { diff --git a/samples/propgrid/tests.cpp b/samples/propgrid/tests.cpp index 17dfbae98c..0c8085141f 100644 --- a/samples/propgrid/tests.cpp +++ b/samples/propgrid/tests.cpp @@ -1023,6 +1023,24 @@ bool FormMain::RunTests( bool fullTest, bool interactive ) } } + { + RT_START_TEST(Choice_Manipulation) + + wxPGProperty* enumProp = pgman->GetProperty(wxT("EnumProperty")); + + pgman->SelectPage(2); + pgman->SelectProperty(enumProp); + wxASSERT(pgman->GetGrid()->GetSelection() == enumProp); + + const wxPGChoices& choices = enumProp->GetChoices(); + int ind = enumProp->InsertChoice(wxT("New Choice"), choices.GetCount()/2); + enumProp->DeleteChoice(ind); + + // Recreate the original grid + CreateGrid( -1, -1 ); + pgman = m_pPropGridManager; + } + //if ( !(pgman->GetWindowStyleFlag()&wxPG_HIDE_CATEGORIES) ) { RT_START_TEST(RandomCollapse) diff --git a/src/propgrid/advprops.cpp b/src/propgrid/advprops.cpp index dcc6b98207..da269ea3f4 100644 --- a/src/propgrid/advprops.cpp +++ b/src/propgrid/advprops.cpp @@ -1808,13 +1808,6 @@ bool wxMultiChoiceProperty::OnEvent( wxPropertyGrid* propgrid, return false; } -int wxMultiChoiceProperty::GetChoiceInfo( wxPGChoiceInfo* choiceinfo ) -{ - if ( choiceinfo ) - choiceinfo->m_choices = &m_choices; - return -1; -} - bool wxMultiChoiceProperty::StringToValue( wxVariant& variant, const wxString& text, int ) const { wxArrayString arr; diff --git a/src/propgrid/editors.cpp b/src/propgrid/editors.cpp index fd0a8c663c..0cf23e0faa 100644 --- a/src/propgrid/editors.cpp +++ b/src/propgrid/editors.cpp @@ -794,11 +794,15 @@ void wxPropertyGrid::OnComboItemPaint( wxPGCustomComboControl* pCc, wxPGProperty* p = m_selected; wxString text; - const wxPGChoices* pChoices = &p->GetChoices(); + const wxPGChoices& choices = p->GetChoices(); const wxPGCommonValue* comVal = NULL; - int choiceCount = p->GetChoiceCount(); int comVals = p->GetDisplayedCommonValueCount(); int comValIndex = -1; + + int choiceCount = 0; + if ( choices.IsOk() ) + choiceCount = choices.GetCount(); + if ( item >= choiceCount && comVals > 0 ) { comValIndex = item - choiceCount; @@ -826,8 +830,8 @@ void wxPropertyGrid::OnComboItemPaint( wxPGCustomComboControl* pCc, const wxBitmap* itemBitmap = NULL; - if ( item >= 0 && pChoices && pChoices->Item(item).GetBitmap().Ok() && comValIndex == -1 ) - itemBitmap = &pChoices->Item(item).GetBitmap(); + if ( item >= 0 && choices.IsOk() && choices.Item(item).GetBitmap().Ok() && comValIndex == -1 ) + itemBitmap = &choices.Item(item).GetBitmap(); // // Decide what custom image size to use @@ -929,9 +933,9 @@ void wxPropertyGrid::OnComboItemPaint( wxPGCustomComboControl* pCc, if ( item < 0 && (flags & wxODCB_PAINTING_CONTROL) ) item = pCb->GetSelection(); - if ( pChoices && item >= 0 && comValIndex < 0 ) + if ( choices.IsOk() && item >= 0 && comValIndex < 0 ) { - const wxPGChoiceEntry& cell = pChoices->Item(item); + const wxPGChoiceEntry& cell = choices.Item(item); wxPGCellRenderer* renderer = wxPGGlobalVars->m_defaultRenderer; int imageOffset = renderer->PreDrawCell( dc, rect, cell, renderFlags ); if ( imageOffset ) @@ -992,20 +996,15 @@ wxWindow* wxPGChoiceEditor::CreateControlsBase( wxPropertyGrid* propGrid, const wxSize& sz, long extraStyle ) const { - wxString defString; - - // Get choices. - int index = property->GetChoiceInfo( NULL ); + const wxPGChoices& choices = property->GetChoices(); + wxString defString; + int index = property->GetChoiceSelection(); bool isUnspecified = property->IsValueUnspecified(); - if ( isUnspecified ) - index = -1; - else + if ( !isUnspecified ) defString = property->GetDisplayedString(); - const wxPGChoices& choices = property->GetChoices(); - wxArrayString labels = choices.GetLabels(); wxPGComboBox* cb; @@ -1052,20 +1051,10 @@ wxWindow* wxPGChoiceEditor::CreateControlsBase( wxPropertyGrid* propGrid, labels, odcbFlags); - //int extRight = propGrid->GetClientSize().x - (po.x+si.x); - //int extRight = - (po.x+si.x); - cb->SetButtonPosition(si.y,0,wxRIGHT); - //cb->SetPopupExtents( 1, extRight ); cb->SetTextIndent(wxPG_XBEFORETEXT-1); wxPGChoiceEditor_SetCustomPaintWidth( propGrid, cb, property->GetCommonValue() ); - /*if ( property->GetFlags() & wxPG_PROP_CUSTOMIMAGE ) - { - wxSize imageSize = propGrid->GetImageSize(property, index); - if ( imageSize.x ) imageSize.x += ODCB_CUST_PAINT_MARGIN; - cb->SetCustomPaintWidth( imageSize.x ); - }*/ if ( index >= 0 && index < (int)cb->GetCount() ) { @@ -1091,7 +1080,7 @@ void wxPGChoiceEditor::UpdateControl( wxPGProperty* property, wxWindow* ctrl ) c wxASSERT( ctrl ); wxOwnerDrawnComboBox* cb = (wxOwnerDrawnComboBox*)ctrl; wxASSERT( cb->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox))); - int ind = property->GetChoiceInfo( (wxPGChoiceInfo*)NULL ); + int ind = property->GetChoiceSelection(); cb->SetSelection(ind); } @@ -1164,7 +1153,7 @@ bool wxPGChoiceEditor::GetValueFromControl( wxVariant& variant, wxPGProperty* pr int index = cb->GetSelection(); - if ( index != property->GetChoiceInfo( (wxPGChoiceInfo*) NULL ) || + if ( index != property->GetChoiceSelection() || // Changing unspecified always causes event (returning // true here should be enough to trigger it). property->IsValueUnspecified() @@ -1610,7 +1599,7 @@ wxPGWindowList wxPGCheckBoxEditor::CreateControls( wxPropertyGrid* propGrid, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) &wxPropertyGrid::OnCustomEditorEvent, NULL, propGrid ); - if ( property->GetChoiceInfo((wxPGChoiceInfo*)NULL) && + if ( property->GetChoiceSelection() > 0 && !property->IsValueUnspecified() ) cb->m_state = 1; @@ -1669,7 +1658,7 @@ void wxPGCheckBoxEditor::DrawValue( wxDC& dc, const wxRect& rect, wxPGProperty* int state = 0; if ( !property->IsValueUnspecified() ) { - state = property->GetChoiceInfo((wxPGChoiceInfo*)NULL); + state = property->GetChoiceSelection(); if ( dc.GetFont().GetWeight() == wxBOLD ) state |= 2; } DrawSimpleCheckBox(dc,rect,dc.GetCharHeight(),state,dc.GetTextForeground()); @@ -1678,7 +1667,7 @@ void wxPGCheckBoxEditor::DrawValue( wxDC& dc, const wxRect& rect, wxPGProperty* void wxPGCheckBoxEditor::UpdateControl( wxPGProperty* property, wxWindow* ctrl ) const { wxASSERT( ctrl ); - ((wxSimpleCheckBox*)ctrl)->m_state = property->GetChoiceInfo((wxPGChoiceInfo*)NULL); + ((wxSimpleCheckBox*)ctrl)->m_state = property->GetChoiceSelection(); ctrl->Refresh(); } @@ -1700,7 +1689,7 @@ bool wxPGCheckBoxEditor::GetValueFromControl( wxVariant& variant, wxPGProperty* int index = cb->m_state; - if ( index != property->GetChoiceInfo( (wxPGChoiceInfo*) NULL ) || + if ( index != property->GetChoiceSelection() || // Changing unspecified always causes event (returning // true here should be enough to trigger it). property->IsValueUnspecified() diff --git a/src/propgrid/property.cpp b/src/propgrid/property.cpp index abaa782c13..262d4648c2 100644 --- a/src/propgrid/property.cpp +++ b/src/propgrid/property.cpp @@ -210,11 +210,16 @@ void wxPGDefaultRenderer::Render( wxDC& dc, const wxRect& rect, // Use choice cell? if ( column == 1 && (flags & Control) ) { - const wxPGCell* ccell = property->GetCurrentChoice(); - if ( ccell && - ( ccell->GetBitmap().IsOk() || ccell->GetFgCol().IsOk() || ccell->GetBgCol().IsOk() ) - ) - cell = ccell; + int selectedIndex = property->GetChoiceSelection(); + if ( selectedIndex != wxNOT_FOUND ) + { + const wxPGChoices& choices = property->GetChoices(); + const wxPGCell* ccell = &choices[selectedIndex]; + if ( ccell && + ( ccell->GetBitmap().IsOk() || ccell->GetFgCol().IsOk() || ccell->GetBgCol().IsOk() ) + ) + cell = ccell; + } } if ( cell ) @@ -1099,104 +1104,6 @@ void wxPGProperty::SetCell( int column, wxPGCell* cellObj ) m_cells[column] = cellObj; } -void wxPGProperty::SetChoiceSelection( int newValue, const wxPGChoiceInfo& choiceInfo ) -{ - // Changes value of a property with choices, but only - // works if the value type is long or string. - wxString ts = GetValue().GetType(); - - wxCHECK_RET( choiceInfo.m_choices, wxT("invalid choiceinfo") ); - - if ( ts == wxS("long") ) - { - SetValue( (long) newValue ); - } - else if ( ts == wxS("string") ) - { - SetValue( choiceInfo.m_choices->GetLabel(newValue) ); - } -} - - -wxString wxPGProperty::GetChoiceString( unsigned int index ) -{ - wxPGChoiceInfo ci; - GetChoiceInfo(&ci); - wxASSERT(ci.m_choices); - return ci.m_choices->GetLabel(index); -} - -int wxPGProperty::InsertChoice( const wxString& label, int index, int value ) -{ - wxPropertyGrid* pg = GetGrid(); - - wxPGChoiceInfo ci; - ci.m_choices = (wxPGChoices*) NULL; - int sel = GetChoiceInfo(&ci); - - if ( ci.m_choices ) - { - int newSel = sel; - - if ( index < 0 ) - index = ci.m_choices->GetCount(); - - if ( index <= sel ) - newSel++; - - ci.m_choices->Insert(label, index, value); - - if ( sel != newSel ) - SetChoiceSelection(newSel, ci); - - if ( this == pg->GetSelection() ) - GetEditorClass()->InsertItem(pg->GetEditorControl(),label,index); - - return index; - } - - return -1; -} - - -void wxPGProperty::DeleteChoice( int index ) -{ - wxPropertyGrid* pg = GetGrid(); - - wxPGChoiceInfo ci; - ci.m_choices = (wxPGChoices*) NULL; - int sel = GetChoiceInfo(&ci); - - if ( ci.m_choices ) - { - int newSel = sel; - - // Adjust current value - if ( sel == index ) - { - SetValueToUnspecified(); - newSel = 0; - } - else if ( index < sel ) - { - newSel--; - } - - ci.m_choices->RemoveAt(index); - - if ( sel != newSel ) - SetChoiceSelection(newSel, ci); - - if ( this == pg->GetSelection() ) - GetEditorClass()->DeleteItem(pg->GetEditorControl(), index); - } -} - -int wxPGProperty::GetChoiceInfo( wxPGChoiceInfo* WXUNUSED(info) ) -{ - return -1; -} - wxPGEditorDialogAdapter* wxPGProperty::GetEditorDialog() const { return NULL; @@ -1349,63 +1256,116 @@ wxValidator* wxPGProperty::DoGetValidator() const return (wxValidator*) NULL; } -wxPGChoices& wxPGProperty::GetChoices() +int wxPGProperty::InsertChoice( const wxString& label, int index, int value ) { - wxPGChoiceInfo choiceInfo; - choiceInfo.m_choices = NULL; - GetChoiceInfo(&choiceInfo); - return *choiceInfo.m_choices; + wxPropertyGrid* pg = GetGrid(); + int sel = GetChoiceSelection(); + + int newSel = sel; + + if ( index == wxNOT_FOUND ) + index = m_choices.GetCount(); + + if ( index <= sel ) + newSel++; + + m_choices.Insert(label, index, value); + + if ( sel != newSel ) + SetChoiceSelection(newSel); + + if ( this == pg->GetSelection() ) + GetEditorClass()->InsertItem(pg->GetEditorControl(),label,index); + + return index; } -const wxPGChoices& wxPGProperty::GetChoices() const + +void wxPGProperty::DeleteChoice( int index ) { - return (const wxPGChoices&) ((wxPGProperty*)this)->GetChoices(); + wxPropertyGrid* pg = GetGrid(); + + int sel = GetChoiceSelection(); + int newSel = sel; + + // Adjust current value + if ( sel == index ) + { + SetValueToUnspecified(); + newSel = 0; + } + else if ( index < sel ) + { + newSel--; + } + + m_choices.RemoveAt(index); + + if ( sel != newSel ) + SetChoiceSelection(newSel); + + if ( this == pg->GetSelection() ) + GetEditorClass()->DeleteItem(pg->GetEditorControl(), index); } -unsigned int wxPGProperty::GetChoiceCount() const +int wxPGProperty::GetChoiceSelection() const { - const wxPGChoices& choices = GetChoices(); - if ( &choices && choices.IsOk() ) - return choices.GetCount(); - return 0; + wxVariant value = GetValue(); + wxString valueType = value.GetType(); + int index = wxNOT_FOUND; + + if ( IsValueUnspecified() || !m_choices.GetCount() ) + return wxNOT_FOUND; + + if ( valueType == wxPG_VARIANT_TYPE_LONG ) + { + index = value.GetLong(); + } + else if ( valueType == wxPG_VARIANT_TYPE_STRING ) + { + index = m_choices.Index(value.GetString()); + } + else if ( valueType == wxPG_VARIANT_TYPE_BOOL ) + { + index = value.GetBool()? 1 : 0; + } + + return index; } -const wxPGChoiceEntry* wxPGProperty::GetCurrentChoice() const +void wxPGProperty::SetChoiceSelection( int newValue ) { - wxPGChoiceInfo ci; - ci.m_choices = (wxPGChoices*) NULL; - int index = ((wxPGProperty*)this)->GetChoiceInfo(&ci); - if ( index == -1 || !ci.m_choices || index >= (int)ci.m_choices->GetCount() ) - return NULL; + // Changes value of a property with choices, but only + // works if the value type is long or string. + wxString valueType = GetValue().GetType(); - return &(*ci.m_choices)[index]; + wxCHECK_RET( m_choices.IsOk(), wxT("invalid choiceinfo") ); + + if ( valueType == wxPG_VARIANT_TYPE_STRING ) + { + SetValue( m_choices.GetLabel(newValue) ); + } + else // if ( valueType == wxPG_VARIANT_TYPE_LONG ) + { + SetValue( (long) newValue ); + } } bool wxPGProperty::SetChoices( wxPGChoices& choices ) { - wxPGChoiceInfo ci; - ci.m_choices = (wxPGChoices*) NULL; + m_choices.Assign(choices); - // Unref existing - GetChoiceInfo(&ci); - if ( ci.m_choices ) { - ci.m_choices->Assign(choices); + // This may be needed to trigger some initialization + // (but don't do it if property is somewhat uninitialized) + wxVariant defVal = GetDefaultValue(); + if ( defVal.IsNull() ) + return false; - //if ( m_parent ) - { - // This may be needed to trigger some initialization - // (but don't do it if property is somewhat uninitialized) - wxVariant defVal = GetDefaultValue(); - if ( defVal.IsNull() ) - return false; - - SetValue(defVal); - - return true; - } + SetValue(defVal); } - return false; + + return true; } @@ -1436,18 +1396,6 @@ const wxPGEditor* wxPGProperty::GetEditorClass() const return editor; } - -// Privatizes set of choices -void wxPGProperty::SetChoicesExclusive() -{ - wxPGChoiceInfo ci; - ci.m_choices = (wxPGChoices*) NULL; - - GetChoiceInfo(&ci); - if ( ci.m_choices ) - ci.m_choices->SetExclusive(); -} - bool wxPGProperty::HasVisibleChildren() const { unsigned int i; diff --git a/src/propgrid/propgrid.cpp b/src/propgrid/propgrid.cpp index 11ef4ae1b9..fc40bcf90b 100644 --- a/src/propgrid/propgrid.cpp +++ b/src/propgrid/propgrid.cpp @@ -3397,7 +3397,7 @@ wxSize wxPropertyGrid::GetImageSize( wxPGProperty* p, int item ) const wxSize cis = p->OnMeasureImage(item); - int choiceCount = p->GetChoiceCount(); + int choiceCount = p->m_choices.GetCount(); int comVals = p->GetDisplayedCommonValueCount(); if ( item >= choiceCount && comVals > 0 ) { diff --git a/src/propgrid/propgridiface.cpp b/src/propgrid/propgridiface.cpp index 8ee1c101dc..74b071871d 100644 --- a/src/propgrid/propgridiface.cpp +++ b/src/propgrid/propgridiface.cpp @@ -221,38 +221,7 @@ wxPGProperty* wxPGPropArgCls::GetPtr( wxPropertyGridInterface* iface ) const } // ----------------------------------------------------------------------- -// Choice related methods -// ----------------------------------------------------------------------- - -void wxPropertyGridInterface::AddPropertyChoice( wxPGPropArg id, - const wxString& label, - int value ) -{ - wxPG_PROP_ARG_CALL_PROLOG() - - p->InsertChoice(label,-1,value); -} - - -void wxPropertyGridInterface::InsertPropertyChoice( wxPGPropArg id, - const wxString& label, - int index, - int value ) -{ - wxPG_PROP_ARG_CALL_PROLOG() - - p->InsertChoice(label,index,value); -} - - -void wxPropertyGridInterface::DeletePropertyChoice( wxPGPropArg id, - int index ) -{ - wxPG_PROP_ARG_CALL_PROLOG() - - p->DeleteChoice(index); -} - +// wxPropertyGridInterface // ----------------------------------------------------------------------- void wxPropertyGridInterface::RefreshGrid( wxPropertyGridPageState* state ) @@ -646,25 +615,6 @@ void wxPropertyGridInterface::SetBoolChoices( const wxString& trueChoice, // ----------------------------------------------------------------------- -wxPGChoices gs_emptyChoices; - -wxPGChoices& wxPropertyGridInterface::GetPropertyChoices( wxPGPropArg id ) -{ - wxPG_PROP_ARG_CALL_PROLOG_RETVAL(gs_emptyChoices) - - wxPGChoiceInfo ci; - ci.m_choices = (wxPGChoices*) NULL; - - p->GetChoiceInfo(&ci); - - if ( !ci.m_choices ) - return gs_emptyChoices; - - return *ci.m_choices; -} - -// ----------------------------------------------------------------------- - wxPGProperty* wxPropertyGridInterface::DoGetPropertyByName( const wxString& name ) const { return m_pState->BaseGetPropertyByName(name); diff --git a/src/propgrid/props.cpp b/src/propgrid/props.cpp index b161d8c10d..9c5433f1d0 100644 --- a/src/propgrid/props.cpp +++ b/src/propgrid/props.cpp @@ -748,6 +748,8 @@ const wxPGEditor* wxBoolProperty::DoGetEditorClass() const wxBoolProperty::wxBoolProperty( const wxString& label, const wxString& name, bool value ) : wxPGProperty(label,name) { + m_choices.Assign(wxPGGlobalVars->m_boolChoices); + SetValue(wxPGVariant_Bool(value)); m_flags |= wxPG_PROP_USE_DCC; @@ -795,16 +797,6 @@ wxString wxBoolProperty::GetValueAsString( int argFlags ) const return text; } -int wxBoolProperty::GetChoiceInfo( wxPGChoiceInfo* choiceinfo ) -{ - if ( IsValueUnspecified() ) - return -1; - - if ( choiceinfo ) - choiceinfo->m_choices = &wxPGGlobalVars->m_boolChoices; - return m_value.GetBool()?1:0; -} - bool wxBoolProperty::StringToValue( wxVariant& variant, const wxString& text, int WXUNUSED(argFlags) ) const { int value = 0; @@ -1161,17 +1153,6 @@ const wxString* wxEnumProperty::GetEntry( size_t index, int* pvalue ) const return (const wxString*) NULL; } -int wxEnumProperty::GetChoiceInfo( wxPGChoiceInfo* choiceinfo ) -{ - if ( choiceinfo ) - choiceinfo->m_choices = &m_choices; - - if ( !m_choices.IsOk() ) - return -1; - - return GetIndex(); -} - // ----------------------------------------------------------------------- // wxEditEnumProperty // ----------------------------------------------------------------------- @@ -1549,13 +1530,6 @@ void wxFlagsProperty::ChildChanged( wxVariant& thisValue, int childIndex, wxVari thisValue = (long)(oldValue & ~(vi)); } -int wxFlagsProperty::GetChoiceInfo( wxPGChoiceInfo* choiceinfo ) -{ - if ( choiceinfo ) - choiceinfo->m_choices = &m_choices; - return -1; -} - // ----------------------------------------------------------------------- // wxDirProperty // -----------------------------------------------------------------------