667 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			667 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /////////////////////////////////////////////////////////////////////////////
 | |
| // Name:        samples/propgrid/sampleprops.cpp
 | |
| // Purpose:     wxPropertyGrid Sample Properties
 | |
| // Author:      Jaakko Salli
 | |
| // Modified by:
 | |
| // Created:     2006-03-05
 | |
| // Copyright:   (c) Jaakko Salli
 | |
| // Licence:     wxWindows licence
 | |
| /////////////////////////////////////////////////////////////////////////////
 | |
| 
 | |
| // For compilers that support precompilation, includes "wx/wx.h".
 | |
| #include "wx/wxprec.h"
 | |
| 
 | |
| 
 | |
| // for all others, include the necessary headers (this file is usually all you
 | |
| // need because it includes almost all "standard" wxWidgets headers)
 | |
| #ifndef WX_PRECOMP
 | |
|     #include "wx/wx.h"
 | |
| #endif
 | |
| 
 | |
| #include "wx/fontdlg.h"
 | |
| #include "wx/numformatter.h"
 | |
| 
 | |
| // -----------------------------------------------------------------------
 | |
| 
 | |
| 
 | |
| #include "wx/propgrid/propgrid.h"
 | |
| #include "wx/propgrid/advprops.h"
 | |
| 
 | |
| #ifndef WX_PROPGRID_SAMPLEPROPS_H
 | |
|     #include "sampleprops.h"
 | |
| #endif
 | |
| 
 | |
| 
 | |
| // -----------------------------------------------------------------------
 | |
| // wxFontDataProperty
 | |
| // -----------------------------------------------------------------------
 | |
| 
 | |
| // Dummy comparison required by value type implementation.
 | |
| bool operator == (const wxFontData&, const wxFontData&)
 | |
| {
 | |
|     return false;
 | |
| }
 | |
| 
 | |
| template<> inline wxVariant WXVARIANT(const wxFontData& value)
 | |
| {
 | |
|     wxVariant variant;
 | |
|     variant << value;
 | |
|     return variant;
 | |
| }
 | |
| 
 | |
| // Custom version of wxFontProperty that also holds colour in the value.
 | |
| // Original version by Vladimir Vainer.
 | |
| 
 | |
| IMPLEMENT_VARIANT_OBJECT_SHALLOWCMP(wxFontData)
 | |
| 
 | |
| wxPG_IMPLEMENT_PROPERTY_CLASS(wxFontDataProperty,wxFontProperty,TextCtrlAndButton)
 | |
| 
 | |
| wxFontDataProperty::wxFontDataProperty( const wxString& label, const wxString& name,
 | |
|    const wxFontData& value ) : wxFontProperty(label,name,value.GetInitialFont())
 | |
| {
 | |
|     wxFontData fontData(value);
 | |
| 
 | |
|     // Fix value.
 | |
|     wxFont font;
 | |
|     font << m_value;  // Get font data from base object.
 | |
|     fontData.SetChosenFont(font);
 | |
|     if ( !fontData.GetColour().IsOk() )
 | |
|         fontData.SetColour(*wxBLACK);
 | |
| 
 | |
|     // Set initial value - should be done in a simpler way like this
 | |
|     // (instead of calling SetValue) in derived (wxObject) properties.
 | |
|     m_value_wxFontData = WXVARIANT(fontData);
 | |
| 
 | |
|     // Add extra children.
 | |
|     AddPrivateChild( new wxColourProperty("Colour", wxPG_LABEL,
 | |
|                                           fontData.GetColour() ) );
 | |
| }
 | |
| 
 | |
| wxFontDataProperty::~wxFontDataProperty () { }
 | |
| 
 | |
| void wxFontDataProperty::OnSetValue()
 | |
