1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/propgrid/props.cpp 
   3 // Purpose:     Basic Property Classes 
   4 // Author:      Jaakko Salli 
   8 // Copyright:   (c) Jaakko Salli 
   9 // Licence:     wxWindows license 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // For compilers that support precompilation, includes "wx/wx.h". 
  13 #include "wx/wxprec.h" 
  23     #include "wx/object.h" 
  25     #include "wx/string.h" 
  28     #include "wx/window.h" 
  31     #include "wx/dcclient.h" 
  32     #include "wx/dcmemory.h" 
  33     #include "wx/button.h" 
  36     #include "wx/cursor.h" 
  37     #include "wx/dialog.h" 
  38     #include "wx/settings.h" 
  39     #include "wx/msgdlg.h" 
  40     #include "wx/choice.h" 
  41     #include "wx/stattext.h" 
  42     #include "wx/scrolwin.h" 
  43     #include "wx/dirdlg.h" 
  44     #include "wx/combobox.h" 
  45     #include "wx/layout.h" 
  47     #include "wx/textdlg.h" 
  48     #include "wx/filedlg.h" 
  52 #include "wx/filename.h" 
  54 #include "wx/propgrid/propgrid.h" 
  56 #define wxPG_CUSTOM_IMAGE_WIDTH     20 // for wxColourProperty etc. 
  59 // ----------------------------------------------------------------------- 
  61 // ----------------------------------------------------------------------- 
  63 WX_PG_IMPLEMENT_PROPERTY_CLASS(wxStringProperty
,wxPGProperty
, 
  64                                wxString
,const wxString
&,TextCtrl
) 
  66 wxStringProperty::wxStringProperty( const wxString
& label
, 
  68                                     const wxString
& value 
) 
  69     : wxPGProperty(label
,name
) 
  74 void wxStringProperty::OnSetValue() 
  76     if ( !m_value
.IsNull() && m_value
.GetString() == wxS("<composed>") ) 
  77         SetFlag(wxPG_PROP_COMPOSED_VALUE
); 
  79     if ( HasFlag(wxPG_PROP_COMPOSED_VALUE
) ) 
  82         GenerateComposedValue(s
, 0); 
  87 wxStringProperty::~wxStringProperty() { } 
  89 wxString 
wxStringProperty::GetValueAsString( int argFlags 
) const 
  91     wxString s 
= m_value
.GetString(); 
  93     if ( GetChildCount() && HasFlag(wxPG_PROP_COMPOSED_VALUE
) ) 
  95         // Value stored in m_value is non-editable, non-full value 
  96         if ( (argFlags 
& wxPG_FULL_VALUE
) || (argFlags 
& wxPG_EDITABLE_VALUE
) ) 
  97             GenerateComposedValue(s
, argFlags
); 
 102     // If string is password and value is for visual purposes, 
 103     // then return asterisks instead the actual string. 
 104     if ( (m_flags 
& wxPG_PROP_PASSWORD
) && !(argFlags 
& (wxPG_FULL_VALUE
|wxPG_EDITABLE_VALUE
)) ) 
 105         return wxString(wxChar('*'), s
.Length()); 
 110 bool wxStringProperty::StringToValue( wxVariant
& variant
, const wxString
& text
, int argFlags 
) const 
 112     if ( GetChildCount() && HasFlag(wxPG_PROP_COMPOSED_VALUE
) ) 
 113         return wxPGProperty::StringToValue(variant
, text
, argFlags
); 
 115     if ( variant 
!= text 
) 
 124 bool wxStringProperty::DoSetAttribute( const wxString
& name
, wxVariant
& value 
) 
 126     if ( name 
== wxPG_STRING_PASSWORD 
) 
 128         m_flags 
