📄 propgrid.cpp
字号:
*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 )
{
wxASSERT ( target.Find(wxT('.')) != wxNOT_FOUND );
// Remove excess zeroes (do not remove this code just yet)
int cur_pos = target.length() - 1;
wxChar a;
a = target.GetChar ( cur_pos );
while ( a == '0' && cur_pos > 0 )
{
cur_pos--;
a = target.GetChar ( cur_pos );
}
if ( target.GetChar ( cur_pos ) != wxT('.') )
cur_pos += 1;
target.Truncate ( cur_pos );
}
}
wxString wxFloatPropertyClass::GetValueAsString ( int arg_flags ) const
{
wxString text;
wxPropertyGrid::DoubleToString(text,m_value,
m_precision,
!(arg_flags & wxPG_FULL_VALUE),
(wxString*) NULL);
return text;
}
bool wxFloatPropertyClass::SetValueFromString ( const wxString& text, int arg_flags )
{
wxString s;
double value;
bool res = text.ToDouble(&value);
if ( res )
{
#if wxPG_USE_VALIDATORS
if ( m_validator )
{
m_validator->AssertDataType(wxT("double"));
wxPGVariant tvariant(value);
if ( !m_validator->Validate(tvariant,s) )
{
ShowError(s);
return FALSE;
}
}
#endif
if ( m_value != value )
{
m_value = value;
return TRUE;
}
}
else if ( arg_flags & wxPG_REPORT_ERROR )
{
s.Printf ( _("\"%s\" is not a floating-point number."), text.c_str() );
ShowError(s);
}
return FALSE;
}
void wxFloatPropertyClass::SetAttribute ( int id, wxVariant value )
{
if ( id == wxPG_FLOAT_PRECISION )
{
m_precision = value.GetLong();
}
}
// -----------------------------------------------------------------------
// wxBoolProperty
// -----------------------------------------------------------------------
#define wxPG_PROP_USE_CHECKBOX wxPG_PROP_CLASS_SPECIFIC_1
// DCC = Double Click Cycles
#define wxPG_PROP_USE_DCC wxPG_PROP_CLASS_SPECIFIC_2
wxPG_BEGIN_PROPERTY_CLASS_BODY2(wxBoolPropertyClass,wxPGProperty,bool,int,bool,class)
WX_PG_DECLARE_BASIC_TYPE_METHODS()
WX_PG_DECLARE_CHOICE_METHODS()
WX_PG_DECLARE_ATTRIBUTE_METHODS()
// Allows changing strings in choice control.
static void SetBoolChoices ( const wxChar* true_choice, const wxChar* false_choice );
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)
wxPG_GETCLASSNAME_IMPLEMENTATION(wxBoolProperty)
const wxPGValueType* wxBoolPropertyClass::GetValueType() const { return wxPG_VALUETYPE(bool); }
const wxPGEditor* wxBoolPropertyClass::GetEditorClass() 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
}
void wxBoolPropertyClass::SetBoolChoices ( const wxChar* true_choice,
const wxChar* false_choice )
{
wxPGGlobalVars->m_boolChoices[0] = false_choice;
wxPGGlobalVars->m_boolChoices[1] = true_choice;
}
wxBoolPropertyClass::wxBoolPropertyClass ( const wxString& label, const wxString& name, bool value ) :
wxPGProperty(label,name)
{
int useval = 0;
if ( value ) useval = 1;
DoSetValue(useval);
}
wxBoolPropertyClass::~wxBoolPropertyClass () { }
void wxBoolPropertyClass::DoSetValue ( wxPGVariant value )
{
m_value = 0;
if ( wxPGVariantToLong(value) != 0 )
m_value = 1;
}
wxPGVariant wxBoolPropertyClass::DoGetValue () const
{
return wxPGVariant(m_value);
}
wxString wxBoolPropertyClass::GetValueAsString ( int arg_flags ) const
{
if ( !(arg_flags & 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 )
{
choiceinfo->m_itemCount = 2;
choiceinfo->m_arrWxString = wxPGGlobalVars->m_boolChoices;
}
return m_value;
}
bool wxBoolPropertyClass::SetValueFromString ( const wxString& text, int /*arg_flags*/ )
{
int value = 0;
if ( text.CmpNoCase(wxPGGlobalVars->m_boolChoices[1]) == 0 || text.CmpNoCase(wxT("TRUE")) == 0 )
value = 1;
if ( m_value != value )
{
DoSetValue ( value );
return TRUE;
}
/*
else if ( arg_flags & 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;
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);
}
}
// -----------------------------------------------------------------------
// Choice related methods from various classes
// -----------------------------------------------------------------------
WX_DECLARE_HASH_MAP(size_t, // type of the keys
wxPGConstants*, // type of the values
wxIntegerHash, // hasher
wxIntegerEqual, // key equality predicate
wxPGHashMapConstants); // name of the class
// -----------------------------------------------------------------------
// If last id was valid (i.e. non-zero), then clears it.
// Then sets this wxPGConstants to new id.
void wxPGConstants::SetId( size_t id )
{
wxASSERT ( IsOk() );
if ( !IsTemporary() )
{
wxPGHashMapConstants* socs =
(wxPGHashMapConstants*) wxPGGlobalVars->m_dictConstants;
if ( m_id )
socs->erase(m_id);
(*socs)[id] = this;
}
m_id = id;
}
// -----------------------------------------------------------------------
#ifdef __WXDEBUG__
// Displays what dynamic arrays are allocated
void wxPropertyGrid::DumpAllocatedChoiceSets()
{
wxPGHashMapConstants* socs = (wxPGHashMapConstants*) wxPGGlobalVars->m_dictConstants;
wxLogDebug(wxT("****************************************************************"));
wxPGHashMapConstants::iterator soc_it;
int soc_count = 0;
//
// NOTE: May fail to iterate through every and each item.
// (I have no idea why)
for( soc_it = socs->begin(); soc_it != socs->end(); ++soc_it )
{
wxPGConstants* soc = soc_it->second;
wxASSERT ( soc );
wxArrayString& labels = soc->GetLabels();
wxArrayInt& values = soc->GetValues();
wxLogDebug(wxT("."));
wxLogDebug(wxT("**** Dumping 0x%X (%i labels, %i values, %i references)****"),
(unsigned int)soc,(int)labels.GetCount(),(int)values.GetCount(),
(int)soc->GetRefCount());
wxASSERT( !values.GetCount() || labels.GetCount() == values.GetCount() );
wxASSERT_MSG( soc->GetRefCount(),
wxT("soc with no references should have been deleted") );
wxASSERT_MSG( soc->IsOk() && !soc->IsTemporary(),
wxT("soc in hash map was invalid") );
size_t i;
for ( i=0; i<labels.GetCount(); i++ )
{
if ( values.GetCount() )
{
wxLogDebug(wxT(" %s = %i"),
labels[i].c_str(),values[i]);
wxASSERT( values[i] != ((int)wxPG_INVALID_VALUE) );
}
else
wxLogDebug(wxT(" %s"),
labels[i].c_str());
}
wxLogDebug(wxT("."));
soc_count++;
}
wxLogDebug(wxT("Total %i sets"),soc_count);
wxLogDebug(wxT("****************************************************************"));
}
#endif
// -----------------------------------------------------------------------
wxPGConstants* wxPropertyGrid::AddConstantsArray(const wxChar** labels,
const long* values,
int itemcount)
{
wxPGHashMapConstants* socs =
(wxPGHashMapConstants*) wxPGGlobalVars->m_dictConstants;
wxPGConstants* soc;
size_t id = (size_t)labels;
wxPGHashMapConstants::iterator it;
it = socs->find(id);
if ( it != socs->end() )
{
soc = (wxPGConstants*) it->second;
#ifdef __WXDEBUG__
// Validate array pairing
wxASSERT_MSG ( values == soc->m_origValueArray,
wxT("one set of labels must always be paired with the same set of values") );
#endif
soc->Ref();
return soc;
}
// if necessary, determine itemcount
if ( !itemcount && labels )
{
const wxChar** p = &labels[0];
while ( *p ) { p++; itemcount++; }
}
//wxASSERT ( itemcount > 0 );
soc = new wxPGConstants();
#ifdef __WXDEBUG__
soc->m_origValueArray = values;
#endif
//
// Populate arrays
size_t i;
for ( i=0; i<(size_t)itemcount; i++ )
soc->AddString(labels[i]);
if ( values )
for ( i=0; i<(size_t)itemcount; i++ )
soc->AddInt(values[i]);
// If no labels given, then this is unique array:
// set labels to point at created string array
if ( !labels )
labels = (const wxChar**) &soc->GetLabels();
#ifdef __WXDEBUG__
// Make sure id is not already in use
it = socs->find(id);
wxASSERT_MSG( it == socs->end(),
wxT("id for this set of choices was already in use") );
#endif
// Cannot use SetId because we have zero refcount
soc->SetupId(id);
(*socs)[id] = soc;
soc->Ref();
return soc;
}
// -----------------------------------------------------------------------
wxPGConstants* wxPropertyGrid::AddConstantsArray(const wxArrayString& labels,
const wxArrayInt& values,
bool acceptLabelsAsId)
{
wxPGHashMapConstants* socs =
(wxPGHashMapConstants*) wxPGGlobalVars->m_dictConstants;
wxPGConstants* soc;
size_t id = 0;
if ( acceptLabelsAsId )
{
size_t id = (size_t) &labels;
wxPGHashMapConstants::iterator it;
it = socs->find(id);
if ( it != socs->end() )
{
soc = (wxPGConstants*) it->second;
soc->Ref();
return soc;
}
}
soc = new wxPGConstants();
// If so preferred, create new id to avoid stack aliasing
if ( !id )
id = (size_t) soc;
#ifdef __WXDEBUG__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -