X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/895e26a04bb70facbc8d6bb54c1da8a872725557..12bb29f5432174ecbd65549bda832d70d34a98ae:/src/propgrid/props.cpp diff --git a/src/propgrid/props.cpp b/src/propgrid/props.cpp index b21beda0d4..8c7f259679 100644 --- a/src/propgrid/props.cpp +++ b/src/propgrid/props.cpp @@ -6,7 +6,7 @@ // Created: 2005-05-14 // RCS-ID: $Id$ // Copyright: (c) Jaakko Salli -// Licence: wxWindows license +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// // For compilers that support precompilation, includes "wx/wx.h". @@ -31,6 +31,7 @@ #include "wx/dcclient.h" #include "wx/dcmemory.h" #include "wx/button.h" + #include "wx/bmpbuttn.h" #include "wx/pen.h" #include "wx/brush.h" #include "wx/cursor.h" @@ -94,7 +95,9 @@ wxString wxStringProperty::ValueToString( wxVariant& value, if ( GetChildCount() && HasFlag(wxPG_PROP_COMPOSED_VALUE) ) { // Value stored in m_value is non-editable, non-full value - if ( (argFlags & wxPG_FULL_VALUE) || (argFlags & wxPG_EDITABLE_VALUE) ) + if ( (argFlags & wxPG_FULL_VALUE) || + (argFlags & wxPG_EDITABLE_VALUE) || + !s.length() ) { // Calling this under incorrect conditions will fail wxASSERT_MSG( argFlags & wxPG_VALUE_IS_CURRENT, @@ -141,6 +144,80 @@ bool wxStringProperty::DoSetAttribute( const wxString& name, wxVariant& value ) return true; } +// ----------------------------------------------------------------------- +// wxNumericPropertyValidator +// ----------------------------------------------------------------------- + +#if wxUSE_VALIDATORS + +wxNumericPropertyValidator:: + wxNumericPropertyValidator( NumericType numericType, int base ) + : wxTextValidator(wxFILTER_INCLUDE_CHAR_LIST) +{ + wxArrayString arr; + arr.Add(wxS("0")); + arr.Add(wxS("1")); + arr.Add(wxS("2")); + arr.Add(wxS("3")); + arr.Add(wxS("4")); + arr.Add(wxS("5")); + arr.Add(wxS("6")); + arr.Add(wxS("7")); + + if ( base >= 10 ) + { + arr.Add(wxS("8")); + arr.Add(wxS("9")); + if ( base >= 16 ) + { + arr.Add(wxS("a")); arr.Add(wxS("A")); + arr.Add(wxS("b")); arr.Add(wxS("B")); + arr.Add(wxS("c")); arr.Add(wxS("C")); + arr.Add(wxS("d")); arr.Add(wxS("D")); + arr.Add(wxS("e")); arr.Add(wxS("E")); + arr.Add(wxS("f")); arr.Add(wxS("F")); + } + } + + if ( numericType == Signed ) + { + arr.Add(wxS("+")); + arr.Add(wxS("-")); + } + else if ( numericType == Float ) + { + arr.Add(wxS("+")); + arr.Add(wxS("-")); + arr.Add(wxS("e")); + + // Use locale-specific decimal point + arr.Add(wxString::Format("%g", 1.1)[1]); + } + + SetIncludes(arr); +} + +bool wxNumericPropertyValidator::Validate(wxWindow* parent) +{ + if ( !wxTextValidator::Validate(parent) ) + return false; + + wxWindow* wnd = GetWindow(); + if ( !wxDynamicCast(wnd, wxTextCtrl) ) + return true; + + // Do not allow zero-length string + wxTextCtrl* tc = static_cast(wnd); + wxString text = tc->GetValue(); + + if ( text.empty() ) + return false; + + return true; +} + +#endif // wxUSE_VALIDATORS + // ----------------------------------------------------------------------- // wxIntProperty // ----------------------------------------------------------------------- @@ -183,7 +260,7 @@ bool wxIntProperty::StringToValue( wxVariant& variant, const wxString& text, int wxString s; long value32; - if ( text.length() == 0 ) + if ( text.empty() ) { variant.MakeNull(); return true; @@ -260,11 +337,22 @@ bool wxIntProperty::IntToValue( wxVariant& variant, int value, int WXUNUSED(argF return false; } -bool wxIntProperty::DoValidation( const wxPGProperty* property, wxLongLong_t& value, wxPGValidationInfo* pValidationInfo, int mode ) -{ - // Check for min/max - wxLongLong_t min = wxINT64_MIN; - wxLongLong_t max = wxINT64_MAX; +// +// Common validation code to be called in ValidateValue() +// implementations. +// +// Note that 'value' is reference on purpose, so we can write +// back to it when mode is wxPG_PROPERTY_VALIDATION_SATURATE. +// +template +bool NumericValidation( const wxPGProperty* property, + T& value, + wxPGValidationInfo* pValidationInfo, + int mode, + const wxString& strFmt ) +{ + T min = (T) wxINT64_MIN; + T max = (T) wxINT64_MAX; wxVariant variant; bool minOk = false; bool maxOk = false; @@ -272,14 +360,14 @@ bool wxIntProperty::DoValidation( const wxPGProperty* property, wxLongLong_t& va variant = property->GetAttribute(wxPGGlobalVars->m_strMin); if ( !variant.IsNull() ) { - min = variant.GetLongLong().GetValue(); + variant.Convert(&min); minOk = true; } variant = property->GetAttribute(wxPGGlobalVars->m_strMax); if ( !variant.IsNull() ) { - max = variant.GetLongLong().GetValue(); + variant.Convert(&max); maxOk = true; } @@ -290,13 +378,16 @@ bool wxIntProperty::DoValidation( const wxPGProperty* property, wxLongLong_t& va if ( mode == wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE ) { wxString msg; + wxString smin = wxString::Format(strFmt, min); + wxString smax = wxString::Format(strFmt, max); if ( !maxOk ) msg = wxString::Format( - _("Value must be %lld or higher."), min); + _("Value must be %s or higher."), + smin.c_str()); else msg = wxString::Format( - _("Value must be between %lld and %lld."), - min, max); + _("Value must be between %s and %s."), + smin.c_str(), smax.c_str()); pValidationInfo->SetFailureMessage(msg); } else if ( mode == wxPG_PROPERTY_VALIDATION_SATURATE ) @@ -314,13 +405,16 @@ bool wxIntProperty::DoValidation( const wxPGProperty* property, wxLongLong_t& va if ( mode == wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE ) { wxString msg; + wxString smin = wxString::Format(strFmt, min); + wxString smax = wxString::Format(strFmt, max); if ( !minOk ) msg = wxString::Format( - _("Value must be %lld or lower."), max); + _("Value must be %s or less."), + smax.c_str()); else msg = wxString::Format( - _("Value must be between %lld and %lld."), - min, max); + _("Value must be between %s and %s."), + smin.c_str(), smax.c_str()); pValidationInfo->SetFailureMessage(msg); } else if ( mode == wxPG_PROPERTY_VALIDATION_SATURATE ) @@ -333,6 +427,18 @@ bool wxIntProperty::DoValidation( const wxPGProperty* property, wxLongLong_t& va return true; } +bool wxIntProperty::DoValidation( const wxPGProperty* property, + wxLongLong_t& value, + wxPGValidationInfo* pValidationInfo, + int mode ) +{ + return NumericValidation(property, + value, + pValidationInfo, + mode, + wxS("%lld")); +} + bool wxIntProperty::ValidateValue( wxVariant& value, wxPGValidationInfo& validationInfo ) const { @@ -346,9 +452,8 @@ wxValidator* wxIntProperty::GetClassValidator() #if wxUSE_VALIDATORS 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); + wxValidator* validator = new wxNumericPropertyValidator( + wxNumericPropertyValidator::Signed); WX_PG_DOGETVALIDATOR_EXIT(validator) #else @@ -369,9 +474,9 @@ wxValidator* wxIntProperty::DoGetValidator() const #define wxPG_UINT_TEMPLATE_MAX 8 static const wxChar* const gs_uintTemplates32[wxPG_UINT_TEMPLATE_MAX] = { - wxT("%x"),wxT("0x%x"),wxT("$%x"), - wxT("%X"),wxT("0x%X"),wxT("$%X"), - wxT("%u"),wxT("%o") + wxT("%lx"),wxT("0x%lx"),wxT("$%lx"), + wxT("%lX"),wxT("0x%lX"),wxT("$%lX"), + wxT("%lu"),wxT("%lo") }; static const char* const gs_uintTemplates64[wxPG_UINT_TEMPLATE_MAX] = { @@ -434,7 +539,7 @@ bool wxUIntProperty::StringToValue( wxVariant& variant, const wxString& text, in wxString variantType = variant.GetType(); bool isPrevLong = variantType == wxPG_VARIANT_TYPE_LONG; - if ( text.length() == 0 ) + if ( text.empty() ) { variant.MakeNull(); return true; @@ -492,39 +597,28 @@ bool wxUIntProperty::IntToValue( wxVariant& variant, int number, int WXUNUSED(ar bool wxUIntProperty::ValidateValue( wxVariant& value, wxPGValidationInfo& validationInfo ) const { - // Check for min/max - wxULongLong_t ll = value.GetULongLong().GetValue(); + wxULongLong_t uul = value.GetULongLong().GetValue(); + return + NumericValidation(this, + uul, + &validationInfo, + wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE, + wxS("%llu")); +} - wxULongLong_t min = 0; - wxULongLong_t max = wxUINT64_MAX; - wxVariant variant; +wxValidator* wxUIntProperty::DoGetValidator() const +{ +#if wxUSE_VALIDATORS + WX_PG_DOGETVALIDATOR_ENTRY() - variant = GetAttribute(wxPGGlobalVars->m_strMin); - if ( !variant.IsNull() ) - { - min = variant.GetULongLong().GetValue(); - if ( ll < min ) - { - validationInfo.SetFailureMessage( - wxString::Format(_("Value must be %llu or higher"),min) - ); - return false; - } - } - variant = GetAttribute(wxPGGlobalVars->m_strMax); - if ( !variant.IsNull() ) - { - max = variant.GetULongLong().GetValue(); - if ( ll > max ) - { - validationInfo.SetFailureMessage( - wxString::Format(_("Value must be %llu or less"),max) - ); - return false; - } - } + wxValidator* validator = new wxNumericPropertyValidator( + wxNumericPropertyValidator::Unsigned, + m_realBase); - return true; + WX_PG_DOGETVALIDATOR_EXIT(validator) +#else + return NULL; +#endif } bool wxUIntProperty::DoSetAttribute( const wxString& name, wxVariant& value ) @@ -576,11 +670,11 @@ wxFloatProperty::~wxFloatProperty() { } // 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) +const wxString& wxPropertyGrid::DoubleToString(wxString& target, + double value, + int precision, + bool removeZeroes, + wxString* precTemplate) { if ( precision >= 0 ) { @@ -588,7 +682,7 @@ void wxPropertyGrid::DoubleToString(wxString& target, if (!precTemplate) precTemplate = &text1; - if ( !precTemplate->length() ) + if ( precTemplate->empty() ) { *precTemplate = wxS("%."); *precTemplate << wxString::Format( wxS("%i"), precision ); @@ -602,7 +696,7 @@ void wxPropertyGrid::DoubleToString(wxString& target, target.Printf( wxS("%f"), value ); } - if ( removeZeroes && precision != 0 && target.length() ) + if ( removeZeroes && precision != 0 && !target.empty() ) { // Remove excess zeroes (do not remove this code just yet, // since sprintf can't do the same consistently across platforms). @@ -623,6 +717,27 @@ void wxPropertyGrid::DoubleToString(wxString& target, if ( new_len != target.length() ) target.resize(new_len); } + + // Remove sign from zero + if ( target.length() >= 2 && target[0] == wxS('-') ) + { + bool isZero = true; + wxString::const_iterator i = target.begin() + 1; + + for ( ; i != target.end(); i++ ) + { + if ( *i != wxS('0') && *i != wxS('.') && *i != wxS(',') ) + { + isZero = false; + break; + } + } + + if ( isZero ) + target.erase(target.begin()); + } + + return target; } wxString wxFloatProperty::ValueToString( wxVariant& value, @@ -645,7 +760,7 @@ bool wxFloatProperty::StringToValue( wxVariant& variant, const wxString& text, i wxString s; double value; - if ( text.length() == 0 ) + if ( text.empty() ) { variant.MakeNull(); return true; @@ -671,60 +786,11 @@ bool wxFloatProperty::DoValidation( const wxPGProperty* property, wxPGValidationInfo* pValidationInfo, int mode ) { - // Check for min/max - double min = (double)wxINT64_MIN; - double max = (double)wxINT64_MAX; - wxVariant variant; - bool minOk = false; - bool maxOk = false; - - variant = property->GetAttribute(wxPGGlobalVars->m_strMin); - if ( !variant.IsNull() ) - { - min = variant.GetDouble(); - minOk = true; - } - - variant = property->GetAttribute(wxPGGlobalVars->m_strMax); - if ( !variant.IsNull() ) - { - max = variant.GetDouble(); - maxOk = true; - } - - if ( minOk ) - { - if ( value < min ) - { - if ( mode == wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE ) - pValidationInfo->SetFailureMessage( - wxString::Format(_("Value must be %f or higher"),min) - ); - else if ( mode == wxPG_PROPERTY_VALIDATION_SATURATE ) - value = min; - else - value = max - (min - value); - return false; - } - } - - if ( maxOk ) - { - max = variant.GetDouble(); - if ( value > max ) - { - if ( mode == wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE ) - pValidationInfo->SetFailureMessage( - wxString::Format(_("Value must be %f or less"),max) - ); - else if ( mode == wxPG_PROPERTY_VALIDATION_SATURATE ) - value = max; - else - value = min + (value - max); - return false; - } - } - return true; + return NumericValidation(property, + value, + pValidationInfo, + mode, + wxS("%g")); } bool @@ -746,9 +812,24 @@ bool wxFloatProperty::DoSetAttribute( const wxString& name, wxVariant& value ) return false; } +wxValidator* +wxFloatProperty::GetClassValidator() +{ +#if wxUSE_VALIDATORS + WX_PG_DOGETVALIDATOR_ENTRY() + + wxValidator* validator = new wxNumericPropertyValidator( + wxNumericPropertyValidator::Float); + + WX_PG_DOGETVALIDATOR_EXIT(validator) +#else + return NULL; +#endif +} + wxValidator* wxFloatProperty::DoGetValidator() const { - return wxIntProperty::GetClassValidator(); + return GetClassValidator(); } // ----------------------------------------------------------------------- @@ -833,7 +914,7 @@ bool wxBoolProperty::StringToValue( wxVariant& variant, const wxString& text, in text.CmpNoCase(m_label) == 0 ) boolValue = true; - if ( text.length() == 0 ) + if ( text.empty() ) { variant.MakeNull(); return true; @@ -999,7 +1080,7 @@ bool wxEnumProperty::ValidateValue( wxVariant& value, wxPGValidationInfo& WXUNUS // unless property has string as preferred value type // To reduce code size, use conversion here as well if ( value.GetType() == wxPG_VARIANT_TYPE_STRING && - !this->IsKindOf(CLASSINFO(wxEditEnumProperty)) ) + !wxDynamicCastThis(wxEditEnumProperty) ) return ValueFromString_( value, value.GetString(), wxPG_PROPERTY_SPECIFIC ); return true; @@ -1046,7 +1127,7 @@ bool wxEnumProperty::ValueFromString_( wxVariant& value, const wxString& text, i bool asText = false; - bool isEdit = this->IsKindOf(CLASSINFO(wxEditEnumProperty)); + bool isEdit = this->IsKindOf(wxCLASSINFO(wxEditEnumProperty)); // If text not any of the choices, store as text instead // (but only if we are wxEditEnumProperty) @@ -1388,7 +1469,7 @@ void wxFlagsProperty::OnSetValue() flag = choices.GetValue(i); if ( (newFlags & flag) != (m_oldValue & flag) ) - Item(i)->SetFlag( wxPG_PROP_MODIFIED ); + Item(i)->ChangeFlag( wxPG_PROP_MODIFIED, true ); } m_oldValue = newFlags; @@ -1437,7 +1518,7 @@ bool wxFlagsProperty::StringToValue( wxVariant& variant, const wxString& text, i // semicolons are no longer valid delimeters WX_PG_TOKENIZER1_BEGIN(text,wxS(',')) - if ( token.length() ) + if ( !token.empty() ) { // Determine which one it is long bit = IdToBit( token ); @@ -1496,7 +1577,7 @@ void wxFlagsProperty::RefreshChildren() wxPGProperty* p = Item(i); if ( subVal != (m_oldValue & flag) ) - p->SetFlag( wxPG_PROP_MODIFIED ); + p->ChangeFlag( wxPG_PROP_MODIFIED, true ); p->SetValue( subVal?true:false ); } @@ -1602,14 +1683,14 @@ bool wxPGFileDialogAdapter::DoShowDialog( wxPropertyGrid* propGrid, wxPGProperty wxString path; int indFilter = -1; - if ( property->IsKindOf(CLASSINFO(wxFileProperty)) ) + if ( wxDynamicCast(property, wxFileProperty) ) { fileProp = ((wxFileProperty*)property); wxFileName filename = fileProp->GetValue().GetString(); path = filename.GetPath(); indFilter = fileProp->m_indFilter; - if ( !path.length() && fileProp->m_basePath.length() ) + if ( path.empty() && !fileProp->m_basePath.empty() ) path = fileProp->m_basePath; } else @@ -1622,8 +1703,8 @@ bool wxPGFileDialogAdapter::DoShowDialog( wxPropertyGrid* propGrid, wxPGProperty property->GetAttribute(wxS("DialogTitle"), _("Choose a file")), property->GetAttribute(wxS("InitialPath"), path), wxEmptyString, - property->GetAttribute(wxPG_FILE_WILDCARD, _("All files (*.*)|*.*")), - 0, + property->GetAttribute(wxPG_FILE_WILDCARD, wxALL_FILES), + property->GetAttributeAsLong(wxPG_FILE_DIALOG_STYLE, 0), wxDefaultPosition ); if ( indFilter >= 0 ) @@ -1651,7 +1732,7 @@ wxFileProperty::wxFileProperty( const wxString& label, const wxString& name, { m_flags |= wxPG_PROP_SHOW_FULL_FILENAME; m_indFilter = -1; - SetAttribute( wxPG_FILE_WILDCARD, _("All files (*.*)|*.*") ); + SetAttribute( wxPG_FILE_WILDCARD, wxALL_FILES); SetValue(value); } @@ -1700,7 +1781,7 @@ void wxFileProperty::OnSetValue() } // Find index for extension. - if ( m_indFilter < 0 && fnstr.length() ) + if ( m_indFilter < 0 && !fnstr.empty() ) { wxString ext = filename.GetExt(); int curind = 0; @@ -1717,7 +1798,7 @@ void wxFileProperty::OnSetValue() pos = len; wxString found_ext = m_wildcard.substr(ext_begin, pos-ext_begin); - if ( found_ext.length() > 0 ) + if ( !found_ext.empty() ) { if ( found_ext[0] == wxS('*') ) { @@ -1758,7 +1839,7 @@ wxString wxFileProperty::ValueToString( wxVariant& value, return wxEmptyString; wxString fullName = filename.GetFullName(); - if ( !fullName.length() ) + if ( fullName.empty() ) return wxEmptyString; if ( argFlags & wxPG_FULL_VALUE ) @@ -1767,7 +1848,7 @@ wxString wxFileProperty::ValueToString( wxVariant& value, } else if ( m_flags & wxPG_PROP_SHOW_FULL_FILENAME ) { - if ( m_basePath.Length() ) + if ( !m_basePath.empty() ) { wxFileName fn2(filename); fn2.MakeRelativeTo(m_basePath); @@ -2105,7 +2186,7 @@ bool wxPGArrayEditorDialog::Create( wxWindow *parent, wxBoxSizer* topsizer = new wxBoxSizer( wxVERTICAL ); // Message - if ( message.length() ) + if ( !message.empty() ) topsizer->Add( new wxStaticText(this,-1,message), 0, wxALIGN_LEFT|wxALIGN_CENTRE_VERTICAL|wxALL, spacing ); @@ -2128,26 +2209,26 @@ bool wxPGArrayEditorDialog::Create( wxWindow *parent, but = m_elb->GetNewButton(); m_elbSubPanel = but->GetParent(); - but->Connect(but->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, + but->Connect(but->GetId(), wxEVT_BUTTON, wxCommandEventHandler(wxPGArrayEditorDialog::OnAddClick), NULL, this); but = m_elb->GetDelButton(); - but->Connect(but->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, + but->Connect(but->GetId(), wxEVT_BUTTON, wxCommandEventHandler(wxPGArrayEditorDialog::OnDeleteClick), NULL, this); but = m_elb->GetUpButton(); - but->Connect(but->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, + but->Connect(but->GetId(), wxEVT_BUTTON, wxCommandEventHandler(wxPGArrayEditorDialog::OnUpClick), NULL, this); but = m_elb->GetDownButton(); - but->Connect(but->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, + but->Connect(but->GetId(), wxEVT_BUTTON, wxCommandEventHandler(wxPGArrayEditorDialog::OnDownClick), NULL, this); - lc->Connect(lc->GetId(), wxEVT_COMMAND_LIST_END_LABEL_EDIT, + lc->Connect(lc->GetId(), wxEVT_LIST_END_LABEL_EDIT, wxListEventHandler(wxPGArrayEditorDialog::OnEndLabelEdit), NULL, this); @@ -2198,7 +2279,7 @@ void wxPGArrayEditorDialog::OnAddClick(wxCommandEvent& event) wxListCtrl* lc = m_elb->GetListCtrl(); int newItemIndex = lc->GetItemCount() - 1; - if ( m_hasCustomNewAction ) + if ( m_hasCustomNewAction ) { wxString str; if ( OnCustomNewAction(&str) ) @@ -2387,6 +2468,7 @@ wxArrayStringProperty::wxArrayStringProperty( const wxString& label, const wxArrayString& array ) : wxPGProperty(label,name) { + m_delimiter = ','; SetValue( array ); } @@ -2397,8 +2479,28 @@ void wxArrayStringProperty::OnSetValue() GenerateValueAsString(); } -#define ARRSTRPROP_ARRAY_TO_STRING(STRING,ARRAY) \ - wxPropertyGrid::ArrayStringToString(STRING,ARRAY,wxS('"'),wxS('"'),1) +void +wxArrayStringProperty::ConvertArrayToString(const wxArrayString& arr, + wxString* pString, + const wxUniChar& delimiter) const +{ + if ( delimiter == '"' || delimiter == '\'' ) + { + // Quoted strings + ArrayStringToString(*pString, + arr, + delimiter, + Escape | QuoteStrings); + } + else + { + // Regular delimiter + ArrayStringToString(*pString, + arr, + delimiter, + 0); + } +} wxString wxArrayStringProperty::ValueToString( wxVariant& WXUNUSED(value), int argFlags ) const @@ -2412,51 +2514,49 @@ wxString wxArrayStringProperty::ValueToString( wxVariant& WXUNUSED(value), wxArrayString arr = m_value.GetArrayString(); wxString s; - ARRSTRPROP_ARRAY_TO_STRING(s, arr); + ConvertArrayToString(arr, &s, m_delimiter); return s; } // 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 ) +void +wxArrayStringProperty::ArrayStringToString( wxString& dst, + const wxArrayString& src, + wxUniChar delimiter, int flags ) { wxString pdr; + wxString preas; unsigned int i; unsigned int itemCount = src.size(); - wxChar preas[2] = { 0, 0 }; - dst.Empty(); - if ( flags & 1 ) + if ( flags & Escape ) { - preas[0] = preDelim; + preas = delimiter; pdr = wxS("\\"); - pdr += preDelim; + pdr += delimiter; } if ( itemCount ) dst.append( preas ); - wxASSERT( postDelim ); - wxString postDelimStr(postDelim); - //wxString preDelimStr(preDelim); + wxString delimStr(delimiter); for ( i = 0; i < itemCount; i++ ) { wxString str( src.Item(i) ); // Do some character conversion. - // Convertes \ to \\ and to \ - // Useful when preDelim and postDelim are "\"". - if ( flags & 1 ) + // Converts \ to \\ and $delimiter to \$delimiter + // Useful when quoting. + if ( flags & Escape ) { str.Replace( wxS("\\"), wxS("\\\\"), true ); - if ( pdr.length() ) + if ( !pdr.empty() ) str.Replace( preas, pdr, true ); } @@ -2464,19 +2564,19 @@ void wxPropertyGrid::ArrayStringToString( wxString& dst, const wxArrayString& sr if ( i < (itemCount-1) ) { - dst.append( postDelimStr ); + dst.append( delimStr ); dst.append( wxS(" ") ); dst.append( preas ); } - else if ( preDelim ) - dst.append( postDelimStr ); + else if ( flags & QuoteStrings ) + dst.append( delimStr ); } } void wxArrayStringProperty::GenerateValueAsString() { wxArrayString arr = m_value.GetArrayString(); - ARRSTRPROP_ARRAY_TO_STRING(m_display, arr); + ConvertArrayToString(arr, &m_display, m_delimiter); } // Default implementation doesn't do anything. @@ -2534,9 +2634,10 @@ bool wxArrayStringProperty::OnButtonClick( wxPropertyGrid* propGrid, { wxArrayString actualValue = value.GetArrayString(); wxString tempStr; - ARRSTRPROP_ARRAY_TO_STRING(tempStr, actualValue); + ConvertArrayToString(actualValue, &tempStr, m_delimiter); #if wxUSE_VALIDATORS - if ( dialogValidator.DoValidate( propGrid, validator, tempStr ) ) + if ( dialogValidator.DoValidate(propGrid, validator, + tempStr) ) #endif { SetValueInEvent( actualValue ); @@ -2565,25 +2666,48 @@ bool wxArrayStringProperty::OnEvent( wxPropertyGrid* propGrid, return false; } -bool wxArrayStringProperty::StringToValue( wxVariant& variant, const wxString& text, int ) const +bool wxArrayStringProperty::StringToValue( wxVariant& variant, + const wxString& text, int ) const { wxArrayString arr; - WX_PG_TOKENIZER2_BEGIN(text,wxS('"')) + if ( m_delimiter == '"' || m_delimiter == '\'' ) + { + // Quoted strings + WX_PG_TOKENIZER2_BEGIN(text, m_delimiter) - // Need to replace backslashes with empty characters - // (opposite what is done in GenerateValueString). - token.Replace ( wxS("\\\\"), wxS("\\"), true ); + // Need to replace backslashes with empty characters + // (opposite what is done in ConvertArrayToString()). + token.Replace ( wxS("\\\\"), wxS("\\"), true ); - arr.Add( token ); + arr.Add( token ); - WX_PG_TOKENIZER2_END() + WX_PG_TOKENIZER2_END() + } + else + { + // Regular delimiter + WX_PG_TOKENIZER1_BEGIN(text, m_delimiter) + arr.Add( token ); + WX_PG_TOKENIZER1_END() + } variant = arr; return true; } +bool wxArrayStringProperty::DoSetAttribute( const wxString& name, wxVariant& value ) +{ + if ( name == wxPG_ARRAY_DELIMITER ) + { + m_delimiter = value.GetChar(); + GenerateValueAsString(); + return false; + } + return true; +} + // ----------------------------------------------------------------------- // wxPGInDialogValidator // -----------------------------------------------------------------------