1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/propgrid/propgridiface.cpp
3 // Purpose: wxPropertyGridInterface class
4 // Author: Jaakko Salli
8 // Copyright: (c) Jaakko Salli
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx/wx.h".
13 #include "wx/wxprec.h"
23 #include "wx/object.h"
25 #include "wx/string.h"
28 #include "wx/window.h"
31 #include "wx/dcmemory.h"
32 #include "wx/button.h"
35 #include "wx/settings.h"
40 #include "wx/propgrid/property.h"
41 #include "wx/propgrid/propgrid.h"
44 const wxChar
*wxPGTypeName_long
= wxT("long");
45 const wxChar
*wxPGTypeName_bool
= wxT("bool");
46 const wxChar
*wxPGTypeName_double
= wxT("double");
47 const wxChar
*wxPGTypeName_wxString
= wxT("string");
48 const wxChar
*wxPGTypeName_void
= wxT("void*");
49 const wxChar
*wxPGTypeName_wxArrayString
= wxT("arrstring");
52 // ----------------------------------------------------------------------------
54 // ----------------------------------------------------------------------------
56 WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED(wxPoint
, WXDLLIMPEXP_PROPGRID
)
57 WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED(wxSize
, WXDLLIMPEXP_PROPGRID
)
58 WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED_DUMMY_EQ(wxArrayInt
, WXDLLIMPEXP_PROPGRID
)
60 // For wxLongLong and wxULongLong have custom classname << variant
61 // implementation for improved flexibility.
62 WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED_NO_EQ_NO_GETTER(wxLongLong
, WXDLLIMPEXP_PROPGRID
)
63 WX_PG_IMPLEMENT_VARIANT_DATA_EQ(wxLongLong
, WXDLLIMPEXP_PROPGRID
)
64 WXDLLIMPEXP_PROPGRID wxLongLong
& operator << ( wxLongLong
&value
, const wxVariant
&variant
)
67 if ( !wxPGVariantToLongLong(variant
, &ll
) )
69 wxFAIL_MSG("Cannot convert to wxLongLong");
74 WXDLLIMPEXP_PROPGRID wxLongLong_t
& operator << ( wxLongLong_t
&value
, const wxVariant
&variant
)
76 if ( !wxPGVariantToLongLong(variant
, &value
) )
78 wxFAIL_MSG("Cannot convert to wxLongLong");
83 WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED_NO_EQ_NO_GETTER(wxULongLong
, WXDLLIMPEXP_PROPGRID
)
84 WX_PG_IMPLEMENT_VARIANT_DATA_EQ(wxULongLong
, WXDLLIMPEXP_PROPGRID
)
85 WXDLLIMPEXP_PROPGRID wxULongLong
& operator << ( wxULongLong
&value
, const wxVariant
&variant
)
88 if ( !wxPGVariantToULongLong(variant
, &ull
) )
90 wxFAIL_MSG("Cannot convert to wxULongLong");
95 WXDLLIMPEXP_PROPGRID wxULongLong_t
& operator << ( wxULongLong_t
&value
, const wxVariant
&variant
)
97 if ( !wxPGVariantToULongLong(variant
, &value
) )
99 wxFAIL_MSG("Cannot convert to wxULongLong");
104 IMPLEMENT_VARIANT_OBJECT_EXPORTED(wxFont
, WXDLLIMPEXP_PROPGRID
)
106 // -----------------------------------------------------------------------
108 // -----------------------------------------------------------------------
110 long wxPGVariantToInt( const wxVariant
& variant
, long defVal
)
112 if ( variant
.IsNull() )
115 if ( variant
.GetType() == wxS("long") )
116 return variant
.GetLong();
118 if ( variant
.GetType() == wxS("bool") )
119 return variant
.GetBool() ? 1 : 0;
121 if ( variant
.GetType() == wxS("wxLongLong") )
125 if ( ll
>= LONG_MAX
)
127 else if ( ll
<= LONG_MIN
)
134 if ( variant
.GetType() == wxPG_VARIANT_TYPE_STRING
)
135 variant
.GetString().ToLong(&l
, 0);
140 // -----------------------------------------------------------------------
142 bool wxPGVariantToLongLong( const wxVariant
& variant
, wxLongLong_t
* pResult
)
144 if ( variant
.IsNull() )
147 wxString variantType
= variant
.GetType();
149 if ( variantType
== wxPG_VARIANT_TYPE_LONG
)
151 *pResult
= variant
.GetLong();
155 if ( variantType
== wxLongLong_VariantType
)
157 // NOTE: << operator uses this functions, so we can't use it here
158 *pResult
= wxLongLongRefFromVariant(variant
).GetValue();
165 // -----------------------------------------------------------------------
167 bool wxPGVariantToULongLong( const wxVariant
& variant
, wxULongLong_t
* pResult
)
169 if ( variant
.IsNull() )
172 wxString variantType
= variant
.GetType();
174 if ( variantType
== wxPG_VARIANT_TYPE_LONG
)
176 *pResult
= (unsigned long)variant
.GetLong();
180 if ( variantType
== wxULongLong_VariantType
)
182 // NOTE: << operator uses this functions, so we can't use it here
183 *pResult
= wxULongLongRefFromVariant(variant
).GetValue();
190 // -----------------------------------------------------------------------
192 bool wxPGVariantToDouble( const wxVariant
& variant
, double* pResult
)
194 if ( variant
.IsNull() )
197 wxString variantType
= variant
.GetType();
199 if ( variantType
== wxPG_VARIANT_TYPE_DOUBLE
)
201 *pResult
= variant
.GetDouble();
205 if ( variantType
== wxPG_VARIANT_TYPE_LONG
)
207 *pResult
= (double)variant
.GetLong();
211 if ( variantType
== wxLongLong_VariantType
)
215 *pResult
= ll
.ToDouble();
219 if ( variantType
== wxPG_VARIANT_TYPE_STRING
)
220 if ( variant
.GetString().ToDouble(pResult
) )
226 // -----------------------------------------------------------------------
228 // -----------------------------------------------------------------------
230 wxPGProperty
* wxPGPropArgCls::GetPtr( wxPropertyGridInterface
* iface
) const
232 if ( m_flags
== IsProperty
)
234 wxASSERT_MSG( m_ptr
.property
, wxT("invalid property ptr") );
235 return m_ptr
.property
;
237 else if ( m_flags
& IsWxString
)
238 return iface
->GetPropertyByNameA(*m_ptr
.stringName
);
239 else if ( m_flags
& IsCharPtr
)
240 return iface
->GetPropertyByNameA(m_ptr
.charName
);
242 else if ( m_flags
& IsWCharPtr
)
243 return iface
->GetPropertyByNameA(m_ptr
.wcharName
);
249 // -----------------------------------------------------------------------
250 // wxPropertyGridInterface
251 // -----------------------------------------------------------------------
253 void wxPropertyGridInterface::RefreshGrid( wxPropertyGridPageState
* state
)
258 wxPropertyGrid
* grid
= state
->GetGrid();
259 if ( grid
->GetState() == state
&& !grid
->IsFrozen() )
265 // -----------------------------------------------------------------------
267 wxPGProperty
* wxPropertyGridInterface::Append( wxPGProperty
* property
)
269 wxPGProperty
* retp
= m_pState
->DoAppend(property
);
271 wxPropertyGrid
* grid
= m_pState
->GetGrid();
278 // -----------------------------------------------------------------------
280 wxPGProperty
* wxPropertyGridInterface::AppendIn( wxPGPropArg id
, wxPGProperty
* newproperty
)
282 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty
)
283 wxPGProperty
* pwc
= (wxPGProperty
*) p
;
284 wxPGProperty
* retp
= m_pState
->DoInsert(pwc
, pwc
->GetChildCount(), newproperty
);
288 // -----------------------------------------------------------------------
290 wxPGProperty
* wxPropertyGridInterface::Insert( wxPGPropArg id
, wxPGProperty
* property
)
292 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty
)
293 wxPGProperty
* retp
= m_pState
->DoInsert(p
->GetParent(), p
->GetIndexInParent(), property
);
298 // -----------------------------------------------------------------------
300 wxPGProperty
* wxPropertyGridInterface::Insert( wxPGPropArg id
, int index
, wxPGProperty
* newproperty
)
302 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty
)
303 wxPGProperty
* retp
= m_pState
->DoInsert((wxPGProperty
*)p
,index
,newproperty
);
308 // -----------------------------------------------------------------------
310 void wxPropertyGridInterface::DeleteProperty( wxPGPropArg id
)
312 wxPG_PROP_ARG_CALL_PROLOG()
314 wxPropertyGridPageState
* state
= p
->GetParentState();
315 wxPropertyGrid
* grid
= state
->GetGrid();
317 if ( grid
->GetState() == state
)
318 grid
->DoSelectProperty(NULL
, wxPG_SEL_DELETING
|wxPG_SEL_NOVALIDATE
);
320 state
->DoDelete( p
, true );
325 // -----------------------------------------------------------------------
327 wxPGProperty
* wxPropertyGridInterface::RemoveProperty( wxPGPropArg id
)
329 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty
)
331 wxCHECK( !p
->GetChildCount() || p
->HasFlag(wxPG_PROP_AGGREGATE
),
334 wxPropertyGridPageState
* state
= p
->GetParentState();
335 wxPropertyGrid
* grid
= state
->GetGrid();
337 if ( grid
->GetState() == state
)
339 grid
->DoSelectProperty(NULL
,
340 wxPG_SEL_DELETING
|wxPG_SEL_NOVALIDATE
);
343 state
->DoDelete( p
, false );
345 // Mark the property as 'unattached'
346 p
->m_parentState
= NULL
;
354 // -----------------------------------------------------------------------
356 wxPGProperty
* wxPropertyGridInterface::ReplaceProperty( wxPGPropArg id
, wxPGProperty
* property
)
358 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty
)
360 wxPGProperty
* replaced
= p
;
361 wxCHECK_MSG( replaced
&& property
,
363 wxT("NULL property") );
364 wxCHECK_MSG( !replaced
->IsCategory(),
366 wxT("cannot replace this type of property") );
367 wxCHECK_MSG( !m_pState
->IsInNonCatMode(),
369 wxT("cannot replace properties in alphabetic mode") );
371 // Get address to the slot
372 wxPGProperty
* parent
= replaced
->GetParent();
373 int ind
= replaced
->GetIndexInParent();
375 wxPropertyGridPageState
* state
= replaced
->GetParentState();
376 DeleteProperty(replaced
); // Must use generic Delete
377 state
->DoInsert(parent
,ind
,property
);
382 // -----------------------------------------------------------------------
383 // wxPropertyGridInterface property operations
384 // -----------------------------------------------------------------------
386 bool wxPropertyGridInterface::ClearSelection( bool validation
)
390 flags
|= wxPG_SEL_NOVALIDATE
;
392 wxPropertyGridPageState
* state
= m_pState
;
396 wxPropertyGrid
* pg
= state
->GetGrid();
397 if ( pg
->GetState() == state
)
398 return pg
->DoSelectProperty(NULL
, flags
);
400 state
->SetSelection(NULL
);
406 // -----------------------------------------------------------------------
408 void wxPropertyGridInterface::LimitPropertyEditing( wxPGPropArg id
, bool limit
)
410 wxPG_PROP_ARG_CALL_PROLOG()
412 m_pState
->DoLimitPropertyEditing(p
, limit
);
416 // -----------------------------------------------------------------------
418 bool wxPropertyGridInterface::EnableProperty( wxPGPropArg id
, bool enable
)
420 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
422 wxPropertyGridPageState
* state
= p
->GetParentState();
423 wxPropertyGrid
* grid
= state
->GetGrid();
427 if ( !(p
->m_flags
& wxPG_PROP_DISABLED
) )
430 // If active, Set active Editor.
431 if ( grid
->GetState() == state
&& p
== grid
->GetSelection() )
432 grid
->DoSelectProperty( p
, wxPG_SEL_FORCE
);
436 if ( p
->m_flags
& wxPG_PROP_DISABLED
)
439 // If active, Disable as active Editor.
440 if ( grid
->GetState() == state
&& p
== grid
->GetSelection() )
441 grid
->DoSelectProperty( p
, wxPG_SEL_FORCE
);
444 state
->DoEnableProperty(p
, enable
);
446 RefreshProperty( p
);
451 // -----------------------------------------------------------------------
453 bool wxPropertyGridInterface::ExpandAll( bool doExpand
)
455 wxPropertyGridPageState
* state
= m_pState
;
457 if ( !state
->DoGetRoot()->GetChildCount() )
460 wxPropertyGrid
* pg
= state
->GetGrid();
462 if ( GetSelection() && GetSelection() != state
->DoGetRoot() &&
465 pg
->ClearSelection(false);
470 for ( it
= GetVIterator( wxPG_ITERATE_ALL
); !it
.AtEnd(); it
.Next() )
472 wxPGProperty
* p
= (wxPGProperty
*) it
.GetProperty();
473 if ( p
->GetChildCount() )
477 if ( !p
->IsExpanded() )
484 if ( p
->IsExpanded() )
486 state
->DoCollapse(p
);
492 pg
->RecalculateVirtualSize();
499 // -----------------------------------------------------------------------
501 void wxPropertyGridInterface::SetPropertyValueUnspecified( wxPGPropArg id
)
503 wxPG_PROP_ARG_CALL_PROLOG()
504 wxPropertyGrid
* propGrid
= p
->GetGridIfDisplayed();
506 propGrid
->DoSetPropertyValueUnspecified(p
);
508 p
->GetParentState()->DoSetPropertyValueUnspecified(p
);
511 // -----------------------------------------------------------------------
513 void wxPropertyGridInterface::ClearModifiedStatus()
515 unsigned int pageIndex
= 0;
519 wxPropertyGridPageState
* page
= GetPageState(pageIndex
);
522 page
->DoGetRoot()->SetFlagRecursively(wxPG_PROP_MODIFIED
, false);
527 // Update active editor control, if any
528 GetPropertyGrid()->RefreshEditor();
531 // -----------------------------------------------------------------------
532 // wxPropertyGridInterface property value setting and getting
533 // -----------------------------------------------------------------------
535 void wxPGGetFailed( const wxPGProperty
* p
, const wxString
& typestr
)
537 wxPGTypeOperationFailed(p
, typestr
, wxS("Get"));
540 // -----------------------------------------------------------------------
542 void wxPGTypeOperationFailed( const wxPGProperty
* p
,
543 const wxString
& typestr
,
546 wxASSERT( p
!= NULL
);
547 wxLogError( _("Type operation \"%s\" failed: Property labeled \"%s\" is of type \"%s\", NOT \"%s\"."),
548 op
.c_str(), p
->GetLabel().c_str(), p
->GetValue().GetType().c_str(), typestr
.c_str() );
551 // -----------------------------------------------------------------------
553 void wxPropertyGridInterface::SetPropVal( wxPGPropArg id
, wxVariant
& value
)
555 wxPG_PROP_ARG_CALL_PROLOG()
560 wxPropertyGrid
* propGrid
= p
->GetGridIfDisplayed();
562 propGrid
->DrawItemAndValueRelated( p
);
567 // -----------------------------------------------------------------------
569 void wxPropertyGridInterface::SetPropertyValueString( wxPGPropArg id
, const wxString
& value
)
571 wxPG_PROP_ARG_CALL_PROLOG()
573 if ( m_pState
->DoSetPropertyValueString(p
,value
) )
575 wxPropertyGrid
* propGrid
= p
->GetGridIfDisplayed();
577 propGrid
->DrawItemAndValueRelated( p
);
581 // -----------------------------------------------------------------------
583 void wxPropertyGridInterface::SetValidationFailureBehavior( int vfbFlags
)
585 GetPropertyGrid()->m_permanentValidationFailureBehavior
= vfbFlags
;
588 // -----------------------------------------------------------------------
590 wxPGProperty
* wxPropertyGridInterface::GetPropertyByNameA( const wxString
& name
) const
592 wxPGProperty
* p
= GetPropertyByName(name
);
593 wxASSERT_MSG(p
,wxString::Format(wxT("no property with name '%s'"),name
.c_str()));
597 // ----------------------------------------------------------------------------
599 wxPGProperty
* wxPropertyGridInterface::GetPropertyByLabel( const wxString
& label
) const
603 for ( it
= GetVIterator( wxPG_ITERATE_PROPERTIES
); !it
.AtEnd(); it
.Next() )
605 if ( it
.GetProperty()->GetLabel() == label
)
606 return it
.GetProperty();
609 return wxNullProperty
;
612 // ----------------------------------------------------------------------------
614 void wxPropertyGridInterface::DoSetPropertyAttribute( wxPGPropArg id
, const wxString
& name
,
615 wxVariant
& value
, long argFlags
)
617 wxPG_PROP_ARG_CALL_PROLOG()
619 p
->SetAttribute( name
, value
);
621 if ( argFlags
& wxPG_RECURSE
)
624 for ( i
= 0; i
< p
->GetChildCount(); i
++ )
625 DoSetPropertyAttribute(p
->Item(i
), name
, value
, argFlags
);
629 // -----------------------------------------------------------------------
631 void wxPropertyGridInterface::SetPropertyAttributeAll( const wxString
& attrName
,
634 unsigned int pageIndex
= 0;
638 wxPropertyGridPageState
* page
= GetPageState(pageIndex
);
641 DoSetPropertyAttribute(page
->DoGetRoot(), attrName
, value
, wxPG_RECURSE
);
647 // -----------------------------------------------------------------------
649 void wxPropertyGridInterface::GetPropertiesWithFlag( wxArrayPGProperty
* targetArr
,
650 wxPGProperty::FlagType flags
,
652 int iterFlags
) const
654 wxASSERT( targetArr
);
655 wxPGVIterator it
= GetVIterator( iterFlags
);
661 const wxPGProperty
* property
= it
.GetProperty();
665 if ( (property
->GetFlags() & flags
) == flags
)
666 targetArr
->push_back((wxPGProperty
*)property
);
670 if ( (property
->GetFlags() & flags
) != flags
)
671 targetArr
->push_back((wxPGProperty
*)property
);
676 // -----------------------------------------------------------------------
678 void wxPropertyGridInterface::SetBoolChoices( const wxString
& trueChoice
,
679 const wxString
& falseChoice
)
681 wxPGGlobalVars
->m_boolChoices
[0] = falseChoice
;
682 wxPGGlobalVars
->m_boolChoices
[1] = trueChoice
;
685 // -----------------------------------------------------------------------
687 wxPGProperty
* wxPropertyGridInterface::DoGetPropertyByName( const wxString
& name
) const
689 return m_pState
->BaseGetPropertyByName(name
);
692 // -----------------------------------------------------------------------
694 wxPGProperty
* wxPropertyGridInterface::GetPropertyByName( const wxString
& name
,
695 const wxString
& subname
) const
697 wxPGProperty
* p
= DoGetPropertyByName(name
);
698 if ( !p
|| !p
->GetChildCount() )
699 return wxNullProperty
;
701 return p
->GetPropertyByName(subname
);
704 // -----------------------------------------------------------------------
706 // Since GetPropertyByName is used *a lot*, this makes sense
707 // since non-virtual method can be called with less code.
708 wxPGProperty
* wxPropertyGridInterface::GetPropertyByName( const wxString
& name
) const
710 wxPGProperty
* p
= DoGetPropertyByName(name
);
714 // Check if its "Property.SubProperty" format
715 int pos
= name
.Find(wxT('.'));
719 return GetPropertyByName(name
.substr(0,pos
),
720 name
.substr(pos
+1,name
.length()-pos
-1));
723 // -----------------------------------------------------------------------
725 bool wxPropertyGridInterface::HideProperty( wxPGPropArg id
, bool hide
, int flags
)
727 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
729 wxPropertyGrid
* pg
= m_pState
->GetGrid();
731 if ( pg
== p
->GetGrid() )
732 return pg
->DoHideProperty(p
, hide
, flags
);
734 m_pState
->DoHideProperty(p
, hide
, flags
);
739 // -----------------------------------------------------------------------
741 bool wxPropertyGridInterface::Collapse( wxPGPropArg id
)
743 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
744 wxPropertyGrid
* pg
= p
->GetGridIfDisplayed();
746 return pg
->DoCollapse(p
);
748 return p
->GetParentState()->DoCollapse(p
);
751 // -----------------------------------------------------------------------
753 bool wxPropertyGridInterface::Expand( wxPGPropArg id
)
755 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
756 wxPropertyGrid
* pg
= p
->GetGridIfDisplayed();
758 return pg
->DoExpand(p
);
760 return p
->GetParentState()->DoExpand(p
);
763 // -----------------------------------------------------------------------
765 void wxPropertyGridInterface::Sort( int flags
)
767 wxPropertyGrid
* pg
= GetPropertyGrid();
769 pg
->ClearSelection(false);
771 unsigned int pageIndex
= 0;
775 wxPropertyGridPageState
* page
= GetPageState(pageIndex
);
782 // -----------------------------------------------------------------------
784 void wxPropertyGridInterface::SetPropertyLabel( wxPGPropArg id
, const wxString
& newproplabel
)
786 wxPG_PROP_ARG_CALL_PROLOG()
788 p
->SetLabel( newproplabel
);
790 wxPropertyGridPageState
* state
= p
->GetParentState();
791 wxPropertyGrid
* pg
= state
->GetGrid();
793 if ( pg
->HasFlag(wxPG_AUTO_SORT
) )
794 pg
->SortChildren(p
->GetParent());
796 if ( pg
->GetState() == state
)
798 if ( pg
->HasFlag(wxPG_AUTO_SORT
) )
805 // -----------------------------------------------------------------------
807 bool wxPropertyGridInterface::SetPropertyMaxLength( wxPGPropArg id
, int maxLen
)
809 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
811 wxPropertyGrid
* pg
= m_pState
->GetGrid();
813 p
->m_maxLen
= (short) maxLen
;
815 // Adjust control if selected currently
816 if ( pg
== p
->GetGrid() && p
== m_pState
->GetSelection() )
818 wxWindow
* wnd
= pg
->GetEditorControl();
819 wxTextCtrl
* tc
= wxDynamicCast(wnd
,wxTextCtrl
);
821 tc
->SetMaxLength( maxLen
);
830 // -----------------------------------------------------------------------
833 wxPropertyGridInterface::SetPropertyBackgroundColour( wxPGPropArg id
,
834 const wxColour
& colour
,
837 wxPG_PROP_ARG_CALL_PROLOG()
838 p
->SetBackgroundColour( colour
, recursively
);
839 RefreshProperty( p
);
842 // -----------------------------------------------------------------------
844 void wxPropertyGridInterface::SetPropertyTextColour( wxPGPropArg id
,
845 const wxColour
& colour
,
848 wxPG_PROP_ARG_CALL_PROLOG()
849 p
->SetTextColour( colour
, recursively
);
850 RefreshProperty( p
);
853 // -----------------------------------------------------------------------
855 void wxPropertyGridInterface::SetPropertyColoursToDefault( wxPGPropArg id
)
857 wxPG_PROP_ARG_CALL_PROLOG()
862 // -----------------------------------------------------------------------
864 void wxPropertyGridInterface::SetPropertyCell( wxPGPropArg id
,
866 const wxString
& text
,
867 const wxBitmap
& bitmap
,
868 const wxColour
& fgCol
,
869 const wxColour
& bgCol
)
871 wxPG_PROP_ARG_CALL_PROLOG()
873 wxPGCell
& cell
= p
->GetCell(column
);
874 if ( text
.length() && text
!= wxPG_LABEL
)
877 cell
.SetBitmap(bitmap
);
878 if ( fgCol
!= wxNullColour
)
879 cell
.SetFgCol(fgCol
);
880 if ( bgCol
!= wxNullColour
)
881 cell
.SetBgCol(bgCol
);
884 // -----------------------------------------------------------------------
885 // GetPropertyValueAsXXX methods
887 #define IMPLEMENT_GET_VALUE(T,TRET,BIGNAME,DEFRETVAL) \
888 TRET wxPropertyGridInterface::GetPropertyValueAs##BIGNAME( wxPGPropArg id ) const \
890 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(DEFRETVAL) \
891 wxVariant value = p->GetValue(); \
892 if ( wxStrcmp(value.GetType(), wxPGTypeName_##T) != 0 ) \
894 wxPGGetFailed(p,wxPGTypeName_##T); \
895 return (TRET)DEFRETVAL; \
897 return (TRET)value.Get##BIGNAME(); \
900 // String is different than others.
901 wxString
wxPropertyGridInterface::GetPropertyValueAsString( wxPGPropArg id
) const
903 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxEmptyString
)
904 return p
->GetValueAsString(wxPG_FULL_VALUE
);
907 bool wxPropertyGridInterface::GetPropertyValueAsBool( wxPGPropArg id
) const
909 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
910 wxVariant value
= p
->GetValue();
911 if ( wxStrcmp(value
.GetType(), wxPGTypeName_bool
) == 0 )
913 return value
.GetBool();
915 if ( wxStrcmp(value
.GetType(), wxPGTypeName_long
) == 0 )
917 return value
.GetLong()?true:false;
919 wxPGGetFailed(p
,wxPGTypeName_bool
);
923 IMPLEMENT_GET_VALUE(long,long,Long
,0)
924 IMPLEMENT_GET_VALUE(double,double,Double
,0.0)
926 bool wxPropertyGridInterface::IsPropertyExpanded( wxPGPropArg id
) const
928 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
929 return p
->IsExpanded();
932 // -----------------------------------------------------------------------
933 // wxPropertyGridInterface wrappers
934 // -----------------------------------------------------------------------
936 bool wxPropertyGridInterface::ChangePropertyValue( wxPGPropArg id
, wxVariant newValue
)
938 return GetPropertyGrid()->ChangePropertyValue(id
, newValue
);
941 // -----------------------------------------------------------------------
943 void wxPropertyGridInterface::BeginAddChildren( wxPGPropArg id
)
945 wxPG_PROP_ARG_CALL_PROLOG()
946 wxCHECK_RET( p
->HasFlag(wxPG_PROP_AGGREGATE
), wxT("only call on properties with fixed children") );
947 p
->ClearFlag(wxPG_PROP_AGGREGATE
);
948 p
->SetFlag(wxPG_PROP_MISC_PARENT
);
951 // -----------------------------------------------------------------------
953 bool wxPropertyGridInterface::EditorValidate()
955 return GetPropertyGrid()->DoEditorValidate();
958 // -----------------------------------------------------------------------
960 void wxPropertyGridInterface::EndAddChildren( wxPGPropArg id
)
962 wxPG_PROP_ARG_CALL_PROLOG()
963 wxCHECK_RET( p
->HasFlag(wxPG_PROP_MISC_PARENT
), wxT("only call on properties for which BeginAddChildren was called prior") );
964 p
->ClearFlag(wxPG_PROP_MISC_PARENT
);
965 p
->SetFlag(wxPG_PROP_AGGREGATE
);
968 // -----------------------------------------------------------------------
969 // wxPGVIterator_State
970 // -----------------------------------------------------------------------
972 // Default returned by wxPropertyGridInterface::GetVIterator().
973 class wxPGVIteratorBase_State
: public wxPGVIteratorBase
976 wxPGVIteratorBase_State( wxPropertyGridPageState
* state
, int flags
)
978 m_it
.Init( state
, flags
);
980 virtual ~wxPGVIteratorBase_State() { }
981 virtual void Next() { m_it
.Next(); }
984 wxPGVIterator
wxPropertyGridInterface::GetVIterator( int flags
) const
986 return wxPGVIterator( new wxPGVIteratorBase_State( m_pState
, flags
) );
989 // -----------------------------------------------------------------------
990 // wxPGEditableState related functions
991 // -----------------------------------------------------------------------
993 // EscapeDelimiters() changes ";" into "\;" and "|" into "\|"
994 // in the input string. This is an internal functions which is
995 // used for saving states
996 // NB: Similar function exists in aui/framemanager.cpp
997 static wxString
EscapeDelimiters(const wxString
& s
)
1000 result
.Alloc(s
.length());
1001 const wxChar
* ch
= s
.c_str();
1004 if (*ch
== wxT(';') || *ch
== wxT('|') || *ch
== wxT(','))
1005 result
+= wxT('\\');
1012 wxString
wxPropertyGridInterface::SaveEditableState( int includedStates
) const
1017 // Save state on page basis
1018 unsigned int pageIndex
= 0;
1019 wxArrayPtrVoid pageStates
;
1023 wxPropertyGridPageState
* page
= GetPageState(pageIndex
);
1026 pageStates
.Add(page
);
1031 for ( pageIndex
=0; pageIndex
< pageStates
.size(); pageIndex
++ )
1033 wxPropertyGridPageState
* pageState
= (wxPropertyGridPageState
*) pageStates
[pageIndex
];
1035 if ( includedStates
& SelectionState
)
1038 if ( pageState
->GetSelection() )
1039 sel
= pageState
->GetSelection()->GetName();
1040 result
+= wxS("selection=");
1041 result
+= EscapeDelimiters(sel
);
1044 if ( includedStates
& ExpandedState
)
1046 wxArrayPGProperty ptrs
;
1047 wxPropertyGridConstIterator it
=
1048 wxPropertyGridConstIterator( pageState
,
1049 wxPG_ITERATE_ALL_PARENTS_RECURSIVELY
|wxPG_ITERATE_HIDDEN
,
1052 result
+= wxS("expanded=");
1058 const wxPGProperty
* p
= it
.GetProperty();
1060 if ( !p
->HasFlag(wxPG_PROP_COLLAPSED
) )
1061 result
+= EscapeDelimiters(p
->GetName());
1066 if ( result
.Last() == wxS(',') )
1067 result
.RemoveLast();
1071 if ( includedStates
& ScrollPosState
)
1074 GetPropertyGrid()->GetViewStart(&x
,&y
);
1075 result
+= wxString::Format(wxS("scrollpos=%i,%i;"), x
, y
);
1077 if ( includedStates
& SplitterPosState
)
1079 result
+= wxS("splitterpos=");
1081 for ( size_t i
=0; i
<pageState
->GetColumnCount(); i
++ )
1082 result
+= wxString::Format(wxS("%i,"), pageState
->DoGetSplitterPosition(i
));
1084 result
.RemoveLast(); // Remove last comma
1087 if ( includedStates
& PageState
)
1089 result
+= wxS("ispageselected=");
1091 if ( GetPageState(-1) == pageState
)
1092 result
+= wxS("1;");
1094 result
+= wxS("0;");
1096 if ( includedStates
& DescBoxState
)
1098 wxVariant v
= GetEditableStateItem(wxS("descboxheight"));
1100 result
+= wxString::Format(wxS("descboxheight=%i;"), (int)v
.GetLong());
1102 result
.RemoveLast(); // Remove last semicolon
1107 if ( result
.length() )
1108 result
.RemoveLast();
1113 bool wxPropertyGridInterface::RestoreEditableState( const wxString
& src
, int restoreStates
)
1115 wxPropertyGrid
* pg
= GetPropertyGrid();
1116 wxPGProperty
* newSelection
= NULL
;
1120 long selectedPage
= -1;
1121 bool pgSelectionSet
= false;
1125 wxArrayString pageStrings
= ::wxSplit(src
, wxS('|'), wxS('\\'));
1127 for ( pageIndex
=0; pageIndex
<pageStrings
.size(); pageIndex
++ )
1129 wxPropertyGridPageState
* pageState
= GetPageState(pageIndex
);
1133 wxArrayString kvpairStrings
= ::wxSplit(pageStrings
[pageIndex
], wxS(';'), wxS('\\'));
1135 for ( size_t i
=0; i
<kvpairStrings
.size(); i
++ )
1137 const wxString
& kvs
= kvpairStrings
[i
];
1138 int eq_pos
= kvs
.Find(wxS('='));
1139 if ( eq_pos
!= wxNOT_FOUND
)
1141 wxString key
= kvs
.substr(0, eq_pos
);
1142 wxString value
= kvs
.substr(eq_pos
+1);
1144 // Further split value by commas
1145 wxArrayString values
= ::wxSplit(value
, wxS(','), wxS('\\'));
1147 if ( key
== wxS("expanded") )
1149 if ( restoreStates
& ExpandedState
)
1151 wxPropertyGridIterator it
=
1152 wxPropertyGridIterator( pageState
,
1156 // First collapse all
1157 for ( ; !it
.AtEnd(); it
.Next() )
1159 wxPGProperty
* p
= it
.GetProperty();
1160 pageState
->DoCollapse(p
);
1163 // Then expand those which names are in values
1164 for ( size_t n
=0; n
<values
.size(); n
++ )
1166 const wxString
& name
= values
[n
];
1167 wxPGProperty
* prop
= GetPropertyByName(name
);
1169 pageState
->DoExpand(prop
);
1173 else if ( key
== wxS("scrollpos") )
1175 if ( restoreStates
& ScrollPosState
)
1177 if ( values
.size() == 2 )
1179 values
[0].ToLong(&vx
);
1180 values
[1].ToLong(&vy
);
1188 else if ( key
== wxS("splitterpos") )
1190 if ( restoreStates
& SplitterPosState
)
1192 for ( size_t n
=1; n
<values
.size(); n
++ )
1195 values
[n
].ToLong(&pos
);
1197 pageState
->DoSetSplitterPosition(pos
, n
);
1201 else if ( key
== wxS("selection") )
1203 if ( restoreStates
& SelectionState
)
1205 if ( values
.size() > 0 )
1207 if ( pageState
->IsDisplayed() )
1209 if ( values
[0].length() )
1210 newSelection
= GetPropertyByName(value
);
1211 pgSelectionSet
= true;
1215 if ( values
[0].length() )
1216 pageState
->SetSelection(GetPropertyByName(value
));
1218 pageState
->DoClearSelection();
1223 else if ( key
== wxS("ispageselected") )
1225 if ( restoreStates
& PageState
)
1228 if ( values
.size() == 1 && values
[0].ToLong(&pageSelStatus
) )
1230 if ( pageSelStatus
)
1231 selectedPage
= pageIndex
;
1239 else if ( key
== wxS("descboxheight") )
1241 if ( restoreStates
& DescBoxState
)
1244 if ( values
.size() == 1 && values
[0].ToLong(&descBoxHeight
) )
1246 SetEditableStateItem(wxS("descboxheight"), descBoxHeight
);
1263 // Force recalculation of virtual heights of all pages
1264 // (may be needed on unclean source string).
1266 wxPropertyGridPageState
* pageState
= GetPageState(pageIndex
);
1269 pageState
->VirtualHeightChanged();
1271 pageState
= GetPageState(pageIndex
);
1277 // Selection of visible grid page must be set after Thaw() call
1278 if ( pgSelectionSet
)
1281 pg
->SelectProperty(newSelection
);
1283 pg
->ClearSelection();
1286 if ( selectedPage
!= -1 )
1288 DoSelectPage(selectedPage
);
1299 #endif // wxUSE_PROPGRID