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