| {
 | |
|     if ( !m_value.IsType("wxFontData") )
 | |
|     {
 | |
|         if ( m_value.IsType("wxFont") )
 | |
|         {
 | |
|             wxFont font;
 | |
|             font << m_value;
 | |
|             wxFontData fontData;
 | |
|             fontData.SetChosenFont(font);
 | |
|             if ( !m_value_wxFontData.IsNull() )
 | |
|             {
 | |
|                 wxFontData oldFontData;
 | |
|                 oldFontData << m_value_wxFontData;
 | |
|                 fontData.SetColour(oldFontData.GetColour());
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 fontData.SetColour(*wxBLACK);
 | |
|             }
 | |
|             m_value_wxFontData = WXVARIANT(fontData);
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             wxFAIL_MSG("Value to wxFontDataProperty must be either wxFontData or wxFont");
 | |
|         }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         // Set m_value to wxFont so that wxFontProperty methods will work
 | |
|         // correctly.
 | |
|         m_value_wxFontData = m_value;
 | |
| 
 | |
|         wxFontData fontData;
 | |
|         fontData << m_value_wxFontData;
 | |
| 
 | |
|         wxFont font = fontData.GetChosenFont();
 | |
|         if ( !font.IsOk() )
 | |
|             font = wxFontInfo(10).Family(wxFONTFAMILY_SWISS);
 | |
| 
 | |
|         m_value = WXVARIANT(font);
 | |
|     }
 | |
| }
 | |
| 
 | |
| wxVariant wxFontDataProperty::DoGetValue() const
 | |
| {
 | |
|     return m_value_wxFontData;
 | |
| }
 | |
| 
 | |
| bool wxFontDataProperty::DisplayEditorDialog(wxPropertyGrid* pg, wxVariant& value)
 | |
| {
 | |
|     wxASSERT_MSG(value.IsType(wxS("wxFontData")), "Function called for incompatible property");
 | |
| 
 | |
|     wxFontData fontData;
 | |
|     fontData << value;
 | |
| 
 | |
|     fontData.SetInitialFont(fontData.GetChosenFont());
 | |
| 
 | |
|     wxFontDialog dlg(pg->GetPanel(), fontData);
 | |
|     if ( !m_dlgTitle.empty() )
 | |
|     {
 | |
|         dlg.SetTitle(m_dlgTitle);
 | |
|     }
 | |
| 
 | |
|     if ( dlg.ShowModal() == wxID_OK )
 | |
|     {
 | |
|         value = WXVARIANT(dlg.GetFontData());
 | |
|         return true;
 | |
|     }
 | |
|     return false;
 | |
| }
 | |
| 
 | |
| void wxFontDataProperty::RefreshChildren()
 | |
| {
 | |
|     wxFontProperty::RefreshChildren();
 | |
|     if ( GetChildCount() < 6 ) // Number is count of wxFontProperty's children + 1.
 | |
|         return;
 | |
|     wxFontData fontData; fontData << m_value_wxFontData;
 | |
|     wxVariant variant = WXVARIANT(fontData.GetColour());
 | |
|     Item(6)->SetValue( variant );
 | |
| }
 | |
| 
 | |
| wxVariant wxFontDataProperty::ChildChanged( wxVariant& thisValue,
 | |
|                                             int childIndex,
 | |
|                                             wxVariant& childValue ) const
 | |
| {
 | |
|     wxFontData fontData;
 | |
|     fontData << thisValue;
 | |
|     wxColour col;
 | |
|     wxVariant variant;
 | |
| 
 | |
|     switch ( childIndex )
 | |
|     {
 | |
|         case 6:
 | |
|             col << childValue;
 | |
|             fontData.SetColour( col );
 | |
|             break;
 | |
|         default:
 | |
|             // Transfer from subset to superset.
 | |
|             wxFont font = fontData.GetChosenFont();
 | |
|             variant = WXVARIANT(font);
 | |
|             variant = wxFontProperty::ChildChanged( variant, childIndex, childValue );
 | |
|             font << variant;
 | |
|             fontData.SetChosenFont(font);
 | |
|     }
 | |
| 
 | |
|     wxVariant newVariant = WXVARIANT(fontData);
 | |
|     return newVariant;
 | |
| }
 | |
| 
 | |
| // -----------------------------------------------------------------------
 | |
