// 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".
#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"
if ( HasFlag(wxPG_PROP_COMPOSED_VALUE) )
{
wxString s;
- GenerateComposedValue(s, 0);
+ DoGenerateComposedValue(s);
m_value = s;
}
}
wxStringProperty::~wxStringProperty() { }
-wxString wxStringProperty::GetValueAsString( int argFlags ) const
+wxString wxStringProperty::ValueToString( wxVariant& value,
+ int argFlags ) const
{
- wxString s = m_value.GetString();
+ wxString s = value.GetString();
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) )
- GenerateComposedValue(s, argFlags);
+ {
+ // Calling this under incorrect conditions will fail
+ wxASSERT_MSG( argFlags & wxPG_VALUE_IS_CURRENT,
+ "Sorry, currently default wxPGProperty::ValueToString() "
+ "implementation only works if value is m_value." );
+
+ DoGenerateComposedValue(s, argFlags);
+ }
return s;
}
if ( name == wxPG_STRING_PASSWORD )
{
m_flags &= ~(wxPG_PROP_PASSWORD);
- if ( wxPGVariantToInt(value) ) m_flags |= wxPG_PROP_PASSWORD;
+ if ( value.GetLong() ) m_flags |= wxPG_PROP_PASSWORD;
RecreateEditor();
return false;
}
wxIntProperty::~wxIntProperty() { }
-wxString wxIntProperty::GetValueAsString( int ) const
+wxString wxIntProperty::ValueToString( wxVariant& value,
+ int WXUNUSED(argFlags) ) const
{
- if ( m_value.GetType() == wxPG_VARIANT_TYPE_LONG )
+ if ( value.GetType() == wxPG_VARIANT_TYPE_LONG )
{
- return wxString::Format(wxS("%li"),m_value.GetLong());
+ return wxString::Format(wxS("%li"),value.GetLong());
}
- else if ( m_value.GetType() == wxLongLong_VariantType )
+ else if ( value.GetType() == wxPG_VARIANT_TYPE_LONGLONG )
{
- wxLongLong ll;
- ll << m_value;
- return ll.ToString();
+ wxLongLong ll = value.GetLongLong();
+ return ll.ToString();
}
return wxEmptyString;
int firstNonZeroPos = 0;
- for ( ; i != iMax; i++ )
+ for ( ; i != iMax; ++i )
{
wxChar c = *i;
if ( c != wxS('0') && c != wxS(' ') )
{
bool doChangeValue = isPrevLong;
- if ( !isPrevLong && variantType == wxLongLong_VariantType )
+ if ( !isPrevLong && variantType == wxPG_VARIANT_TYPE_LONGLONG )
{
- wxLongLong oldValue;
- oldValue << variant;
+ wxLongLong oldValue = variant.GetLongLong();
if ( oldValue.GetValue() != value64 )
doChangeValue = true;
}
if ( doChangeValue )
{
wxLongLong ll(value64);
- variant << ll;
+ variant = ll;
return true;
}
}
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<typename T>
+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;
variant = property->GetAttribute(wxPGGlobalVars->m_strMin);
if ( !variant.IsNull() )
{
- wxPGVariantToLongLong(variant, &min);
+ variant.Convert(&min);
minOk = true;
}
variant = property->GetAttribute(wxPGGlobalVars->m_strMax);
if ( !variant.IsNull() )
{
- wxPGVariantToLongLong(variant, &max);
+ variant.Convert(&max);
maxOk = true;
}
if ( value < min )
{
if ( mode == wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE )
- pValidationInfo->SetFailureMessage(
- wxString::Format(_("Value must be %lld or higher"),min)
- );
+ {
+ wxString msg;
+ wxString smin = wxString::Format(strFmt, min);
+ wxString smax = wxString::Format(strFmt, max);
+ if ( !maxOk )
+ msg = wxString::Format(
+ _("Value must be %s or higher."),
+ smin.c_str());
+ else
+ msg = wxString::Format(
+ _("Value must be between %s and %s."),
+ smin.c_str(), smax.c_str());
+ pValidationInfo->SetFailureMessage(msg);
+ }
else if ( mode == wxPG_PROPERTY_VALIDATION_SATURATE )
value = min;
else
if ( value > max )
{
if ( mode == wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE )
- pValidationInfo->SetFailureMessage(
- wxString::Format(_("Value must be %lld or higher"),min)
- );
+ {
+ wxString msg;
+ wxString smin = wxString::Format(strFmt, min);
+ wxString smax = wxString::Format(strFmt, max);
+ if ( !minOk )
+ msg = wxString::Format(
+ _("Value must be %s or less."),
+ smax.c_str());
+ else
+ msg = wxString::Format(
+ _("Value must be between %s and %s."),
+ smin.c_str(), smax.c_str());
+ pValidationInfo->SetFailureMessage(msg);
+ }
else if ( mode == wxPG_PROPERTY_VALIDATION_SATURATE )
value = max;
else
return true;
}
-bool wxIntProperty::ValidateValue( wxVariant& value, wxPGValidationInfo& validationInfo ) const
+bool wxIntProperty::DoValidation( const wxPGProperty* property,
+ wxLongLong_t& value,
+ wxPGValidationInfo* pValidationInfo,
+ int mode )
{
- wxLongLong_t ll;
- if ( wxPGVariantToLongLong(value, &ll) )
- return DoValidation(this, ll, &validationInfo, wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE);
- return true;
+ return NumericValidation<wxLongLong_t>(property,
+ value,
+ pValidationInfo,
+ mode,
+ wxS("%lld"));
+}
+
+bool wxIntProperty::ValidateValue( wxVariant& value,
+ wxPGValidationInfo& validationInfo ) const
+{
+ wxLongLong_t ll = value.GetLongLong().GetValue();
+ return DoValidation(this, ll, &validationInfo,
+ wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE);
}
wxValidator* wxIntProperty::GetClassValidator()
#define wxPG_UINT_TEMPLATE_MAX 8
-static const wxChar* gs_uintTemplates32[wxPG_UINT_TEMPLATE_MAX] = {
+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")
};
-static const wxChar* gs_uintTemplates64[wxPG_UINT_TEMPLATE_MAX] = {
- wxT("%") wxLongLongFmtSpec wxT("x"),
- wxT("0x%") wxLongLongFmtSpec wxT("x"),
- wxT("$%") wxLongLongFmtSpec wxT("x"),
- wxT("%") wxLongLongFmtSpec wxT("X"),
- wxT("0x%") wxLongLongFmtSpec wxT("X"),
- wxT("$%") wxLongLongFmtSpec wxT("X"),
- wxT("%") wxLongLongFmtSpec wxT("u"),
- wxT("%") wxLongLongFmtSpec wxT("o")
+static const char* const gs_uintTemplates64[wxPG_UINT_TEMPLATE_MAX] = {
+ "%" wxLongLongFmtSpec "x",
+ "0x%" wxLongLongFmtSpec "x",
+ "$%" wxLongLongFmtSpec "x",
+ "%" wxLongLongFmtSpec "X",
+ "0x%" wxLongLongFmtSpec "X",
+ "$%" wxLongLongFmtSpec "X",
+ "%" wxLongLongFmtSpec "u",
+ "%" wxLongLongFmtSpec "o"
};
WX_PG_IMPLEMENT_PROPERTY_CLASS(wxUIntProperty,wxPGProperty,
wxUIntProperty::~wxUIntProperty() { }
-wxString wxUIntProperty::GetValueAsString( int ) const
+wxString wxUIntProperty::ValueToString( wxVariant& value,
+ int WXUNUSED(argFlags) ) const
{
size_t index = m_base + m_prefix;
if ( index >= wxPG_UINT_TEMPLATE_MAX )
index = wxPG_BASE_DEC;
- if ( m_value.GetType() == wxPG_VARIANT_TYPE_LONG )
+ if ( value.GetType() == wxPG_VARIANT_TYPE_LONG )
{
- return wxString::Format(gs_uintTemplates32[index], (unsigned long)m_value.GetLong());
+ return wxString::Format(gs_uintTemplates32[index],
+ (unsigned long)value.GetLong());
}
- wxULongLong ull;
- ull << m_value;
+ wxULongLong ull = value.GetULongLong();
return wxString::Format(gs_uintTemplates64[index], ull.GetValue());
}
{
bool doChangeValue = isPrevLong;
- if ( !isPrevLong && variantType == wxULongLong_VariantType )
+ if ( !isPrevLong && variantType == wxPG_VARIANT_TYPE_ULONGLONG )
{
- wxULongLong oldValue;
- oldValue << variant;
+ wxULongLong oldValue = variant.GetULongLong();
if ( oldValue.GetValue() != value64 )
doChangeValue = true;
}
if ( doChangeValue )
{
- wxULongLong ull(value64);
- variant << ull;
+ variant = wxULongLong(value64);
return true;
}
}
return false;
}
-#ifdef ULLONG_MAX
- #define wxUINT64_MAX ULLONG_MAX
- #define wxUINT64_MIN wxULL(0)
-#else
- #define wxUINT64_MAX wxULL(0xFFFFFFFFFFFFFFFF)
- #define wxUINT64_MIN wxULL(0)
-#endif
-
bool wxUIntProperty::ValidateValue( wxVariant& value, wxPGValidationInfo& validationInfo ) const
{
- // Check for min/max
- wxULongLong_t ll;
- if ( wxPGVariantToULongLong(value, &ll) )
- {
- wxULongLong_t min = wxUINT64_MIN;
- wxULongLong_t max = wxUINT64_MAX;
- wxVariant variant;
-
- variant = GetAttribute(wxPGGlobalVars->m_strMin);
- if ( !variant.IsNull() )
- {
- wxPGVariantToULongLong(variant, &min);
- if ( ll < min )
- {
- validationInfo.SetFailureMessage(
- wxString::Format(_("Value must be %llu or higher"),min)
- );
- return false;
- }
- }
- variant = GetAttribute(wxPGGlobalVars->m_strMax);
- if ( !variant.IsNull() )
- {
- wxPGVariantToULongLong(variant, &max);
- if ( ll > max )
- {
- validationInfo.SetFailureMessage(
- wxString::Format(_("Value must be %llu or less"),max)
- );
- return false;
- }
- }
- }
- return true;
+ wxULongLong_t uul = value.GetULongLong().GetValue();
+ return
+ NumericValidation<wxULongLong_t>(this,
+ uul,
+ &validationInfo,
+ wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE,
+ wxS("%llu"));
}
bool wxUIntProperty::DoSetAttribute( const wxString& name, wxVariant& value )
wxString::const_iterator i = target.end() - 1;
size_t new_len = target.length() - 1;
- for ( ; i != target.begin(); i-- )
+ for ( ; i != target.begin(); --i )
{
if ( *i != wxS('0') )
break;
}
}
-wxString wxFloatProperty::GetValueAsString( int argFlags ) const
+wxString wxFloatProperty::ValueToString( wxVariant& value,
+ int argFlags ) const
{
wxString text;
- if ( !m_value.IsNull() )
+ if ( !value.IsNull() )
{
wxPropertyGrid::DoubleToString(text,
- m_value,
+ value,
m_precision,
!(argFlags & wxPG_FULL_VALUE),
- (wxString*) NULL);
+ NULL);
}
return text;
}
return false;
}
-bool wxFloatProperty::DoValidation( const wxPGProperty* property, double& value, wxPGValidationInfo* pValidationInfo, int mode )
+bool wxFloatProperty::DoValidation( const wxPGProperty* property,
+ double& value,
+ 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() )
- {
- wxPGVariantToDouble(variant, &min);
- minOk = true;
- }
-
- variant = property->GetAttribute(wxPGGlobalVars->m_strMax);
- if ( !variant.IsNull() )
- {
- wxPGVariantToDouble(variant, &max);
- 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 )
- {
- wxPGVariantToDouble(variant, &max);
- 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<double>(property,
+ value,
+ pValidationInfo,
+ mode,
+ wxS("%g"));
}
-bool wxFloatProperty::ValidateValue( wxVariant& value, wxPGValidationInfo& validationInfo ) const
+bool
+wxFloatProperty::ValidateValue( wxVariant& value,
+ wxPGValidationInfo& validationInfo ) const
{
- double fpv;
- if ( wxPGVariantToDouble(value, &fpv) )
- return DoValidation(this, fpv, &validationInfo, wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE);
- return true;
+ double fpv = value.GetDouble();
+ return DoValidation(this, fpv, &validationInfo,
+ wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE);
}
bool wxFloatProperty::DoSetAttribute( const wxString& name, wxVariant& value )
wxBoolProperty::~wxBoolProperty() { }
-wxString wxBoolProperty::GetValueAsString( int argFlags ) const
+wxString wxBoolProperty::ValueToString( wxVariant& value,
+ int argFlags ) const
{
- bool value = m_value.GetBool();
+ bool boolValue = value.GetBool();
// As a fragment of composite string value,
// make it a little more readable.
if ( argFlags & wxPG_COMPOSITE_FRAGMENT )
{
- if ( value )
+ if ( boolValue )
{
return m_label;
}
if ( !(argFlags & wxPG_FULL_VALUE) )
{
- return wxPGGlobalVars->m_boolChoices[value?1:0].GetText();
+ return wxPGGlobalVars->m_boolChoices[boolValue?1:0].GetText();
}
wxString text;
- if (value) text = wxS("true");
+ if ( boolValue ) text = wxS("true");
else text = wxS("false");
return text;
#if wxPG_INCLUDE_CHECKBOX
if ( name == wxPG_BOOL_USE_CHECKBOX )
{
- int ival = wxPGVariantToInt(value);
- if ( ival )
+ if ( value.GetLong() )
m_flags |= wxPG_PROP_USE_CHECKBOX;
else
m_flags &= ~(wxPG_PROP_USE_CHECKBOX);
#endif
if ( name == wxPG_BOOL_USE_DOUBLE_CLICK_CYCLING )
{
- int ival = wxPGVariantToInt(value);
- if ( ival )
+ if ( value.GetLong() )
m_flags |= wxPG_PROP_USE_DCC;
else
m_flags &= ~(wxPG_PROP_USE_DCC);
}
// -----------------------------------------------------------------------
-// wxBaseEnumProperty
+// wxEnumProperty
// -----------------------------------------------------------------------
-int wxBaseEnumProperty::ms_nextIndex = -2;
+IMPLEMENT_DYNAMIC_CLASS(wxEnumProperty, wxPGProperty)
+
+WX_PG_IMPLEMENT_PROPERTY_CLASS_PLAIN(wxEnumProperty,long,Choice)
+
+wxEnumProperty::wxEnumProperty( const wxString& label, const wxString& name, const wxChar* const* labels,
+ const long* values, int value ) : wxPGProperty(label,name)
+{
+ SetIndex(0);
+
+ if ( labels )
+ {
+ m_choices.Add(labels,values);
+
+ if ( GetItemCount() )
+ SetValue( (long)value );
+ }
+}
+
+wxEnumProperty::wxEnumProperty( const wxString& label, const wxString& name, const wxChar* const* labels,
+ const long* values, wxPGChoices* choicesCache, int value )
+ : wxPGProperty(label,name)
+{
+ SetIndex(0);
+
+ wxASSERT( choicesCache );
+
+ if ( choicesCache->IsOk() )
+ {
+ m_choices.Assign( *choicesCache );
+ m_value = wxPGVariant_Zero;
+ }
+ else if ( labels )
+ {
+ m_choices.Add(labels,values);
+
+ if ( GetItemCount() )
+ SetValue( (long)value );
+ }
+}
-wxBaseEnumProperty::wxBaseEnumProperty( const wxString& label, const wxString& name )
+wxEnumProperty::wxEnumProperty( const wxString& label, const wxString& name,
+ const wxArrayString& labels, const wxArrayInt& values, int value )
: wxPGProperty(label,name)
{
- m_value = wxPGVariant_Zero;
+ SetIndex(0);
+
+ if ( &labels && labels.size() )
+ {
+ m_choices.Set(labels, values);
+
+ if ( GetItemCount() )
+ SetValue( (long)value );
+ }
}
-/** If has values array, then returns number at index with value -
- otherwise just returns the value.
-*/
-int wxBaseEnumProperty::GetIndexForValue( int value ) const
+wxEnumProperty::wxEnumProperty( const wxString& label, const wxString& name,
+ wxPGChoices& choices, int value )
+ : wxPGProperty(label,name)
{
+ m_choices.Assign( choices );
+
+ if ( GetItemCount() )
+ SetValue( (long)value );
+}
+
+int wxEnumProperty::GetIndexForValue( int value ) const
+{
+ if ( !m_choices.IsOk() )
+ return -1;
+
+ int intVal = m_choices.Index(value);
+ if ( intVal >= 0 )
+ return intVal;
+
return value;
}
-void wxBaseEnumProperty::OnSetValue()
+wxEnumProperty::~wxEnumProperty ()
+{
+}
+
+int wxEnumProperty::ms_nextIndex = -2;
+
+void wxEnumProperty::OnSetValue()
{
wxString variantType = m_value.GetType();
if ( variantType == wxPG_VARIANT_TYPE_LONG )
+ {
ValueFromInt_( m_value, m_value.GetLong(), wxPG_FULL_VALUE );
+ }
else if ( variantType == wxPG_VARIANT_TYPE_STRING )
+ {
ValueFromString_( m_value, m_value.GetString(), 0 );
+ }
else
- wxASSERT( false );
+ {
+ wxFAIL;
+ }
if ( ms_nextIndex != -2 )
{
}
}
-bool wxBaseEnumProperty::ValidateValue( wxVariant& value, wxPGValidationInfo& WXUNUSED(validationInfo) ) const
+bool wxEnumProperty::ValidateValue( wxVariant& value, wxPGValidationInfo& WXUNUSED(validationInfo) ) const
{
// Make sure string value is in the list,
// unless property has string as preferred value type
return true;
}
-wxString wxBaseEnumProperty::GetValueAsString( int ) const
+wxString wxEnumProperty::ValueToString( wxVariant& value,
+ int WXUNUSED(argFlags) ) const
{
- if ( m_value.GetType() == wxPG_VARIANT_TYPE_STRING )
- return m_value.GetString();
+ if ( value.GetType() == wxPG_VARIANT_TYPE_STRING )
+ return value.GetString();
- if ( m_index >= 0 )
- {
- int unusedVal;
- const wxString* pstr = GetEntry( m_index, &unusedVal );
+ int index = m_choices.Index(value.GetLong());
+ if ( index < 0 )
+ return wxEmptyString;
- if ( pstr )
- return *pstr;
- }
- return wxEmptyString;
+ return m_choices.GetLabel(index);
}
-bool wxBaseEnumProperty::StringToValue( wxVariant& variant, const wxString& text, int argFlags ) const
+bool wxEnumProperty::StringToValue( wxVariant& variant, const wxString& text, int argFlags ) const
{
return ValueFromString_( variant, text, argFlags );
}
-bool wxBaseEnumProperty::IntToValue( wxVariant& variant, int intVal, int argFlags ) const
+bool wxEnumProperty::IntToValue( wxVariant& variant, int intVal, int argFlags ) const
{
return ValueFromInt_( variant, intVal, argFlags );
}
-bool wxBaseEnumProperty::ValueFromString_( wxVariant& value, const wxString& text, int argFlags ) const
+bool wxEnumProperty::ValueFromString_( wxVariant& value, const wxString& text, int argFlags ) const
{
- size_t i = 0;
- const wxString* entryLabel;
- int entryValue;
int useIndex = -1;
long useValue = 0;
- entryLabel = GetEntry(i, &entryValue);
- while ( entryLabel )
+ for ( unsigned int i=0; i<m_choices.GetCount(); i++ )
{
- if ( text.CmpNoCase(*entryLabel) == 0 )
+ const wxString& entryLabel = m_choices.GetLabel(i);
+ if ( text.CmpNoCase(entryLabel) == 0 )
{
useIndex = (int)i;
- useValue = (long)entryValue;
+ useValue = m_choices.GetValue(i);
break;
}
-
- i++;
- entryLabel = GetEntry(i, &entryValue);
}
bool asText = false;
// If text not any of the choices, store as text instead
// (but only if we are wxEditEnumProperty)
- if ( useIndex == -1 &&
- (value.GetType() != wxPG_VARIANT_TYPE_STRING || (m_value.GetString() != text)) &&
- isEdit )
+ if ( useIndex == -1 && isEdit )
{
asText = true;
}
setAsNextIndex = -1;
value = text;
}
- else if ( m_index != useIndex )
+ else if ( useIndex != GetIndex() )
{
if ( useIndex != -1 )
{
return false;
}
-bool wxBaseEnumProperty::ValueFromInt_( wxVariant& variant, int intVal, int argFlags ) const
+bool wxEnumProperty::ValueFromInt_( wxVariant& variant, int intVal, int argFlags ) const
{
// If wxPG_FULL_VALUE is *not* in argFlags, then intVal is index from combo box.
//
}
else
{
- if ( m_index != intVal )
+ if ( intVal != GetIndex() )
{
ms_nextIndex = intVal;
}
if ( ms_nextIndex != -2 )
{
if ( !(argFlags & wxPG_FULL_VALUE) )
- GetEntry(intVal, &intVal);
+ intVal = m_choices.GetValue(intVal);
variant = (long)intVal;
return false;
}
-void wxBaseEnumProperty::SetIndex( int index )
-{
- ms_nextIndex = -2;
- m_index = index;
-}
-
-int wxBaseEnumProperty::GetIndex() const
-{
- if ( ms_nextIndex != -2 )
- return ms_nextIndex;
- return m_index;
-}
-
-// -----------------------------------------------------------------------
-// wxEnumProperty
-// -----------------------------------------------------------------------
-
-IMPLEMENT_DYNAMIC_CLASS(wxEnumProperty, wxPGProperty)
-
-WX_PG_IMPLEMENT_PROPERTY_CLASS_PLAIN(wxEnumProperty,long,Choice)
-
-wxEnumProperty::wxEnumProperty( const wxString& label, const wxString& name, const wxChar** labels,
- const long* values, int value ) : wxBaseEnumProperty(label,name)
+void
+wxEnumProperty::OnValidationFailure( wxVariant& WXUNUSED(pendingValue) )
{
- SetIndex(0);
-
- if ( labels )
- {
- m_choices.Add(labels,values);
-
- if ( GetItemCount() )
- SetValue( (long)value );
- }
+ // Revert index
+ ResetNextIndex();
}
-wxEnumProperty::wxEnumProperty( const wxString& label, const wxString& name, const wxChar** labels,
- const long* values, wxPGChoices* choicesCache, int value )
- : wxBaseEnumProperty(label,name)
+void wxEnumProperty::SetIndex( int index )
{
- SetIndex(0);
-
- wxASSERT( choicesCache );
-
- if ( choicesCache->IsOk() )
- {
- m_choices.Assign( *choicesCache );
- m_value = wxPGVariant_Zero;
- }
- else if ( labels )
- {
- m_choices.Add(labels,values);
-
- if ( GetItemCount() )
- SetValue( (long)value );
- }
-}
-
-wxEnumProperty::wxEnumProperty( const wxString& label, const wxString& name,
- const wxArrayString& labels, const wxArrayInt& values, int value ) : wxBaseEnumProperty(label,name)
-{
- SetIndex(0);
-
- if ( &labels && labels.size() )
- {
- m_choices.Set(labels, values);
-
- if ( GetItemCount() )
- SetValue( (long)value );
- }
-}
-
-wxEnumProperty::wxEnumProperty( const wxString& label, const wxString& name,
- wxPGChoices& choices, int value )
- : wxBaseEnumProperty(label,name)
-{
- m_choices.Assign( choices );
-
- if ( GetItemCount() )
- SetValue( (long)value );
+ ms_nextIndex = -2;
+ m_index = index;
}
-int wxEnumProperty::GetIndexForValue( int value ) const
+int wxEnumProperty::GetIndex() const
{
- if ( !m_choices.IsOk() )
+ if ( m_value.IsNull() )
return -1;
- if ( m_choices.HasValues() )
- {
- int intVal = m_choices.Index(value);
- if ( intVal >= 0 )
- return intVal;
- }
-
- return value;
-}
-
-wxEnumProperty::~wxEnumProperty ()
-{
-}
-
-const wxString* wxEnumProperty::GetEntry( size_t index, int* pvalue ) const
-{
- if ( m_choices.IsOk() && index < m_choices.GetCount() )
- {
- int value = (int)index;
- if ( m_choices.HasValue(index) )
- value = m_choices.GetValue(index);
-
- if ( pvalue )
- *pvalue = value;
+ if ( ms_nextIndex != -2 )
+ return ms_nextIndex;
- return &m_choices.GetLabel(index);
- }
- return (const wxString*) NULL;
+ return m_index;
}
// -----------------------------------------------------------------------
WX_PG_IMPLEMENT_PROPERTY_CLASS_PLAIN(wxEditEnumProperty,wxString,ComboBox)
-wxEditEnumProperty::wxEditEnumProperty( const wxString& label, const wxString& name, const wxChar** labels,
+wxEditEnumProperty::wxEditEnumProperty( const wxString& label, const wxString& name, const wxChar* const* labels,
const long* values, const wxString& value )
: wxEnumProperty(label,name,labels,values,0)
{
SetValue( value );
}
-wxEditEnumProperty::wxEditEnumProperty( const wxString& label, const wxString& name, const wxChar** labels,
+wxEditEnumProperty::wxEditEnumProperty( const wxString& label, const wxString& name, const wxChar* const* labels,
const long* values, wxPGChoices* choicesCache, const wxString& value )
: wxEnumProperty(label,name,labels,values,choicesCache,0)
{
void wxFlagsProperty::Init()
{
- SetFlag(wxPG_PROP_AGGREGATE); // This is must be done here to support flag props
- // with inital zero children.
-
long value = m_value;
//
m_children.clear();
+ // Relay wxPG_BOOL_USE_CHECKBOX and wxPG_BOOL_USE_DOUBLE_CLICK_CYCLING
+ // to child bool property controls.
+ long attrUseCheckBox = GetAttributeAsLong(wxPG_BOOL_USE_CHECKBOX, 0);
+ long attrUseDCC = GetAttributeAsLong(wxPG_BOOL_USE_DOUBLE_CLICK_CYCLING,
+ 0);
+
if ( m_choices.IsOk() )
{
const wxPGChoices& choices = m_choices;
for ( i=0; i<GetItemCount(); i++ )
{
bool child_val;
- if ( choices.HasValue(i) )
- child_val = ( value & choices.GetValue(i) )?true:false;
- else
- child_val = ( value & (1<<i) )?true:false;
+ child_val = ( value & choices.GetValue(i) )?true:false;
wxPGProperty* boolProp;
wxString label = GetLabel(i);
{
boolProp = new wxBoolProperty( label, label, child_val );
}
- AddChild(boolProp);
+ if ( attrUseCheckBox )
+ boolProp->SetAttribute(wxPG_BOOL_USE_CHECKBOX,
+ true);
+ if ( attrUseDCC )
+ boolProp->SetAttribute(wxPG_BOOL_USE_DOUBLE_CLICK_CYCLING,
+ true);
+ AddPrivateChild(boolProp);
}
m_oldChoicesData = m_choices.GetDataPtr();
}
wxFlagsProperty::wxFlagsProperty( const wxString& label, const wxString& name,
- const wxChar** labels, const long* values, long value ) : wxPGProperty(label,name)
+ const wxChar* const* labels, const long* values, long value ) : wxPGProperty(label,name)
{
- m_oldChoicesData = (wxPGChoicesData*) NULL;
+ m_oldChoicesData = NULL;
if ( labels )
{
const wxArrayString& labels, const wxArrayInt& values, int value )
: wxPGProperty(label,name)
{
- m_oldChoicesData = (wxPGChoicesData*) NULL;
+ m_oldChoicesData = NULL;
if ( &labels && labels.size() )
{
wxPGChoices& choices, long value )
: wxPGProperty(label,name)
{
- m_oldChoicesData = (wxPGChoicesData*) NULL;
+ m_oldChoicesData = NULL;
if ( choices.IsOk() )
{
const wxPGChoices& choices = m_choices;
for ( i = 0; i < GetItemCount(); i++ )
{
- if ( choices.HasValue(i) )
- fullFlags |= choices.GetValue(i);
- else
- fullFlags |= (1<<i);
+ fullFlags |= choices.GetValue(i);
}
val &= fullFlags;
{
int flag;
- if ( choices.HasValue(i) )
- flag = choices.GetValue(i);
- else
- flag = (1<<i);
+ 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;
}
}
-wxString wxFlagsProperty::GetValueAsString( int ) const
+wxString wxFlagsProperty::ValueToString( wxVariant& value,
+ int WXUNUSED(argFlags) ) const
{
wxString text;
if ( !m_choices.IsOk() )
return text;
- long flags = m_value;
+ long flags = value;
unsigned int i;
const wxPGChoices& choices = m_choices;
for ( i = 0; i < GetItemCount(); i++ )
{
int doAdd;
- if ( choices.HasValue(i) )
- doAdd = ( flags & choices.GetValue(i) );
- else
- doAdd = ( flags & (1<<i) );
+ doAdd = ( flags & choices.GetValue(i) );
if ( doAdd )
{
{
if ( id == GetLabel(i) )
{
- if ( m_choices.HasValue(i) )
- return m_choices.GetValue(i);
- return (1<<i);
+ return m_choices.GetValue(i);
}
}
return -1;
{
long flag;
- if ( choices.HasValue(i) )
- flag = choices.GetValue(i);
- else
- flag = (1<<i);
+ flag = choices.GetValue(i);
long subVal = flags & flag;
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 );
}
m_oldValue = flags;
}
-void wxFlagsProperty::ChildChanged( wxVariant& thisValue, int childIndex, wxVariant& childValue ) const
+wxVariant wxFlagsProperty::ChildChanged( wxVariant& thisValue,
+ int childIndex,
+ wxVariant& childValue ) const
{
long oldValue = thisValue.GetLong();
long val = childValue.GetLong();
- unsigned long vi = (1<<childIndex);
- if ( m_choices.HasValue(childIndex) ) vi = m_choices.GetValue(childIndex);
+ unsigned long vi = m_choices.GetValue(childIndex);
+
if ( val )
- thisValue = (long)(oldValue | vi);
- else
- thisValue = (long)(oldValue & ~(vi));
+ return (long) (oldValue | vi);
+
+ return (long) (oldValue & ~(vi));
+}
+
+bool wxFlagsProperty::DoSetAttribute( const wxString& name, wxVariant& value )
+{
+ if ( name == wxPG_BOOL_USE_CHECKBOX ||
+ name == wxPG_BOOL_USE_DOUBLE_CLICK_CYCLING )
+ {
+ for ( size_t i=0; i<GetChildCount(); i++ )
+ {
+ Item(i)->SetAttribute(name, value);
+ }
+ // Must return false so that the attribute is stored in
+ // flag property's actual property storage
+ return false;
+ }
+ return false;
}
// -----------------------------------------------------------------------
bool wxDirProperty::OnButtonClick( wxPropertyGrid* propGrid, wxString& value )
{
// Update property value from editor, if necessary
- PrepareValueForDialogEditing(propGrid);
-
wxSize dlg_sz(300,400);
+ wxString dlgMessage(m_dlgMessage);
+ if ( dlgMessage.empty() )
+ dlgMessage = _("Choose a directory:");
wxDirDialog dlg( propGrid,
- m_dlgMessage.length() ? m_dlgMessage : wxString(_("Choose a directory:")),
+ dlgMessage,
value,
0,
#if !wxPG_SMALL_SCREEN
propGrid->GetGoodEditorDialogPosition(this,dlg_sz),
- dlg_sz );
+ dlg_sz
#else
wxDefaultPosition,
- wxDefaultSize );
+ wxDefaultSize
#endif
+ );
if ( dlg.ShowModal() == wxID_OK )
{
if ( property->IsKindOf(CLASSINFO(wxFileProperty)) )
{
fileProp = ((wxFileProperty*)property);
- path = fileProp->m_filename.GetPath();
+ wxFileName filename = fileProp->GetValue().GetString();
+ path = filename.GetPath();
indFilter = fileProp->m_indFilter;
if ( !path.length() && fileProp->m_basePath.length() )
wxFileProperty::~wxFileProperty() {}
-#if wxUSE_VALIDATORS
-
wxValidator* wxFileProperty::GetClassValidator()
{
+#if wxUSE_VALIDATORS
WX_PG_DOGETVALIDATOR_ENTRY()
// Atleast wxPython 2.6.2.1 required that the string argument is given
validator->SetExcludes(exChars);
WX_PG_DOGETVALIDATOR_EXIT(validator)
+#else
+ return NULL;
+#endif
}
wxValidator* wxFileProperty::DoGetValidator() const
return GetClassValidator();
}
-#endif
-
void wxFileProperty::OnSetValue()
{
const wxString& fnstr = m_value.GetString();
- m_filename = fnstr;
+ wxFileName filename = fnstr;
- if ( !m_filename.HasName() )
+ if ( !filename.HasName() )
{
m_value = wxPGVariant_EmptyString;
- m_filename.Clear();
}
// Find index for extension.
if ( m_indFilter < 0 && fnstr.length() )
{
- wxString ext = m_filename.GetExt();
+ wxString ext = filename.GetExt();
int curind = 0;
size_t pos = 0;
size_t len = m_wildcard.length();
}
}
-wxString wxFileProperty::GetValueAsString( int argFlags ) const
+wxFileName wxFileProperty::GetFileName() const
+{
+ wxFileName filename;
+
+ if ( !m_value.IsNull() )
+ filename = m_value.GetString();
+
+ return filename;
+}
+
+wxString wxFileProperty::ValueToString( wxVariant& value,
+ int argFlags ) const
{
- // Always return empty string when name component is empty
- wxString fullName = m_filename.GetFullName();
+ wxFileName filename = value.GetString();
+
+ if ( !filename.HasName() )
+ return wxEmptyString;
+
+ wxString fullName = filename.GetFullName();
if ( !fullName.length() )
- return fullName;
+ return wxEmptyString;
if ( argFlags & wxPG_FULL_VALUE )
{
- return m_filename.GetFullPath();
+ return filename.GetFullPath();
}
else if ( m_flags & wxPG_PROP_SHOW_FULL_FILENAME )
{
if ( m_basePath.Length() )
{
- wxFileName fn2(m_filename);
+ wxFileName fn2(filename);
fn2.MakeRelativeTo(m_basePath);
return fn2.GetFullPath();
}
- return m_filename.GetFullPath();
+ return filename.GetFullPath();
}
- return m_filename.GetFullName();
+ return filename.GetFullName();
}
wxPGEditorDialogAdapter* wxFileProperty::GetEditorDialog() const
bool wxFileProperty::StringToValue( wxVariant& variant, const wxString& text, int argFlags ) const
{
+ wxFileName filename = variant.GetString();
+
if ( (m_flags & wxPG_PROP_SHOW_FULL_FILENAME) || (argFlags & wxPG_FULL_VALUE) )
{
- if ( m_filename != text )
+ if ( filename != text )
{
variant = text;
return true;
}
else
{
- if ( m_filename.GetFullName() != text )
+ if ( filename.GetFullName() != text )
{
- wxFileName fn = m_filename;
+ wxFileName fn = filename;
fn.SetFullName(text);
variant = fn.GetFullPath();
return true;
// stored in m_attributes.
if ( name == wxPG_FILE_SHOW_FULL_PATH )
{
- if ( wxPGVariantToInt(value) )
+ if ( value.GetLong() )
m_flags |= wxPG_PROP_SHOW_FULL_FILENAME;
else
m_flags &= ~(wxPG_PROP_SHOW_FULL_FILENAME);
wxLongStringProperty::~wxLongStringProperty() {}
-wxString wxLongStringProperty::GetValueAsString( int ) const
+wxString wxLongStringProperty::ValueToString( wxVariant& value,
+ int WXUNUSED(argFlags) ) const
{
- return m_value;
+ return value;
}
bool wxLongStringProperty::OnEvent( wxPropertyGrid* propGrid, wxWindow* WXUNUSED(primary),
if ( propGrid->IsMainButtonEvent(event) )
{
// Update the value
- PrepareValueForDialogEditing(propGrid);
+ wxVariant useValue = propGrid->GetUncommittedPropertyValue();
- wxString val1 = GetValueAsString(0);
+ wxString val1 = useValue.GetString();
wxString val_orig = val1;
wxString value;
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 );
+
+ wxStdDialogButtonSizer* buttonSizer = new wxStdDialogButtonSizer();
+ buttonSizer->AddButton(new wxButton(dlg, wxID_OK));
+ buttonSizer->AddButton(new wxButton(dlg, wxID_CANCEL));
+ buttonSizer->Realize();
+ topsizer->Add( buttonSizer, 0,
+ wxALIGN_RIGHT|wxALIGN_CENTRE_VERTICAL|wxBOTTOM|wxRIGHT,
+ spacing );
dlg->SetSizer( topsizer );
topsizer->SetSizeHints( dlg );
return false;
}
+#if wxUSE_EDITABLELISTBOX
+
// -----------------------------------------------------------------------
-// wxArrayEditorDialog
+// wxPGArrayEditorDialog
// -----------------------------------------------------------------------
-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)
+BEGIN_EVENT_TABLE(wxPGArrayEditorDialog, wxDialog)
+ EVT_IDLE(wxPGArrayEditorDialog::OnIdle)
END_EVENT_TABLE()
-IMPLEMENT_ABSTRACT_CLASS(wxArrayEditorDialog, wxDialog)
+IMPLEMENT_ABSTRACT_CLASS(wxPGArrayEditorDialog, wxDialog)
-#include "wx/statline.h"
+#include "wx/editlbox.h"
+#include "wx/listctrl.h"
// -----------------------------------------------------------------------
-void wxArrayEditorDialog::OnIdle(wxIdleEvent& event)
+void wxPGArrayEditorDialog::OnIdle(wxIdleEvent& event)
{
- //
- // Do control focus detection here.
- //
+ // Repair focus - wxEditableListBox has bitmap buttons, which
+ // get focus, and lose focus (into the oblivion) when they
+ // become disabled due to change in control state.
- wxWindow* focused = FindFocus();
+ wxWindow* lastFocused = m_lastFocused;
+ wxWindow* focus = ::wxWindow::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 )
- {
- // 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*/ )
+ // If last focused control became disabled, set focus back to
+ // wxEditableListBox
+ if ( lastFocused && focus != lastFocused &&
+ lastFocused->GetParent() == m_elbSubPanel &&
+ !lastFocused->IsEnabled() )
{
- // 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;
+ m_elb->GetListCtrl()->SetFocus();
}
+ m_lastFocused = focus;
+
event.Skip();
}
// -----------------------------------------------------------------------
-wxArrayEditorDialog::wxArrayEditorDialog()
+wxPGArrayEditorDialog::wxPGArrayEditorDialog()
: wxDialog()
{
Init();
// -----------------------------------------------------------------------
-void wxArrayEditorDialog::Init()
+void wxPGArrayEditorDialog::Init()
{
- m_custBtText = (const wxChar*) NULL;
+ m_lastFocused = NULL;
+ m_hasCustomNewAction = false;
+ m_itemPendingAtIndex = -1;
}
// -----------------------------------------------------------------------
-wxArrayEditorDialog::wxArrayEditorDialog( wxWindow *parent,
+wxPGArrayEditorDialog::wxPGArrayEditorDialog( wxWindow *parent,
const wxString& message,
const wxString& caption,
long style,
// -----------------------------------------------------------------------
-bool wxArrayEditorDialog::Create( wxWindow *parent,
+bool wxPGArrayEditorDialog::Create( wxWindow *parent,
const wxString& message,
const wxString& caption,
long style,
// On wxMAC the dialog shows incorrectly if style is not exactly wxCAPTION
// FIXME: This should be only a temporary fix.
#ifdef __WXMAC__
+ wxUnusedVar(style);
int useStyle = wxCAPTION;
#else
int useStyle = style;
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
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 );
+ m_elb = new wxEditableListBox(this, wxID_ANY, message,
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxEL_ALLOW_NEW |
+ wxEL_ALLOW_EDIT |
+ wxEL_ALLOW_DELETE);
- 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();
+ // Populate the list box
+ wxArrayString arr;
+ for ( unsigned int i=0; i<ArrayGetCount(); i++ )
+ arr.push_back(ArrayGet(i));
+ m_elb->SetStrings(arr);
+
+ // Connect event handlers
+ wxButton* but;
+ wxListCtrl* lc = m_elb->GetListCtrl();
+
+ but = m_elb->GetNewButton();
+ m_elbSubPanel = but->GetParent();
+ but->Connect(but->GetId(), wxEVT_COMMAND_BUTTON_CLICKED,
+ wxCommandEventHandler(wxPGArrayEditorDialog::OnAddClick),
+ NULL, this);
+
+ but = m_elb->GetDelButton();
+ but->Connect(but->GetId(), wxEVT_COMMAND_BUTTON_CLICKED,
+ wxCommandEventHandler(wxPGArrayEditorDialog::OnDeleteClick),
+ NULL, this);
+
+ but = m_elb->GetUpButton();
+ but->Connect(but->GetId(), wxEVT_COMMAND_BUTTON_CLICKED,
+ wxCommandEventHandler(wxPGArrayEditorDialog::OnUpClick),
+ NULL, this);
+
+ but = m_elb->GetDownButton();
+ but->Connect(but->GetId(), wxEVT_COMMAND_BUTTON_CLICKED,
+ wxCommandEventHandler(wxPGArrayEditorDialog::OnDownClick),
+ NULL, this);
+
+ lc->Connect(lc->GetId(), wxEVT_COMMAND_LIST_END_LABEL_EDIT,
+ wxListEventHandler(wxPGArrayEditorDialog::OnEndLabelEdit),
+ NULL, this);
+
+ topsizer->Add( m_elb, 1, wxEXPAND, spacing );
+
+ // Standard dialog buttons
+ wxStdDialogButtonSizer* buttonSizer = new wxStdDialogButtonSizer();
+ buttonSizer->AddButton(new wxButton(this, wxID_OK));
+ buttonSizer->AddButton(new wxButton(this, wxID_CANCEL));
+ buttonSizer->Realize();
+ topsizer->Add( buttonSizer, 0,
+ wxALIGN_RIGHT|wxALIGN_CENTRE_VERTICAL|wxALL,
+ spacing );
+
+ m_elb->SetFocus();
SetSizer( topsizer );
topsizer->SetSizeHints( this );
// -----------------------------------------------------------------------
-void wxArrayEditorDialog::OnAddClick(wxCommandEvent& )
+int wxPGArrayEditorDialog::GetSelection() const
+{
+ wxListCtrl* lc = m_elb->GetListCtrl();
+
+ int index = lc->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
+ if ( index == -1 )
+ return wxNOT_FOUND;
+
+ return index;
+}
+
+// -----------------------------------------------------------------------
+
+void wxPGArrayEditorDialog::OnAddClick(wxCommandEvent& event)
{
- wxString text = m_edValue->GetValue();
- if ( text.length() )
+ wxListCtrl* lc = m_elb->GetListCtrl();
+ int newItemIndex = lc->GetItemCount() - 1;
+
+ if ( m_hasCustomNewAction )
{
- if ( ArrayInsert( text, -1 ) )
+ wxString str;
+ if ( OnCustomNewAction(&str) )
{
- m_lbStrings->Append( text );
- m_modified = true;
- m_edValue->Clear();
+ if ( ArrayInsert(str, newItemIndex) )
+ {
+ lc->InsertItem(newItemIndex, str);
+ m_modified = true;
+ }
}
+
+ // Do *not* skip the event! We do not want the wxEditableListBox
+ // to do anything.
+ }
+ else
+ {
+ m_itemPendingAtIndex = newItemIndex;
+
+ event.Skip();
}
}
// -----------------------------------------------------------------------
-void wxArrayEditorDialog::OnDeleteClick(wxCommandEvent& )
+void wxPGArrayEditorDialog::OnDeleteClick(wxCommandEvent& event)
{
- int index = m_lbStrings->GetSelection();
+ int index = GetSelection();
if ( index >= 0 )
{
ArrayRemoveAt( index );
- m_lbStrings->Delete ( index );
m_modified = true;
}
+
+ event.Skip();
}
// -----------------------------------------------------------------------
-void wxArrayEditorDialog::OnUpClick(wxCommandEvent& )
+void wxPGArrayEditorDialog::OnUpClick(wxCommandEvent& event)
{
- int index = m_lbStrings->GetSelection();
+ int index = 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;
}
+
+ event.Skip();
}
// -----------------------------------------------------------------------
-void wxArrayEditorDialog::OnDownClick(wxCommandEvent& )
+void wxPGArrayEditorDialog::OnDownClick(wxCommandEvent& event)
{
- int index = m_lbStrings->GetSelection();
- int lastStringIndex = ((int) m_lbStrings->GetCount()) - 1;
+ wxListCtrl* lc = m_elb->GetListCtrl();
+ int index = GetSelection();
+ int lastStringIndex = lc->GetItemCount() - 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 );
+ ArraySwap(index, index+1);
m_modified = true;
}
+
+ event.Skip();
}
// -----------------------------------------------------------------------
-void wxArrayEditorDialog::OnUpdateClick(wxCommandEvent& )
+void wxPGArrayEditorDialog::OnEndLabelEdit(wxListEvent& event)
{
- int index = m_lbStrings->GetSelection();
- if ( index >= 0 )
+ wxString str = event.GetLabel();
+
+ if ( m_itemPendingAtIndex >= 0 )
{
- wxString str = m_edValue->GetValue();
- if ( ArraySet(index,str) )
+ // Add a new item
+ if ( ArrayInsert(str, m_itemPendingAtIndex) )
{
- m_lbStrings->SetString ( index, str );
- //m_array[index] = str;
m_modified = true;
}
+ else
+ {
+ // Editable list box doesn't really respect Veto(), but
+ // it recognizes if no text was added, so we simulate
+ // Veto() using it.
+ event.m_item.SetText(wxEmptyString);
+ m_elb->GetListCtrl()->SetItemText(m_itemPendingAtIndex,
+ wxEmptyString);
+
+ event.Veto();
+ }
}
-}
-
-// -----------------------------------------------------------------------
-
-void wxArrayEditorDialog::OnListBoxClick(wxCommandEvent& )
-{
- int index = m_lbStrings->GetSelection();
- if ( index >= 0 )
+ else
{
- m_edValue->SetValue( m_lbStrings->GetString(index) );
+ // Change an existing item
+ int index = GetSelection();
+ wxASSERT( index != wxNOT_FOUND );
+ if ( ArraySet(index, str) )
+ m_modified = true;
+ else
+ event.Veto();
}
+
+ event.Skip();
}
+#endif // wxUSE_EDITABLELISTBOX
+
// -----------------------------------------------------------------------
// wxPGArrayStringEditorDialog
// -----------------------------------------------------------------------
-IMPLEMENT_DYNAMIC_CLASS(wxPGArrayStringEditorDialog, wxArrayEditorDialog)
+IMPLEMENT_DYNAMIC_CLASS(wxPGArrayStringEditorDialog, wxPGArrayEditorDialog)
-BEGIN_EVENT_TABLE(wxPGArrayStringEditorDialog, wxArrayEditorDialog)
- EVT_BUTTON(28, wxPGArrayStringEditorDialog::OnCustomEditClick)
+BEGIN_EVENT_TABLE(wxPGArrayStringEditorDialog, wxPGArrayEditorDialog)
END_EVENT_TABLE()
// -----------------------------------------------------------------------
}
wxPGArrayStringEditorDialog::wxPGArrayStringEditorDialog()
- : wxArrayEditorDialog()
+ : wxPGArrayEditorDialog()
{
Init();
}
void wxPGArrayStringEditorDialog::Init()
{
- m_pCallingClass = (wxArrayStringProperty*) NULL;
+ m_pCallingClass = NULL;
}
-void wxPGArrayStringEditorDialog::OnCustomEditClick(wxCommandEvent& )
+bool
+wxPGArrayStringEditorDialog::OnCustomNewAction(wxString* resString)
{
- 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;
- }
+ return m_pCallingClass->OnCustomStringEdit(m_parent, *resString);
}
// -----------------------------------------------------------------------
const wxArrayString& array )
: wxPGProperty(label,name)
{
+ m_delimiter = ',';
SetValue( array );
}
GenerateValueAsString();
}
-wxString wxArrayStringProperty::GetValueAsString( int WXUNUSED(argFlags) ) const
+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
{
- return m_display;
+ //
+ // If this is called from GetValueAsString(), return cached string
+ if ( argFlags & wxPG_VALUE_IS_CURRENT )
+ {
+ return m_display;
+ }
+
+ wxArrayString arr = m_value.GetArrayString();
+ wxString s;
+ 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];
-
dst.Empty();
- if ( !preDelim )
- preas[0] = 0;
- else if ( (flags & 1) )
+ if ( flags & Escape )
{
- preas[0] = preDelim;
- preas[1] = 0;
- pdr = wxS("\\");
- pdr += preDelim;
+ preas = delimiter;
+ pdr = wxS("\\") + static_cast<wchar_t>(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 <preDelim> to \<preDelim>
- // 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 ( 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 );
}
}
-#define ARRSTRPROP_ARRAY_TO_STRING(STRING,ARRAY) \
- wxPropertyGrid::ArrayStringToString(STRING,ARRAY,wxS('"'),wxS('"'),1);
-
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.
return false;
}
-wxArrayEditorDialog* wxArrayStringProperty::CreateEditorDialog()
+wxPGArrayEditorDialog* wxArrayStringProperty::CreateEditorDialog()
{
return new wxPGArrayStringEditorDialog();
}
const wxChar* cbt )
{
// Update the value
- PrepareValueForDialogEditing(propGrid);
+ wxVariant useValue = propGrid->GetUncommittedPropertyValue();
if ( !propGrid->EditorValidate() )
return false;
// Create editor dialog.
- wxArrayEditorDialog* dlg = CreateEditorDialog();
+ wxPGArrayEditorDialog* dlg = CreateEditorDialog();
#if wxUSE_VALIDATORS
wxValidator* validator = GetValidator();
wxPGInDialogValidator dialogValidator;
if ( strEdDlg )
strEdDlg->SetCustomButton(cbt, this);
- dlg->SetDialogValue( wxVariant(m_value) );
+ dlg->SetDialogValue( useValue );
dlg->Create(propGrid, wxEmptyString, m_label);
#if !wxPG_SMALL_SCREEN
{
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 );
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("\\"), wxEmptyString, 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
// -----------------------------------------------------------------------