Aegisub/assdraw/libpropgrid/props.cpp
Amar Takhar dc404a954e Add UNIX (and with luck, OS X) support to assdraw. This (unfortunatly)
includes propgrid, the build system for propgrid is brutal rather than fend of
users trying to build it themselves it's worth it to just include it with
assdraw for now.

Originally committed to SVN as r2177.
2008-04-13 06:57:09 +00:00

2717 lines
72 KiB
C++

/////////////////////////////////////////////////////////////////////////////
// Name: props.cpp
// Purpose: Basic Property Classes
// Author: Jaakko Salli
// Modified by:
// Created: May-14-2004
// RCS-ID: $Id:
// Copyright: (c) Jaakko Salli
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/defs.h"
#include "wx/object.h"
#include "wx/hash.h"
#include "wx/string.h"
#include "wx/log.h"
#include "wx/event.h"
#include "wx/window.h"
#include "wx/panel.h"
#include "wx/dc.h"
#include "wx/dcclient.h"
#include "wx/dcmemory.h"
#include "wx/button.h"
#include "wx/pen.h"
#include "wx/brush.h"
#include "wx/cursor.h"
#include "wx/dialog.h"
#include "wx/settings.h"
#include "wx/msgdlg.h"
#include "wx/choice.h"
#include "wx/stattext.h"
#include "wx/scrolwin.h"
#include "wx/dirdlg.h"
#include "wx/combobox.h"
#include "wx/layout.h"
#include "wx/sizer.h"
#include "wx/textdlg.h"
#include "wx/filedlg.h"
#include "wx/statusbr.h"
#include "wx/intl.h"
#endif
#include <wx/filename.h>
#include <wx/propgrid/propgrid.h>
#include <wx/propgrid/propdev.h>
#define wxPG_CUSTOM_IMAGE_WIDTH 20 // for wxColourProperty etc.
// -----------------------------------------------------------------------
// wxStringProperty
// -----------------------------------------------------------------------
WX_PG_IMPLEMENT_PROPERTY_CLASS(wxStringProperty,wxBaseProperty,
wxString,const wxString&,TextCtrl)
wxStringPropertyClass::wxStringPropertyClass( const wxString& label,
const wxString& name,
const wxString& value )
: wxPGProperty(label,name)
{
DoSetValue(value);
}
wxStringPropertyClass::~wxStringPropertyClass() { }
void wxStringPropertyClass::DoSetValue( wxPGVariant value )
{
m_value = wxPGVariantToString(value);
}
wxPGVariant wxStringPropertyClass::DoGetValue() const
{
return wxPGVariant(m_value);
}
wxString wxStringPropertyClass::GetValueAsString( int argFlags ) const
{
// If string is password and value is for visual purposes,
// then return asterisks instead the actual string.
if ( (m_flags & wxPG_PROP_PASSWORD) && !(argFlags & (wxPG_FULL_VALUE|wxPG_EDITABLE_VALUE)) )
return wxString(wxChar('*'), m_value.Length());
return m_value;
}
bool wxStringPropertyClass::SetValueFromString( const wxString& text, int )
{
if ( m_value != text )
return StdValidationProcedure(text);
return false;
}
void wxStringPropertyClass::SetAttribute( int id, wxVariant& value )
{
if ( id == wxPG_STRING_PASSWORD )
{
m_flags &= ~(wxPG_PROP_PASSWORD);
if ( value.GetLong() ) m_flags |= wxPG_PROP_PASSWORD;
RecreateEditor();
}
}
// -----------------------------------------------------------------------
// wxIntProperty
// -----------------------------------------------------------------------
wxPG_BEGIN_PROPERTY_CLASS_BODY(wxIntProperty,wxPGProperty,long,long)
WX_PG_DECLARE_BASIC_TYPE_METHODS()
virtual bool SetValueFromInt( long value, int flags );
#if wxUSE_VALIDATORS
static wxValidator* GetClassValidator();
virtual wxValidator* DoGetValidator() const;
#endif
wxPG_END_PROPERTY_CLASS_BODY()
WX_PG_IMPLEMENT_PROPERTY_CLASS(wxIntProperty,wxBaseProperty,
long,long,TextCtrl)
wxIntPropertyClass::wxIntPropertyClass( const wxString& label, const wxString& name,
long value ) : wxPGProperty(label,name)
{
DoSetValue(value);
}
wxIntPropertyClass::~wxIntPropertyClass() { }
void wxIntPropertyClass::DoSetValue( wxPGVariant value )
{
m_value = wxPGVariantToLong(value);
}
wxPGVariant wxIntPropertyClass::DoGetValue() const
{
return wxPGVariant(m_value);
}
wxString wxIntPropertyClass::GetValueAsString( int ) const
{
return wxString::Format(wxT("%li"),m_value);
}
bool wxIntPropertyClass::SetValueFromString( const wxString& text, int argFlags )
{
wxString s;
long value;
if ( text.length() == 0 )
{
SetValueToUnspecified();
return true;
}
// We know it is a number, but let's still check
// the return value.
if ( text.IsNumber() && text.ToLong( &value, 0 ) )
{
if ( m_value != value )
{
return StdValidationProcedure(value);
}
}
else if ( argFlags & wxPG_REPORT_ERROR )
{
s.Printf( wxT("! %s: \"%s\" is not a number."), m_label.c_str(), text.c_str() );
ShowError(s);
}
return false;
}
bool wxIntPropertyClass::SetValueFromInt( long value, int WXUNUSED(flags) )
{
if ( m_value != value )
{
m_value = value;
return true;
}
return false;
}
#if wxUSE_VALIDATORS
wxValidator* wxIntPropertyClass::GetClassValidator()
{
WX_PG_DOGETVALIDATOR_ENTRY()
// Atleast wxPython 2.6.2.1 required that the string argument is given
static wxString v;
wxTextValidator* validator = new wxTextValidator(wxFILTER_NUMERIC,&v);
WX_PG_DOGETVALIDATOR_EXIT(validator)
}
wxValidator* wxIntPropertyClass::DoGetValidator() const
{
return GetClassValidator();
}
#endif
// -----------------------------------------------------------------------
// wxUIntProperty
// -----------------------------------------------------------------------
#define wxPG_UINT_TEMPLATE_MAX 8
static const wxChar* gs_uintTemplates[wxPG_UINT_TEMPLATE_MAX] = {
wxT("%x"),wxT("0x%x"),wxT("$%x"),
wxT("%X"),wxT("0x%X"),wxT("$%X"),
wxT("%u"),wxT("%o")
};
wxPG_BEGIN_PROPERTY_CLASS_BODY(wxUIntProperty,wxBasePropertyClass,long,unsigned long)
WX_PG_DECLARE_BASIC_TYPE_METHODS()
WX_PG_DECLARE_ATTRIBUTE_METHODS()
virtual bool SetValueFromInt ( long value, int flags );
protected:
wxByte m_base;
wxByte m_realBase; // translated to 8,16,etc.
wxByte m_prefix;
wxPG_END_PROPERTY_CLASS_BODY()
WX_PG_IMPLEMENT_PROPERTY_CLASS(wxUIntProperty,wxBaseProperty,
long,unsigned long,TextCtrl)
wxUIntPropertyClass::wxUIntPropertyClass( const wxString& label, const wxString& name,
unsigned long value ) : wxBasePropertyClass(label,name)
{
m_base = 6; // This is magic number for dec base (must be same as in setattribute)
m_realBase = 10;
m_prefix = wxPG_PREFIX_NONE;
DoSetValue((long)value);
}
wxUIntPropertyClass::~wxUIntPropertyClass() { }
void wxUIntPropertyClass::DoSetValue( wxPGVariant value )
{
m_value = wxPGVariantToLong(value);
}
wxPGVariant wxUIntPropertyClass::DoGetValue() const
{
return wxPGVariant(m_value);
}
wxString wxUIntPropertyClass::GetValueAsString( int ) const
{
//return wxString::Format(wxPGGlobalVars->m_uintTemplate.c_str(),m_value);
size_t index = m_base + m_prefix;
if ( index >= wxPG_UINT_TEMPLATE_MAX )
index = wxPG_BASE_DEC;
return wxString::Format(gs_uintTemplates[index],m_value);
}
bool wxUIntPropertyClass::SetValueFromString( const wxString& text, int WXUNUSED(argFlags) )
{
//wxString s;
long unsigned value = 0;
if ( text.length() == 0 )
{
SetValueToUnspecified();
return true;
}
size_t start = 0;
if ( text.length() > 0 && !wxIsalnum(text[0]) )
start++;
wxString s = text.substr(start, text.length() - start);
bool res = s.ToULong(&value, (unsigned int)m_realBase);
//wxChar *end;
//value = wxStrtoul(text.c_str() + ((size_t)start), &end, (unsigned int)m_realBase);
if ( res && m_value != (long)value )
{
return StdValidationProcedure((long)value);
}
/*}
else if ( argFlags & wxPG_REPORT_ERROR )
{
s.Printf ( wxT("! %s: \"%s\" is not a number."), m_label.c_str(), text.c_str() );
ShowError(s);
}*/
return false;
}
bool wxUIntPropertyClass::SetValueFromInt( long value, int WXUNUSED(flags) )
{
if ( m_value != value )
{
m_value = value;
return true;
}
return false;
}
void wxUIntPropertyClass::SetAttribute( int id, wxVariant& value )
{
if ( id == wxPG_UINT_BASE )
{
int val = value.GetLong();
m_realBase = (wxByte) val;
if ( m_realBase > 16 )
m_realBase = 16;
//
// Translate logical base to a template array index
m_base = 7; // oct
if ( val == wxPG_BASE_HEX )
m_base = 3;
else if ( val == wxPG_BASE_DEC )
m_base = 6;
else if ( val == wxPG_BASE_HEXL )
m_base = 0;
}
else if ( id == wxPG_UINT_PREFIX )
m_prefix = (wxByte) value.GetLong();
}
// -----------------------------------------------------------------------
// wxFloatProperty
// -----------------------------------------------------------------------
wxPG_BEGIN_PROPERTY_CLASS_BODY(wxFloatProperty,wxPGProperty,double,double)
WX_PG_DECLARE_BASIC_TYPE_METHODS()
WX_PG_DECLARE_ATTRIBUTE_METHODS()
protected:
int m_precision;
#if wxUSE_VALIDATORS
//static wxValidator* GetClassValidator ();
virtual wxValidator* DoGetValidator () const;
#endif
wxPG_END_PROPERTY_CLASS_BODY()
WX_PG_IMPLEMENT_PROPERTY_CLASS(wxFloatProperty,wxBaseProperty,
double,double,TextCtrl)
wxFloatPropertyClass::wxFloatPropertyClass( const wxString& label,
const wxString& name,
double value )
: wxPGProperty(label,name)
{
m_precision = -1;
DoSetValue(value);
}
wxFloatPropertyClass::~wxFloatPropertyClass() { }
void wxFloatPropertyClass::DoSetValue( wxPGVariant value )
{
m_value = wxPGVariantToDouble(value);
}
wxPGVariant wxFloatPropertyClass::DoGetValue() const
{
return wxPGVariant(m_value);
}
// This helper method provides standard way for floating point-using
// properties to convert values to string.
void wxPropertyGrid::DoubleToString(wxString& target,
double value,
int precision,
bool removeZeroes,
wxString* precTemplate)
{
if ( precision >= 0 )
{
wxString text1;
if (!precTemplate)
precTemplate = &text1;
if ( !precTemplate->length() )
{
*precTemplate = wxT("%.");
*precTemplate << wxString::Format( wxT("%i"), precision );
*precTemplate << wxT('f');
}
target.Printf( precTemplate->c_str(), value );
}
else
{
target.Printf( wxT("%f"), value );
}
if ( removeZeroes && precision != 0 && target.length() )
{
// Remove excess zeroes (do not remove this code just yet,
// since sprintf can't do the same consistently across platforms).
wxString::const_iterator i = target.end() - 1;
size_t new_len = target.length() - 1;
for ( ; i != target.begin(); i-- )
{
if ( wxPGGetIterChar(target, i) != wxT('0') )
break;
new_len--;
}
wxChar cur_char = wxPGGetIterChar(target, i);
if ( cur_char != wxT('.') && cur_char != wxT(',') )
new_len++;
if ( new_len != target.length() )
target.resize(new_len);
/*
unsigned int cur_pos = target.length() - 1;
wxChar a;
a = target.GetChar( cur_pos );
while ( a == wxT('0') && cur_pos > 0 )
{
cur_pos--;
a = target.GetChar( cur_pos );
}
wxChar cur_char = target.GetChar( cur_pos );
if ( cur_char != wxT('.') && cur_char != wxT(',') )
cur_pos += 1;
if ( cur_pos < target.length() )
target.Truncate( cur_pos );
*/
}
}
wxString wxFloatPropertyClass::GetValueAsString( int argFlags ) const
{
wxString text;
wxPropertyGrid::DoubleToString(text,m_value,
m_precision,
!(argFlags & wxPG_FULL_VALUE),
(wxString*) NULL);
return text;
}
bool wxFloatPropertyClass::SetValueFromString( const wxString& text, int argFlags )
{
wxString s;
double value;
if ( text.length() == 0 )
{
SetValueToUnspecified();
return true;
}
bool res = text.ToDouble(&value);
if ( res )
{
if ( m_value != value )
{
m_value = value;
return true;
}
}
else if ( argFlags & wxPG_REPORT_ERROR )
{
ShowError(wxString::Format( _("\"%s\" is not a floating-point number"), text.c_str() ));
}
return false;
}
void wxFloatPropertyClass::SetAttribute( int id, wxVariant& value )
{
if ( id == wxPG_FLOAT_PRECISION )
{
m_precision = value.GetLong();
}
}
#if wxUSE_VALIDATORS
wxValidator* wxFloatPropertyClass::DoGetValidator() const
{
return wxIntPropertyClass::GetClassValidator();
}
#endif
// -----------------------------------------------------------------------
// wxBoolProperty
// -----------------------------------------------------------------------
wxPG_BEGIN_PROPERTY_CLASS_BODY2(wxBoolPropertyClass,wxPGProperty,bool,long,bool,class)
WX_PG_DECLARE_BASIC_TYPE_METHODS()
WX_PG_DECLARE_CHOICE_METHODS()
WX_PG_DECLARE_ATTRIBUTE_METHODS()
wxPG_END_PROPERTY_CLASS_BODY()
// We cannot use standard WX_PG_IMPLEMENT_PROPERTY_CLASS macro, since
// there is a custom GetEditorClass.
WX_PG_IMPLEMENT_CONSTFUNC(wxBoolProperty,bool)
WX_PG_IMPLEMENT_CLASSINFO(wxBoolProperty,wxBasePropertyClass)
wxPG_GETCLASSNAME_IMPLEMENTATION(wxBoolProperty)
wxPG_VALUETYPE_MSGVAL wxBoolPropertyClass::GetValueType() const { return wxPG_VALUETYPE(bool); }
const wxChar* wxPG_ClassName_wxBoolProperty = wxBoolProperty_ClassName;
const wxPGEditor* wxBoolPropertyClass::DoGetEditorClass() const
{
// Select correct editor control.
#if wxPG_INCLUDE_CHECKBOX
if ( !(m_flags & wxPG_PROP_USE_CHECKBOX) )
return wxPG_EDITOR(Choice);
return wxPG_EDITOR(CheckBox);
#else
return wxPG_EDITOR(Choice);
#endif
}
wxBoolPropertyClass::wxBoolPropertyClass( const wxString& label, const wxString& name, bool value ) :
wxPGProperty(label,name)
{
int useVal;
if ( value ) useVal = 1;
else useVal = 0;
DoSetValue((long)useVal);
m_flags |= wxPG_PROP_USE_DCC;
}
wxBoolPropertyClass::~wxBoolPropertyClass() { }
void wxBoolPropertyClass::DoSetValue( wxPGVariant value )
{
long v = wxPGVariantToLong(value);
if ( v == 2 )
SetValueToUnspecified();
else if ( v != 0 )
m_value = 1;
else
m_value = 0;
}
wxPGVariant wxBoolPropertyClass::DoGetValue() const
{
return wxPGVariant(m_value);
}
wxString wxBoolPropertyClass::GetValueAsString( int argFlags ) const
{
if ( !(argFlags & wxPG_FULL_VALUE) )
{
return wxPGGlobalVars->m_boolChoices[m_value];
}
wxString text;
if (m_value) text = wxT("true");
else text = wxT("false");
return text;
}
int wxBoolPropertyClass::GetChoiceInfo( wxPGChoiceInfo* choiceinfo )
{
if ( choiceinfo )
{
// 3 choice mode (ie. true, false, unspecified) does not work well (yet).
//choiceinfo->m_itemCount = wxPGGlobalVars->m_numBoolChoices;
choiceinfo->m_itemCount = 2;
choiceinfo->m_arrWxString = wxPGGlobalVars->m_boolChoices;
}
return m_value;
}
bool wxBoolPropertyClass::SetValueFromString( const wxString& text, int /*argFlags*/ )
{
int value = 0;
if ( text.CmpNoCase(wxPGGlobalVars->m_boolChoices[1]) == 0 || text.CmpNoCase(wxT("true")) == 0 )
value = 1;
if ( text.length() == 0 )
{
SetValueToUnspecified();
return true;
}
if ( (m_value && !value) || (!m_value && value) )
{
DoSetValue( (long) value );
return true;
}
/*
else if ( argFlags & wxPG_REPORT_ERROR )
{
wxLogError ( wxT("Property %s: \"%s\" is not a boolean value (True and False are valid)."), m_label.c_str(), text.c_str() );
}
*/
return false;
}
bool wxBoolPropertyClass::SetValueFromInt( long value, int )
{
if ( value != 0 ) value = 1;
if ( (m_value && !value) || (!m_value && value) )
{
// (wxPG_BOOLPROP_VAL_INTERNAL_LONG)
m_value = value;
return true;
}
return false;
}
void wxBoolPropertyClass::SetAttribute( int id, wxVariant& value )
{
int ival = value.GetLong();
#if wxPG_INCLUDE_CHECKBOX
if ( id == wxPG_BOOL_USE_CHECKBOX )
{
if ( ival )
m_flags |= wxPG_PROP_USE_CHECKBOX;
else
m_flags &= ~(wxPG_PROP_USE_CHECKBOX);
}
//else
#endif
if ( id == wxPG_BOOL_USE_DOUBLE_CLICK_CYCLING )
{
if ( ival )
m_flags |= wxPG_PROP_USE_DCC;
else
m_flags &= ~(wxPG_PROP_USE_DCC);
}
}
// -----------------------------------------------------------------------
// wxBaseEnumPropertyClass
// -----------------------------------------------------------------------
// Class body is in propdev.h.
wxBaseEnumPropertyClass::wxBaseEnumPropertyClass( const wxString& label, const wxString& name )
: wxPGProperty(label,name)
{
}
/** If has values array, then returns number at index with value -
otherwise just returns the value.
*/
int wxBaseEnumPropertyClass::GetIndexForValue( int value ) const
{
return value;
}
void wxBaseEnumPropertyClass::DoSetValue( wxPGVariant value )
{
int intval = (int) value.GetLong();
m_index = GetIndexForValue(intval);
}
wxPGVariant wxBaseEnumPropertyClass::DoGetValue() const
{
if ( m_index < 0 )
return wxPGVariant((long)-1);
int val;
GetEntry(m_index,&val);
return wxPGVariantCreator(val);
}
wxString wxBaseEnumPropertyClass::GetValueAsString( int ) const
{
if ( m_index >= 0 )
{
int unused_val;
const wxString* pstr = GetEntry( m_index, &unused_val );
if ( pstr )
return *pstr;
}
return wxEmptyString;
}
bool wxBaseEnumPropertyClass::SetValueFromString ( const wxString& text, int WXUNUSED(argFlags) )
{
size_t i = 0;
const wxString* entry_label;
int entry_value;
int use_index = -1;
long use_value = 0;
entry_label = GetEntry(i,&entry_value);
while ( entry_label )
{
if ( text.CmpNoCase(*entry_label) == 0 )
{
use_index = (int)i;
use_value = (long)entry_value;
break;
}
i++;
entry_label = GetEntry(i,&entry_value);
}
if ( m_index != use_index )
{
if ( use_index != -1 )
// FIXME: Why can't this be virtual call?
wxBaseEnumPropertyClass::DoSetValue ( use_value );
else
m_index = -1;
return true;
}
/*}
else if ( argFlags & wxPG_REPORT_ERROR )
{
wxString s;
s.Printf ( wxT("\"%s\" was not among valid choices."), text.c_str() );
ShowError(s);
}*/
return false;
}
bool wxBaseEnumPropertyClass::SetValueFromInt ( long value, int argFlags )
{
if ( argFlags & wxPG_FULL_VALUE )
{
DoSetValue(value);
return true;
}
else
{
if ( m_index != value )
{
m_index = value;
return true;
}
}
return false;
}
// -----------------------------------------------------------------------
// wxEnumProperty
// -----------------------------------------------------------------------
// Class body is in propdev.h.
wxPGProperty* wxEnumProperty( const wxString& label, const wxString& name, const wxChar** labels,
const long* values, int value )
{
return new wxEnumPropertyClass (label,name,labels,values,value);
}
wxPGProperty* wxEnumProperty( const wxString& label, const wxString& name,
const wxArrayString& labels, const wxArrayInt& values, int value )
{
return new wxEnumPropertyClass(label,name,labels,values,value);
}
wxPGProperty* wxEnumProperty( const wxString& label, const wxString& name,
const wxArrayString& labels, int value )
{
return new wxEnumPropertyClass (label,name,labels,*((const wxArrayInt*)NULL),value);
}
wxPGProperty* wxEnumProperty( const wxString& label, const wxString& name,
wxPGChoices& choices, int value )
{
return new wxEnumPropertyClass (label,name,choices,value);
}
WX_PG_IMPLEMENT_CLASSINFO(wxEnumProperty,wxBasePropertyClass)
WX_PG_IMPLEMENT_PROPERTY_CLASS_PLAIN(wxEnumProperty,long,Choice)
wxEnumPropertyClass::wxEnumPropertyClass ( const wxString& label, const wxString& name, const wxChar** labels,
const long* values, int value ) : wxBaseEnumPropertyClass(label,name)
{
m_index = 0;
if ( labels )
{
m_choices.Add(labels,values);
if ( GetItemCount() )
wxEnumPropertyClass::DoSetValue( (long)value );
}
}
wxEnumPropertyClass::wxEnumPropertyClass ( const wxString& label, const wxString& name, const wxChar** labels,
const long* values, wxPGChoices* choicesCache, int value )
: wxBaseEnumPropertyClass(label,name)
{
m_index = 0;
wxASSERT( choicesCache );
if ( choicesCache->IsOk() )
{
m_choices.Assign( *choicesCache );
}
else if ( labels )
{
m_choices.Add(labels,values);
if ( GetItemCount() )
wxEnumPropertyClass::DoSetValue( (long)value );
}
}
wxEnumPropertyClass::wxEnumPropertyClass ( const wxString& label, const wxString& name,
const wxArrayString& labels, const wxArrayInt& values, int value ) : wxBaseEnumPropertyClass(label,name)
{
m_index = 0;
if ( &labels )
{
wxPGChoices choices(labels,values);
m_choices = choices.ExtractData();
if ( GetItemCount() )
wxEnumPropertyClass::DoSetValue( (long)value );
}
}
wxEnumPropertyClass::wxEnumPropertyClass ( const wxString& label, const wxString& name,
wxPGChoices& choices, int value )
: wxBaseEnumPropertyClass(label,name)
{
m_choices.Assign( choices );
if ( GetItemCount() )
wxEnumPropertyClass::DoSetValue( (long)value );
}
int wxEnumPropertyClass::GetIndexForValue( int value ) const
{
if ( !m_choices.IsOk() )
return -1;
const wxArrayInt& arrValues = m_choices.GetValues();
if ( arrValues.GetCount() )
{
int intval = arrValues.Index(value);
// TODO: Use real default instead of 0.
if ( intval < 0 )
intval = 0;
return intval;
}
return value;
}
wxEnumPropertyClass::~wxEnumPropertyClass ()
{
}
const wxString* wxEnumPropertyClass::GetEntry( size_t index, int* pvalue ) const
{
if ( m_choices.IsOk() && index < m_choices.GetCount() )
{
const wxArrayInt& arrValues = m_choices.GetValues();
int value = (int)index;
if ( arrValues.GetCount() )
value = arrValues[index];
*pvalue = value;
return &m_choices.GetLabel(index);
}
return (const wxString*) NULL;
}
int wxEnumPropertyClass::GetChoiceInfo( wxPGChoiceInfo* choiceinfo )
{
if ( choiceinfo )
{
if ( !(m_flags & wxPG_PROP_STATIC_CHOICES) )
choiceinfo->m_choices = &m_choices;
if ( !m_choices.IsOk() )
return -1;
choiceinfo->m_itemCount = m_choices.GetCount();
if ( m_choices.GetCount() )
choiceinfo->m_arrWxString = (wxString*)&m_choices.GetLabel(0);
}
if ( !m_choices.IsOk() )
return -1;
return m_index;
}
// -----------------------------------------------------------------------
// wxEditEnumProperty
// -----------------------------------------------------------------------
class wxEditEnumPropertyClass : public wxEnumPropertyClass
{
WX_PG_DECLARE_PROPERTY_CLASS()
public:
wxEditEnumPropertyClass( const wxString& label, const wxString& name, const wxChar** labels,
const long* values, const wxString& value );
wxEditEnumPropertyClass( const wxString& label, const wxString& name,
const wxArrayString& labels, const wxArrayInt& values, const wxString& value );
wxEditEnumPropertyClass( const wxString& label, const wxString& name,
wxPGChoices& choices, const wxString& value );
// Special constructor for caching choices (used by derived class)
wxEditEnumPropertyClass( const wxString& label, const wxString& name, const wxChar** labels,
const long* values, wxPGChoices* choicesCache, const wxString& value );
WX_PG_DECLARE_BASIC_TYPE_METHODS()
int GetChoiceInfo( wxPGChoiceInfo* choiceinfo );
virtual ~wxEditEnumPropertyClass ();
protected:
wxString m_value_wxString;
};
wxPGProperty* wxEditEnumProperty( const wxString& label, const wxString& name, const wxChar** labels,
const long* values, const wxString& value )
{
return new wxEditEnumPropertyClass(label,name,labels,values,value);
}
wxPGProperty* wxEditEnumProperty( const wxString& label, const wxString& name,
const wxArrayString& labels, const wxArrayInt& values, const wxString& value )
{
return new wxEditEnumPropertyClass(label,name,labels,values,value);
}
wxPGProperty* wxEditEnumProperty( const wxString& label, const wxString& name,
const wxArrayString& labels, const wxString& value )
{
return new wxEditEnumPropertyClass(label,name,labels,*((const wxArrayInt*)NULL),value);
}
wxPGProperty* wxEditEnumProperty( const wxString& label, const wxString& name,
wxPGChoices& choices, const wxString& value )
{
return new wxEditEnumPropertyClass(label,name,choices,value);
}
WX_PG_IMPLEMENT_CLASSINFO(wxEditEnumProperty,wxBasePropertyClass)
WX_PG_IMPLEMENT_PROPERTY_CLASS_PLAIN(wxEditEnumProperty,wxString,ComboBox)
wxEditEnumPropertyClass::wxEditEnumPropertyClass( const wxString& label, const wxString& name, const wxChar** labels,
const long* values, const wxString& value )
: wxEnumPropertyClass(label,name,labels,values,0)
{
wxEditEnumPropertyClass::DoSetValue( value );
}
wxEditEnumPropertyClass::wxEditEnumPropertyClass( const wxString& label, const wxString& name, const wxChar** labels,
const long* values, wxPGChoices* choicesCache, const wxString& value )
: wxEnumPropertyClass(label,name,labels,values,choicesCache,0)
{
wxEditEnumPropertyClass::DoSetValue( value );
}
wxEditEnumPropertyClass::wxEditEnumPropertyClass( const wxString& label, const wxString& name,
const wxArrayString& labels, const wxArrayInt& values, const wxString& value )
: wxEnumPropertyClass(label,name,labels,values,0)
{
wxEditEnumPropertyClass::DoSetValue( value );
}
wxEditEnumPropertyClass::wxEditEnumPropertyClass( const wxString& label, const wxString& name,
wxPGChoices& choices, const wxString& value )
: wxEnumPropertyClass(label,name,choices,0)
{
wxEditEnumPropertyClass::DoSetValue( value );
}
wxEditEnumPropertyClass::~wxEditEnumPropertyClass()
{
}
void wxEditEnumPropertyClass::DoSetValue( wxPGVariant value )
{
m_value_wxString = wxPGVariantToString(value);
}
wxPGVariant wxEditEnumPropertyClass::DoGetValue() const
{
return wxPGVariant(m_value_wxString);
}
wxString wxEditEnumPropertyClass::GetValueAsString( int ) const
{
return m_value_wxString;
}
bool wxEditEnumPropertyClass::SetValueFromString( const wxString& text, int )
{
if ( m_value_wxString != text )
return StdValidationProcedure(text);
return false;
}
int wxEditEnumPropertyClass::GetChoiceInfo( wxPGChoiceInfo* choiceinfo )
{
wxEnumPropertyClass::GetChoiceInfo(choiceinfo);
// However, select index using the current value
wxPGChoices& choices = m_choices;
const wxString& value = m_value_wxString;
int index = -1;
unsigned int k;
for ( k=0; k<choices.GetCount(); k++ )
{
if ( choices.GetLabel(k) == value )
{
index = (int) k;
break;
}
}
return index;
}
// -----------------------------------------------------------------------
// wxFlagsProperty
// -----------------------------------------------------------------------
// Class body is in propdev.h.
wxPGProperty* wxFlagsProperty( const wxString& label, const wxString& name, const wxChar** labels,
const long* values, int value )
{
return new wxFlagsPropertyClass(label,name,labels,values,value);
}
wxPGProperty* wxFlagsProperty( const wxString& label, const wxString& name,
const wxArrayString& labels, const wxArrayInt& values, int value )
{
return new wxFlagsPropertyClass(label,name,labels,values,value);
}
wxPGProperty* wxFlagsProperty( const wxString& label, const wxString& name,
const wxArrayString& labels, int value )
{
return new wxFlagsPropertyClass(label,name,labels,*((const wxArrayInt*)NULL),value);
}
wxPGProperty* wxFlagsProperty( const wxString& label, const wxString& name,
wxPGChoices& constants, int value )
{
return new wxFlagsPropertyClass(label,name,constants,value);
}
WX_PG_IMPLEMENT_CLASSINFO(wxFlagsProperty,wxBaseParentPropertyClass)
WX_PG_IMPLEMENT_PROPERTY_CLASS_PLAIN(wxFlagsProperty,long,TextCtrl)
void wxFlagsPropertyClass::Init()
{
long value = m_value;
//
// Generate children
//
unsigned int i;
unsigned int prevChildCount = m_children.GetCount();
int oldSel = -1;
if ( prevChildCount )
{
wxPropertyGridState* state = GetParentState();
// State safety check (it may be NULL in immediate parent)
//wxPGPropertyWithChildren* parent = GetParent();
//while ( !state ) { wxASSERT(parent); state = parent->GetParentState(); parent = parent->GetParent(); }
wxASSERT( state );
if ( state )
{
wxPGProperty* selected = state->GetSelection();
if ( selected )
{
if ( selected->GetParent() == this )
oldSel = selected->GetArrIndex();
else if ( selected == this )
oldSel = -2;
}
}
state->ClearSelection();
}
// Delete old children
for ( i=0; i<prevChildCount; i++ )
delete ( (wxPGProperty*) m_children[i] );
m_children.Empty();
if ( m_choices.IsOk() )
{
const wxArrayInt& values = GetValues();
for ( i=0; i<GetItemCount(); i++ )
{
bool child_val;
if ( values.GetCount() )
child_val = ( value & values[i] )?TRUE:FALSE;
else
child_val = ( value & (1<<i) )?TRUE:FALSE;
wxPGProperty* bool_prop;
#if wxUSE_INTL
if ( wxPGGlobalVars->m_autoGetTranslation )
{
bool_prop = wxBoolProperty( ::wxGetTranslation ( GetLabel(i) ), wxEmptyString, child_val );
}
else
#endif
{
bool_prop = wxBoolProperty( GetLabel(i), wxEmptyString, child_val );
}
AddChild(bool_prop);
}
m_oldChoicesData = m_choices.GetDataPtr();
}
if ( prevChildCount )
SubPropsChanged(oldSel);
}
wxFlagsPropertyClass::wxFlagsPropertyClass ( const wxString& label, const wxString& name,
const wxChar** labels, const long* values, long value ) : wxPGPropertyWithChildren(label,name)
{
m_value = 0;
m_oldChoicesData = (wxPGChoicesData*) NULL;
if ( labels )
{
m_choices.Set(labels,values);
wxASSERT ( GetItemCount() );
DoSetValue( value );
}
}
wxFlagsPropertyClass::wxFlagsPropertyClass ( const wxString& label, const wxString& name,
const wxArrayString& labels, const wxArrayInt& values, int value )
: wxPGPropertyWithChildren(label,name)
{
m_value = 0;
m_oldChoicesData = (wxPGChoicesData*) NULL;
if ( &labels )
{
m_choices.Set(labels,values);
wxASSERT( GetItemCount() );
DoSetValue( (long)value );
}
}
wxFlagsPropertyClass::wxFlagsPropertyClass ( const wxString& label, const wxString& name,
wxPGChoices& choices, long value )
: wxPGPropertyWithChildren(label,name)
{
m_oldChoicesData = (wxPGChoicesData*) NULL;
m_choices.Assign(choices);
wxASSERT ( GetItemCount() );
DoSetValue( value );
}
wxFlagsPropertyClass::~wxFlagsPropertyClass ()
{
//wxPGUnRefChoices(m_choices);
}
void wxFlagsPropertyClass::DoSetValue ( wxPGVariant value )
{
if ( !m_choices.IsOk() || !GetItemCount() )
{
m_value = 0;
return;
}
long val = value.GetLong();
long full_flags = 0;
// normalize the value (i.e. remove extra flags)
unsigned int i;
const wxArrayInt& values = GetValues();
if ( values.GetCount() )
{
for ( i = 0; i < GetItemCount(); i++ )
full_flags |= values[i];
}
else
{
for ( i = 0; i < GetItemCount(); i++ )
full_flags |= (1<<i);
}
val &= full_flags;
m_value = val;
// Need to (re)init now?
if ( GetCount() != GetItemCount() ||
m_choices.GetDataPtr() != m_oldChoicesData )
{
Init();
}
RefreshChildren();
}
wxPGVariant wxFlagsPropertyClass::DoGetValue () const
{
return wxPGVariant((long)m_value);
}
wxString wxFlagsPropertyClass::GetValueAsString ( int ) const
{
wxString text;
if ( !m_choices.IsOk() )
return text;
long flags = m_value;
unsigned int i;
const wxArrayInt& values = GetValues();
if ( values.GetCount() )
{
for ( i = 0; i < GetItemCount(); i++ )
{
if ( flags & values[i] )
{
text += GetLabel(i);
text += wxT(", ");
}
}
}
else
{
for ( i = 0; i < GetItemCount(); i++ )
if ( flags & (1<<i) )
{
text += GetLabel(i);
text += wxT(", ");
}
}
// remove last comma
if ( text.Len() > 1 )
text.Truncate ( text.Len() - 2 );
return text;
}
// Translate string into flag tokens
bool wxFlagsPropertyClass::SetValueFromString ( const wxString& text, int )
{
if ( !m_choices.IsOk() || !GetItemCount() )
return false;
long new_flags = 0;
// semicolons are no longer valid delimeters
WX_PG_TOKENIZER1_BEGIN(text,wxT(','))
if ( token.length() )
{
// Determine which one it is
long bit = IdToBit( token );
if ( bit != -1 )
{
// Changed?
new_flags |= bit;
}
else
{
// Unknown identifier
wxString s;
s.Printf ( wxT("! %s: Unknown flag identifier \"%s\""), m_label.c_str(), token.c_str() );
ShowError(s);
}
}
WX_PG_TOKENIZER1_END()
if ( new_flags != m_value )
{
// Set child modified states
unsigned int i;
const wxArrayInt& values = GetValues();
if ( values.GetCount() )
for ( i = 0; i < GetItemCount(); i++ )
{
long flag = values[i];
if ( (new_flags & flag) != (m_value & flag) )
((wxPGProperty*)m_children.Item( i ))->SetFlag ( wxPG_PROP_MODIFIED );
}
else
for ( i = 0; i < GetItemCount(); i++ )
{
long flag = (1<<i);
if ( (new_flags & flag) != (m_value & flag) )
((wxPGProperty*)m_children.Item( i ))->SetFlag ( wxPG_PROP_MODIFIED );
}
DoSetValue ( new_flags );
return TRUE;
}
return FALSE;
}
// Converts string id to a relevant bit.
long wxFlagsPropertyClass::IdToBit ( const wxString& id ) const
{
unsigned int i;
const wxArrayInt& values = GetValues();
for ( i = 0; i < GetItemCount(); i++ )
{
#if wxCHECK_VERSION(2,9,0)
const wxString ptr = GetLabel(i);
#else
const wxChar* ptr = GetLabel(i);
#endif
if ( id == ptr )
{
//*pindex = i;
if ( values.GetCount() )
return values[i];
return (1<<i);
}
}
return -1;
}
void wxFlagsPropertyClass::RefreshChildren()
{
if ( !m_choices.IsOk() || !GetCount() ) return;
const wxArrayInt& values = GetValues();
long flags = m_value;
unsigned int i;
if ( values.GetCount() )
for ( i = 0; i < GetItemCount(); i++ )
Item(i)->DoSetValue ( ((long)((flags & values[i])?TRUE:FALSE)) );
else
for ( i = 0; i < GetItemCount(); i++ )
Item(i)->DoSetValue ( ((long)((flags & (1<<i))?TRUE:FALSE)) );
}
void wxFlagsPropertyClass::ChildChanged ( wxPGProperty* p )
{
wxASSERT( this == p->GetParent() );
const wxArrayInt& values = GetValues();
long val = p->DoGetValue().GetLong(); // bypass type checking
unsigned int iip = p->GetIndexInParent();
unsigned long vi = (1<<iip);
if ( values.GetCount() ) vi = values[iip];
if ( val )
m_value |= vi;
else
m_value &= ~(vi);
}
int wxFlagsPropertyClass::GetChoiceInfo( wxPGChoiceInfo* choiceinfo )
{
if ( choiceinfo )
choiceinfo->m_choices = &m_choices;
return -1;
}
// -----------------------------------------------------------------------
// wxDirProperty
// -----------------------------------------------------------------------
class wxDirPropertyClass : public wxLongStringPropertyClass
{
WX_PG_DECLARE_DERIVED_PROPERTY_CLASS()
public:
wxDirPropertyClass( const wxString& name, const wxString& label, const wxString& value );
virtual ~wxDirPropertyClass();
WX_PG_DECLARE_ATTRIBUTE_METHODS()
WX_PG_DECLARE_VALIDATOR_METHODS()
virtual bool OnButtonClick ( wxPropertyGrid* propGrid, wxString& value );
protected:
wxString m_dlgMessage;
};
WX_PG_IMPLEMENT_DERIVED_PROPERTY_CLASS(wxDirProperty,wxLongStringProperty,const wxString&)
wxDirPropertyClass::wxDirPropertyClass( const wxString& name, const wxString& label, const wxString& value )
: wxLongStringPropertyClass(name,label,value)
{
m_flags |= wxPG_NO_ESCAPE;
}
wxDirPropertyClass::~wxDirPropertyClass() { }
#if wxUSE_VALIDATORS
wxValidator* wxDirPropertyClass::DoGetValidator() const
{
return wxFilePropertyClass::GetClassValidator();
}
#endif
bool wxDirPropertyClass::OnButtonClick( wxPropertyGrid* propGrid, wxString& value )
{
wxSize dlg_sz(300,400);
wxDirDialog dlg( propGrid,
m_dlgMessage.length() ? m_dlgMessage : wxString(_("Choose a directory:")),
value,
0,
#if !wxPG_SMALL_SCREEN
propGrid->GetGoodEditorDialogPosition(this,dlg_sz),
dlg_sz );
#else
wxDefaultPosition,
wxDefaultSize );
#endif
if ( dlg.ShowModal() == wxID_OK )
{
value = dlg.GetPath();
return true;
}
return false;
}
void wxDirPropertyClass::SetAttribute( int id, wxVariant& value )
{
if ( id == wxPG_DIR_DIALOG_MESSAGE )
{
m_dlgMessage = value.GetString();
}
}
// -----------------------------------------------------------------------
// wxFileProperty
// -----------------------------------------------------------------------
// Class body is in propdev.h.
WX_PG_IMPLEMENT_PROPERTY_CLASS(wxFileProperty,wxBaseProperty,
wxString,const wxString&,TextCtrlAndButton)
wxFilePropertyClass::wxFilePropertyClass( const wxString& label, const wxString& name,
const wxString& value ) : wxPGProperty(label,name)
{
m_wildcard = _("All files (*.*)|*.*");
m_flags |= wxPG_PROP_SHOW_FULL_FILENAME;
m_indFilter = -1;
DoSetValue(value);
}
wxFilePropertyClass::~wxFilePropertyClass() {}
#if wxUSE_VALIDATORS
wxValidator* wxFilePropertyClass::GetClassValidator()
{
WX_PG_DOGETVALIDATOR_ENTRY()
// Atleast wxPython 2.6.2.1 required that the string argument is given
static wxString v;
wxTextValidator* validator = new wxTextValidator(wxFILTER_EXCLUDE_CHAR_LIST,&v);
wxArrayString exChars;
exChars.Add(wxT("?"));
exChars.Add(wxT("*"));
exChars.Add(wxT("|"));
exChars.Add(wxT("<"));
exChars.Add(wxT(">"));
exChars.Add(wxT("\""));
validator->SetExcludes(exChars);
WX_PG_DOGETVALIDATOR_EXIT(validator)
}
wxValidator* wxFilePropertyClass::DoGetValidator() const
{
return GetClassValidator();
}
#endif
void wxFilePropertyClass::DoSetValue( wxPGVariant value )
{
const wxString& str = wxPGVariantToString(value);
m_fnstr = str;
m_filename = str;
if ( !m_filename.HasName() )
{
m_fnstr = wxEmptyString;
m_filename.Clear();
}
// Find index for extension.
if ( m_indFilter < 0 && m_fnstr.length() )
{
wxString ext = m_filename.GetExt();
int curind = 0;
size_t pos = 0;
size_t len = m_wildcard.length();
pos = m_wildcard.find(wxT("|"), pos);
while ( pos != wxString::npos && pos < (len-3) )
{
size_t ext_begin = pos + 3;
pos = m_wildcard.find(wxT("|"), ext_begin);
if ( pos == wxString::npos )
pos = len;
wxString found_ext = m_wildcard.substr(ext_begin, pos-ext_begin);
if ( found_ext.length() > 0 )
{
if ( found_ext[0] == wxT('*') )
{
m_indFilter = curind;
break;
}
if ( ext.CmpNoCase(found_ext) == 0 )
{
m_indFilter = curind;
break;
}
}
if ( pos != len )
pos = m_wildcard.find(wxT("|"), pos+1);
curind++;
}
/*
wxChar a = wxT(' ');
const wxChar* p = m_wildcard.c_str();
wxString ext = m_filename.GetExt();
int curind = 0;
do
{
while ( a && a != wxT('|') ) { a = *p; p++; }
if ( !a ) break;
a = *p;
p++;
if ( !a ) break;
a = *p;
p++;
const wxChar* ext_begin = p;
if ( *ext_begin == wxT('*') )
{
m_indFilter = curind;
break;
}
while ( a && a != '|' ) { a = *p; p++; }
a = wxT(' ');
int count = p-ext_begin-1;
if ( count > 0 )
{
wxASSERT( count < 32 );
wxString found_ext = m_wildcard.Mid(ext_begin-m_wildcard.c_str(),count);
if ( ext.CmpNoCase(found_ext) == 0 )
{
m_indFilter = curind;
break;
}
}
curind++;
} while ( a );
*/
}
}
wxPGVariant wxFilePropertyClass::DoGetValue() const
{
return wxPGVariant(m_fnstr);
}
wxString wxFilePropertyClass::GetValueAsString( int argFlags ) const
{
if ( argFlags & wxPG_FULL_VALUE )
{
return m_filename.GetFullPath();
}
else if ( m_flags & wxPG_PROP_SHOW_FULL_FILENAME )
{
if ( m_basePath.Length() )
{
wxFileName fn2(m_filename);
fn2.MakeRelativeTo(m_basePath);
return fn2.GetFullPath();
}
return m_filename.GetFullPath();
}
return m_filename.GetFullName();
}
bool wxFilePropertyClass::OnEvent( wxPropertyGrid* propGrid,
wxWindow* primary,
wxEvent& event )
{
if ( event.GetEventType() == wxEVT_COMMAND_BUTTON_CLICKED )
{
// If text in control is changed, then update it to value.
PrepareValueForDialogEditing(propGrid);
wxString path;
path = m_filename.GetPath();
wxFileDialog dlg( propGrid,
m_dlgTitle.length() ? m_dlgTitle : wxString(_("Choose a file")),
!m_initialPath.empty() ? m_initialPath : m_filename.GetPath(),
wxEmptyString,
m_wildcard,
0,
wxDefaultPosition );
if ( m_indFilter >= 0 )
dlg.SetFilterIndex( m_indFilter );
if ( dlg.ShowModal() == wxID_OK )
{
m_indFilter = dlg.GetFilterIndex();
wxString path = dlg.GetPath();
SetValueFromString( path, wxPG_FULL_VALUE );
if ( primary )
GetEditorClass()->SetControlStringValue( primary, GetValueAsString(0) );
return true;
}
}
return false;
}
bool wxFilePropertyClass::SetValueFromString( const wxString& text, int argFlags )
{
if ( (m_flags & wxPG_PROP_SHOW_FULL_FILENAME) || (argFlags & wxPG_FULL_VALUE) )
{
if ( m_filename != text )
{
return StdValidationProcedure( text );
}
}
else
{
if ( m_filename.GetFullName() != text )
{
wxFileName fn = m_filename;
fn.SetFullName(text);
wxString val = fn.GetFullPath();
return StdValidationProcedure( val );
}
}
return false;
}
void wxFilePropertyClass::SetAttribute( int id, wxVariant& value )
{
if ( id == wxPG_FILE_SHOW_FULL_PATH )
{
if ( value.GetLong() )
m_flags |= wxPG_PROP_SHOW_FULL_FILENAME;
else
m_flags &= ~(wxPG_PROP_SHOW_FULL_FILENAME);
}
else if ( id == wxPG_FILE_WILDCARD )
{
m_wildcard = value.GetString();
}
else if ( id == wxPG_FILE_SHOW_RELATIVE_PATH )
{
m_basePath = value.GetString();
}
else if ( id == wxPG_FILE_INITIAL_PATH )
{
m_initialPath = value.GetString();
}
else if ( id == wxPG_FILE_DIALOG_TITLE )
{
m_dlgTitle = value.GetString();
}
}
// -----------------------------------------------------------------------
// wxLongStringProperty
// -----------------------------------------------------------------------
// Class body is in propdev.h.
WX_PG_IMPLEMENT_PROPERTY_CLASS(wxLongStringProperty,wxBaseProperty,
wxString,const wxString&,TextCtrlAndButton)
wxLongStringPropertyClass::wxLongStringPropertyClass( const wxString& label, const wxString& name,
const wxString& value ) : wxBasePropertyClass(label,name)
{
DoSetValue(value);
}
wxLongStringPropertyClass::~wxLongStringPropertyClass() {}
void wxLongStringPropertyClass::DoSetValue( wxPGVariant value )
{
m_value = wxPGVariantToString(value);
}
wxPGVariant wxLongStringPropertyClass::DoGetValue() const
{
return wxPGVariant(m_value);
}
wxString wxLongStringPropertyClass::GetValueAsString( int ) const
{
return m_value;
}
bool wxLongStringPropertyClass::OnEvent( wxPropertyGrid* propGrid, wxWindow* primary,
wxEvent& event )
{
if ( event.GetEventType() == wxEVT_COMMAND_BUTTON_CLICKED )
{
// Update the value
PrepareValueForDialogEditing(propGrid);
wxString val1 = GetValueAsString(0);
wxString val_orig = val1;
wxString value;
if ( !(m_flags & wxPG_PROP_NO_ESCAPE) )
wxPropertyGrid::ExpandEscapeSequences(value,val1);
else
value = wxString(val1);
// Run editor dialog.
if ( OnButtonClick(propGrid,value) )
{
if ( !(m_flags & wxPG_PROP_NO_ESCAPE) )
wxPropertyGrid::CreateEscapeSequences(val1,value);
else
val1 = value;
if ( val1 != val_orig )
{
SetValueFromString ( val1, 0 );
UpdateControl ( primary );
return true;
}
}
}
return false;
}
bool wxLongStringPropertyClass::OnButtonClick( wxPropertyGrid* propGrid, wxString& value )
{
// launch editor dialog
wxDialog* dlg = new wxDialog(propGrid,-1,m_label,wxDefaultPosition,wxDefaultSize,
wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxCLIP_CHILDREN);
dlg->SetFont(propGrid->GetFont()); // To allow entering chars of the same set as the propGrid
// Multi-line text editor dialog.
#if !wxPG_SMALL_SCREEN
const int spacing = 8;
#else
const int spacing = 4;
#endif
wxBoxSizer* topsizer = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* rowsizer = new wxBoxSizer( wxHORIZONTAL );
wxTextCtrl* ed = new wxTextCtrl(dlg,11,value,
wxDefaultPosition,wxDefaultSize,wxTE_MULTILINE);
rowsizer->Add( ed, 1, wxEXPAND|wxALL, spacing );
topsizer->Add( rowsizer, 1, wxEXPAND, 0 );
rowsizer = new wxBoxSizer( wxHORIZONTAL );
const int but_sz_flags =
wxALIGN_RIGHT|wxALIGN_CENTRE_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT;
rowsizer->Add( new wxButton(dlg,wxID_OK,_("Ok")),
0, but_sz_flags, spacing );
rowsizer->Add( new wxButton(dlg,wxID_CANCEL,_("Cancel")),
0, but_sz_flags, spacing );
topsizer->Add( rowsizer, 0, wxALIGN_RIGHT|wxALIGN_CENTRE_VERTICAL, 0 );
dlg->SetSizer( topsizer );
topsizer->SetSizeHints( dlg );
#if !wxPG_SMALL_SCREEN
dlg->SetSize(400,300);
dlg->Move( propGrid->GetGoodEditorDialogPosition(this,dlg->GetSize()) );
#endif
int res = dlg->ShowModal();
if ( res == wxID_OK )
{
value = ed->GetValue();
dlg->Destroy();
return true;
}
dlg->Destroy();
return false;
}
bool wxLongStringPropertyClass::SetValueFromString( const wxString& text, int )
{
if ( m_value != text )
{
DoSetValue ( text );
return true;
}
return false;
}
// -----------------------------------------------------------------------
// wxArrayEditorDialog
// -----------------------------------------------------------------------
BEGIN_EVENT_TABLE(wxArrayEditorDialog, wxDialog)
EVT_IDLE(wxArrayEditorDialog::OnIdle)
EVT_LISTBOX(24, wxArrayEditorDialog::OnListBoxClick)
EVT_TEXT_ENTER(21, wxArrayEditorDialog::OnAddClick)
EVT_BUTTON(22, wxArrayEditorDialog::OnAddClick)
EVT_BUTTON(23, wxArrayEditorDialog::OnDeleteClick)
EVT_BUTTON(25, wxArrayEditorDialog::OnUpClick)
EVT_BUTTON(26, wxArrayEditorDialog::OnDownClick)
EVT_BUTTON(27, wxArrayEditorDialog::OnUpdateClick)
//EVT_BUTTON(28, wxArrayEditorDialog::OnCustomEditClick)
END_EVENT_TABLE()
IMPLEMENT_ABSTRACT_CLASS(wxArrayEditorDialog, wxDialog)
#include <wx/statline.h>
// -----------------------------------------------------------------------
void wxArrayEditorDialog::OnIdle(wxIdleEvent& event)
{
//
// Do control focus detection here.
//
wxWindow* focused = FindFocus();
// This strange focus thing is a workaround for wxGTK wxListBox focus
// reporting bug.
if ( m_curFocus == 0 && focused != m_edValue &&
focused != m_butAdd && focused != m_butUpdate &&
m_lbStrings->GetSelection() >= 0 )
{
//wxLogDebug(wxT("Focused: %s"),focused?focused->GetClassInfo()->GetClassName():wxT("NULL"));
// ListBox was just focused.
m_butAdd->Enable(false);
m_butUpdate->Enable(false);
m_butRemove->Enable(true);
m_butUp->Enable(true);
m_butDown->Enable(true);
m_curFocus = 1;
}
else if ( (m_curFocus == 1 && focused == m_edValue) /*|| m_curFocus == 2*/ )
{
//wxLogDebug(wxT("Focused: %s"),focused?focused->GetClassInfo()->GetClassName():wxT("NULL"));
// TextCtrl was just focused.
m_butAdd->Enable(true);
bool upd_enable = false;
if ( m_lbStrings->GetCount() && m_lbStrings->GetSelection() >= 0 )
upd_enable = true;
m_butUpdate->Enable(upd_enable);
m_butRemove->Enable(false);
m_butUp->Enable(false);
m_butDown->Enable(false);
m_curFocus = 0;
}
event.Skip();
}
// -----------------------------------------------------------------------
wxArrayEditorDialog::wxArrayEditorDialog()
: wxDialog()
{
Init();
}
// -----------------------------------------------------------------------
void wxArrayEditorDialog::Init()
{
m_custBtText = (const wxChar*) NULL;
//m_pCallingClass = (wxArrayStringPropertyClass*) NULL;
}
// -----------------------------------------------------------------------
wxArrayEditorDialog::wxArrayEditorDialog( wxWindow *parent,
const wxString& message,
const wxString& caption,
long style,
const wxPoint& pos,
const wxSize& sz )
: wxDialog()
{
Init();
Create(parent,message,caption,style,pos,sz);
}
// -----------------------------------------------------------------------
bool wxArrayEditorDialog::Create( wxWindow *parent,
const wxString& message,
const wxString& caption,
long style,
const wxPoint& pos,
const wxSize& sz )
{
// On wxMAC the dialog shows incorrectly if style is not exactly wxCAPTION
// FIXME: This should be only a temporary fix.
#ifdef __WXMAC__
int useStyle = wxCAPTION;
#else
int useStyle = style;
#endif
bool res = wxDialog::Create(parent, wxID_ANY, caption, pos, sz, useStyle);
SetFont(parent->GetFont()); // To allow entering chars of the same set as the propGrid
#if !wxPG_SMALL_SCREEN
const int spacing = 4;
#else
const int spacing = 3;
#endif
m_modified = false;
m_curFocus = 1;
const int but_sz_flags =
wxALIGN_RIGHT|wxALIGN_CENTRE_VERTICAL|wxALL; //wxBOTTOM|wxLEFT|wxRIGHT;
wxBoxSizer* topsizer = new wxBoxSizer( wxVERTICAL );
// Message
if ( message.length() )
topsizer->Add( new wxStaticText(this,-1,message),
0, wxALIGN_LEFT|wxALIGN_CENTRE_VERTICAL|wxALL, spacing );
// String editor
wxBoxSizer* rowsizer = new wxBoxSizer( wxHORIZONTAL );
m_edValue = new wxTextCtrl(this,21,wxEmptyString,
wxDefaultPosition,wxDefaultSize,wxTE_PROCESS_ENTER);
wxValidator* validator = GetTextCtrlValidator();
if ( validator )
{
m_edValue->SetValidator( *validator );
delete validator;
}
rowsizer->Add( m_edValue,
1, wxALIGN_LEFT|wxALIGN_CENTRE_VERTICAL|wxALL, spacing );
// Add button
m_butAdd = new wxButton(this,22,_("Add"));
rowsizer->Add( m_butAdd,
0, wxALIGN_LEFT|wxALIGN_CENTRE_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT, spacing );
topsizer->Add( rowsizer, 0, wxEXPAND, spacing );
// Separator line
topsizer->Add( new wxStaticLine(this,-1),
0, wxEXPAND|wxBOTTOM|wxLEFT|wxRIGHT, spacing );
rowsizer = new wxBoxSizer( wxHORIZONTAL );
// list box
m_lbStrings = new wxListBox(this, 24, wxDefaultPosition, wxDefaultSize);
unsigned int i;
for ( i=0; i<ArrayGetCount(); i++ )
m_lbStrings->Append( ArrayGet(i) );
rowsizer->Add( m_lbStrings, 1, wxEXPAND|wxRIGHT, spacing );
// Manipulator buttons
wxBoxSizer* colsizer = new wxBoxSizer( wxVERTICAL );
m_butCustom = (wxButton*) NULL;
if ( m_custBtText )
{
m_butCustom = new wxButton(this,28,::wxGetTranslation(m_custBtText));
colsizer->Add( m_butCustom,
0, wxALIGN_CENTER|wxTOP/*wxALIGN_LEFT|wxALIGN_CENTRE_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT*/,
spacing );
}
m_butUpdate = new wxButton(this,27,_("Update"));
colsizer->Add( m_butUpdate,
0, wxALIGN_CENTER|wxTOP, spacing );
m_butRemove = new wxButton(this,23,_("Remove"));
colsizer->Add( m_butRemove,
0, wxALIGN_CENTER|wxTOP, spacing );
m_butUp = new wxButton(this,25,_("Up"));
colsizer->Add( m_butUp,
0, wxALIGN_CENTER|wxTOP, spacing );
m_butDown = new wxButton(this,26,_("Down"));
colsizer->Add( m_butDown,
0, wxALIGN_CENTER|wxTOP, spacing );
rowsizer->Add( colsizer, 0, 0, spacing );
topsizer->Add( rowsizer, 1, wxLEFT|wxRIGHT|wxEXPAND, spacing );
// Separator line
topsizer->Add( new wxStaticLine(this,-1),
0, wxEXPAND|wxTOP|wxLEFT|wxRIGHT, spacing );
// buttons
rowsizer = new wxBoxSizer( wxHORIZONTAL );
/*
const int but_sz_flags =
wxALIGN_RIGHT|wxALIGN_CENTRE_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT;
*/
rowsizer->Add( new wxButton(this,wxID_OK,_("Ok")),
0, but_sz_flags, spacing );
rowsizer->Add( new wxButton(this,wxID_CANCEL,_("Cancel")),
0, but_sz_flags, spacing );
topsizer->Add( rowsizer, 0, wxALIGN_RIGHT|wxALIGN_CENTRE_VERTICAL, 0 );
m_edValue->SetFocus();
SetSizer( topsizer );
topsizer->SetSizeHints( this );
#if !wxPG_SMALL_SCREEN
if ( sz.x == wxDefaultSize.x &&
sz.y == wxDefaultSize.y )
SetSize( wxSize(275,360) );
else
SetSize(sz);
#endif
return res;
}
// -----------------------------------------------------------------------
void wxArrayEditorDialog::OnAddClick(wxCommandEvent& )
{
wxString text = m_edValue->GetValue();
if ( text.length() )
{
if ( ArrayInsert( text, -1 ) )
{
m_lbStrings->Append( text );
m_modified = true;
m_edValue->Clear();
}
}
}
// -----------------------------------------------------------------------
void wxArrayEditorDialog::OnDeleteClick(wxCommandEvent& )
{
int index = m_lbStrings->GetSelection();
if ( index >= 0 )
{
ArrayRemoveAt( index );
m_lbStrings->Delete ( index );
m_modified = true;
}
}
// -----------------------------------------------------------------------
void wxArrayEditorDialog::OnUpClick(wxCommandEvent& )
{
int index = m_lbStrings->GetSelection();
if ( index > 0 )
{
ArraySwap(index-1,index);
/*wxString old_str = m_array[index-1];
wxString new_str = m_array[index];
m_array[index-1] = new_str;
m_array[index] = old_str;*/
m_lbStrings->SetString ( index-1, ArrayGet(index-1) );
m_lbStrings->SetString ( index, ArrayGet(index) );
m_lbStrings->SetSelection ( index-1 );
m_modified = true;
}
}
// -----------------------------------------------------------------------
void wxArrayEditorDialog::OnDownClick(wxCommandEvent& )
{
int index = m_lbStrings->GetSelection();
int lastStringIndex = ((int) m_lbStrings->GetCount()) - 1;
if ( index >= 0 && index < lastStringIndex )
{
ArraySwap(index,index+1);
/*wxString old_str = m_array[index+1];
wxString new_str = m_array[index];
m_array[index+1] = new_str;
m_array[index] = old_str;*/
m_lbStrings->SetString ( index+1, ArrayGet(index+1) );
m_lbStrings->SetString ( index, ArrayGet(index) );
m_lbStrings->SetSelection ( index+1 );
m_modified = true;
}
}
// -----------------------------------------------------------------------
void wxArrayEditorDialog::OnUpdateClick(wxCommandEvent& )
{
int index = m_lbStrings->GetSelection();
if ( index >= 0 )
{
wxString str = m_edValue->GetValue();
if ( ArraySet(index,str) )
{
m_lbStrings->SetString ( index, str );
//m_array[index] = str;
m_modified = true;
}
}
}
// -----------------------------------------------------------------------
/*void wxArrayEditorDialog::OnCustomEditClick(wxCommandEvent& )
{
wxASSERT ( m_pCallingClass );
wxString str = m_edValue->GetValue();
if ( m_pCallingClass->OnCustomStringEdit(m_parent,str) )
{
//m_edValue->SetValue ( str );
if ( ArrayInsert(-1,str) )
{
m_lbStrings->Append ( str );
m_modified = true;
}
}
}*/
// -----------------------------------------------------------------------
void wxArrayEditorDialog::OnListBoxClick(wxCommandEvent& )
{
int index = m_lbStrings->GetSelection();
if ( index >= 0 )
{
m_edValue->SetValue( m_lbStrings->GetString(index) );
}
}
// -----------------------------------------------------------------------
// wxArrayStringEditorDialog
// -----------------------------------------------------------------------
class wxArrayStringEditorDialog : public wxArrayEditorDialog
{
public:
wxArrayStringEditorDialog();
void Init();
virtual void SetDialogValue( const wxVariant& value )
{
m_array = value.GetArrayString();
}
virtual wxVariant GetDialogValue() const
{
return m_array;
}
inline void SetCustomButton( const wxChar* custBtText, wxArrayStringPropertyClass* pcc )
{
m_custBtText = custBtText;
m_pCallingClass = pcc;
}
void OnCustomEditClick(wxCommandEvent& event);
protected:
wxArrayString m_array;
wxArrayStringPropertyClass* m_pCallingClass;
virtual wxString ArrayGet( size_t index );
virtual size_t ArrayGetCount();
virtual bool ArrayInsert( const wxString& str, int index );
virtual bool ArraySet( size_t index, const wxString& str );
virtual void ArrayRemoveAt( int index );
virtual void ArraySwap( size_t first, size_t second );
private:
DECLARE_DYNAMIC_CLASS_NO_COPY(wxArrayStringEditorDialog)
DECLARE_EVENT_TABLE()
};
BEGIN_EVENT_TABLE(wxArrayStringEditorDialog, wxArrayEditorDialog)
EVT_BUTTON(28, wxArrayStringEditorDialog::OnCustomEditClick)
END_EVENT_TABLE()
IMPLEMENT_DYNAMIC_CLASS(wxArrayStringEditorDialog, wxArrayEditorDialog)
// -----------------------------------------------------------------------
wxString wxArrayStringEditorDialog::ArrayGet( size_t index )
{
return m_array[index];
}
size_t wxArrayStringEditorDialog::ArrayGetCount()
{
return m_array.GetCount();
}
bool wxArrayStringEditorDialog::ArrayInsert( const wxString& str, int index )
{
if (index<0)
m_array.Add(str);
else
m_array.Insert(str,index);
return true;
}
bool wxArrayStringEditorDialog::ArraySet( size_t index, const wxString& str )
{
m_array[index] = str;
return true;
}
void wxArrayStringEditorDialog::ArrayRemoveAt( int index )
{
m_array.RemoveAt(index);
}
void wxArrayStringEditorDialog::ArraySwap( size_t first, size_t second )
{
wxString old_str = m_array[first];
wxString new_str = m_array[second];
m_array[first] = new_str;
m_array[second] = old_str;
}
wxArrayStringEditorDialog::wxArrayStringEditorDialog()
: wxArrayEditorDialog()
{
Init();
}
void wxArrayStringEditorDialog::Init()
{
m_pCallingClass = (wxArrayStringPropertyClass*) NULL;
}
void wxArrayStringEditorDialog::OnCustomEditClick(wxCommandEvent& )
{
wxASSERT( m_pCallingClass );
wxString str = m_edValue->GetValue();
if ( m_pCallingClass->OnCustomStringEdit(m_parent,str) )
{
//m_edValue->SetValue ( str );
m_lbStrings->Append ( str );
m_array.Add ( str );
m_modified = true;
}
}
// -----------------------------------------------------------------------
// wxArrayStringProperty
// -----------------------------------------------------------------------
// Class body is in propdev.h
WX_PG_IMPLEMENT_PROPERTY_CLASS(wxArrayStringProperty, // Property name
wxBaseProperty, // Property we inherit from
wxArrayString, // Value type name
const wxArrayString&, // Value type, as given in constructor
TextCtrlAndButton) // Initial editor
wxArrayStringPropertyClass::wxArrayStringPropertyClass( const wxString& label,
const wxString& name,
const wxArrayString& array )
: wxPGProperty(label,name)
{
DoSetValue( array );
}
wxArrayStringPropertyClass::~wxArrayStringPropertyClass() { }
void wxArrayStringPropertyClass::DoSetValue( wxPGVariant value )
{
m_value = wxPGVariantToArrayString(value);
GenerateValueAsString();
}
wxPGVariant wxArrayStringPropertyClass::DoGetValue() const
{
return wxPGVariantCreator(m_value);
}
wxString wxArrayStringPropertyClass::GetValueAsString( int WXUNUSED(argFlags) ) const
{
return m_display;
}
// Converts wxArrayString to a string separated by delimeters and spaces.
// preDelim is useful for "str1" "str2" style. Set flags to 1 to do slash
// conversion.
void wxPropertyGrid::ArrayStringToString( wxString& dst, const wxArrayString& src,
wxChar preDelim, wxChar postDelim,
int flags )
{
wxString pdr;
unsigned int i;
unsigned int itemCount = src.GetCount();
wxChar preas[2];
dst.Empty();
if ( !preDelim )
preas[0] = 0;
else if ( (flags & 1) )
{
preas[0] = preDelim;
preas[1] = 0;
pdr = wxT("\\");
pdr += preDelim;
}
if ( itemCount )
dst.append( preas );
wxASSERT( postDelim );
for ( i = 0; i < itemCount; i++ )
{
wxString str( src.Item(i) );
// Do some character conversion.
// Convertes \ to \\ and <preDelim> to \<preDelim>
// Useful when preDelim and postDelim are "\"".
if ( flags & 1 )
{
str.Replace( wxT("\\"), wxT("\\\\"), true );
if ( pdr.length() )
str.Replace( preas, pdr, true );
}
dst.append ( str );
if ( i < (itemCount-1) )
{
dst.append( wxString(postDelim) );
dst.append( wxT(" ") );
dst.append( wxString(preas) );
}
else if ( preDelim )
dst.append( wxString(postDelim) );
}
}
#define ARRSTRPROP_ARRAY_TO_STRING(STRING,ARRAY) \
wxPropertyGrid::ArrayStringToString(STRING,ARRAY,wxT('"'),wxT('"'),1);
void wxArrayStringPropertyClass::GenerateValueAsString()
{
ARRSTRPROP_ARRAY_TO_STRING(m_display, m_value)
}
// Default implementation doesn't do anything.
bool wxArrayStringPropertyClass::OnCustomStringEdit( wxWindow*, wxString& )
{
return false;
}
wxArrayEditorDialog* wxArrayStringPropertyClass::CreateEditorDialog()
{
return new wxArrayStringEditorDialog();
}
bool wxArrayStringPropertyClass::OnButtonClick( wxPropertyGrid* propGrid,
wxWindow* primaryCtrl,
const wxChar* cbt )
{
// Update the value
PrepareValueForDialogEditing(propGrid);
if ( !propGrid->EditorValidate() )
return false;
// Create editor dialog.
wxArrayEditorDialog* dlg = CreateEditorDialog();
wxValidator* validator = GetValidator();
wxPGInDialogValidator dialogValidator;
wxArrayStringEditorDialog* strEdDlg = wxDynamicCast(dlg, wxArrayStringEditorDialog);
if ( strEdDlg )
strEdDlg->SetCustomButton(cbt, this);
dlg->SetDialogValue( wxVariant(m_value) );
dlg->Create(propGrid, wxEmptyString, m_label);
#if !wxPG_SMALL_SCREEN
dlg->Move( propGrid->GetGoodEditorDialogPosition(this,dlg->GetSize()) );
#endif
bool retVal;
for (;;)
{
retVal = false;
int res = dlg->ShowModal();
if ( res == wxID_OK && dlg->IsModified() )
{
wxVariant value = dlg->GetDialogValue();
if ( !value.IsNull() )
{
wxArrayString actualValue = value.GetArrayString();
wxString tempStr;
ARRSTRPROP_ARRAY_TO_STRING(tempStr, actualValue)
if ( dialogValidator.DoValidate( propGrid, validator, tempStr ) )
{
DoSetValue( actualValue );
UpdateControl( primaryCtrl );
retVal = true;
break;
}
}
else
break;
}
else
break;
}
delete dlg;
return retVal;
}
bool wxArrayStringPropertyClass::OnEvent( wxPropertyGrid* propGrid,
wxWindow* primary,
wxEvent& event )
{
if ( event.GetEventType() == wxEVT_COMMAND_BUTTON_CLICKED )
return OnButtonClick(propGrid,primary,(const wxChar*) NULL);
return false;
}
bool wxArrayStringPropertyClass::SetValueFromString( const wxString& text, int )
{
m_value.Empty();
WX_PG_TOKENIZER2_BEGIN(text,wxT('"'))
// Need to replace backslashes with empty characters
// (opposite what is done in GenerateValueString).
token.Replace ( wxT("\\"), wxT(""), true );
m_value.Add ( token );
WX_PG_TOKENIZER2_END()
GenerateValueAsString();
return true;
}
// -----------------------------------------------------------------------
// wxCustomProperty
// -----------------------------------------------------------------------
wxPGProperty* wxCustomProperty( const wxString& label, const wxString& name )
{
return new wxCustomPropertyClass (label,name);
}
WX_PG_IMPLEMENT_CLASSINFO(wxCustomProperty,wxBaseParentPropertyClass)
wxPG_GETCLASSNAME_IMPLEMENTATION(wxCustomProperty)
wxPG_VALUETYPE_MSGVAL wxCustomPropertyClass::GetValueType() const
{
return wxPG_VALUETYPE(wxString);
}
const wxPGEditor* wxCustomPropertyClass::DoGetEditorClass() const
{
return wxPG_EDITOR(TextCtrl);
}
wxCustomPropertyClass::wxCustomPropertyClass(const wxString& label,
const wxString& name)
: wxPGPropertyWithChildren(label,name)
{
m_parentingType = -2;
#ifdef wxPG_COMPATIBILITY_1_0_0
m_callback = (wxPropertyGridCallback) NULL;
#endif
//m_choices = &wxPGGlobalVars->m_emptyChoicesData;
m_paintCallback = (wxPGPaintCallback) NULL;
}
wxCustomPropertyClass::~wxCustomPropertyClass()
{
//wxPGUnRefChoices(m_choices);
}
void wxCustomPropertyClass::DoSetValue ( wxPGVariant value )
{
m_value = value.GetString();
}
wxPGVariant wxCustomPropertyClass::DoGetValue () const
{
return m_value;
}
bool wxCustomPropertyClass::SetValueFromString ( const wxString& text, int /*flags*/ )
{
if ( text != m_value )
{
m_value = text;
return true;
}
return false;
}
wxString wxCustomPropertyClass::GetValueAsString ( int /*argFlags*/ ) const
{
return m_value;
}
// Need to do some extra event handling.
#ifdef wxPG_COMPATIBILITY_1_0_0
bool wxCustomPropertyClass::OnEvent ( wxPropertyGrid* propGrid, wxWindow* primary, wxEvent& event )
{
if ( event.GetEventType() == wxEVT_COMMAND_BUTTON_CLICKED )
{
if ( m_callback )
return m_callback(propGrid,this,primary,0);
}
return false;
}
#endif
wxSize wxCustomPropertyClass::GetImageSize() const
{
if ( m_paintCallback )
return wxSize(-wxPG_CUSTOM_IMAGE_WIDTH,-wxPG_CUSTOM_IMAGE_WIDTH);
return wxPGPropertyWithChildren::GetImageSize();
}
void wxCustomPropertyClass::OnCustomPaint( wxDC& dc,
const wxRect& rect,
wxPGPaintData& paintData )
{
if ( m_paintCallback )
m_paintCallback(this,dc,rect,paintData);
else
wxPGPropertyWithChildren::OnCustomPaint(dc,rect,paintData);
}
bool wxCustomPropertyClass::SetValueFromInt ( long value, int )
{
size_t index = value;
const wxArrayInt& values = m_choices.GetValues();
if ( values.GetCount() )
index = values.Index(value);
const wxString& sAtIndex = m_choices.GetLabel(index);
if ( sAtIndex != m_value )
{
m_value = sAtIndex;
return true;
}
return false;
}
int wxCustomPropertyClass::GetChoiceInfo( wxPGChoiceInfo* choiceinfo )
{
if ( choiceinfo )
{
choiceinfo->m_choices = &m_choices;
if ( !m_choices.IsOk() )
return -1;
choiceinfo->m_itemCount = m_choices.GetCount();
if ( m_choices.GetCount() )
choiceinfo->m_arrWxString = (wxString*)&m_choices.GetLabel(0);
}
if ( !m_choices.IsOk() )
return -1;
return m_choices.GetLabels().Index(m_value);
}
void wxCustomPropertyClass::SetAttribute ( int id, wxVariant& value )
{
#ifdef wxPG_COMPATIBILITY_1_0_0
wxPropertyGrid* grid = GetGrid();
if ( id == wxPG_CUSTOM_EDITOR )
{
if ( grid )
grid->SetPropertyEditor( wxPGIdGen(this), (wxPGEditor*) value.GetVoidPtr() );
else
SetEditor( (wxPGEditor*) value.GetVoidPtr() );
}
else if ( id == wxPG_CUSTOM_IMAGE )
{
wxBitmap* bmp = (wxBitmap*) value.GetWxObjectPtr();
if ( grid )
grid->SetPropertyImage(wxPGIdGen(this),*bmp);
else
SetValueImage(*bmp);
}
else if ( id == wxPG_CUSTOM_CALLBACK )
{
m_callback = (wxPropertyGridCallback) value.GetVoidPtr();
}
else
#endif
if ( id == wxPG_CUSTOM_PAINT_CALLBACK )
{
void* voidValue = value.GetVoidPtr();
m_paintCallback = (wxPGPaintCallback) voidValue;
if ( voidValue )
m_flags |= wxPG_PROP_CUSTOMIMAGE;
else if ( !GetValueImage() )
m_flags &= ~(wxPG_PROP_CUSTOMIMAGE);
}
else
if ( id == wxPG_CUSTOM_PRIVATE_CHILDREN )
{
if ( value.GetLong() )
m_parentingType = -1;
else
m_parentingType = -2;
}
}
// -----------------------------------------------------------------------