| // wxSizeProperty
 | |
| // -----------------------------------------------------------------------
 | |
| 
 | |
| wxPG_IMPLEMENT_PROPERTY_CLASS(wxSizeProperty,wxPGProperty,TextCtrl)
 | |
| 
 | |
| wxSizeProperty::wxSizeProperty( const wxString& label, const wxString& name,
 | |
|     const wxSize& value) : wxPGProperty(label,name)
 | |
| {
 | |
|     SetValueI(value);
 | |
|     AddPrivateChild( new wxIntProperty("Width",wxPG_LABEL,value.x) );
 | |
|     AddPrivateChild( new wxIntProperty("Height",wxPG_LABEL,value.y) );
 | |
| }
 | |
| 
 | |
| wxSizeProperty::~wxSizeProperty() { }
 | |
| 
 | |
| void wxSizeProperty::RefreshChildren()
 | |
| {
 | |
|     if ( !GetChildCount() ) return;
 | |
|     const wxSize& size = wxSizeRefFromVariant(m_value);
 | |
|     Item(0)->SetValue( (long)size.x );
 | |
|     Item(1)->SetValue( (long)size.y );
 | |
| }
 | |
| 
 | |
| wxVariant wxSizeProperty::ChildChanged( wxVariant& thisValue,
 | |
|                                         int childIndex,
 | |
|                                         wxVariant& childValue ) const
 | |
| {
 | |
|     wxSize& size = wxSizeRefFromVariant(thisValue);
 | |
|     int val = childValue.GetLong();
 | |
|     switch ( childIndex )
 | |
|     {
 | |
|         case 0: size.x = val; break;
 | |
|         case 1: size.y = val; break;
 | |
|     }
 | |
|     wxVariant newVariant;
 | |
|     newVariant << size;
 | |
|     return newVariant;
 | |
| }
 | |
| 
 | |
| // -----------------------------------------------------------------------
 | |
| // wxPointProperty
 | |
| // -----------------------------------------------------------------------
 | |
| 
 | |
| wxPG_IMPLEMENT_PROPERTY_CLASS(wxPointProperty,wxPGProperty,TextCtrl)
 | |
| 
 | |
| wxPointProperty::wxPointProperty( const wxString& label, const wxString& name,
 | |
|     const wxPoint& value) : wxPGProperty(label,name)
 | |
| {
 | |
|     SetValueI(value);
 | |
|     AddPrivateChild( new wxIntProperty("X",wxPG_LABEL,value.x) );
 | |
|     AddPrivateChild( new wxIntProperty("Y",wxPG_LABEL,value.y) );
 | |
| }
 | |
| 
 | |
| wxPointProperty::~wxPointProperty() { }
 | |
| 
 | |
| void wxPointProperty::RefreshChildren()
 | |
| {
 | |
|     if ( !GetChildCount() ) return;
 | |
|     const wxPoint& point = wxPointRefFromVariant(m_value);
 | |
|     Item(0)->SetValue( (long)point.x );
 | |
|     Item(1)->SetValue( (long)point.y );
 | |
| }
 | |
| 
 | |
| wxVariant wxPointProperty::ChildChanged( wxVariant& thisValue,
 | |
|                                          int childIndex,
 | |
|                                          wxVariant& childValue ) const
 | |
| {
 | |
|     wxPoint& point = wxPointRefFromVariant(thisValue);
 | |
|     int val = childValue.GetLong();
 | |
|     switch ( childIndex )
 | |
|     {
 | |
|         case 0: point.x = val; break;
 | |
|         case 1: point.y = val; break;
 | |
|     }
 | |
|     wxVariant newVariant;
 | |
|     newVariant << point;
 | |
|     return newVariant;
 | |
| }
 | |
| 
 | |
| 
 | |
| // -----------------------------------------------------------------------
 | |
| // Dirs Property
 | |
| // -----------------------------------------------------------------------
 | |
| 
 | |
| WX_PG_IMPLEMENT_ARRAYSTRING_PROPERTY_WITH_VALIDATOR(wxDirsProperty, ',', "Browse")
 | |
