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"
21 #include "wx/object.h"
23 #include "wx/string.h"
26 #include "wx/window.h"
29 #include "wx/dcmemory.h"
30 #include "wx/button.h"
33 #include "wx/cursor.h"
34 #include "wx/dialog.h"
35 #include "wx/settings.h"
36 #include "wx/msgdlg.h"
37 #include "wx/choice.h"
38 #include "wx/stattext.h"
39 #include "wx/scrolwin.h"
40 #include "wx/dirdlg.h"
41 #include "wx/layout.h"
43 #include "wx/textdlg.h"
44 #include "wx/filedlg.h"
45 #include "wx/statusbr.h"
50 #include <wx/propgrid/property.h>
51 #include <wx/propgrid/propgrid.h>
54 const wxChar
*wxPGTypeName_long
= wxT("long");
55 const wxChar
*wxPGTypeName_bool
= wxT("bool");
56 const wxChar
*wxPGTypeName_double
= wxT("double");
57 const wxChar
*wxPGTypeName_wxString
= wxT("string");
58 const wxChar
*wxPGTypeName_void
= wxT("void*");
59 const wxChar
*wxPGTypeName_wxArrayString
= wxT("arrstring");
62 // ----------------------------------------------------------------------------
64 // ----------------------------------------------------------------------------
66 WX_PG_IMPLEMENT_VARIANT_DATA(wxPGVariantDataPoint
, wxPoint
)
67 WX_PG_IMPLEMENT_VARIANT_DATA(wxPGVariantDataSize
, wxSize
)
68 WX_PG_IMPLEMENT_VARIANT_DATA(wxPGVariantDataArrayInt
, wxArrayInt
)
69 WX_PG_IMPLEMENT_VARIANT_DATA(wxPGVariantDataLongLong
, wxLongLong
)
70 WX_PG_IMPLEMENT_VARIANT_DATA(wxPGVariantDataULongLong
, wxULongLong
)
72 WX_PG_IMPLEMENT_WXOBJECT_VARIANT_DATA(wxPGVariantDataFont
, wxFont
)
74 wxObject
* wxPG_VariantToWxObject( const wxVariant
& variant
, wxClassInfo
* classInfo
)
76 if ( !variant
.IsValueKindOf(classInfo
) )
77 return (wxObject
*) NULL
;
79 wxVariantData
* vdata
= variant
.GetData();
81 wxPGVariantData
* pgvdata
= wxDynamicCastVariantData(vdata
, wxPGVariantData
);
83 return (wxObject
*) pgvdata
->GetValuePtr();
85 if ( wxPGIsVariantClassInfo(wxPGVariantDataGetClassInfo(vdata
), wxobject
) )
86 return variant
.GetWxObjectPtr();
88 return (wxObject
*) NULL
;
91 // -----------------------------------------------------------------------
93 // -----------------------------------------------------------------------
95 long wxPGVariantToInt( const wxVariant
& variant
, long defVal
)
97 if ( variant
.IsNull() )
100 if ( wxPGIsVariantType(variant
, long) )
101 return variant
.GetLong();
103 if ( wxPGIsVariantType(variant
, bool) )
104 return variant
.GetBool() ? 1 : 0;
106 if ( typeid(*variant
.GetData()) == typeid(wxPGVariantDataLongLong
) )
108 wxLongLong ll
= ((const wxPGVariantDataLongLong
&)variant
).GetValue();
109 if ( ll
>= LONG_MAX
)
111 else if ( ll
<= LONG_MIN
)
118 if ( wxPGIsVariantType(variant
, string
) )
119 variant
.GetString().ToLong(&l
, 0);
124 // -----------------------------------------------------------------------
126 bool wxPGVariantToLongLong( const wxVariant
& variant
, wxLongLong_t
* pResult
)
128 if ( variant
.IsNull() )
131 if ( wxPGIsVariantType(variant
, long) )
133 *pResult
= variant
.GetLong();
137 if ( typeid(*variant
.GetData()) == typeid(wxPGVariantDataLongLong
) )
139 *pResult
= ((const wxPGVariantDataLongLong
&)variant
).GetValue().GetValue();
146 // -----------------------------------------------------------------------
148 bool wxPGVariantToULongLong( const wxVariant
& variant
, wxULongLong_t
* pResult
)
150 if ( variant
.IsNull() )
153 if ( wxPGIsVariantType(variant
, long) )
155 *pResult
= (unsigned long)variant
.GetLong();
159 if ( typeid(*variant
.GetData()) == typeid(wxPGVariantDataULongLong
) )
161 *pResult
= ((const wxPGVariantDataULongLong
&)variant
).GetValue().GetValue();
168 // -----------------------------------------------------------------------
170 bool wxPGVariantToDouble( const wxVariant
& variant
, double* pResult
)
172 if ( variant
.IsNull() )
175 if ( wxPGIsVariantType(variant
, double) )
177 *pResult
= variant
.GetDouble();
181 if ( wxPGIsVariantType(variant
, long) )
183 *pResult
= (double)variant
.GetLong();
187 if ( typeid(*variant
.GetData()) == typeid(wxPGVariantDataLongLong
) )
189 wxLongLong ll
= ((const wxPGVariantDataLongLong
&)variant
).GetValue();
190 *pResult
= ll
.ToDouble();
194 if ( wxPGIsVariantType(variant
, string
) )
195 if ( variant
.GetString().ToDouble(pResult
) )
201 // -----------------------------------------------------------------------
202 // Choice related methods
203 // -----------------------------------------------------------------------
205 void wxPropertyGridInterface::AddPropertyChoice( wxPGPropArg id
,
206 const wxString
& label
,
209 wxPG_PROP_ARG_CALL_PROLOG()
211 p
->InsertChoice(label
,-1,value
);
215 void wxPropertyGridInterface::InsertPropertyChoice( wxPGPropArg id
,
216 const wxString
& label
,
220 wxPG_PROP_ARG_CALL_PROLOG()
222 p
->InsertChoice(label
,index
,value
);
226 void wxPropertyGridInterface::DeletePropertyChoice( wxPGPropArg id
,
229 wxPG_PROP_ARG_CALL_PROLOG()
231 p
->DeleteChoice(index
);
234 // -----------------------------------------------------------------------
236 void wxPropertyGridInterface::RefreshGrid( wxPropertyGridPageState
* state
)
241 wxPropertyGrid
* grid
= state
->GetGrid();
242 if ( grid
->GetState() == state
&& !grid
->IsFrozen() )
248 // -----------------------------------------------------------------------
250 wxPGProperty
* wxPropertyGridInterface::Append( wxPGProperty
* property
)
252 wxPGProperty
* retp
= m_pState
->DoAppend(property
);
254 wxPropertyGrid
* grid
= m_pState
->GetGrid();
261 // -----------------------------------------------------------------------
263 wxPGProperty
* wxPropertyGridInterface::AppendIn( wxPGPropArg id
, wxPGProperty
* newproperty
)
265 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty
)
266 wxPGProperty
* pwc
= (wxPGProperty
*) p
;
267 wxPGProperty
* retp
= m_pState
->DoInsert(pwc
, pwc
->GetChildCount(), newproperty
);
271 // -----------------------------------------------------------------------
273 wxPGProperty
* wxPropertyGridInterface::Insert( wxPGPropArg id
, wxPGProperty
* property
)
275 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty
)
276 wxPGProperty
* retp
= m_pState
->DoInsert(p
->GetParent(), p
->GetArrIndex(), property
);
281 // -----------------------------------------------------------------------
283 wxPGProperty
* wxPropertyGridInterface::Insert( wxPGPropArg id
, int index
, wxPGProperty
* newproperty
)
285 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty
)
286 wxPGProperty
* retp
= m_pState
->DoInsert((wxPGProperty
*)p
,index
,newproperty
);
291 // -----------------------------------------------------------------------
293 void wxPropertyGridInterface::DeleteProperty( wxPGPropArg id
)
295 wxPG_PROP_ARG_CALL_PROLOG()
297 wxPropertyGridPageState
* state
= p
->GetParentState();
298 wxPropertyGrid
* grid
= state
->GetGrid();
300 if ( grid
->GetState() == state
)
302 bool selRes
= grid
->DoSelectProperty(NULL
, wxPG_SEL_DELETING
);
303 wxPG_CHECK_RET_DBG( selRes
,
304 wxT("failed to deselect a property (editor probably had invalid value)") );
307 state
->DoDelete( p
);
312 // -----------------------------------------------------------------------
314 wxPGProperty
* wxPropertyGridInterface::ReplaceProperty( wxPGPropArg id
, wxPGProperty
* property
)
316 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty
)
318 wxPGProperty
* replaced
= p
;
319 wxCHECK_MSG( replaced
&& property
,
321 wxT("NULL property") );
322 wxCHECK_MSG( !replaced
->IsCategory(),
324 wxT("cannot replace this type of property") );
325 wxCHECK_MSG( !m_pState
->IsInNonCatMode(),
327 wxT("cannot replace properties in alphabetic mode") );
329 // Get address to the slot
330 wxPGProperty
* parent
= replaced
->GetParent();
331 int ind
= replaced
->GetIndexInParent();
333 wxPropertyGridPageState
* state
= replaced
->GetParentState();
334 DeleteProperty(replaced
); // Must use generic Delete
335 state
->DoInsert(parent
,ind
,property
);
340 // -----------------------------------------------------------------------
341 // wxPropertyGridInterface property operations
342 // -----------------------------------------------------------------------
344 bool wxPropertyGridInterface::ClearSelection()
346 wxPropertyGridPageState
* state
= m_pState
;
347 wxPropertyGrid
* pg
= state
->GetGrid();
348 if ( pg
->GetState() == state
)
349 return pg
->DoClearSelection();
351 state
->SetSelection(NULL
);
355 // -----------------------------------------------------------------------
357 void wxPropertyGridInterface::LimitPropertyEditing( wxPGPropArg id
, bool limit
)
359 wxPG_PROP_ARG_CALL_PROLOG()
361 m_pState
->DoLimitPropertyEditing(p
, limit
);
365 // -----------------------------------------------------------------------
367 bool wxPropertyGridInterface::EnableProperty( wxPGPropArg id
, bool enable
)
369 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
371 wxPropertyGridPageState
* state
= p
->GetParentState();
372 wxPropertyGrid
* grid
= state
->GetGrid();
376 if ( !(p
->m_flags
& wxPG_PROP_DISABLED
) )
379 // If active, Set active Editor.
380 if ( grid
->GetState() == state
&& p
== grid
->GetSelection() )
381 grid
->DoSelectProperty( p
, wxPG_SEL_FORCE
);
385 if ( p
->m_flags
& wxPG_PROP_DISABLED
)
388 // If active, Disable as active Editor.
389 if ( grid
->GetState() == state
&& p
== grid
->GetSelection() )
390 grid
->DoSelectProperty( p
, wxPG_SEL_FORCE
);
393 state
->DoEnableProperty(p
, enable
);
395 RefreshProperty( p
);
400 // -----------------------------------------------------------------------
402 bool wxPropertyGridInterface::ExpandAll( bool doExpand
)
404 wxPropertyGridPageState
* state
= m_pState
;
406 if ( !state
->DoGetRoot()->GetChildCount() )
409 wxPropertyGrid
* pg
= state
->GetGrid();
411 if ( GetSelection() && GetSelection() != state
->DoGetRoot() &&
414 if ( !pg
->ClearSelection() )
420 for ( it
= GetVIterator( wxPG_ITERATE_ALL
); !it
.AtEnd(); it
.Next() )
422 wxPGProperty
* p
= (wxPGProperty
*) it
.GetProperty();
423 if ( p
->GetChildCount() )
427 if ( !p
->IsExpanded() )
434 if ( p
->IsExpanded() )
436 state
->DoCollapse(p
);
442 pg
->RecalculateVirtualSize();
449 // -----------------------------------------------------------------------
451 void wxPropertyGridInterface::SetPropertyValueUnspecified( wxPGPropArg id
)
453 wxPG_PROP_ARG_CALL_PROLOG()
454 wxPropertyGrid
* propGrid
= p
->GetGridIfDisplayed();
456 propGrid
->DoSetPropertyValueUnspecified(p
);
458 p
->GetParentState()->DoSetPropertyValueUnspecified(p
);
461 // -----------------------------------------------------------------------
462 // wxPropertyGridInterface property value setting and getting
463 // -----------------------------------------------------------------------
465 void wxPGGetFailed( const wxPGProperty
* p
, const wxChar
* typestr
)
467 wxPGTypeOperationFailed(p
,typestr
,wxT("Get"));
470 // -----------------------------------------------------------------------
472 void wxPGTypeOperationFailed( const wxPGProperty
* p
, const wxChar
* typestr
,
475 wxASSERT( p
!= NULL
);
476 wxLogError( _("Type operation \"%s\" failed: Property labeled \"%s\" is of type \"%s\", NOT \"%s\"."),
477 op
,p
->GetLabel().c_str(),p
->GetValue().GetType().c_str(),typestr
);
480 // -----------------------------------------------------------------------
482 void wxPropertyGridInterface::SetPropVal( wxPGPropArg id
, wxVariant
& value
)
484 wxPG_PROP_ARG_CALL_PROLOG()
489 wxPropertyGrid
* propGrid
= p
->GetGridIfDisplayed();
491 propGrid
->DrawItemAndValueRelated( p
);
496 // -----------------------------------------------------------------------
498 void wxPropertyGridInterface::SetPropertyValueString( wxPGPropArg id
, const wxString
& value
)
500 wxPG_PROP_ARG_CALL_PROLOG()
502 if ( m_pState
->DoSetPropertyValueString(p
,value
) )
504 wxPropertyGrid
* propGrid
= p
->GetGridIfDisplayed();
506 propGrid
->DrawItemAndValueRelated( p
);
510 // -----------------------------------------------------------------------
512 void wxPropertyGridInterface::SetValidationFailureBehavior( int vfbFlags
)
514 GetPropertyGrid()->m_permanentValidationFailureBehavior
= vfbFlags
;
517 // -----------------------------------------------------------------------
519 wxPGProperty
* wxPropertyGridInterface::GetPropertyByNameA( const wxString
& name
) const
521 wxPGProperty
* p
= GetPropertyByName(name
);
522 wxASSERT_MSG(p
,wxString::Format(wxT("no property with name '%s'"),name
.c_str()));
526 // ----------------------------------------------------------------------------
528 wxPGProperty
* wxPropertyGridInterface::GetPropertyByLabel( const wxString
& label
) const
532 for ( it
= GetVIterator( wxPG_ITERATE_PROPERTIES
); !it
.AtEnd(); it
.Next() )
534 if ( it
.GetProperty()->GetLabel() == label
)
535 return it
.GetProperty();
538 return wxNullProperty
;
541 // ----------------------------------------------------------------------------
543 void wxPropertyGridInterface::DoSetPropertyAttribute( wxPGPropArg id
, const wxString
& name
,
544 wxVariant
& value
, long argFlags
)
546 wxPG_PROP_ARG_CALL_PROLOG()
548 p
->SetAttribute( name
, value
);
550 if ( argFlags
& wxPG_RECURSE
)
553 for ( i
= 0; i
< p
->GetChildCount(); i
++ )
554 DoSetPropertyAttribute(p
->Item(i
), name
, value
, argFlags
);
558 // -----------------------------------------------------------------------
560 void wxPropertyGridInterface::GetPropertiesWithFlag( wxArrayPGProperty
* targetArr
,
561 wxPGProperty::FlagType flags
,
563 int iterFlags
) const
565 wxASSERT( targetArr
);
566 wxPGVIterator it
= GetVIterator( iterFlags
);
572 const wxPGProperty
* property
= it
.GetProperty();
576 if ( (property
->GetFlags() & flags
) == flags
)
577 targetArr
->push_back((wxPGProperty
*)property
);
581 if ( (property
->GetFlags() & flags
) != flags
)
582 targetArr
->push_back((wxPGProperty
*)property
);
587 // -----------------------------------------------------------------------
589 void wxPropertyGridInterface::SetPropertiesFlag( const wxArrayPGProperty
& srcArr
,
590 wxPGProperty::FlagType flags
,
595 for ( i
=0; i
<srcArr
.size(); i
++ )
597 wxPGProperty
* property
= srcArr
[i
];
600 property
->SetFlag(flags
);
602 property
->ClearFlag(flags
);
605 // If collapsed flag or hidden was manipulated, we need to update virtual
607 wxPropertyGrid
* pg
= GetPropertyGrid();
608 if ( flags
& (wxPG_PROP_COLLAPSED
|wxPG_PROP_HIDDEN
) )
610 GetState()->VirtualHeightChanged();
611 pg
->RecalculateVirtualSize();
615 // -----------------------------------------------------------------------
617 void wxPropertyGridInterface::SetBoolChoices( const wxString
& trueChoice
,
618 const wxString
& falseChoice
)
620 wxPGGlobalVars
->m_boolChoices
[0] = falseChoice
;
621 wxPGGlobalVars
->m_boolChoices
[1] = trueChoice
;
624 // -----------------------------------------------------------------------
626 wxPGChoices gs_emptyChoices
;
628 wxPGChoices
& wxPropertyGridInterface::GetPropertyChoices( wxPGPropArg id
)
630 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(gs_emptyChoices
)
633 ci
.m_choices
= (wxPGChoices
*) NULL
;
635 p
->GetChoiceInfo(&ci
);
638 return gs_emptyChoices
;
640 return *ci
.m_choices
;
643 // -----------------------------------------------------------------------
645 wxPGProperty
* wxPropertyGridInterface::DoGetPropertyByName( const wxString
& name
) const
647 return m_pState
->BaseGetPropertyByName(name
);
650 // -----------------------------------------------------------------------
652 wxPGProperty
* wxPropertyGridInterface::GetPropertyByName( const wxString
& name
,
653 const wxString
& subname
) const
655 wxPGProperty
* p
= DoGetPropertyByName(name
);
656 if ( !p
|| !p
->GetChildCount() )
657 return wxNullProperty
;
659 return p
->GetPropertyByName(subname
);
662 // -----------------------------------------------------------------------
664 // Since GetPropertyByName is used *a lot*, this makes sense
665 // since non-virtual method can be called with less code.
666 wxPGProperty
* wxPropertyGridInterface::GetPropertyByName( const wxString
& name
) const
668 wxPGProperty
* p
= DoGetPropertyByName(name
);
672 // Check if its "Property.SubProperty" format
673 int pos
= name
.Find(wxT('.'));
677 return GetPropertyByName(name
.substr(0,pos
),
678 name
.substr(pos
+1,name
.length()-pos
-1));
681 // -----------------------------------------------------------------------
683 bool wxPropertyGridInterface::HideProperty( wxPGPropArg id
, bool hide
, int flags
)
685 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
687 wxPropertyGrid
* pg
= m_pState
->GetGrid();
689 if ( pg
== p
->GetGrid() )
690 return pg
->DoHideProperty(p
, hide
, flags
);
692 m_pState
->DoHideProperty(p
, hide
, flags
);
697 // -----------------------------------------------------------------------
699 bool wxPropertyGridInterface::Collapse( wxPGPropArg id
)
701 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
702 wxPropertyGrid
* pg
= p
->GetGridIfDisplayed();
704 return pg
->DoCollapse(p
);
706 return p
->GetParentState()->DoCollapse(p
);
709 // -----------------------------------------------------------------------
711 bool wxPropertyGridInterface::Expand( wxPGPropArg id
)
713 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
714 wxPropertyGrid
* pg
= p
->GetGridIfDisplayed();
716 return pg
->DoExpand(p
);
718 return p
->GetParentState()->DoExpand(p
);
721 // -----------------------------------------------------------------------
723 void wxPropertyGridInterface::SetPropertyLabel( wxPGPropArg id
, const wxString
& newproplabel
)
725 wxPG_PROP_ARG_CALL_PROLOG()
727 p
->SetLabel( newproplabel
);
729 wxPropertyGridPageState
* state
= p
->GetParentState();
730 wxPropertyGrid
* pg
= state
->GetGrid();
732 if ( pg
->HasFlag(wxPG_AUTO_SORT
) )
733 pg
->SortChildren(p
->GetParent());
735 if ( pg
->GetState() == state
)
737 if ( pg
->HasFlag(wxPG_AUTO_SORT
) )
744 // -----------------------------------------------------------------------
746 bool wxPropertyGridInterface::SetPropertyMaxLength( wxPGPropArg id
, int maxLen
)
748 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
750 wxPropertyGrid
* pg
= m_pState
->GetGrid();
752 p
->m_maxLen
= (short) maxLen
;
754 // Adjust control if selected currently
755 if ( pg
== p
->GetGrid() && p
== m_pState
->GetSelection() )
757 wxWindow
* wnd
= pg
->GetEditorControl();
758 wxTextCtrl
* tc
= wxDynamicCast(wnd
,wxTextCtrl
);
760 tc
->SetMaxLength( maxLen
);
769 // -----------------------------------------------------------------------
770 // GetPropertyValueAsXXX methods
772 #define IMPLEMENT_GET_VALUE(T,TRET,BIGNAME,DEFRETVAL) \
773 TRET wxPropertyGridInterface::GetPropertyValueAs##BIGNAME( wxPGPropArg id ) const \
775 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(DEFRETVAL) \
776 wxVariant value = p->GetValue(); \
777 if ( wxStrcmp(value.GetType(), wxPGTypeName_##T) != 0 ) \
779 wxPGGetFailed(p,wxPGTypeName_##T); \
780 return (TRET)DEFRETVAL; \
782 return (TRET)value.Get##BIGNAME(); \
785 // String is different than others.
786 wxString
wxPropertyGridInterface::GetPropertyValueAsString( wxPGPropArg id
) const
788 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxEmptyString
)
789 return p
->GetValueAsString(wxPG_FULL_VALUE
);
792 bool wxPropertyGridInterface::GetPropertyValueAsBool( wxPGPropArg id
) const
794 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
795 wxVariant value
= p
->GetValue();
796 if ( wxStrcmp(value
.GetType(), wxPGTypeName_bool
) == 0 )
798 return value
.GetBool();
800 if ( wxStrcmp(value
.GetType(), wxPGTypeName_long
) == 0 )
802 return value
.GetLong()?true:false;
804 wxPGGetFailed(p
,wxPGTypeName_bool
);
808 IMPLEMENT_GET_VALUE(long,long,Long
,0)
809 IMPLEMENT_GET_VALUE(double,double,Double
,0.0)
810 IMPLEMENT_GET_VALUE(void,void*,VoidPtr
,NULL
)
812 // wxObject is different than others.
813 wxObject
* wxPropertyGridInterface::GetPropertyValueAsWxObjectPtr( wxPGPropArg id
) const
815 wxPG_PROP_ARG_CALL_PROLOG_RETVAL((wxObject
*)NULL
)
817 wxVariant value
= p
->GetValue();
818 wxVariantData
* vdata
= value
.GetData();
820 if ( !vdata
->GetValueClassInfo() )
821 return (wxObject
*) NULL
;
823 wxPGVariantData
* pgvdata
= wxDynamicCastVariantData(vdata
, wxPGVariantData
);
825 return (wxObject
*) pgvdata
->GetValuePtr();
827 if ( wxPGIsVariantClassInfo(wxPGVariantDataGetClassInfo(vdata
), wxobject
) )
828 return (wxObject
*) value
.GetWxObjectPtr();
830 return (wxObject
*) NULL
;
833 // -----------------------------------------------------------------------
835 bool wxPropertyGridInterface::IsPropertyExpanded( wxPGPropArg id
) const
837 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
838 return p
->IsExpanded();
841 // -----------------------------------------------------------------------
842 // wxPropertyGridInterface wrappers
843 // -----------------------------------------------------------------------
845 bool wxPropertyGridInterface::ChangePropertyValue( wxPGPropArg id
, wxVariant newValue
)
847 return GetPropertyGrid()->ChangePropertyValue(id
, newValue
);
850 // -----------------------------------------------------------------------
852 void wxPropertyGridInterface::BeginAddChildren( wxPGPropArg id
)
854 wxPG_PROP_ARG_CALL_PROLOG()
855 wxCHECK_RET( p
->HasFlag(wxPG_PROP_AGGREGATE
), wxT("only call on properties with fixed children") );
856 p
->ClearFlag(wxPG_PROP_AGGREGATE
);
857 p
->SetFlag(wxPG_PROP_MISC_PARENT
);
860 // -----------------------------------------------------------------------
862 bool wxPropertyGridInterface::EditorValidate()
864 return GetPropertyGrid()->DoEditorValidate();
867 // -----------------------------------------------------------------------
869 void wxPropertyGridInterface::EndAddChildren( wxPGPropArg id
)
871 wxPG_PROP_ARG_CALL_PROLOG()
872 wxCHECK_RET( p
->HasFlag(wxPG_PROP_MISC_PARENT
), wxT("only call on properties for which BeginAddChildren was called prior") );
873 p
->ClearFlag(wxPG_PROP_MISC_PARENT
);
874 p
->SetFlag(wxPG_PROP_AGGREGATE
);
877 // -----------------------------------------------------------------------
878 // wxPGVIterator_State
879 // -----------------------------------------------------------------------
881 // Default returned by wxPropertyGridInterface::GetVIterator().
882 class wxPGVIteratorBase_State
: public wxPGVIteratorBase
885 wxPGVIteratorBase_State( wxPropertyGridPageState
* state
, int flags
)
887 m_it
.Init( state
, flags
);
889 virtual ~wxPGVIteratorBase_State() { }
890 virtual void Next() { m_it
.Next(); }
893 wxPGVIterator
wxPropertyGridInterface::GetVIterator( int flags
) const
895 return wxPGVIterator( new wxPGVIteratorBase_State( m_pState
, flags
) );
898 // -----------------------------------------------------------------------
899 // wxPGEditableState related functions
900 // -----------------------------------------------------------------------
902 // EscapeDelimiters() changes ";" into "\;" and "|" into "\|"
903 // in the input string. This is an internal functions which is
904 // used for saving states
905 // NB: Similar function exists in aui/framemanager.cpp
906 static wxString
EscapeDelimiters(const wxString
& s
)
909 result
.Alloc(s
.length());
910 const wxChar
* ch
= s
.c_str();
913 if (*ch
== wxT(';') || *ch
== wxT('|') || *ch
== wxT(','))
921 wxString
wxPropertyGridInterface::SaveEditableState( int includedStates
) const
926 // Save state on page basis
927 size_t pageIndex
= 0;
928 wxPropertyGridPageState
* pageState
= GetPageState(pageIndex
);
929 wxArrayPtrVoid pageStates
;
932 pageStates
.Add(pageState
);
934 pageState
= GetPageState(pageIndex
);
937 for ( pageIndex
=0; pageIndex
< pageStates
.size(); pageIndex
++ )
939 wxPropertyGridPageState
* pageState
= (wxPropertyGridPageState
*) pageStates
[pageIndex
];
941 if ( includedStates
& SelectionState
)
944 if ( pageState
->GetSelection() )
945 sel
= pageState
->GetSelection()->GetName();
946 result
+= wxS("selection=");
947 result
+= EscapeDelimiters(sel
);
950 if ( includedStates
& ExpandedState
)
952 wxArrayPGProperty ptrs
;
953 wxPropertyGridConstIterator it
=
954 wxPropertyGridConstIterator( pageState
,
955 wxPG_ITERATE_ALL_PARENTS_RECURSIVELY
|wxPG_ITERATE_HIDDEN
,
958 result
+= wxS("expanded=");
964 const wxPGProperty
* p
= it
.GetProperty();
966 if ( !p
->HasFlag(wxPG_PROP_COLLAPSED
) )
967 result
+= EscapeDelimiters(p
->GetName());
972 if ( result
.Last() == wxS(',') )
977 if ( includedStates
& ScrollPosState
)
980 GetPropertyGrid()->GetViewStart(&x
,&y
);
981 result
+= wxString::Format(wxS("scrollpos=%i,%i;"), x
, y
);
983 if ( includedStates
& SplitterPosState
)
985 result
+= wxS("splitterpos=");
987 for ( size_t i
=0; i
<pageState
->GetColumnCount(); i
++ )
988 result
+= wxString::Format(wxS("%i,"), pageState
->DoGetSplitterPosition(i
));
990 result
.RemoveLast(); // Remove last comma
993 if ( includedStates
& PageState
)
995 result
+= wxS("ispageselected=");
997 if ( GetPageState(-1) == pageState
)
1000 result
+= wxS("0;");
1002 result
.RemoveLast(); // Remove last semicolon
1007 if ( result
.length() )
1008 result
.RemoveLast();
1013 bool wxPropertyGridInterface::RestoreEditableState( const wxString
& src
, int restoreStates
)
1015 wxPropertyGrid
* pg
= GetPropertyGrid();
1016 wxPGProperty
* newSelection
= NULL
;
1020 long selectedPage
= -1;
1021 bool pgSelectionSet
= false;
1025 wxArrayString pageStrings
= ::wxSplit(src
, wxS('|'), wxS('\\'));
1027 for ( pageIndex
=0; pageIndex
<pageStrings
.size(); pageIndex
++ )
1029 wxPropertyGridPageState
* pageState
= GetPageState(pageIndex
);
1033 wxArrayString kvpairStrings
= ::wxSplit(pageStrings
[pageIndex
], wxS(';'), wxS('\\'));
1035 for ( size_t i
=0; i
<kvpairStrings
.size(); i
++ )
1037 const wxString
& kvs
= kvpairStrings
[i
];
1038 int eq_pos
= kvs
.Find(wxS('='));
1039 if ( eq_pos
!= wxNOT_FOUND
)
1041 wxString key
= kvs
.substr(0, eq_pos
);
1042 wxString value
= kvs
.substr(eq_pos
+1);
1044 // Further split value by commas
1045 wxArrayString values
= ::wxSplit(value
, wxS(','), wxS('\\'));
1047 if ( key
== wxS("expanded") )
1049 if ( restoreStates
& ExpandedState
)
1051 wxPropertyGridIterator it
=
1052 wxPropertyGridIterator( pageState
,
1056 // First collapse all
1057 for ( ; !it
.AtEnd(); it
.Next() )
1059 wxPGProperty
* p
= it
.GetProperty();
1060 pageState
->DoCollapse(p
);
1063 // Then expand those which names are in values
1064 for ( size_t n
=0; n
<values
.size(); n
++ )
1066 const wxString
& name
= values
[n
];
1067 wxPGProperty
* prop
= GetPropertyByName(name
);
1069 pageState
->DoExpand(prop
);
1073 else if ( key
== wxS("scrollpos") )
1075 if ( restoreStates
& ScrollPosState
)
1077 if ( values
.size() == 2 )
1079 values
[0].ToLong(&vx
);
1080 values
[1].ToLong(&vy
);
1088 else if ( key
== wxS("splitterpos") )
1090 if ( restoreStates
& SplitterPosState
)
1092 for ( size_t n
=1; n
<values
.size(); n
++ )
1095 values
[n
].ToLong(&pos
);
1097 pageState
->DoSetSplitterPosition(pos
, n
);
1101 else if ( key
== wxS("selection") )
1103 if ( restoreStates
& SelectionState
)
1105 if ( values
.size() > 0 )
1107 if ( pageState
->IsDisplayed() )
1109 if ( values
[0].length() )
1110 newSelection
= GetPropertyByName(value
);
1111 pgSelectionSet
= true;
1115 if ( values
[0].length() )
1116 pageState
->SetSelection(GetPropertyByName(value
));
1118 pageState
->DoClearSelection();
1123 else if ( key
== wxS("ispageselected") )
1125 if ( restoreStates
& PageState
)
1128 if ( values
.size() == 1 && values
[0].ToLong(&pageSelStatus
) )
1130 if ( pageSelStatus
)
1131 selectedPage
= pageIndex
;
1148 // Force recalculation of virtual heights of all pages
1149 // (may be needed on unclean source string).
1151 wxPropertyGridPageState
* pageState
= GetPageState(pageIndex
);
1154 pageState
->VirtualHeightChanged();
1156 pageState
= GetPageState(pageIndex
);
1162 // Selection of visible grid page must be set after Thaw() call
1163 if ( pgSelectionSet
)
1166 pg
->SelectProperty(newSelection
);
1168 pg
->ClearSelection();
1171 if ( selectedPage
!= -1 )
1173 DoSelectPage(selectedPage
);