&= ~(wxPG_PROP_PASSWORD
); 
 129         if ( wxPGVariantToInt(value
) ) m_flags 
|= wxPG_PROP_PASSWORD
; 
 136 // ----------------------------------------------------------------------- 
 138 // ----------------------------------------------------------------------- 
 140 WX_PG_IMPLEMENT_PROPERTY_CLASS(wxIntProperty
,wxPGProperty
, 
 143 wxIntProperty::wxIntProperty( const wxString
& label
, const wxString
& name
, 
 144     long value 
) : wxPGProperty(label
,name
) 
 149 wxIntProperty::wxIntProperty( const wxString
& label
, const wxString
& name
, 
 150     const wxLongLong
& value 
) : wxPGProperty(label
,name
) 
 152     SetValue(WXVARIANT(value
)); 
 155 wxIntProperty::~wxIntProperty() { } 
 157 wxString 
wxIntProperty::GetValueAsString( int ) const 
 159     if ( m_value
.GetType() == wxPG_VARIANT_TYPE_LONG 
) 
 161         return wxString::Format(wxS("%li"),m_value
.GetLong()); 
 163     else if ( m_value
.GetType() == wxLongLong_VariantType 
) 
 167             return ll
.ToString(); 
 170     return wxEmptyString
; 
 173 bool wxIntProperty::StringToValue( wxVariant
& variant
, const wxString
& text
, int argFlags 
) const 
 178     if ( text
.length() == 0 ) 
 184     // We know it is a number, but let's still check 
 186     if ( text
.IsNumber() ) 
 188         // Remove leading zeroes, so that the number is not interpreted as octal 
 189         wxString::const_iterator i 
= text
.begin(); 
 190         wxString::const_iterator iMax 
= text
.end() - 1;  // Let's allow one, last zero though 
 192         int firstNonZeroPos 
= 0; 
 194         for ( ; i 
!= iMax
; i
++ ) 
 197             if ( c 
!= wxS('0') && c 
!= wxS(' ') ) 
 202         wxString useText 
= text
.substr(firstNonZeroPos
, text
.length() - firstNonZeroPos
); 
 204         wxString variantType 
= variant
.GetType(); 
 205         bool isPrevLong 
= variantType 
== wxPG_VARIANT_TYPE_LONG
; 
 207         wxLongLong_t value64 
= 0; 
 209         if ( useText
.ToLongLong(&value64
, 10) && 
 210              ( value64 
>= INT_MAX 
|| value64 
<= INT_MIN 
) 
 213             bool doChangeValue 
= isPrevLong
; 
 215             if ( !isPrevLong 
&& variantType 
== wxLongLong_VariantType 
) 
 219                 if ( oldValue
.GetValue() != value64 
) 
 220                     doChangeValue 
= true; 
 225                 wxLongLong 
ll(value64
); 
 231         if ( useText
.ToLong( &value32
, 0 ) ) 
 233             if ( !isPrevLong 
|| variant 
!= value32 
) 
 240     else if ( argFlags 
& wxPG_REPORT_ERROR 
) 
 246 bool wxIntProperty::IntToValue( wxVariant
& variant
, int value
, int WXUNUSED(argFlags
) ) const 
 248     if ( variant
.GetType() != wxPG_VARIANT_TYPE_LONG 
|| variant 
!= (long)value 
) 
 250         variant 
= (long)value
; 
 256 bool wxIntProperty::DoValidation( const wxPGProperty
* property
, wxLongLong_t
& value
, wxPGValidationInfo
* pValidationInfo
, int mode 
) 
 259     wxLongLong_t min 
= wxINT64_MIN
; 
 260     wxLongLong_t max 
= wxINT64_MAX
; 
 265     variant 
= property
->GetAttribute(wxPGGlobalVars
->m_strMin
); 
 266     if ( !variant
.IsNull() ) 
 268         wxPGVariantToLongLong(variant
, &min
); 
 272     variant 
= property
->GetAttribute(wxPGGlobalVars
->m_strMax
); 
 273     if ( !variant
.IsNull() ) 
 275         wxPGVariantToLongLong(variant
, &max
); 
 283             if ( mode 
== wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE 
) 
 284                 pValidationInfo
->SetFailureMessage( 
 285                     wxString::Format(_("Value must be %lld or higher"),min
) 
 287             else if ( mode 
== wxPG_PROPERTY_VALIDATION_SATURATE 
) 
 290                 value 
= max 
- (min 
- value
); 
 299             if ( mode 
== wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE 
) 
 300                 pValidationInfo
->SetFailureMessage( 
 301                     wxString::Format(_("Value must be %lld or higher"),min
) 
 303             else if ( mode 
== wxPG_PROPERTY_VALIDATION_SATURATE 
) 
 306                 value 
= min 
+ (value 
- max
); 
 313 bool wxIntProperty::ValidateValue( wxVariant
& value
, wxPGValidationInfo
& validationInfo 
) const 
 316     if ( wxPGVariantToLongLong(value
, &ll
) ) 
 317         return DoValidation(this, ll
, &validationInfo
, wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE
); 
 321 wxValidator
* wxIntProperty::GetClassValidator() 
 324     WX_PG_DOGETVALIDATOR_ENTRY() 
 326     // Atleast wxPython 2.6.2.1 required that the string argument is given 
 328     wxTextValidator
* validator 
= new wxTextValidator(wxFILTER_NUMERIC
,&v
); 
 330     WX_PG_DOGETVALIDATOR_EXIT(validator
) 
 336 wxValidator
* wxIntProperty::DoGetValidator() const 
 338     return GetClassValidator(); 
 341 // ----------------------------------------------------------------------- 
 343 // ----------------------------------------------------------------------- 
 346 #define wxPG_UINT_TEMPLATE_MAX 8 
 348 static const wxChar
* gs_uintTemplates32
[wxPG_UINT_TEMPLATE_MAX
] = { 
 349     wxT("%x"),wxT("0x%x"),wxT("$%x"), 
 350     wxT("%X"),wxT("0x%X"),wxT("$%X"), 
 354 static const wxChar
* gs_uintTemplates64
[wxPG_UINT_TEMPLATE_MAX
] = { 
 355     wxT("%") wxLongLongFmtSpec 
wxT("x"), 
 356     wxT("0x%") wxLongLongFmtSpec 
wxT("x"), 
 357     wxT("$%") wxLongLongFmtSpec 
wxT("x"), 
 358     wxT("%") wxLongLongFmtSpec 
wxT("X"), 
 359     wxT("0x%") wxLongLongFmtSpec 
wxT("X"), 
 360     wxT("$%") wxLongLongFmtSpec 
wxT("X"), 
 361     wxT("%") wxLongLongFmtSpec 
wxT("u"), 
 362     wxT("%") wxLongLongFmtSpec 
wxT("o") 
 365 WX_PG_IMPLEMENT_PROPERTY_CLASS(wxUIntProperty
,wxPGProperty
, 
 366                                long,unsigned long,TextCtrl
) 
 368 void wxUIntProperty::Init() 
 370     m_base 
= 6; // This is magic number for dec base (must be same as in setattribute) 
 372     m_prefix 
= wxPG_PREFIX_NONE
; 
 375 wxUIntProperty::wxUIntProperty( const wxString
& label
, const wxString
& name
, 
 376     unsigned long value 
) : wxPGProperty(label
,name
) 
 379     SetValue((long)value
); 
 382 wxUIntProperty::wxUIntProperty( const wxString
& label
, const wxString
& name
, 
 383     const wxULongLong
& value 
) : wxPGProperty(label
,name
) 
 386     SetValue(WXVARIANT(value
)); 
 389 wxUIntProperty::~wxUIntProperty() { } 
 391 wxString 
wxUIntProperty::GetValueAsString( int ) const 
 393     size_t index 
= m_base 
+ m_prefix
; 
 394     if ( index 
>= wxPG_UINT_TEMPLATE_MAX 
) 
 395         index 
= wxPG_BASE_DEC
; 
 397     if ( m_value
.GetType() == wxPG_VARIANT_TYPE_LONG 
) 
 399         return wxString::Format(gs_uintTemplates32
[index
], (unsigned long)m_value
.GetLong()); 
 405     return wxString::Format(gs_uintTemplates64
[index
], ull
.GetValue()); 
 408 bool wxUIntProperty::StringToValue( wxVariant
& variant
, const wxString
& text
, int WXUNUSED(argFlags
) ) const 
 410     wxString variantType 
= variant
.GetType(); 
 411     bool isPrevLong 
= variantType 
== wxPG_VARIANT_TYPE_LONG
; 
 413     if ( text
.length() == 0 ) 
 420     if ( text
[0] == wxS('$') ) 
 423     wxULongLong_t value64 
= 0; 
 424     wxString s 
= text
.substr(start
, text
.length() - start
); 
 426     if ( s
.ToULongLong(&value64
, (unsigned int)m_realBase
) ) 
 428         if ( value64 
>= LONG_MAX 
) 
 430             bool doChangeValue 
= isPrevLong
; 
 432             if ( !isPrevLong 
&& variantType 
== wxULongLong_VariantType 
) 
 434                 wxULongLong oldValue
; 
 436                 if ( oldValue
.GetValue() != value64 
) 
 437                     doChangeValue 
= true; 
 442                 wxULongLong 
ull(value64
); 
 449             unsigned long value32 
= wxLongLong(value64
).GetLo(); 
 450             if ( !isPrevLong 
|| m_value 
!= (long)value32 
) 
 452                 variant 
= (long)value32
; 
 461 bool wxUIntProperty::IntToValue( wxVariant
& variant
, int number
, int WXUNUSED(argFlags
) ) const 
 463     if ( variant 
!= (long)number 
) 
 465         variant 
= (long)number
; 
 472   #define wxUINT64_MAX ULLONG_MAX 
 473   #define wxUINT64_MIN wxULL(0) 
 475   #define wxUINT64_MAX wxULL(0xFFFFFFFFFFFFFFFF) 
 476   #define wxUINT64_MIN wxULL(0) 
 479 bool wxUIntProperty::ValidateValue( wxVariant
& value
, wxPGValidationInfo
& validationInfo 
) const 
 483     if ( wxPGVariantToULongLong(value
, &ll
) ) 
 485         wxULongLong_t min 
= wxUINT64_MIN
; 
 486         wxULongLong_t max 
= wxUINT64_MAX
; 
 489         variant 
= GetAttribute(wxPGGlobalVars
->m_strMin
); 
 490         if ( !variant
.IsNull() ) 
 492             wxPGVariantToULongLong(variant
, &min
); 
 495                 validationInfo
.SetFailureMessage( 
 496                     wxString::Format(_("Value must be %llu or higher"),min
) 
 501         variant 
= GetAttribute(wxPGGlobalVars
->m_strMax
); 
 502         if ( !variant
.IsNull() ) 
 504             wxPGVariantToULongLong(variant
, &max
); 
 507                 validationInfo
.SetFailureMessage( 
 508                     wxString::Format(_("Value must be %llu or less"),max
) 
 517 bool wxUIntProperty::DoSetAttribute( const wxString
& name
, wxVariant
& value 
) 
 519     if ( name 
== wxPG_UINT_BASE 
) 
 521         int val 
= value
.GetLong(); 
 523         m_realBase 
= (wxByte
) val
; 
 524         if ( m_realBase 
> 16 ) 
 528         // Translate logical base to a template array index 
 530         if ( val 
== wxPG_BASE_HEX 
) 
 532         else if ( val 
== wxPG_BASE_DEC 
) 
 534         else if ( val 
== wxPG_BASE_HEXL 
) 
 538     else if ( name 
== wxPG_UINT_PREFIX 
) 
 540         m_prefix 
= (wxByte
) value
.GetLong(); 
 546 // ----------------------------------------------------------------------- 
 548 // ----------------------------------------------------------------------- 
 550 WX_PG_IMPLEMENT_PROPERTY_CLASS(wxFloatProperty
,wxPGProperty
, 
 551                                double,double,TextCtrl
) 
 553 wxFloatProperty::wxFloatProperty( const wxString
& label
, 
 554                                             const wxString
& name
, 
 556     : wxPGProperty(label
,name
) 
 562 wxFloatProperty::~wxFloatProperty() { } 
 564 // This helper method provides standard way for floating point-using 
 565 // properties to convert values to string. 
 566 void wxPropertyGrid::DoubleToString(wxString
& target
, 
 570                                     wxString
* precTemplate
) 
 572     if ( precision 
>= 0 ) 
 576             precTemplate 
= &text1
; 
 578         if ( !precTemplate
->length() ) 
 580             *precTemplate 
= wxS("%."); 
 581             *precTemplate 
<< wxString::Format( wxS("%i"), precision 
); 
 582             *precTemplate 
<< wxS('f'); 
 585         target
.Printf( precTemplate
->c_str(), value 
); 
 589         target
.Printf( wxS("%f"), value 
); 
 592     if ( removeZeroes 
&& precision 
!= 0 && target
.length() ) 
 594         // Remove excess zeroes (do not remove this code just yet, 
 595         // since sprintf can't do the same consistently across platforms). 
 596         wxString::const_iterator i 
= target
.end() - 1; 
 597         size_t new_len 
= target
.length() - 1; 
 599         for ( ; i 
!= target
.begin(); i
-- ) 
 601             if ( *i 
!= wxS('0') ) 
 606         wxChar cur_char 
= *i
; 
 607         if ( cur_char 
!= wxS('.') && cur_char 
!= wxS(',') ) 
 610         if ( new_len 
!= target
.length() ) 
 611             target
.resize(new_len
); 
 615 wxString 
wxFloatProperty::GetValueAsString( int argFlags 
) const 
 618     if ( !m_value
.IsNull() ) 
 620         wxPropertyGrid::DoubleToString(text
, 
 623                                        !(argFlags 
& wxPG_FULL_VALUE
), 
 629 bool wxFloatProperty::StringToValue( wxVariant
& variant
, const wxString
& text
, int argFlags 
) const 
 634     if ( text
.length() == 0 ) 
 640     bool res 
= text
.ToDouble(&value
); 
 643         if ( variant 
!= value 
) 
 649     else if ( argFlags 
& wxPG_REPORT_ERROR 
) 
 655 bool wxFloatProperty::DoValidation( const wxPGProperty
* property
, double& value
, wxPGValidationInfo
* pValidationInfo
, int mode 
) 
 658     double min 
= (double)wxINT64_MIN
; 
 659     double max 
= (double)wxINT64_MAX
; 
 664     variant 
= property
->GetAttribute(wxPGGlobalVars
->m_strMin
); 
 665     if ( !variant
.IsNull() ) 
 667         wxPGVariantToDouble(variant
, &min
); 
 671     variant 
= property
->GetAttribute(wxPGGlobalVars
->m_strMax
); 
 672     if ( !variant
.IsNull() ) 
 674         wxPGVariantToDouble(variant
, &max
); 
 682             if ( mode 
== wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE 
) 
 683                 pValidationInfo
->SetFailureMessage( 
 684                     wxString::Format(_("Value must be %f or higher"),min
) 
 686             else if ( mode 
== wxPG_PROPERTY_VALIDATION_SATURATE 
) 
 689                 value 
= max 
- (min 
- value
); 
 696         wxPGVariantToDouble(variant
, &max
); 
 699             if ( mode 
== wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE 
) 
 700                 pValidationInfo
->SetFailureMessage( 
 701                     wxString::Format(_("Value must be %f or less"),max
) 
 703             else if ( mode 
== wxPG_PROPERTY_VALIDATION_SATURATE 
) 
 706                 value 
= min 
+ (value 
- max
); 
 713 bool wxFloatProperty::ValidateValue( wxVariant
& value
, wxPGValidationInfo
& validationInfo 
) const 
 716     if ( wxPGVariantToDouble(value
, &fpv
) ) 
 717         return DoValidation(this, fpv
, &validationInfo
, wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE
); 
 721 bool wxFloatProperty::DoSetAttribute( const wxString
& name
, wxVariant
& value 
) 
 723     if ( name 
== wxPG_FLOAT_PRECISION 
) 
 725         m_precision 
= value
.GetLong(); 
 731 wxValidator
* wxFloatProperty::DoGetValidator() const 
 733     return wxIntProperty::GetClassValidator(); 
 736 // ----------------------------------------------------------------------- 
 738 // ----------------------------------------------------------------------- 
 740 // We cannot use standard WX_PG_IMPLEMENT_PROPERTY_CLASS macro, since 
 741 // there is a custom GetEditorClass. 
 743 IMPLEMENT_DYNAMIC_CLASS(wxBoolProperty
, wxPGProperty
) 
 745 const wxPGEditor
* wxBoolProperty::DoGetEditorClass() const 
 747     // Select correct editor control. 
 748 #if wxPG_INCLUDE_CHECKBOX 
 749     if ( !(m_flags 
& wxPG_PROP_USE_CHECKBOX
) ) 
 750         return wxPGEditor_Choice
; 
 751     return wxPGEditor_CheckBox
; 
 753     return wxPGEditor_Choice
; 
 757 wxBoolProperty::wxBoolProperty( const wxString
& label
, const wxString
& name
, bool value 
) : 
 758     wxPGProperty(label
,name
) 
 760     m_choices
.Assign(wxPGGlobalVars
->m_boolChoices
); 
 762     SetValue(wxPGVariant_Bool(value
)); 
 764     m_flags 
|= wxPG_PROP_USE_DCC
; 
 767 wxBoolProperty::~wxBoolProperty() { } 
 769 wxString 
wxBoolProperty::GetValueAsString( int argFlags 
) const 
 771     bool value 
= m_value
.GetBool(); 
 773     // As a fragment of composite string value, 
 774     // make it a little more readable. 
 775     if ( argFlags 
& wxPG_COMPOSITE_FRAGMENT 
) 
 783             if ( argFlags 
& wxPG_UNEDITABLE_COMPOSITE_FRAGMENT 
) 
 784                 return wxEmptyString
; 
 787             if ( wxPGGlobalVars
->m_autoGetTranslation 
) 
 788                 notFmt 
= _("Not %s"); 
 790                 notFmt 
= wxS("Not %s"); 
 792             return wxString::Format(notFmt
.c_str(), m_label
.c_str()); 
 796     if ( !(argFlags 
& wxPG_FULL_VALUE
) ) 
 798         return wxPGGlobalVars
->m_boolChoices
[value
?1:0].GetText(); 
 803     if (value
) text 
= wxS("true"); 
 804     else text 
= wxS("false"); 
 809 bool wxBoolProperty::StringToValue( wxVariant
& variant
, const wxString
& text
, int WXUNUSED(argFlags
) ) const 
 811     bool boolValue 
= false; 
 812     if ( text
.CmpNoCase(wxPGGlobalVars
->m_boolChoices
[1].GetText()) == 0 || 
 813          text
.CmpNoCase(wxS("true")) == 0 || 
 814          text
.CmpNoCase(m_label
) == 0 ) 
 817     if ( text
.length() == 0 ) 
 823     if ( variant 
!= boolValue 
) 
 825         variant 
= wxPGVariant_Bool(boolValue
); 
 831 bool wxBoolProperty::IntToValue( wxVariant
& variant
, int value
, int ) const 
 833     bool boolValue 
= value 
? true : false; 
 835     if ( variant 
!= boolValue 
) 
 837         variant 
= wxPGVariant_Bool(boolValue
); 
 843 bool wxBoolProperty::DoSetAttribute( const wxString
& name
, wxVariant
& value 
) 
 845 #if wxPG_INCLUDE_CHECKBOX 
 846     if ( name 
== wxPG_BOOL_USE_CHECKBOX 
) 
 848         int ival 
= wxPGVariantToInt(value
); 
 850             m_flags 
|= wxPG_PROP_USE_CHECKBOX
; 
 852             m_flags 
&= ~(wxPG_PROP_USE_CHECKBOX
); 
 856     if ( name 
== wxPG_BOOL_USE_DOUBLE_CLICK_CYCLING 
) 
 858         int ival 
= wxPGVariantToInt(value
); 
 860             m_flags 
|= wxPG_PROP_USE_DCC
; 
 862             m_flags 
&= ~(wxPG_PROP_USE_DCC
); 
 868 // ----------------------------------------------------------------------- 
 869 // wxBaseEnumProperty 
 870 // ----------------------------------------------------------------------- 
 872 int wxBaseEnumProperty::ms_nextIndex 
= -2; 
 874 wxBaseEnumProperty::wxBaseEnumProperty( const wxString
& label
, const wxString
& name 
) 
 875     : wxPGProperty(label
,name
) 
 877     m_value 
= wxPGVariant_Zero
; 
 880 /** If has values array, then returns number at index with value - 
 881     otherwise just returns the value. 
 883 int wxBaseEnumProperty::GetIndexForValue( int value 
) const 
 888 void wxBaseEnumProperty::OnSetValue() 
 890     wxString variantType 
= m_value
.GetType(); 
 892     if ( variantType 
== wxPG_VARIANT_TYPE_LONG 
) 
 893         ValueFromInt_( m_value
, m_value
.GetLong(), wxPG_FULL_VALUE 
); 
 894     else if ( variantType 
== wxPG_VARIANT_TYPE_STRING 
) 
 895         ValueFromString_( m_value
, m_value
.GetString(), 0 ); 
 899     if ( ms_nextIndex 
!= -2 ) 
 901         m_index 
= ms_nextIndex
; 
 906 bool wxBaseEnumProperty::ValidateValue( wxVariant
& value
, wxPGValidationInfo
& WXUNUSED(validationInfo
) ) const 
 908     // Make sure string value is in the list, 
 909     // unless property has string as preferred value type 
 910     // To reduce code size, use conversion here as well 
 911     if ( value
.GetType() == wxPG_VARIANT_TYPE_STRING 
&& 
 912          !this->IsKindOf(CLASSINFO(wxEditEnumProperty
)) ) 
 913         return ValueFromString_( value
, value
.GetString(), wxPG_PROPERTY_SPECIFIC 
); 
 918 wxString 
wxBaseEnumProperty::GetValueAsString( int ) const 
 920     if ( m_value
.GetType() == wxPG_VARIANT_TYPE_STRING 
) 
 921         return m_value
.GetString(); 
 926         const wxString
* pstr 
= GetEntry( m_index
, &unusedVal 
); 
 931     return wxEmptyString
; 
 934 bool wxBaseEnumProperty::StringToValue( wxVariant
& variant
, const wxString
& text
, int argFlags 
) const 
 936     return ValueFromString_( variant
, text
, argFlags 
); 
 939 bool wxBaseEnumProperty::IntToValue( wxVariant
& variant
, int intVal
, int argFlags 
) const 
 941     return ValueFromInt_( variant
, intVal
, argFlags 
); 
 944 bool wxBaseEnumProperty::ValueFromString_( wxVariant
& value
, const wxString
& text
, int argFlags 
) const 
 947     const wxString
* entryLabel
; 
 952     entryLabel 
= GetEntry(i
, &entryValue
); 
 955         if ( text
.CmpNoCase(*entryLabel
) == 0 ) 
 958             useValue 
= (long)entryValue
; 
 963         entryLabel 
= GetEntry(i
, &entryValue
); 
 968     bool isEdit 
= this->IsKindOf(CLASSINFO(wxEditEnumProperty
)); 
 970     // If text not any of the choices, store as text instead 
 971     // (but only if we are wxEditEnumProperty) 
 972     if ( useIndex 
== -1 && 
 973          (value
.GetType() != wxPG_VARIANT_TYPE_STRING 
|| (m_value
.GetString() != text
)) && 
 979     int setAsNextIndex 
= -2; 
 986     else if ( m_index 
!= useIndex 
) 
 988         if ( useIndex 
!= -1 ) 
 990             setAsNextIndex 
= useIndex
; 
 991             value 
= (long)useValue
; 
 996             value 
= wxPGVariant_MinusOne
; 
1000     if ( setAsNextIndex 
!= -2 ) 
1002         // If wxPG_PROPERTY_SPECIFIC is set, then this is done for 
1003         // validation purposes only, and index must not be changed 
1004         if ( !(argFlags 
& wxPG_PROPERTY_SPECIFIC
) ) 
1005             ms_nextIndex 
= setAsNextIndex
; 
1007         if ( isEdit 
|| setAsNextIndex 
!= -1 ) 
1015 bool wxBaseEnumProperty::ValueFromInt_( wxVariant
& variant
, int intVal
, int argFlags 
) const 
1017     // If wxPG_FULL_VALUE is *not* in argFlags, then intVal is index from combo box. 
1021     if ( argFlags 
& wxPG_FULL_VALUE 
) 
1023         ms_nextIndex 
= GetIndexForValue( intVal 
); 
1027         if ( m_index 
!= intVal 
) 
1029             ms_nextIndex 
= intVal
; 
1033     if ( ms_nextIndex 
!= -2 ) 
1035         if ( !(argFlags 
& wxPG_FULL_VALUE
) ) 
1036             GetEntry(intVal
, &intVal
); 
1038         variant 
= (long)intVal
; 
1046 void wxBaseEnumProperty::SetIndex( int index 
) 
1052 int wxBaseEnumProperty::GetIndex() const 
1054     if ( ms_nextIndex 
!= -2 ) 
1055         return ms_nextIndex
; 
1059 // ----------------------------------------------------------------------- 
1061 // ----------------------------------------------------------------------- 
1063 IMPLEMENT_DYNAMIC_CLASS(wxEnumProperty
, wxPGProperty
) 
1065 WX_PG_IMPLEMENT_PROPERTY_CLASS_PLAIN(wxEnumProperty
,long,Choice
) 
1067 wxEnumProperty::wxEnumProperty( const wxString
& label
, const wxString
& name
, const wxChar
** labels
, 
1068     const long* values
, int value 
) : wxBaseEnumProperty(label
,name
) 
1074         m_choices
.Add(labels
,values
); 
1076         if ( GetItemCount() ) 
1077             SetValue( (long)value 
); 
1081 wxEnumProperty::wxEnumProperty( const wxString
& label
, const wxString
& name
, const wxChar
** labels
, 
1082     const long* values
, wxPGChoices
* choicesCache
, int value 
) 
1083     : wxBaseEnumProperty(label
,name
) 
1087     wxASSERT( choicesCache 
); 
1089     if ( choicesCache
->IsOk() ) 
1091         m_choices
.Assign( *choicesCache 
); 
1092         m_value 
= wxPGVariant_Zero
; 
1096         m_choices
.Add(labels
,values
); 
1098         if ( GetItemCount() ) 
1099             SetValue( (long)value 
); 
1103 wxEnumProperty::wxEnumProperty( const wxString
& label
, const wxString
& name
, 
1104     const wxArrayString
& labels
, const wxArrayInt
& values
, int value 
) : wxBaseEnumProperty(label
,name
) 
1108     if ( &labels 
&& labels
.size() ) 
1110         m_choices
.Set(labels
, values
); 
1112         if ( GetItemCount() ) 
1113             SetValue( (long)value 
); 
1117 wxEnumProperty::wxEnumProperty( const wxString
& label
, const wxString
& name
, 
1118     wxPGChoices
& choices
, int value 
) 
1119     : wxBaseEnumProperty(label
,name
) 
1121     m_choices
.Assign( choices 
); 
1123     if ( GetItemCount() ) 
1124         SetValue( (long)value 
); 
1127 int wxEnumProperty::GetIndexForValue( int value 
) const 
1129     if ( !m_choices
.IsOk() ) 
1132     if ( m_choices
.HasValues() ) 
1134         int intVal 
= m_choices
.Index(value
); 
1142 wxEnumProperty::~wxEnumProperty () 
1146 const wxString
* wxEnumProperty::GetEntry( size_t index
, int* pvalue 
) const 
1148     if ( m_choices
.IsOk() && index 
< m_choices
.GetCount() ) 
1150         int value 
= (int)index
; 
1151         if ( m_choices
.HasValue(index
) ) 
1152             value 
= m_choices
.GetValue(index
); 
1157         return &m_choices
.GetLabel(index
); 
1159     return (const wxString
*) NULL
; 
1162 // ----------------------------------------------------------------------- 
1163 // wxEditEnumProperty 
1164 // ----------------------------------------------------------------------- 
1166 IMPLEMENT_DYNAMIC_CLASS(wxEditEnumProperty
, wxPGProperty
) 
1168 WX_PG_IMPLEMENT_PROPERTY_CLASS_PLAIN(wxEditEnumProperty
,wxString
,ComboBox
) 
1170 wxEditEnumProperty::wxEditEnumProperty( const wxString
& label
, const wxString
& name
, const wxChar
** labels
, 
1171     const long* values
, const wxString
& value 
) 
1172     : wxEnumProperty(label
,name
,labels
,values
,0) 
1177 wxEditEnumProperty::wxEditEnumProperty( const wxString
& label
, const wxString
& name
, const wxChar
** labels
, 
1178     const long* values
, wxPGChoices
* choicesCache
, const wxString
& value 
) 
1179     : wxEnumProperty(label
,name
,labels
,values
,choicesCache
,0) 
1184 wxEditEnumProperty::wxEditEnumProperty( const wxString
& label
, const wxString
& name
, 
1185     const wxArrayString
& labels
, const wxArrayInt
& values
, const wxString
& value 
) 
1186     : wxEnumProperty(label
,name
,labels
,values
,0) 
1191 wxEditEnumProperty::wxEditEnumProperty( const wxString
& label
, const wxString
& name
, 
1192     wxPGChoices
& choices
, const wxString
& value 
) 
1193     : wxEnumProperty(label
,name
,choices
,0) 
1198 wxEditEnumProperty::~wxEditEnumProperty() 
1202 // ----------------------------------------------------------------------- 
1204 // ----------------------------------------------------------------------- 
1206 IMPLEMENT_DYNAMIC_CLASS(wxFlagsProperty
,wxPGProperty
) 
1208 WX_PG_IMPLEMENT_PROPERTY_CLASS_PLAIN(wxFlagsProperty
,long,TextCtrl
) 
1210 void wxFlagsProperty::Init() 
1212     SetParentalType(wxPG_PROP_AGGREGATE
); 
1214     long value 
= m_value
; 
1217     // Generate children 
1221     unsigned int prevChildCount 
= m_children
.size(); 
1224     if ( prevChildCount 
) 
1226         wxPropertyGridPageState
* state 
= GetParentState(); 
1228         // State safety check (it may be NULL in immediate parent) 
1233             wxPGProperty
* selected 
= state
->GetSelection(); 
1236                 if ( selected
->GetParent() == this ) 
1237                     oldSel 
= selected
->GetIndexInParent(); 
1238                 else if ( selected 
== this ) 
1242         state
->DoClearSelection(); 
1245     // Delete old children 
1246     for ( i
=0; i
<prevChildCount
; i
++ ) 
1247         delete m_children
[i
]; 
1251     if ( m_choices
.IsOk() ) 
1253         const wxPGChoices
& choices 
= m_choices
; 
1255         for ( i
=0; i
<GetItemCount(); i
++ ) 
1258             if ( choices
.HasValue(i
) ) 
1259                 child_val 
= ( value 
& choices
.GetValue(i
) )?true:false; 
1261                 child_val 
= ( value 
& (1<<i
) )?true:false; 
1263             wxPGProperty
* boolProp
; 
1264             wxString label 
= GetLabel(i
); 
1267             if ( wxPGGlobalVars
->m_autoGetTranslation 
) 
1269                 boolProp 
= new wxBoolProperty( ::wxGetTranslation(label
), label
, child_val 
); 
1274                 boolProp 
= new wxBoolProperty( label
, label
, child_val 
); 
1279         m_oldChoicesData 
= m_choices
.GetDataPtr(); 
1282     m_oldValue 
= m_value
; 
1284     if ( prevChildCount 
) 
1285         SubPropsChanged(oldSel
); 
1288 wxFlagsProperty::wxFlagsProperty( const wxString
& label
, const wxString
& name
, 
1289     const wxChar
** labels
, const long* values
, long value 
) : wxPGProperty(label
,name
) 
1291     m_oldChoicesData 
= (wxPGChoicesData
*) NULL
; 
1295         m_choices
.Set(labels
,values
); 
1297         wxASSERT( GetItemCount() ); 
1303         m_value 
= wxPGVariant_Zero
; 
1307 wxFlagsProperty::wxFlagsProperty( const wxString
& label
, const wxString
& name
, 
1308         const wxArrayString
& labels
, const wxArrayInt
& values
, int value 
) 
1309     : wxPGProperty(label
,name
) 
1311     m_oldChoicesData 
= (wxPGChoicesData
*) NULL
; 
1313     if ( &labels 
&& labels
.size() ) 
1315         m_choices
.Set(labels
,values
); 
1317         wxASSERT( GetItemCount() ); 
1319         SetValue( (long)value 
); 
1323         m_value 
= wxPGVariant_Zero
; 
1327 wxFlagsProperty::wxFlagsProperty( const wxString
& label
, const wxString
& name
, 
1328     wxPGChoices
& choices
, long value 
) 
1329     : wxPGProperty(label
,name
) 
1331     m_oldChoicesData 
= (wxPGChoicesData
*) NULL
; 
1333     if ( choices
.IsOk() ) 
1335         m_choices
.Assign(choices
); 
1337         wxASSERT( GetItemCount() ); 
1343         m_value 
= wxPGVariant_Zero
; 
1347 wxFlagsProperty::~wxFlagsProperty() 
1351 void wxFlagsProperty::OnSetValue() 
1353     if ( !m_choices
.IsOk() || !GetItemCount() ) 
1355         m_value 
= wxPGVariant_Zero
; 
1359         long val 
= m_value
.GetLong(); 
1363         // normalize the value (i.e. remove extra flags) 
1365         const wxPGChoices
& choices 
= m_choices
; 
1366         for ( i 
= 0; i 
< GetItemCount(); i
++ ) 
1368             if ( choices
.HasValue(i
) ) 
1369                 fullFlags 
|= choices
.GetValue(i
); 
1371                 fullFlags 
|= (1<<i
); 
1378         // Need to (re)init now? 
1379         if ( GetChildCount() != GetItemCount() || 
1380              m_choices
.GetDataPtr() != m_oldChoicesData 
) 
1386     long newFlags 
= m_value
; 
1388     if ( newFlags 
!= m_oldValue 
) 
1390         // Set child modified states 
1392         const wxPGChoices
& choices 
= m_choices
; 
1393         for ( i 
= 0; i
<GetItemCount(); i
++ ) 
1397             if ( choices
.HasValue(i
) ) 
1398                 flag 
= choices
.GetValue(i
); 
1402             if ( (newFlags 
& flag
) != (m_oldValue 
& flag
) ) 
1403                 Item(i
)->SetFlag( wxPG_PROP_MODIFIED 
); 
1406         m_oldValue 
= newFlags
; 
1410 wxString 
wxFlagsProperty::GetValueAsString( int ) const 
1414     if ( !m_choices
.IsOk() ) 
1417     long flags 
= m_value
; 
1419     const wxPGChoices
& choices 
= m_choices
; 
1421     for ( i 
= 0; i 
< GetItemCount(); i
++ ) 
1424         if ( choices
.HasValue(i
) ) 
1425             doAdd 
= ( flags 
& choices
.GetValue(i
) ); 
1427             doAdd 
= ( flags 
& (1<<i
) ); 
1431             text 
+= choices
.GetLabel(i
); 
1436     // remove last comma 
1437     if ( text
.Len() > 1 ) 
1438         text
.Truncate ( text
.Len() - 2 ); 
1443 // Translate string into flag tokens 
1444 bool wxFlagsProperty::StringToValue( wxVariant
& variant
, const wxString
& text
, int ) const 
1446     if ( !m_choices
.IsOk() ) 
1451     // semicolons are no longer valid delimeters 
1452     WX_PG_TOKENIZER1_BEGIN(text
,wxS(',')) 
1454         if ( token
.length() ) 
1456             // Determine which one it is 
1457             long bit 
= IdToBit( token 
); 
1470     WX_PG_TOKENIZER1_END() 
1472     if ( variant 
!= (long)newFlags 
) 
1474         variant 
= (long)newFlags
; 
1481 // Converts string id to a relevant bit. 
1482 long wxFlagsProperty::IdToBit( const wxString
& id 
) const 
1485     for ( i 
= 0; i 
< GetItemCount(); i
++ ) 
1487         if ( id 
== GetLabel(i
) ) 
1489             if ( m_choices
.HasValue(i
) ) 
1490                 return m_choices
.GetValue(i
); 
1497 void wxFlagsProperty::RefreshChildren() 
1499     if ( !m_choices
.IsOk() || !GetChildCount() ) return; 
1501     int flags 
= m_value
.GetLong(); 
1503     const wxPGChoices
& choices 
= m_choices
; 
1505     for ( i 
= 0; i 
< GetItemCount(); i
++ ) 
1509         if ( choices
.HasValue(i
) ) 
1510             flag 
= choices
.GetValue(i
); 
1514         long subVal 
= flags 
& flag
; 
1515         wxPGProperty
* p 
= Item(i
); 
1517         if ( subVal 
!= (m_oldValue 
& flag
) ) 
1518             p
->SetFlag( wxPG_PROP_MODIFIED 
); 
1520         p
->SetValue( subVal
?true:false ); 
1526 void wxFlagsProperty::ChildChanged( wxVariant
& thisValue
, int childIndex
, wxVariant
& childValue 
) const 
1528     long oldValue 
= thisValue
.GetLong(); 
1529     long val 
= childValue
.GetLong(); 
1530     unsigned long vi 
= (1<<childIndex
); 
1531     if ( m_choices
.HasValue(childIndex
) ) vi 
= m_choices
.GetValue(childIndex
); 
1533         thisValue 
= (long)(oldValue 
| vi
); 
1535         thisValue 
= (long)(oldValue 
& ~(vi
)); 
1538 // ----------------------------------------------------------------------- 
1540 // ----------------------------------------------------------------------- 
1542 IMPLEMENT_DYNAMIC_CLASS(wxDirProperty
, wxLongStringProperty
) 
1544 wxDirProperty::wxDirProperty( const wxString
& name
, const wxString
& label
, const wxString
& value 
) 
1545   : wxLongStringProperty(name
,label
,value
) 
1547     m_flags 
|= wxPG_PROP_NO_ESCAPE
; 
1550 wxDirProperty::~wxDirProperty() { } 
1552 wxValidator
* wxDirProperty::DoGetValidator() const 
1554     return wxFileProperty::GetClassValidator(); 
1557 bool wxDirProperty::OnButtonClick( wxPropertyGrid
* propGrid
, wxString
& value 
) 
1559     // Update property value from editor, if necessary 
1560     wxSize 
dlg_sz(300,400); 
1562     wxDirDialog 
dlg( propGrid
, 
1563                      m_dlgMessage
.length() ? m_dlgMessage 
: wxString(_("Choose a directory:")), 
1566 #if !wxPG_SMALL_SCREEN 
1567                      propGrid
->GetGoodEditorDialogPosition(this,dlg_sz
), 
1574     if ( dlg
.ShowModal() == wxID_OK 
) 
1576         value 
= dlg
.GetPath(); 
1582 bool wxDirProperty::DoSetAttribute( const wxString
& name
, wxVariant
& value 
) 
1584     if ( name 
== wxPG_DIR_DIALOG_MESSAGE 
) 
1586         m_dlgMessage 
= value
.GetString(); 
1592 // ----------------------------------------------------------------------- 
1593 // wxPGFileDialogAdapter 
1594 // ----------------------------------------------------------------------- 
1596 bool wxPGFileDialogAdapter::DoShowDialog( wxPropertyGrid
* propGrid
, wxPGProperty
* property 
) 
1598     wxFileProperty
* fileProp 
= NULL
; 
1602     if ( property
->IsKindOf(CLASSINFO(wxFileProperty
)) ) 
1604         fileProp 
= ((wxFileProperty
*)property
); 
1605         path 
= fileProp
->m_filename
.GetPath(); 
1606         indFilter 
= fileProp
->m_indFilter
; 
1608         if ( !path
.length() && fileProp
->m_basePath
.length() ) 
1609             path 
= fileProp
->m_basePath
; 
1613         wxFileName 
fn(property
->GetValue().GetString()); 
1614         path 
= fn
.GetPath(); 
1617     wxFileDialog 
dlg( propGrid
->GetPanel(), 
1618                       property
->GetAttribute(wxS("DialogTitle"), _("Choose a file")), 
1619                       property
->GetAttribute(wxS("InitialPath"), path
), 
1621                       property
->GetAttribute(wxPG_FILE_WILDCARD
, _("All files (*.*)|*.*")), 
1623                       wxDefaultPosition 
); 
1625     if ( indFilter 
>= 0 ) 
1626         dlg
.SetFilterIndex( indFilter 
); 
1628     if ( dlg
.ShowModal() == wxID_OK 
) 
1631             fileProp
->m_indFilter 
= dlg
.GetFilterIndex(); 
1632         SetValue( dlg
.GetPath() ); 
1638 // ----------------------------------------------------------------------- 
1640 // ----------------------------------------------------------------------- 
1642 WX_PG_IMPLEMENT_PROPERTY_CLASS(wxFileProperty
,wxPGProperty
, 
1643                                wxString
,const wxString
&,TextCtrlAndButton
) 
1645 wxFileProperty::wxFileProperty( const wxString
& label
, const wxString
& name
, 
1646     const wxString
& value 
) : wxPGProperty(label
,name
) 
1648     m_flags 
|= wxPG_PROP_SHOW_FULL_FILENAME
; 
1650     SetAttribute( wxPG_FILE_WILDCARD
, _("All files (*.*)|*.*") ); 
1655 wxFileProperty::~wxFileProperty() {} 
1657 #if wxUSE_VALIDATORS 
1659 wxValidator
* wxFileProperty::GetClassValidator() 
1661     WX_PG_DOGETVALIDATOR_ENTRY() 
1663     // Atleast wxPython 2.6.2.1 required that the string argument is given 
1665     wxTextValidator
* validator 
= new wxTextValidator(wxFILTER_EXCLUDE_CHAR_LIST
,&v
); 
1667     wxArrayString exChars
; 
1668     exChars
.Add(wxS("?")); 
1669     exChars
.Add(wxS("*")); 
1670     exChars
.Add(wxS("|")); 
1671     exChars
.Add(wxS("<")); 
1672     exChars
.Add(wxS(">")); 
1673     exChars
.Add(wxS("\"")); 
1675     validator
->SetExcludes(exChars
); 
1677     WX_PG_DOGETVALIDATOR_EXIT(validator
) 
1680 wxValidator
* wxFileProperty::DoGetValidator() const 
1682     return GetClassValidator(); 
1687 void wxFileProperty::OnSetValue() 
1689     const wxString
& fnstr 
= m_value
.GetString(); 
1693     if ( !m_filename
.HasName() ) 
1695         m_value 
= wxPGVariant_EmptyString
; 
1699     // Find index for extension. 
1700     if ( m_indFilter 
< 0 && fnstr
.length() ) 
1702         wxString ext 
= m_filename
.GetExt(); 
1705         size_t len 
= m_wildcard
.length(); 
1707         pos 
= m_wildcard
.find(wxS("|"), pos
); 
1708         while ( pos 
!= wxString::npos 
&& pos 
< (len
-3) ) 
1710             size_t ext_begin 
= pos 
+ 3; 
1712             pos 
= m_wildcard
.find(wxS("|"), ext_begin
); 
1713             if ( pos 
== wxString::npos 
) 
1715             wxString found_ext 
= m_wildcard
.substr(ext_begin
, pos
-ext_begin
); 
1717             if ( found_ext
.length() > 0 ) 
1719                 if ( found_ext
[0] == wxS('*') ) 
1721                     m_indFilter 
= curind
; 
1724                 if ( ext
.CmpNoCase(found_ext
) == 0 ) 
1726                     m_indFilter 
= curind
; 
1732                 pos 
= m_wildcard
.find(wxS("|"), pos
+1); 
1739 wxString 
wxFileProperty::GetValueAsString( int argFlags 
) const 
1741     // Always return empty string when name component is empty 
1742     wxString fullName 
= m_filename
.GetFullName(); 
1743     if ( !fullName
.length() ) 
1746     if ( argFlags 
& wxPG_FULL_VALUE 
) 
1748         return m_filename
.GetFullPath(); 
1750     else if ( m_flags 
& wxPG_PROP_SHOW_FULL_FILENAME 
) 
1752         if ( m_basePath
.Length() ) 
1754             wxFileName 
fn2(m_filename
); 
1755             fn2
.MakeRelativeTo(m_basePath
); 
1756             return fn2
.GetFullPath(); 
1758         return m_filename
.GetFullPath(); 
1761     return m_filename
.GetFullName(); 
1764 wxPGEditorDialogAdapter
* wxFileProperty::GetEditorDialog() const 
1766     return new wxPGFileDialogAdapter(); 
1769 bool wxFileProperty::StringToValue( wxVariant
& variant
, const wxString
& text
, int argFlags 
) const 
1771     if ( (m_flags 
& wxPG_PROP_SHOW_FULL_FILENAME
) || (argFlags 
& wxPG_FULL_VALUE
) ) 
1773         if ( m_filename 
!= text 
) 
1781         if ( m_filename
.GetFullName() != text 
) 
1783             wxFileName fn 
= m_filename
; 
1784             fn
.SetFullName(text
); 
1785             variant 
= fn
.GetFullPath(); 
1793 bool wxFileProperty::DoSetAttribute( const wxString
& name
, wxVariant
& value 
) 
1795     // Return false on some occasions to make sure those attribs will get 
1796     // stored in m_attributes. 
1797     if ( name 
== wxPG_FILE_SHOW_FULL_PATH 
) 
1799         if ( wxPGVariantToInt(value
) ) 
1800             m_flags 
|= wxPG_PROP_SHOW_FULL_FILENAME
; 
1802             m_flags 
&= ~(wxPG_PROP_SHOW_FULL_FILENAME
); 
1805     else if ( name 
== wxPG_FILE_WILDCARD 
) 
1807         m_wildcard 
= value
.GetString(); 
1809     else if ( name 
== wxPG_FILE_SHOW_RELATIVE_PATH 
) 
1811         m_basePath 
= value
.GetString(); 
1813         // Make sure wxPG_FILE_SHOW_FULL_PATH is also set 
1814         m_flags 
|= wxPG_PROP_SHOW_FULL_FILENAME
; 
1816     else if ( name 
== wxPG_FILE_INITIAL_PATH 
) 
1818         m_initialPath 
= value
.GetString(); 
1821     else if ( name 
== wxPG_FILE_DIALOG_TITLE 
) 
1823         m_dlgTitle 
= value
.GetString(); 
1829 // ----------------------------------------------------------------------- 
1830 // wxPGLongStringDialogAdapter 
1831 // ----------------------------------------------------------------------- 
1833 bool wxPGLongStringDialogAdapter::DoShowDialog( wxPropertyGrid
* propGrid
, wxPGProperty
* property 
) 
1835     wxString val1 
= property
->GetValueAsString(0); 
1836     wxString val_orig 
= val1
; 
1839     if ( !property
->HasFlag(wxPG_PROP_NO_ESCAPE
) ) 
1840         wxPropertyGrid::ExpandEscapeSequences(value
, val1
); 
1842         value 
= wxString(val1
); 
1844     // Run editor dialog. 
1845     if ( wxLongStringProperty::DisplayEditorDialog(property
, propGrid
, value
) ) 
1847         if ( !property
->HasFlag(wxPG_PROP_NO_ESCAPE
) ) 
1848             wxPropertyGrid::CreateEscapeSequences(val1
,value
); 
1852         if ( val1 
!= val_orig 
) 
1861 // ----------------------------------------------------------------------- 
1862 // wxLongStringProperty 
1863 // ----------------------------------------------------------------------- 
1865 WX_PG_IMPLEMENT_PROPERTY_CLASS(wxLongStringProperty
,wxPGProperty
, 
1866                                wxString
,const wxString
&,TextCtrlAndButton
) 
1868 wxLongStringProperty::wxLongStringProperty( const wxString
& label
, const wxString
& name
, 
1869     const wxString
& value 
) : wxPGProperty(label
,name
) 
1874 wxLongStringProperty::~wxLongStringProperty() {} 
1876 wxString 
wxLongStringProperty::GetValueAsString( int ) const 
1881 bool wxLongStringProperty::OnEvent( wxPropertyGrid
* propGrid
, wxWindow
* WXUNUSED(primary
), 
1884     if ( propGrid
->IsMainButtonEvent(event
) ) 
1887         wxVariant useValue 
= propGrid
->GetUncommittedPropertyValue(); 
1889         wxString val1 
= useValue
.GetString(); 
1890         wxString val_orig 
= val1
; 
1893         if ( !(m_flags 
& wxPG_PROP_NO_ESCAPE
) ) 
1894             wxPropertyGrid::ExpandEscapeSequences(value
,val1
); 
1896             value 
= wxString(val1
); 
1898         // Run editor dialog. 
1899         if ( OnButtonClick(propGrid
,value
) ) 
1901             if ( !(m_flags 
& wxPG_PROP_NO_ESCAPE
) ) 
1902                 wxPropertyGrid::CreateEscapeSequences(val1
,value
); 
1906             if ( val1 
!= val_orig 
) 
1908                 SetValueInEvent( val1 
); 
1916 bool wxLongStringProperty::OnButtonClick( wxPropertyGrid
* propGrid
, wxString
& value 
) 
1918     return DisplayEditorDialog(this, propGrid
, value
); 
1921 bool wxLongStringProperty::DisplayEditorDialog( wxPGProperty
* prop
, wxPropertyGrid
* propGrid
, wxString
& value 
) 
1924     // launch editor dialog 
1925     wxDialog
* dlg 
= new wxDialog(propGrid
,-1,prop
->GetLabel(),wxDefaultPosition
,wxDefaultSize
, 
1926                                  wxDEFAULT_DIALOG_STYLE
|wxRESIZE_BORDER
|wxCLIP_CHILDREN
); 
1928     dlg
->SetFont(propGrid
->GetFont()); // To allow entering chars of the same set as the propGrid 
1930     // Multi-line text editor dialog. 
1931 #if !wxPG_SMALL_SCREEN 
1932     const int spacing 
= 8; 
1934     const int spacing 
= 4; 
1936     wxBoxSizer
* topsizer 
= new wxBoxSizer( wxVERTICAL 
); 
1937     wxBoxSizer
* rowsizer 
= new wxBoxSizer( wxHORIZONTAL 
); 
1938     wxTextCtrl
* ed 
= new wxTextCtrl(dlg
,11,value
, 
1939         wxDefaultPosition
,wxDefaultSize
,wxTE_MULTILINE
); 
1941     rowsizer
->Add( ed
, 1, wxEXPAND
|wxALL
, spacing 
); 
1942     topsizer
->Add( rowsizer
, 1, wxEXPAND
, 0 ); 
1943     rowsizer 
= new wxBoxSizer( wxHORIZONTAL 
); 
1944     const int but_sz_flags 
= 
1945         wxALIGN_RIGHT
|wxALIGN_CENTRE_VERTICAL
|wxBOTTOM
|wxLEFT
|wxRIGHT
; 
1946     rowsizer
->Add( new wxButton(dlg
,wxID_OK
,_("Ok")), 
1947         0, but_sz_flags
, spacing 
); 
1948     rowsizer
->Add( new wxButton(dlg
,wxID_CANCEL
,_("Cancel")), 
1949         0, but_sz_flags
, spacing 
); 
1950     topsizer
->Add( rowsizer
, 0, wxALIGN_RIGHT
|wxALIGN_CENTRE_VERTICAL
, 0 ); 
1952     dlg
->SetSizer( topsizer 
); 
1953     topsizer
->SetSizeHints( dlg 
); 
1955 #if !wxPG_SMALL_SCREEN 
1956     dlg
->SetSize(400,300); 
1958     dlg
->Move( propGrid
->GetGoodEditorDialogPosition(prop
,dlg
->GetSize()) ); 
1961     int res 
= dlg
->ShowModal(); 
1963     if ( res 
== wxID_OK 
) 
1965         value 
= ed
->GetValue(); 
1973 bool wxLongStringProperty::StringToValue( wxVariant
& variant
, const wxString
& text
, int ) const 
1975     if ( variant 
!= text 
) 
1983 // ----------------------------------------------------------------------- 
1984 // wxArrayEditorDialog 
1985 // ----------------------------------------------------------------------- 
1987 BEGIN_EVENT_TABLE(wxArrayEditorDialog
, wxDialog
) 
1988     EVT_IDLE(wxArrayEditorDialog::OnIdle
) 
1989     EVT_LISTBOX(24, wxArrayEditorDialog::OnListBoxClick
) 
1990     EVT_TEXT_ENTER(21, wxArrayEditorDialog::OnAddClick
) 
1991     EVT_BUTTON(22, wxArrayEditorDialog::OnAddClick
) 
1992     EVT_BUTTON(23, wxArrayEditorDialog::OnDeleteClick
) 
1993     EVT_BUTTON(25, wxArrayEditorDialog::OnUpClick
) 
1994     EVT_BUTTON(26, wxArrayEditorDialog::OnDownClick
) 
1995     EVT_BUTTON(27, wxArrayEditorDialog::OnUpdateClick
) 
1996     //EVT_BUTTON(28, wxArrayEditorDialog::OnCustomEditClick) 
1999 IMPLEMENT_ABSTRACT_CLASS(wxArrayEditorDialog
, wxDialog
) 
2001 #include "wx/statline.h" 
2003 // ----------------------------------------------------------------------- 
2005 void wxArrayEditorDialog::OnIdle(wxIdleEvent
& event
) 
2008     // Do control focus detection here. 
2011     wxWindow
* focused 
= FindFocus(); 
2013     // This strange focus thing is a workaround for wxGTK wxListBox focus 
2015     if ( m_curFocus 
== 0 && focused 
!= m_edValue 
&& 
2016          focused 
!= m_butAdd 
&& focused 
!= m_butUpdate 
&& 
2017          m_lbStrings
->GetSelection() >= 0 ) 
2019         // ListBox was just focused. 
2020         m_butAdd
->Enable(false); 
2021         m_butUpdate
->Enable(false); 
2022         m_butRemove
->Enable(true); 
2023         m_butUp
->Enable(true); 
2024         m_butDown
->Enable(true); 
2027     else if ( (m_curFocus 
== 1 && focused 
== m_edValue
) /*|| m_curFocus == 2*/ ) 
2029         // TextCtrl was just focused. 
2030         m_butAdd
->Enable(true); 
2031         bool upd_enable 
= false; 
2032         if ( m_lbStrings
->GetCount() && m_lbStrings
->GetSelection() >= 0 ) 
2034         m_butUpdate
->Enable(upd_enable
); 
2035         m_butRemove
->Enable(false); 
2036         m_butUp
->Enable(false); 
2037         m_butDown
->Enable(false); 
2044 // ----------------------------------------------------------------------- 
2046 wxArrayEditorDialog::wxArrayEditorDialog() 
2052 // ----------------------------------------------------------------------- 
2054 void wxArrayEditorDialog::Init() 
2056     m_custBtText 
= (const wxChar
*) NULL
; 
2059 // ----------------------------------------------------------------------- 
2061 wxArrayEditorDialog::wxArrayEditorDialog( wxWindow 
*parent
, 
2062                                           const wxString
& message
, 
2063                                           const wxString
& caption
, 
2070     Create(parent
,message
,caption
,style
,pos
,sz
); 
2073 // ----------------------------------------------------------------------- 
2075 bool wxArrayEditorDialog::Create( wxWindow 
*parent
, 
2076                                   const wxString
& message
, 
2077                                   const wxString
& caption
, 
2082     // On wxMAC the dialog shows incorrectly if style is not exactly wxCAPTION 
2083     // FIXME: This should be only a temporary fix. 
2085     int useStyle 
= wxCAPTION
; 
2087     int useStyle 
= style
; 
2090     bool res 
= wxDialog::Create(parent
, wxID_ANY
, caption
, pos
, sz
, useStyle
); 
2092     SetFont(parent
->GetFont()); // To allow entering chars of the same set as the propGrid 
2094 #if !wxPG_SMALL_SCREEN 
2095     const int spacing 
= 4; 
2097     const int spacing 
= 3; 
2104     const int but_sz_flags 
= 
2105         wxALIGN_RIGHT
|wxALIGN_CENTRE_VERTICAL
|wxALL
; //wxBOTTOM|wxLEFT|wxRIGHT; 
2107     wxBoxSizer
* topsizer 
= new wxBoxSizer( wxVERTICAL 
); 
2110     if ( message
.length() ) 
2111         topsizer
->Add( new wxStaticText(this,-1,message
), 
2112             0, wxALIGN_LEFT
|wxALIGN_CENTRE_VERTICAL
|wxALL
, spacing 
); 
2115     wxBoxSizer
* rowsizer 
= new wxBoxSizer( wxHORIZONTAL 
); 
2116     m_edValue 
= new wxTextCtrl(this,21,wxEmptyString
, 
2117         wxDefaultPosition
,wxDefaultSize
,wxTE_PROCESS_ENTER
); 
2118     wxValidator
* validator 
= GetTextCtrlValidator(); 
2121         m_edValue
->SetValidator( *validator 
); 
2124     rowsizer
->Add( m_edValue
, 
2125         1, wxALIGN_LEFT
|wxALIGN_CENTRE_VERTICAL
|wxALL
, spacing 
); 
2128     m_butAdd 
= new wxButton(this,22,_("Add")); 
2129     rowsizer
->Add( m_butAdd
, 
2130         0, wxALIGN_LEFT
|wxALIGN_CENTRE_VERTICAL
|wxTOP
|wxBOTTOM
|wxRIGHT
, spacing 
); 
2131     topsizer
->Add( rowsizer
, 0, wxEXPAND
, spacing 
); 
2134     topsizer
->Add( new wxStaticLine(this,-1), 
2135         0, wxEXPAND
|wxBOTTOM
|wxLEFT
|wxRIGHT
, spacing 
); 
2137     rowsizer 
= new wxBoxSizer( wxHORIZONTAL 
); 
2140     m_lbStrings 
= new wxListBox(this, 24, wxDefaultPosition
, wxDefaultSize
); 
2142     for ( i
=0; i
<ArrayGetCount(); i
++ ) 
2143         m_lbStrings
->Append( ArrayGet(i
) ); 
2144     rowsizer
->Add( m_lbStrings
, 1, wxEXPAND
|wxRIGHT
, spacing 
); 
2146     // Manipulator buttons 
2147     wxBoxSizer
* colsizer 
= new wxBoxSizer( wxVERTICAL 
); 
2148     m_butCustom 
= (wxButton
*) NULL
; 
2151         m_butCustom 
= new wxButton(this,28,::wxGetTranslation(m_custBtText
)); 
2152         colsizer
->Add( m_butCustom
, 
2153             0, wxALIGN_CENTER
|wxTOP
/*wxALIGN_LEFT|wxALIGN_CENTRE_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT*/, 
2156     m_butUpdate 
= new wxButton(this,27,_("Update")); 
2157     colsizer
->Add( m_butUpdate
, 
2158         0, wxALIGN_CENTER
|wxTOP
, spacing 
); 
2159     m_butRemove 
= new wxButton(this,23,_("Remove")); 
2160     colsizer
->Add( m_butRemove
, 
2161         0, wxALIGN_CENTER
|wxTOP
, spacing 
); 
2162     m_butUp 
= new wxButton(this,25,_("Up")); 
2163     colsizer
->Add( m_butUp
, 
2164         0, wxALIGN_CENTER
|wxTOP
, spacing 
); 
2165     m_butDown 
= new wxButton(this,26,_("Down")); 
2166     colsizer
->Add( m_butDown
, 
2167         0, wxALIGN_CENTER
|wxTOP
, spacing 
); 
2168     rowsizer
->Add( colsizer
, 0, 0, spacing 
); 
2170     topsizer
->Add( rowsizer
, 1, wxLEFT
|wxRIGHT
|wxEXPAND
, spacing 
); 
2173     topsizer
->Add( new wxStaticLine(this,-1), 
2174         0, wxEXPAND
|wxTOP
|wxLEFT
|wxRIGHT
, spacing 
); 
2177     rowsizer 
= new wxBoxSizer( wxHORIZONTAL 
); 
2179     const int but_sz_flags = 
2180         wxALIGN_RIGHT|wxALIGN_CENTRE_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT; 
2182     rowsizer
->Add( new wxButton(this,wxID_OK
,_("Ok")), 
2183         0, but_sz_flags
, spacing 
); 
2184     rowsizer
->Add( new wxButton(this,wxID_CANCEL
,_("Cancel")), 
2185         0, but_sz_flags
, spacing 
); 
2186     topsizer
->Add( rowsizer
, 0, wxALIGN_RIGHT
|wxALIGN_CENTRE_VERTICAL
, 0 ); 
2188     m_edValue
->SetFocus(); 
2190     SetSizer( topsizer 
); 
2191     topsizer
->SetSizeHints( this ); 
2193 #if !wxPG_SMALL_SCREEN 
2194     if ( sz
.x 
== wxDefaultSize
.x 
&& 
2195          sz
.y 
== wxDefaultSize
.y 
) 
2196         SetSize( wxSize(275,360) ); 
2204 // ----------------------------------------------------------------------- 
2206 void wxArrayEditorDialog::OnAddClick(wxCommandEvent
& ) 
2208     wxString text 
= m_edValue
->GetValue(); 
2209     if ( text
.length() ) 
2211         if ( ArrayInsert( text
, -1 ) ) 
2213             m_lbStrings
->Append( text 
); 
2220 // ----------------------------------------------------------------------- 
2222 void wxArrayEditorDialog::OnDeleteClick(wxCommandEvent
& ) 
2224     int index 
= m_lbStrings
->GetSelection(); 
2227         ArrayRemoveAt( index 
); 
2228         m_lbStrings
->Delete ( index 
); 
2233 // ----------------------------------------------------------------------- 
2235 void wxArrayEditorDialog::OnUpClick(wxCommandEvent
& ) 
2237     int index 
= m_lbStrings
->GetSelection(); 
2240         ArraySwap(index
-1,index
); 
2241         /*wxString old_str = m_array[index-1]; 
2242         wxString new_str = m_array[index]; 
2243         m_array[index-1] = new_str; 
2244         m_array[index] = old_str;*/ 
2245         m_lbStrings
->SetString ( index
-1, ArrayGet(index
-1) ); 
2246         m_lbStrings
->SetString ( index
, ArrayGet(index
) ); 
2247         m_lbStrings
->SetSelection ( index
-1 ); 
2252 // ----------------------------------------------------------------------- 
2254 void wxArrayEditorDialog::OnDownClick(wxCommandEvent
& ) 
2256     int index 
= m_lbStrings
->GetSelection(); 
2257     int lastStringIndex 
= ((int) m_lbStrings
->GetCount()) - 1; 
2258     if ( index 
>= 0 && index 
< lastStringIndex 
) 
2260         ArraySwap(index
,index
+1); 
2261         /*wxString old_str = m_array[index+1]; 
2262         wxString new_str = m_array[index]; 
2263         m_array[index+1] = new_str; 
2264         m_array[index] = old_str;*/ 
2265         m_lbStrings
->SetString ( index
+1, ArrayGet(index
+1) ); 
2266         m_lbStrings
->SetString ( index
, ArrayGet(index
) ); 
2267         m_lbStrings
->SetSelection ( index
+1 ); 
2272 // ----------------------------------------------------------------------- 
2274 void wxArrayEditorDialog::OnUpdateClick(wxCommandEvent
& ) 
2276     int index 
= m_lbStrings
->GetSelection(); 
2279         wxString str 
= m_edValue
->GetValue(); 
2280         if ( ArraySet(index
,str
) ) 
2282             m_lbStrings
->SetString ( index
, str 
); 
2283             //m_array[index] = str; 
2289 // ----------------------------------------------------------------------- 
2291 void wxArrayEditorDialog::OnListBoxClick(wxCommandEvent
& ) 
2293     int index 
= m_lbStrings
->GetSelection(); 
2296         m_edValue
->SetValue( m_lbStrings
->GetString(index
) ); 
2300 // ----------------------------------------------------------------------- 
2301 // wxPGArrayStringEditorDialog 
2302 // ----------------------------------------------------------------------- 
2304 IMPLEMENT_DYNAMIC_CLASS(wxPGArrayStringEditorDialog
, wxArrayEditorDialog
) 
2306 BEGIN_EVENT_TABLE(wxPGArrayStringEditorDialog
, wxArrayEditorDialog
) 
2307     EVT_BUTTON(28, wxPGArrayStringEditorDialog::OnCustomEditClick
) 
2310 // ----------------------------------------------------------------------- 
2312 wxString 
wxPGArrayStringEditorDialog::ArrayGet( size_t index 
) 
2314     return m_array
[index
]; 
2317 size_t wxPGArrayStringEditorDialog::ArrayGetCount() 
2319     return m_array
.size(); 
2322 bool wxPGArrayStringEditorDialog::ArrayInsert( const wxString
& str
, int index 
) 
2327         m_array
.Insert(str
,index
); 
2331 bool wxPGArrayStringEditorDialog::ArraySet( size_t index
, const wxString
& str 
) 
2333     m_array
[index
] = str
; 
2337 void wxPGArrayStringEditorDialog::ArrayRemoveAt( int index 
) 
2339     m_array
.RemoveAt(index
); 
2342 void wxPGArrayStringEditorDialog::ArraySwap( size_t first
, size_t second 
) 
2344     wxString old_str 
= m_array
[first
]; 
2345     wxString new_str 
= m_array
[second
]; 
2346     m_array
[first
] = new_str
; 
2347     m_array
[second
] = old_str
; 
2350 wxPGArrayStringEditorDialog::wxPGArrayStringEditorDialog() 
2351     : wxArrayEditorDialog() 
2356 void wxPGArrayStringEditorDialog::Init() 
2358     m_pCallingClass 
= (wxArrayStringProperty
*) NULL
; 
2361 void wxPGArrayStringEditorDialog::OnCustomEditClick(wxCommandEvent
& ) 
2363     wxASSERT( m_pCallingClass 
); 
2364     wxString str 
= m_edValue
->GetValue(); 
2365     if ( m_pCallingClass
->OnCustomStringEdit(m_parent
,str
) ) 
2367         //m_edValue->SetValue ( str ); 
2368         m_lbStrings
->Append ( str 
); 
2369         m_array
.Add ( str 
); 
2374 // ----------------------------------------------------------------------- 
2375 // wxArrayStringProperty 
2376 // ----------------------------------------------------------------------- 
2378 WX_PG_IMPLEMENT_PROPERTY_CLASS(wxArrayStringProperty
,  // Property name 
2379                                wxPGProperty
,  // Property we inherit from 
2380                                wxArrayString
,  // Value type name 
2381                                const wxArrayString
&,  // Value type, as given in constructor 
2382                                TextCtrlAndButton
)  // Initial editor 
2384 wxArrayStringProperty::wxArrayStringProperty( const wxString
& label
, 
2385                                                         const wxString
& name
, 
2386                                                         const wxArrayString
& array 
) 
2387     : wxPGProperty(label
,name
) 
2392 wxArrayStringProperty::~wxArrayStringProperty() { } 
2394 void wxArrayStringProperty::OnSetValue() 
2396     GenerateValueAsString(); 
2399 wxString 
wxArrayStringProperty::GetValueAsString( int WXUNUSED(argFlags
) ) const 
2404 // Converts wxArrayString to a string separated by delimeters and spaces. 
2405 // preDelim is useful for "str1" "str2" style. Set flags to 1 to do slash 
2407 void wxPropertyGrid::ArrayStringToString( wxString
& dst
, const wxArrayString
& src
, 
2408                                           wxChar preDelim
, wxChar postDelim
, 
2414     unsigned int itemCount 
= src
.size(); 
2422     else if ( (flags 
& 1) ) 
2424         preas
[0] = preDelim
; 
2431         dst
.append( preas 
); 
2433     wxASSERT( postDelim 
); 
2434     wxString 
postDelimStr(postDelim
); 
2435     //wxString preDelimStr(preDelim); 
2437     for ( i 
= 0; i 
< itemCount
; i
++ ) 
2439         wxString 
str( src
.Item(i
) ); 
2441         // Do some character conversion. 
2442         // Convertes \ to \\ and <preDelim> to \<preDelim> 
2443         // Useful when preDelim and postDelim are "\"". 
2446             str
.Replace( wxS("\\"), wxS("\\\\"), true ); 
2448                 str
.Replace( preas
, pdr
, true ); 
2453         if ( i 
< (itemCount
-1) ) 
2455             dst
.append( postDelimStr 
); 
2456             dst
.append( wxS(" ") ); 
2457             dst
.append( preas 
); 
2459         else if ( preDelim 
) 
2460             dst
.append( postDelimStr 
); 
2464 #define ARRSTRPROP_ARRAY_TO_STRING(STRING,ARRAY) \ 
2465     wxPropertyGrid::ArrayStringToString(STRING,ARRAY,wxS('"'),wxS('"'),1); 
2467 void wxArrayStringProperty::GenerateValueAsString() 
2469     wxArrayString arr 
= m_value
.GetArrayString(); 
2470     ARRSTRPROP_ARRAY_TO_STRING(m_display
, arr
) 
2473 // Default implementation doesn't do anything. 
2474 bool wxArrayStringProperty::OnCustomStringEdit( wxWindow
*, wxString
& ) 
2479 wxArrayEditorDialog
* wxArrayStringProperty::CreateEditorDialog() 
2481     return new wxPGArrayStringEditorDialog(); 
2484 bool wxArrayStringProperty::OnButtonClick( wxPropertyGrid
* propGrid
, 
2485                                            wxWindow
* WXUNUSED(primaryCtrl
), 
2489     wxVariant useValue 
= propGrid
->GetUncommittedPropertyValue(); 
2491     if ( !propGrid
->EditorValidate() ) 
2494     // Create editor dialog. 
2495     wxArrayEditorDialog
* dlg 
= CreateEditorDialog(); 
2496 #if wxUSE_VALIDATORS 
2497     wxValidator
* validator 
= GetValidator(); 
2498     wxPGInDialogValidator dialogValidator
; 
2501     wxPGArrayStringEditorDialog
* strEdDlg 
= wxDynamicCast(dlg
, wxPGArrayStringEditorDialog
); 
2504         strEdDlg
->SetCustomButton(cbt
, this); 
2506     dlg
->SetDialogValue( useValue 
); 
2507     dlg
->Create(propGrid
, wxEmptyString
, m_label
); 
2509 #if !wxPG_SMALL_SCREEN 
2510     dlg
->Move( propGrid
->GetGoodEditorDialogPosition(this,dlg
->GetSize()) ); 
2519         int res 
= dlg
->ShowModal(); 
2521         if ( res 
== wxID_OK 
&& dlg
->IsModified() ) 
2523             wxVariant value 
= dlg
->GetDialogValue(); 
2524             if ( !value
.IsNull() ) 
2526                 wxArrayString actualValue 
= value
.GetArrayString(); 
2528                 ARRSTRPROP_ARRAY_TO_STRING(tempStr
, actualValue
) 
2529             #if wxUSE_VALIDATORS 
2530                 if ( dialogValidator
.DoValidate( propGrid
, validator
, tempStr 
) ) 
2533                     SetValueInEvent( actualValue 
); 
2550 bool wxArrayStringProperty::OnEvent( wxPropertyGrid
* propGrid
, 
2554     if ( propGrid
->IsMainButtonEvent(event
) ) 
2555         return OnButtonClick(propGrid
,primary
,(const wxChar
*) NULL
); 
2559 bool wxArrayStringProperty::StringToValue( wxVariant
& variant
, const wxString
& text
, int ) const 
2563     WX_PG_TOKENIZER2_BEGIN(text
,wxS('"')) 
2565         // Need to replace backslashes with empty characters 
2566         // (opposite what is done in GenerateValueString). 
2567         token
.Replace ( wxS("\\"), wxEmptyString
, true ); 
2571     WX_PG_TOKENIZER2_END() 
2578 // ----------------------------------------------------------------------- 
2579 // wxPGInDialogValidator 
2580 // ----------------------------------------------------------------------- 
2582 #if wxUSE_VALIDATORS 
2583 bool wxPGInDialogValidator::DoValidate( wxPropertyGrid
* propGrid
, 
2584                                         wxValidator
* validator
, 
2585                                         const wxString
& value 
) 
2590     wxTextCtrl
* tc 
= m_textCtrl
; 
2595             tc 
= new wxTextCtrl( propGrid
, wxPG_SUBID_TEMP1
, wxEmptyString
, 
2596                                  wxPoint(30000,30000)); 
2603     tc
->SetValue(value
); 
2605     validator
->SetWindow(tc
); 
2606     bool res 
= validator
->Validate(propGrid
); 
2611 bool wxPGInDialogValidator::DoValidate( wxPropertyGrid
* WXUNUSED(propGrid
), 
2612                                         wxValidator
* WXUNUSED(validator
), 
2613                                         const wxString
& WXUNUSED(value
) ) 
2619 // ----------------------------------------------------------------------- 
2621 #endif  // wxUSE_PROPGRID