| 
 | |
| #if wxUSE_VALIDATORS
 | |
| 
 | |
| wxValidator* wxDirsProperty::DoGetValidator() const
 | |
| {
 | |
|     return wxFileProperty::GetClassValidator();
 | |
| }
 | |
| 
 | |
| #endif
 | |
| 
 | |
| 
 | |
| bool wxDirsProperty::OnCustomStringEdit( wxWindow* parent, wxString& value )
 | |
| {
 | |
|     wxDirDialog dlg(parent,
 | |
|                     "Select a directory to be added to the list:",
 | |
|                     value,
 | |
|                     0);
 | |
| 
 | |
|     if ( dlg.ShowModal() == wxID_OK )
 | |
|     {
 | |
|         value = dlg.GetPath();
 | |
|         return true;
 | |
|     }
 | |
|     return false;
 | |
| }
 | |
| 
 | |
| // -----------------------------------------------------------------------
 | |
| // wxArrayDoubleEditorDialog
 | |
| // -----------------------------------------------------------------------
 | |
| 
 | |
| 
 | |
| //
 | |
| // You can *almost* convert wxArrayDoubleEditorDialog to wxArrayXXXEditorDialog
 | |
| // by replacing each ArrayDouble with ArrayXXX.
 | |
| //
 | |
| 
 | |
| class wxArrayDoubleEditorDialog : public wxPGArrayEditorDialog
 | |
| {
 | |
| public:
 | |
|     wxArrayDoubleEditorDialog();
 | |
| 
 | |
|     void Init();
 | |
| 
 | |
|     wxArrayDoubleEditorDialog(wxWindow *parent,
 | |
|                               const wxString& message,
 | |
|                               const wxString& caption,
 | |
|                               wxArrayDouble& array,
 | |
|                               long style = wxAEDIALOG_STYLE,
 | |
|                               const wxPoint& pos = wxDefaultPosition,
 | |
|                               const wxSize& sz = wxDefaultSize );
 | |
| 
 | |
|     bool Create(wxWindow *parent,
 | |
|                 const wxString& message,
 | |
|                 const wxString& caption,
 | |
|                 wxArrayDouble& array,
 | |
|                 long style = wxAEDIALOG_STYLE,
 | |
|                 const wxPoint& pos = wxDefaultPosition,
 | |
|                 const wxSize& sz = wxDefaultSize );
 | |
| 
 | |
|     const wxArrayDouble& GetArray() const { return m_array; }
 | |
| 
 | |
|     // Extra method for this type of array
 | |
|     void SetPrecision ( int precision )
 | |
|     {
 | |
|         m_precision = precision;
 | |
|     }
 | |
| 
 | |
| protected:
 | |
|     // Mandatory array of type
 | |
|     wxArrayDouble   m_array;
 | |
| 
 | |
|     int             m_precision;
 | |
| 
 | |
|     // Mandatory overridden methods
 | |
|     virtual wxString ArrayGet( size_t index ) wxOVERRIDE;
 | |
|     virtual size_t ArrayGetCount() wxOVERRIDE;
 | |
|     virtual bool ArrayInsert( const wxString& str, int index ) wxOVERRIDE;
 | |
|     virtual bool ArraySet( size_t index, const wxString& str ) wxOVERRIDE;
 | |
|     virtual void ArrayRemoveAt( int index ) wxOVERRIDE;
 | |
|     virtual void ArraySwap( size_t first, size_t second ) wxOVERRIDE;
 | |
| 
 | |
| private:
 | |
|     wxDECLARE_DYNAMIC_CLASS_NO_COPY(wxArrayDoubleEditorDialog);
 | |
| };
 | |
| 
 | |
| wxIMPLEMENT_DYNAMIC_CLASS(wxArrayDoubleEditorDialog, wxPGArrayEditorDialog);
 | |
| 
 | |
| //
 | |
| // Array dialog array access and manipulation
 | |
| //
 | |
| 
 | |
| wxString wxArrayDoubleEditorDialog::ArrayGet( size_t index )
 | |
