X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/8f18b25245b3a5d09ac7caa7c378408edfdd88eb..5a45dd6fd9870de6b68eff437fd5fe4ea5895c3c:/src/propgrid/property.cpp diff --git a/src/propgrid/property.cpp b/src/propgrid/property.cpp index b8a691dbde..1022055d36 100644 --- a/src/propgrid/property.cpp +++ b/src/propgrid/property.cpp @@ -4,7 +4,7 @@ // Author: Jaakko Salli // Modified by: // Created: 2008-08-23 -// RCS-ID: $Id: +// RCS-ID: $Id$ // Copyright: (c) Jaakko Salli // Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// @@ -16,6 +16,8 @@ #pragma hdrstop #endif +#if wxUSE_PROPGRID + #ifndef WX_PRECOMP #include "wx/defs.h" #include "wx/object.h" @@ -27,29 +29,13 @@ #include "wx/panel.h" #include "wx/dc.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/layout.h" - #include "wx/sizer.h" - #include "wx/textdlg.h" - #include "wx/filedlg.h" - #include "wx/statusbr.h" #include "wx/intl.h" - #include "wx/frame.h" #endif -#include - -#include +#include "wx/propgrid/propgrid.h" #define PWC_CHILD_SUMMARY_LIMIT 16 // Maximum number of children summarized in a parent property's @@ -208,11 +194,16 @@ void wxPGDefaultRenderer::Render( wxDC& dc, const wxRect& rect, // Use choice cell? if ( column == 1 && (flags & Control) ) { - const wxPGCell* ccell = property->GetCurrentChoice(); - if ( ccell && - ( ccell->GetBitmap().IsOk() || ccell->GetFgCol().IsOk() || ccell->GetBgCol().IsOk() ) - ) - cell = ccell; + int selectedIndex = property->GetChoiceSelection(); + if ( selectedIndex != wxNOT_FOUND ) + { + const wxPGChoices& choices = property->GetChoices(); + const wxPGCell* ccell = &choices[selectedIndex]; + if ( ccell && + ( ccell->GetBitmap().IsOk() || ccell->GetFgCol().IsOk() || ccell->GetBgCol().IsOk() ) + ) + cell = ccell; + } } if ( cell ) @@ -485,6 +476,15 @@ wxPropertyGrid* wxPGProperty::GetGrid() const return m_parentState->GetGrid(); } +int wxPGProperty::Index( const wxPGProperty* p ) const +{ + for ( unsigned int i = 0; i PWC_CHILD_SUMMARY_LIMIT && !(argFlags & wxPG_FULL_VALUE) ) @@ -774,22 +774,24 @@ bool wxPGProperty::StringToValue( wxVariant& variant, const wxString& text, int const wxPGProperty* child = Item(curChild); - wxVariant variant(child->GetValueRef()); - if ( child->StringToValue( variant, token, propagatedFlags ) ) + wxVariant oldChildValue = child->GetValue(); + wxVariant variant(oldChildValue); + bool stvRes = child->StringToValue( variant, token, propagatedFlags ); + if ( stvRes || (variant != oldChildValue) ) { - variant.SetName(child->GetBaseName()); - list.Append(variant); - changed = true; + if ( stvRes ) + changed = true; } else { // Failed, becomes unspecified - wxVariant variant2; - variant2.SetName(child->GetBaseName()); - list.Append(variant2); + variant.MakeNull(); changed = true; } + variant.SetName(child->GetBaseName()); + list.Append(variant); + curChild++; if ( curChild >= iMax ) break; @@ -878,7 +880,7 @@ void wxPGProperty::OnCustomPaint( wxDC& dc, const wxPGEditor* wxPGProperty::DoGetEditorClass() const { - return wxPG_EDITOR(TextCtrl); + return wxPGEditor_TextCtrl; } // Default extra property event handling - that is, none at all. @@ -890,6 +892,14 @@ bool wxPGProperty::OnEvent( wxPropertyGrid*, wxWindow*, wxEvent& ) void wxPGProperty::SetValue( wxVariant value, wxVariant* pList, int flags ) { + // If auto unspecified values are not wanted (via window or property style), + // then get default value instead of wxNullVariant. + if ( value.IsNull() && (flags & wxPG_SETVAL_BY_USER) && + !UsesAutoUnspecified() ) + { + value = GetDefaultValue(); + } + if ( !value.IsNull() ) { wxVariant tempListVariant; @@ -898,7 +908,7 @@ void wxPGProperty::SetValue( wxVariant value, wxVariant* pList, int flags ) // List variants are reserved a special purpose // as intermediate containers for child values // of properties with children. - if ( wxPGIsVariantType(value, list) ) + if ( value.GetType() == wxPG_VARIANT_TYPE_LIST ) { // // However, situation is different for composed string properties @@ -919,7 +929,7 @@ void wxPGProperty::SetValue( wxVariant value, wxVariant* pList, int flags ) if ( pList && !pList->IsNull() ) { - wxASSERT( wxPGIsVariantType(*pList, list) ); + wxASSERT( pList->GetType() == wxPG_VARIANT_TYPE_LIST ); wxASSERT( GetChildCount() ); wxASSERT( !IsCategory() ); @@ -938,7 +948,7 @@ void wxPGProperty::SetValue( wxVariant value, wxVariant* pList, int flags ) if ( child ) { //wxLogDebug(wxT("%i: child = %s, childValue.GetType()=%s"),i,child->GetBaseName().c_str(),childValue.GetType().c_str()); - if ( wxPGIsVariantType(childValue, list) ) + if ( childValue.GetType() == wxPG_VARIANT_TYPE_LIST ) { if ( child->HasFlag(wxPG_PROP_AGGREGATE) && !(flags & wxPG_SETVAL_AGGREGATED) ) { @@ -951,7 +961,7 @@ void wxPGProperty::SetValue( wxVariant value, wxVariant* pList, int flags ) child->SetValue(oldVal, &childValue, flags|wxPG_SETVAL_FROM_PARENT); } } - else if ( !wxPG_VARIANT_EQ(child->GetValue(), childValue) ) + else if ( child->GetValue() != childValue ) { // For aggregate properties, we will trust RefreshChildren() // to update child values. @@ -967,7 +977,7 @@ void wxPGProperty::SetValue( wxVariant value, wxVariant* pList, int flags ) if ( !value.IsNull() ) { - wxPGVariantAssign(m_value, value); + m_value = value; OnSetValue(); if ( !(flags & wxPG_SETVAL_FROM_PARENT) ) @@ -1053,34 +1063,34 @@ wxVariant wxPGProperty::GetDefaultValue() const if ( !value.IsNull() ) { - wxPGVariantDataClassInfo classInfo = wxPGVariantDataGetClassInfo(value.GetData()); - if ( wxPGIsVariantClassInfo(classInfo, long) ) + wxString valueType(value.GetType()); + + if ( valueType == wxPG_VARIANT_TYPE_LONG ) return wxPGVariant_Zero; - if ( wxPGIsVariantClassInfo(classInfo, string) ) + if ( valueType == wxPG_VARIANT_TYPE_STRING ) return wxPGVariant_EmptyString; - if ( wxPGIsVariantClassInfo(classInfo, bool) ) + if ( valueType == wxPG_VARIANT_TYPE_BOOL ) return wxPGVariant_False; - if ( wxPGIsVariantClassInfo(classInfo, double) ) + if ( valueType == wxPG_VARIANT_TYPE_DOUBLE ) return wxVariant(0.0); - - wxPGVariantData* pgvdata = wxDynamicCastVariantData(m_value.GetData(), wxPGVariantData); - if ( pgvdata ) - return pgvdata->GetDefaultValue(); - - if ( wxPGIsVariantClassInfo(classInfo, arrstring) ) + if ( valueType == wxPG_VARIANT_TYPE_ARRSTRING ) return wxVariant(wxArrayString()); - if ( wxPGIsVariantClassInfo(classInfo, wxColour) ) - return WXVARIANT(*wxRED); + if ( valueType == wxS("wxLongLong") ) + return WXVARIANT(wxLongLong(0)); + if ( valueType == wxS("wxULongLong") ) + return WXVARIANT(wxULongLong(0)); + if ( valueType == wxS("wxColour") ) + return WXVARIANT(*wxBLACK); #if wxUSE_DATETIME - if ( wxPGIsVariantClassInfo(classInfo, datetime) ) + if ( valueType == wxPG_VARIANT_TYPE_DATETIME ) return wxVariant(wxDateTime::Now()); #endif - - wxFAIL_MSG( - wxString::Format(wxT("Inorder for value to have default value, it must be added to") - wxT("wxPGProperty::GetDefaultValue or it's variantdata must inherit") - wxT("from wxPGVariantData (unrecognized type was '%s')"),m_value.GetType().c_str()) - ); + if ( valueType == wxS("wxFont") ) + return WXVARIANT(*wxNORMAL_FONT); + if ( valueType == wxS("wxPoint") ) + return WXVARIANT(wxPoint(0, 0)); + if ( valueType == wxS("wxSize") ) + return WXVARIANT(wxSize(0, 0)); } return wxVariant(); @@ -1095,104 +1105,6 @@ void wxPGProperty::SetCell( int column, wxPGCell* cellObj ) m_cells[column] = cellObj; } -void wxPGProperty::SetChoiceSelection( int newValue, const wxPGChoiceInfo& choiceInfo ) -{ - // Changes value of a property with choices, but only - // works if the value type is long or string. - wxString ts = GetValue().GetType(); - - wxCHECK_RET( choiceInfo.m_choices, wxT("invalid choiceinfo") ); - - if ( ts == wxS("long") ) - { - SetValue( (long) newValue ); - } - else if ( ts == wxS("string") ) - { - SetValue( choiceInfo.m_choices->GetLabel(newValue) ); - } -} - - -wxString wxPGProperty::GetChoiceString( unsigned int index ) -{ - wxPGChoiceInfo ci; - GetChoiceInfo(&ci); - wxASSERT(ci.m_choices); - return ci.m_choices->GetLabel(index); -} - -int wxPGProperty::InsertChoice( const wxString& label, int index, int value ) -{ - wxPropertyGrid* pg = GetGrid(); - - wxPGChoiceInfo ci; - ci.m_choices = (wxPGChoices*) NULL; - int sel = GetChoiceInfo(&ci); - - if ( ci.m_choices ) - { - int newSel = sel; - - if ( index < 0 ) - index = ci.m_choices->GetCount(); - - if ( index <= sel ) - newSel++; - - ci.m_choices->Insert(label, index, value); - - if ( sel != newSel ) - SetChoiceSelection(newSel, ci); - - if ( this == pg->GetSelection() ) - GetEditorClass()->InsertItem(pg->GetEditorControl(),label,index); - - return index; - } - - return -1; -} - - -void wxPGProperty::DeleteChoice( int index ) -{ - wxPropertyGrid* pg = GetGrid(); - - wxPGChoiceInfo ci; - ci.m_choices = (wxPGChoices*) NULL; - int sel = GetChoiceInfo(&ci); - - if ( ci.m_choices ) - { - int newSel = sel; - - // Adjust current value - if ( sel == index ) - { - SetValueToUnspecified(); - newSel = 0; - } - else if ( index < sel ) - { - newSel--; - } - - ci.m_choices->RemoveAt(index); - - if ( sel != newSel ) - SetChoiceSelection(newSel, ci); - - if ( this == pg->GetSelection() ) - GetEditorClass()->DeleteItem(pg->GetEditorControl(), index); - } -} - -int wxPGProperty::GetChoiceInfo( wxPGChoiceInfo* WXUNUSED(info) ) -{ - return -1; -} - wxPGEditorDialogAdapter* wxPGProperty::GetEditorDialog() const { return NULL; @@ -1345,63 +1257,116 @@ wxValidator* wxPGProperty::DoGetValidator() const return (wxValidator*) NULL; } -wxPGChoices& wxPGProperty::GetChoices() +int wxPGProperty::InsertChoice( const wxString& label, int index, int value ) { - wxPGChoiceInfo choiceInfo; - choiceInfo.m_choices = NULL; - GetChoiceInfo(&choiceInfo); - return *choiceInfo.m_choices; + wxPropertyGrid* pg = GetGrid(); + int sel = GetChoiceSelection(); + + int newSel = sel; + + if ( index == wxNOT_FOUND ) + index = m_choices.GetCount(); + + if ( index <= sel ) + newSel++; + + m_choices.Insert(label, index, value); + + if ( sel != newSel ) + SetChoiceSelection(newSel); + + if ( this == pg->GetSelection() ) + GetEditorClass()->InsertItem(pg->GetEditorControl(),label,index); + + return index; } -const wxPGChoices& wxPGProperty::GetChoices() const + +void wxPGProperty::DeleteChoice( int index ) { - return (const wxPGChoices&) ((wxPGProperty*)this)->GetChoices(); + wxPropertyGrid* pg = GetGrid(); + + int sel = GetChoiceSelection(); + int newSel = sel; + + // Adjust current value + if ( sel == index ) + { + SetValueToUnspecified(); + newSel = 0; + } + else if ( index < sel ) + { + newSel--; + } + + m_choices.RemoveAt(index); + + if ( sel != newSel ) + SetChoiceSelection(newSel); + + if ( this == pg->GetSelection() ) + GetEditorClass()->DeleteItem(pg->GetEditorControl(), index); } -unsigned int wxPGProperty::GetChoiceCount() const +int wxPGProperty::GetChoiceSelection() const { - const wxPGChoices& choices = GetChoices(); - if ( &choices && choices.IsOk() ) - return choices.GetCount(); - return 0; + wxVariant value = GetValue(); + wxString valueType = value.GetType(); + int index = wxNOT_FOUND; + + if ( IsValueUnspecified() || !m_choices.GetCount() ) + return wxNOT_FOUND; + + if ( valueType == wxPG_VARIANT_TYPE_LONG ) + { + index = value.GetLong(); + } + else if ( valueType == wxPG_VARIANT_TYPE_STRING ) + { + index = m_choices.Index(value.GetString()); + } + else if ( valueType == wxPG_VARIANT_TYPE_BOOL ) + { + index = value.GetBool()? 1 : 0; + } + + return index; } -const wxPGChoiceEntry* wxPGProperty::GetCurrentChoice() const +void wxPGProperty::SetChoiceSelection( int newValue ) { - wxPGChoiceInfo ci; - ci.m_choices = (wxPGChoices*) NULL; - int index = ((wxPGProperty*)this)->GetChoiceInfo(&ci); - if ( index == -1 || !ci.m_choices || index >= (int)ci.m_choices->GetCount() ) - return NULL; + // Changes value of a property with choices, but only + // works if the value type is long or string. + wxString valueType = GetValue().GetType(); - return &(*ci.m_choices)[index]; + wxCHECK_RET( m_choices.IsOk(), wxT("invalid choiceinfo") ); + + if ( valueType == wxPG_VARIANT_TYPE_STRING ) + { + SetValue( m_choices.GetLabel(newValue) ); + } + else // if ( valueType == wxPG_VARIANT_TYPE_LONG ) + { + SetValue( (long) newValue ); + } } bool wxPGProperty::SetChoices( wxPGChoices& choices ) { - wxPGChoiceInfo ci; - ci.m_choices = (wxPGChoices*) NULL; + m_choices.Assign(choices); - // Unref existing - GetChoiceInfo(&ci); - if ( ci.m_choices ) { - ci.m_choices->Assign(choices); - - //if ( m_parent ) - { - // This may be needed to trigger some initialization - // (but don't do it if property is somewhat uninitialized) - wxVariant defVal = GetDefaultValue(); - if ( defVal.IsNull() ) - return false; - - SetValue(defVal); + // This may be needed to trigger some initialization + // (but don't do it if property is somewhat uninitialized) + wxVariant defVal = GetDefaultValue(); + if ( defVal.IsNull() ) + return false; - return true; - } + SetValue(defVal); } - return false; + + return true; } @@ -1422,28 +1387,16 @@ const wxPGEditor* wxPGProperty::GetEditorClass() const { // TextCtrlAndButton -> ComboBoxAndButton if ( editor->IsKindOf(CLASSINFO(wxPGTextCtrlAndButtonEditor)) ) - editor = wxPG_EDITOR(ChoiceAndButton); + editor = wxPGEditor_ChoiceAndButton; // TextCtrl -> ComboBox else if ( editor->IsKindOf(CLASSINFO(wxPGTextCtrlEditor)) ) - editor = wxPG_EDITOR(ComboBox); + editor = wxPGEditor_ComboBox; } return editor; } - -// Privatizes set of choices -void wxPGProperty::SetChoicesExclusive() -{ - wxPGChoiceInfo ci; - ci.m_choices = (wxPGChoices*) NULL; - - GetChoiceInfo(&ci); - if ( ci.m_choices ) - ci.m_choices->SetExclusive(); -} - bool wxPGProperty::HasVisibleChildren() const { unsigned int i; @@ -1603,37 +1556,17 @@ int wxPGProperty::GetY() const return GetY2(GetGrid()->GetRowHeight()); } - -wxPGProperty* wxPGPropArgCls::GetPtr( wxPropertyGridInterface* methods ) const -{ - if ( !m_isName ) - { - wxASSERT_MSG( m_ptr.property, wxT("invalid property ptr") ); - return m_ptr.property; - } - else if ( m_isName == 1 ) - return methods->GetPropertyByNameA(*m_ptr.name); - else if ( m_isName == 2 ) - return methods->GetPropertyByNameA(m_ptr.rawname); - // 3 is like 1, but ptr is freed in dtor - only needed by wxPython bindings. - else if ( m_isName == 3 ) - return methods->GetPropertyByNameA(*m_ptr.name); - - wxASSERT( m_isName <= 3 ); - return NULL; -} - // This is used by Insert etc. void wxPGProperty::AddChild2( wxPGProperty* prop, int index, bool correct_mode ) { - if ( index < 0 || (size_t)index >= m_children.GetCount() ) + if ( index < 0 || (size_t)index >= m_children.size() ) { - if ( correct_mode ) prop->m_arrIndex = m_children.GetCount(); - m_children.Add( prop ); + if ( correct_mode ) prop->m_arrIndex = m_children.size(); + m_children.push_back( prop ); } else { - m_children.Insert( prop, index ); + m_children.insert( m_children.begin()+index, prop); if ( correct_mode ) FixIndexesOfChildren( index ); } @@ -1646,8 +1579,8 @@ void wxPGProperty::AddChild( wxPGProperty* prop ) wxASSERT_MSG( prop->GetBaseName().length(), "Property's children must have unique, non-empty names within their scope" ); - prop->m_arrIndex = m_children.GetCount(); - m_children.Add( prop ); + prop->m_arrIndex = m_children.size(); + m_children.push_back( prop ); int custImgHeight = prop->OnMeasureImage().y; if ( custImgHeight < 0 /*|| custImgHeight > 1*/ ) @@ -1656,6 +1589,20 @@ void wxPGProperty::AddChild( wxPGProperty* prop ) prop->m_parent = this; } +void wxPGProperty::RemoveChild( wxPGProperty* p ) +{ + wxArrayPGProperty::iterator it; + wxArrayPGProperty& children = m_children; + + for ( it=children.begin(); it != children.end(); it++ ) + { + if ( *it == p ) + { + m_children.erase(it); + break; + } + } +} void wxPGProperty::AdaptListToValue( wxVariant& list, wxVariant* value ) const { @@ -1692,7 +1639,7 @@ void wxPGProperty::AdaptListToValue( wxVariant& list, wxVariant* value ) const { //wxLogDebug(wxT(" %s(n=%i), %s"),childValue.GetName().c_str(),n,childValue.GetType().c_str()); - if ( wxPGIsVariantType(childValue, list) ) + if ( childValue.GetType() == wxPG_VARIANT_TYPE_LIST ) { wxVariant cv2(child->GetValue()); child->AdaptListToValue(childValue, &cv2); @@ -1876,12 +1823,11 @@ void wxPGProperty::Empty() { for ( i=0; iGetType() == wxPG_VARIANT_TYPE_LIST ) childList = listValue; if ( !child->AreAllChildrenSpecified((wxVariant*)childList) ) @@ -2037,7 +1983,7 @@ void wxPGProperty::PrepareSubProperties() depth--; - i = nparent->GetArrIndex() + 1; + i = nparent->GetIndexInParent() + 1; nparent = nparent->GetParent(); } } @@ -2055,11 +2001,11 @@ void wxPGProperty::SubPropsChanged( int oldSelInd ) PrepareSubProperties(); wxPGProperty* sel = (wxPGProperty*) NULL; - if ( oldSelInd >= (int)m_children.GetCount() ) - oldSelInd = (int)m_children.GetCount() - 1; + if ( oldSelInd >= (int)m_children.size() ) + oldSelInd = (int)m_children.size() - 1; if ( oldSelInd >= 0 ) - sel = (wxPGProperty*) m_children[oldSelInd]; + sel = m_children[oldSelInd]; else if ( oldSelInd == -2 ) sel = this; @@ -2177,11 +2123,23 @@ void wxPGAttributeStorage::Set( const wxString& name, const wxVariant& value ) // Free old, if any wxPGHashMapS2P::iterator it = m_map.find(name); if ( it != m_map.end() ) + { ((wxVariantData*)it->second)->DecRef(); + if ( !data ) + { + // If Null variant, just remove from set + m_map.erase(it); + return; + } + } + if ( data ) + { data->IncRef(); - m_map[name] = data; + m_map[name] = data; + } } +#endif // wxUSE_PROPGRID