| {
 | |
|     return wxNumberFormatter::ToString(
 | |
|         m_array[index], m_precision, wxNumberFormatter::Style_NoTrailingZeroes);
 | |
| }
 | |
| 
 | |
| size_t wxArrayDoubleEditorDialog::ArrayGetCount()
 | |
| {
 | |
|     return m_array.GetCount();
 | |
| }
 | |
| 
 | |
| bool wxArrayDoubleEditorDialog::ArrayInsert( const wxString& str, int index )
 | |
| {
 | |
|     double d;
 | |
|     if ( !str.ToDouble(&d) )
 | |
|         return false;
 | |
| 
 | |
|     if (index<0)
 | |
|         m_array.Add(d);
 | |
|     else
 | |
|         m_array.Insert(d,index);
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| bool wxArrayDoubleEditorDialog::ArraySet( size_t index, const wxString& str )
 | |
| {
 | |
|     double d;
 | |
|     if ( !str.ToDouble(&d) )
 | |
|         return false;
 | |
|     m_array[index] = d;
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| void wxArrayDoubleEditorDialog::ArrayRemoveAt( int index )
 | |
| {
 | |
|     m_array.RemoveAt(index);
 | |
| }
 | |
| 
 | |
| void wxArrayDoubleEditorDialog::ArraySwap( size_t first, size_t second )
 | |
| {
 | |
|     wxSwap(m_array[first], m_array[second]);
 | |
| }
 | |
| 
 | |
| //
 | |
| // Array dialog construction etc.
 | |
| //
 | |
| 
 | |
| wxArrayDoubleEditorDialog::wxArrayDoubleEditorDialog()
 | |
|     : wxPGArrayEditorDialog()
 | |
| {
 | |
|     Init();
 | |
| }
 | |
| 
 | |
| void wxArrayDoubleEditorDialog::Init()
 | |
| {
 | |
|     wxPGArrayEditorDialog::Init();
 | |
|     SetPrecision(-1);
 | |
| }
 | |
| 
 | |
| wxArrayDoubleEditorDialog::wxArrayDoubleEditorDialog(wxWindow *parent,
 | |
|                               const wxString& message,
 | |
|                               const wxString& caption,
 | |
|                               wxArrayDouble& array,
 | |
|                               long style,
 | |
|                               const wxPoint& pos,
 | |
|                               const wxSize& sz )
 | |
|                               : wxPGArrayEditorDialog()
 | |
| {
 | |
|     Init();
 | |
|     Create(parent,message,caption,array,style,pos,sz);
 | |
| }
 | |
| 
 | |
| bool wxArrayDoubleEditorDialog::Create(wxWindow *parent,
 | |
|                 const wxString& message,
 | |
|                 const wxString& caption,
 | |
|                 wxArrayDouble& array,
 | |
|                 long style,
 | |
|                 const wxPoint& pos,
 | |
|                 const wxSize& sz )
 | |
| {
 | |
| 
 | |
|     m_array = array;
 | |
| 
 | |
|     return wxPGArrayEditorDialog::Create (parent,message,caption,style,pos,sz);
 | |
| }
 | |
| 
 | |
| // -----------------------------------------------------------------------
 | |
| // wxArrayDoubleProperty
 | |
| // -----------------------------------------------------------------------
 | |
| 
 | |
| #include <math.h> // for fabs
 | |
| 
 | |
| // Comparison required by value type implementation.
 | |
| bool operator == (const wxArrayDouble& a, const wxArrayDouble& b)
 | |
| {
 | |
|     if ( a.GetCount() != b.GetCount() )
 | |
|         return false;
 | |
| 
 | |
|     size_t i;
 | |
| 
 | |
|     for ( i=0; i<a.GetCount(); i++ )
 | |
|     {
 | |
|         // Can't do direct equality comparison with floating point numbers.
 | |
|         if ( fabs(a[i] - b[i]) > 0.0000000001 )
 | |
|         {
 | |
|             //wxLogDebug("%f != %f",a[i],b[i]);
 | |
|             return false;
 | |
|         }
 | |
|     }
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| WX_PG_IMPLEMENT_VARIANT_DATA_DUMMY_EQ(wxArrayDouble)
 | |
| 
 | |
| wxPG_IMPLEMENT_PROPERTY_CLASS(wxArrayDoubleProperty,
 | |
|                               wxEditorDialogProperty,
 | |
|                               TextCtrlAndButton)
 | |
| 
 | |
| 
 | |
| wxArrayDoubleProperty::wxArrayDoubleProperty (const wxString& label,
 | |
|                                                         const wxString& name,
 | |
|                                                         const wxArrayDouble& array )
 | |
|     : wxEditorDialogProperty(label,name)
 | |
|     , m_precision(-1)
 | |
| {
 | |
|     m_dlgStyle = wxAEDIALOG_STYLE;
 | |
| 
 | |
|     // Need to figure out delimiter needed for this locale
 | |
|     // (i.e. can't use comma when comma acts as decimal point in float).
 | |
|     wxChar use_delimiter = ',';
 | |
| 
 | |
|     if (wxString::Format("%.2f",12.34).Find(use_delimiter) >= 0)
 | |
|         use_delimiter = ';';
 | |
| 
 | |
|     m_delimiter = use_delimiter;
 | |
| 
 | |
|     SetValue( WXVARIANT(array) );
 | |
| }
 | |
| 
 | |
| wxArrayDoubleProperty::~wxArrayDoubleProperty () { }
 | |
| 
 | |
| void wxArrayDoubleProperty::OnSetValue()
 | |
| {
 | |
|     // Generate cached display string, to optimize grid drawing
 | |
|     GenerateValueAsString( m_display, m_precision, true );
 | |
| }
 | |
| 
 | |
| wxString wxArrayDoubleProperty::ValueToString( wxVariant& value,
 | |
|                                                int argFlags ) const
 | |
| {
 | |
|     wxString s;
 | |
| 
 | |
|     if ( argFlags & wxPG_FULL_VALUE )
 | |
|     {
 | |
|         GenerateValueAsString(s,-1,false);
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         //
 | |
|         // Display cached string only if value truly matches m_value
 | |
|         if ( value.GetData() == m_value.GetData() )
 | |
|             return m_display;
 | |
|         else
 | |
|             GenerateValueAsString( s, m_precision, true );
 | |
|     }
 | |
| 
 | |
|     return s;
 | |
| }
 | |
| 
 | |
| void wxArrayDoubleProperty::GenerateValueAsString( wxString& target, int prec, bool removeZeroes ) const
 | |
| {
 | |
|     wxString between = ", ";
 | |
| 
 | |
|     between[0] = m_delimiter;
 | |
| 
 | |
|     target.Empty();
 | |
| 
 | |
|     const wxArrayDouble& value = wxArrayDoubleRefFromVariant(m_value);
 | |
|     wxNumberFormatter::Style style = wxNumberFormatter::Style_None;
 | |
|     if (removeZeroes)
 | |
|         style = wxNumberFormatter::Style_NoTrailingZeroes;
 | |
| 
 | |
|     for ( size_t i=0; i<value.GetCount(); i++ )
 | |
|     {
 | |
|         target += wxNumberFormatter::ToString(value[i], prec, style);
 | |
| 
 | |
|         if ( i<(value.GetCount()-1) )
 | |
|             target += between;
 | |
|     }
 | |
| }
 | |
| 
 | |
| bool wxArrayDoubleProperty::DisplayEditorDialog(wxPropertyGrid* pg, wxVariant& value)
 | |
| {
 | |
|     wxASSERT_MSG(value.IsType("wxArrayDouble"), "Function called for incompatible property");
 | |
| 
 | |
|     wxArrayDouble& curValue = wxArrayDoubleRefFromVariant(value);
 | |
| 
 | |
|     // Create editor dialog.
 | |
|     wxArrayDoubleEditorDialog dlg;
 | |
|     dlg.SetPrecision(m_precision);
 | |
|     dlg.Create(pg->GetPanel(), wxEmptyString,
 | |
|                m_dlgTitle.empty() ? GetLabel() : m_dlgTitle, curValue, m_dlgStyle);
 | |
|     dlg.Move( pg->GetGoodEditorDialogPosition(this,dlg.GetSize()) );
 | |
| 
 | |
|     // Execute editor dialog
 | |
|     int res = dlg.ShowModal();
 | |
|     if ( res == wxID_OK && dlg.IsModified() )
 | |
|     {
 | |
|         value = WXVARIANT(dlg.GetArray());
 | |
|         return true;
 | |
|     }
 | |
|     return false;
 | |
| }
 | |
| 
 | |
| bool wxArrayDoubleProperty::StringToValue( wxVariant& variant, const wxString& text, int ) const
 | |
| {
 | |
|     // Add values to a temporary array so that in case
 | |
|     // of error we can opt not to use them.
 | |
|     wxArrayDouble new_array;
 | |
| 
 | |
|     bool ok = true;
 | |
| 
 | |
|     wxChar delimiter = m_delimiter;
 | |
| 
 | |
|     WX_PG_TOKENIZER1_BEGIN(text,delimiter)
 | |
| 
 | |
|         if ( !token.empty() )
 | |
|         {
 | |
|             double tval;
 | |
|             // If token was invalid, exit the loop now
 | |
|             if ( !token.ToDouble(&tval) )
 | |
|             {
 | |
|                 ok = false;
 | |
|                 break;
 | |
|             }
 | |
| 
 | |
|             new_array.Add(tval);
 | |
|         }
 | |
| 
 | |
|     WX_PG_TOKENIZER1_END()
 | |
| 
 | |
|     // When invalid token found signal the error
 | |
|     // by returning pending value of non-wxArrayDouble type.
 | |
|     if ( !ok )
 | |
|     {
 | |
|         variant = 0L;
 | |
|         return true;
 | |
|     }
 | |
| 
 | |
|     if ( !(wxArrayDoubleRefFromVariant(m_value) == new_array) )
 | |
|     {
 | |
|         variant = WXVARIANT(new_array);
 | |
|         return true;
 | |
|     }
 | |
| 
 | |
|     return false;
 | |
| }
 | |
| 
 | |
| bool wxArrayDoubleProperty::DoSetAttribute( const wxString& name, wxVariant& value )
 | |
| {
 | |
|     if ( name == wxPG_FLOAT_PRECISION )
 | |
|     {
 | |
|         m_precision = value.GetLong();
 | |
|         GenerateValueAsString( m_display, m_precision, true );
 | |
|         return true;
 | |
|     }
 | |
|     return wxEditorDialogProperty::DoSetAttribute(name, value);
 | |
| }
 | |
| 
 | |
| wxValidator* wxArrayDoubleProperty::DoGetValidator() const
 | |
| {
 | |
| #if wxUSE_VALIDATORS
 | |
|     WX_PG_DOGETVALIDATOR_ENTRY()
 | |
| 
 | |
|     wxTextValidator* validator =
 | |
|         new wxNumericPropertyValidator(wxNumericPropertyValidator::Float);
 | |
| 
 | |
|     // Accept also a delimiter and space character
 | |
|     validator->AddCharIncludes(m_delimiter);
 | |
|     validator->AddCharIncludes(" ");
 | |
| 
 | |
|     WX_PG_DOGETVALIDATOR_EXIT(validator)
 | |
| #else
 | |
|     return NULL;
 | |
| #endif
 | |
| }
 | |
| 
 | |
| bool wxArrayDoubleProperty::ValidateValue(wxVariant& value,
 | |
|                                  wxPGValidationInfo& validationInfo) const
 | |
| {
 | |
|     if (!value.IsType("wxArrayDouble"))
 | |
|     {
 | |
|         validationInfo.SetFailureMessage("At least one element is not a valid floating-point number.");
 | |
|         return false;
 | |
|     }
 | |
| 
 | |
|     return true;
 | |
| }
 |