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
)
59 IMPLEMENT_VARIANT_OBJECT_EXPORTED(wxFont
, WXDLLIMPEXP_PROPGRID
)
61 // -----------------------------------------------------------------------
63 // -----------------------------------------------------------------------
65 wxPGProperty
* wxPGPropArgCls::GetPtr( wxPropertyGridInterface
* iface
) const
67 if ( m_flags
== IsProperty
)
69 wxASSERT_MSG( m_ptr
.property
, wxT("invalid property ptr") );
70 return m_ptr
.property
;
72 else if ( m_flags
& IsWxString
)
73 return iface
->GetPropertyByNameA(*m_ptr
.stringName
);
74 else if ( m_flags
& IsCharPtr
)
75 return iface
->GetPropertyByNameA(m_ptr
.charName
);
77 else if ( m_flags
& IsWCharPtr
)
78 return iface
->GetPropertyByNameA(m_ptr
.wcharName
);
84 // -----------------------------------------------------------------------
85 // wxPropertyGridInterface
86 // -----------------------------------------------------------------------
88 void wxPropertyGridInterface::RefreshGrid( wxPropertyGridPageState
* state
)
93 wxPropertyGrid
* grid
= state
->GetGrid();
94 if ( grid
->GetState() == state
&& !grid
->IsFrozen() )
100 // -----------------------------------------------------------------------
102 wxPGProperty
* wxPropertyGridInterface::Append( wxPGProperty
* property
)
104 wxPGProperty
* retp
= m_pState
->DoAppend(property
);
106 wxPropertyGrid
* grid
= m_pState
->GetGrid();
113 // -----------------------------------------------------------------------
115 wxPGProperty
* wxPropertyGridInterface::AppendIn( wxPGPropArg id
, wxPGProperty
* newproperty
)
117 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty
)
118 wxPGProperty
* pwc
= (wxPGProperty
*) p
;
119 wxPGProperty
* retp
= m_pState
->DoInsert(pwc
, pwc
->GetChildCount(), newproperty
);
123 // -----------------------------------------------------------------------
125 wxPGProperty
* wxPropertyGridInterface::Insert( wxPGPropArg id
, wxPGProperty
* property
)
127 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty
)
128 wxPGProperty
* retp
= m_pState
->DoInsert(p
->GetParent(), p
->GetIndexInParent(), property
);
133 // -----------------------------------------------------------------------
135 wxPGProperty
* wxPropertyGridInterface::Insert( wxPGPropArg id
, int index
, wxPGProperty
* newproperty
)
137 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty
)
138 wxPGProperty
* retp
= m_pState
->DoInsert((wxPGProperty
*)p
,index
,newproperty
);
143 // -----------------------------------------------------------------------
145 void wxPropertyGridInterface::DeleteProperty( wxPGPropArg id
)
147 wxPG_PROP_ARG_CALL_PROLOG()
149 wxPropertyGridPageState
* state
= p
->GetParentState();
151 state
->DoDelete( p
, true );
156 // -----------------------------------------------------------------------
158 wxPGProperty
* wxPropertyGridInterface::RemoveProperty( wxPGPropArg id
)
160 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty
)
162 wxCHECK( !p
->GetChildCount() || p
->HasFlag(wxPG_PROP_AGGREGATE
),
165 wxPropertyGridPageState
* state
= p
->GetParentState();
167 state
->DoDelete( p
, false );
169 // Mark the property as 'unattached'
170 p
->m_parentState
= NULL
;
178 // -----------------------------------------------------------------------
180 wxPGProperty
* wxPropertyGridInterface::ReplaceProperty( wxPGPropArg id
, wxPGProperty
* property
)
182 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty
)
184 wxPGProperty
* replaced
= p
;
185 wxCHECK_MSG( replaced
&& property
,
187 wxT("NULL property") );
188 wxCHECK_MSG( !replaced
->IsCategory(),
190 wxT("cannot replace this type of property") );
191 wxCHECK_MSG( !m_pState
->IsInNonCatMode(),
193 wxT("cannot replace properties in alphabetic mode") );
195 // Get address to the slot
196 wxPGProperty
* parent
= replaced
->GetParent();
197 int ind
= replaced
->GetIndexInParent();
199 wxPropertyGridPageState
* state
= replaced
->GetParentState();
200 DeleteProperty(replaced
); // Must use generic Delete
201 state
->DoInsert(parent
,ind
,property
);
206 // -----------------------------------------------------------------------
207 // wxPropertyGridInterface property operations
208 // -----------------------------------------------------------------------
210 wxPGProperty
* wxPropertyGridInterface::GetSelection() const
212 return m_pState
->GetSelection();
215 // -----------------------------------------------------------------------
217 bool wxPropertyGridInterface::ClearSelection( bool validation
)
219 bool res
= DoClearSelection(validation
, wxPG_SEL_DONT_SEND_EVENT
);
220 wxPropertyGrid
* pg
= GetPropertyGrid();
226 // -----------------------------------------------------------------------
228 bool wxPropertyGridInterface::DoClearSelection( bool validation
,
232 selFlags
|= wxPG_SEL_NOVALIDATE
;
234 wxPropertyGridPageState
* state
= m_pState
;
238 wxPropertyGrid
* pg
= state
->GetGrid();
239 if ( pg
->GetState() == state
)
240 return pg
->DoSelectProperty(NULL
, selFlags
);
242 state
->DoSetSelection(NULL
);
248 // -----------------------------------------------------------------------
250 void wxPropertyGridInterface::LimitPropertyEditing( wxPGPropArg id
, bool limit
)
252 wxPG_PROP_ARG_CALL_PROLOG()
254 m_pState
->DoLimitPropertyEditing(p
, limit
);
258 // -----------------------------------------------------------------------
260 bool wxPropertyGridInterface::EnableProperty( wxPGPropArg id
, bool enable
)
262 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
264 wxPropertyGridPageState
* state
= p
->GetParentState();
265 wxPropertyGrid
* grid
= state
->GetGrid();
269 if ( !(p
->m_flags
& wxPG_PROP_DISABLED
) )
272 // If active, Set active Editor.
273 if ( grid
->GetState() == state
&& p
== grid
->GetSelection() )
274 grid
->DoSelectProperty( p
, wxPG_SEL_FORCE
);
278 if ( p
->m_flags
& wxPG_PROP_DISABLED
)
281 // If active, Disable as active Editor.
282 if ( grid
->GetState() == state
&& p
== grid
->GetSelection() )
283 grid
->DoSelectProperty( p
, wxPG_SEL_FORCE
);
286 state
->DoEnableProperty(p
, enable
);
288 RefreshProperty( p
);
293 // -----------------------------------------------------------------------
295 bool wxPropertyGridInterface::ExpandAll( bool doExpand
)
297 wxPropertyGridPageState
* state
= m_pState
;
299 if ( !state
->DoGetRoot()->GetChildCount() )
302 wxPropertyGrid
* pg
= state
->GetGrid();
304 if ( GetSelection() && GetSelection() != state
->DoGetRoot() &&
307 pg
->DoClearSelection();
312 for ( it
= GetVIterator( wxPG_ITERATE_ALL
); !it
.AtEnd(); it
.Next() )
314 wxPGProperty
* p
= (wxPGProperty
*) it
.GetProperty();
315 if ( p
->GetChildCount() )
319 if ( !p
->IsExpanded() )
326 if ( p
->IsExpanded() )
328 state
->DoCollapse(p
);
334 pg
->RecalculateVirtualSize();
341 // -----------------------------------------------------------------------
343 void wxPropertyGridInterface::ClearModifiedStatus()
345 unsigned int pageIndex
= 0;
349 wxPropertyGridPageState
* page
= GetPageState(pageIndex
);
352 page
->DoGetRoot()->SetFlagRecursively(wxPG_PROP_MODIFIED
, false);
357 // Update active editor control, if any
358 GetPropertyGrid()->RefreshEditor();
361 // -----------------------------------------------------------------------
362 // wxPropertyGridInterface property value setting and getting
363 // -----------------------------------------------------------------------
365 void wxPGGetFailed( const wxPGProperty
* p
, const wxString
& typestr
)
367 wxPGTypeOperationFailed(p
, typestr
, wxS("Get"));
370 // -----------------------------------------------------------------------
372 void wxPGTypeOperationFailed( const wxPGProperty
* p
,
373 const wxString
& typestr
,
376 wxASSERT( p
!= NULL
);
377 wxLogError( _("Type operation \"%s\" failed: Property labeled \"%s\" is of type \"%s\", NOT \"%s\"."),
378 op
.c_str(), p
->GetLabel().c_str(), p
->GetValue().GetType().c_str(), typestr
.c_str() );
381 // -----------------------------------------------------------------------
383 void wxPropertyGridInterface::SetPropVal( wxPGPropArg id
, wxVariant
& value
)
385 wxPG_PROP_ARG_CALL_PROLOG()
391 // -----------------------------------------------------------------------
393 void wxPropertyGridInterface::SetPropertyValueString( wxPGPropArg id
, const wxString
& value
)
395 wxPG_PROP_ARG_CALL_PROLOG()
398 m_pState
->DoSetPropertyValueString(p
, value
);
401 // -----------------------------------------------------------------------
403 void wxPropertyGridInterface::SetValidationFailureBehavior( int vfbFlags
)
405 GetPropertyGrid()->m_permanentValidationFailureBehavior
= vfbFlags
;
408 // -----------------------------------------------------------------------
410 wxPGProperty
* wxPropertyGridInterface::GetPropertyByNameA( const wxString
& name
) const
412 wxPGProperty
* p
= GetPropertyByName(name
);
413 wxASSERT_MSG(p
,wxString::Format(wxT("no property with name '%s'"),name
.c_str()));
417 // ----------------------------------------------------------------------------
419 wxPGProperty
* wxPropertyGridInterface::GetPropertyByLabel( const wxString
& label
) const
423 for ( it
= GetVIterator( wxPG_ITERATE_PROPERTIES
); !it
.AtEnd(); it
.Next() )
425 if ( it
.GetProperty()->GetLabel() == label
)
426 return it
.GetProperty();
429 return wxNullProperty
;
432 // ----------------------------------------------------------------------------
434 void wxPropertyGridInterface::DoSetPropertyAttribute( wxPGPropArg id
, const wxString
& name
,
435 wxVariant
& value
, long argFlags
)
437 wxPG_PROP_ARG_CALL_PROLOG()
439 p
->SetAttribute( name
, value
);
441 if ( argFlags
& wxPG_RECURSE
)
444 for ( i
= 0; i
< p
->GetChildCount(); i
++ )
445 DoSetPropertyAttribute(p
->Item(i
), name
, value
, argFlags
);
449 // -----------------------------------------------------------------------
451 void wxPropertyGridInterface::SetPropertyAttributeAll( const wxString
& attrName
,
454 unsigned int pageIndex
= 0;
458 wxPropertyGridPageState
* page
= GetPageState(pageIndex
);
461 DoSetPropertyAttribute(page
->DoGetRoot(), attrName
, value
, wxPG_RECURSE
);
467 // -----------------------------------------------------------------------
469 void wxPropertyGridInterface::GetPropertiesWithFlag( wxArrayPGProperty
* targetArr
,
470 wxPGProperty::FlagType flags
,
472 int iterFlags
) const
474 wxASSERT( targetArr
);
475 wxPGVIterator it
= GetVIterator( iterFlags
);
481 const wxPGProperty
* property
= it
.GetProperty();
485 if ( (property
->GetFlags() & flags
) == flags
)
486 targetArr
->push_back((wxPGProperty
*)property
);
490 if ( (property
->GetFlags() & flags
) != flags
)
491 targetArr
->push_back((wxPGProperty
*)property
);
496 // -----------------------------------------------------------------------
498 void wxPropertyGridInterface::SetBoolChoices( const wxString
& trueChoice
,
499 const wxString
& falseChoice
)
501 wxPGGlobalVars
->m_boolChoices
[0] = falseChoice
;
502 wxPGGlobalVars
->m_boolChoices
[1] = trueChoice
;
505 // -----------------------------------------------------------------------
507 wxPGProperty
* wxPropertyGridInterface::DoGetPropertyByName( const wxString
& name
) const
509 return m_pState
->BaseGetPropertyByName(name
);
512 // -----------------------------------------------------------------------
514 wxPGProperty
* wxPropertyGridInterface::GetPropertyByName( const wxString
& name
,
515 const wxString
& subname
) const
517 wxPGProperty
* p
= DoGetPropertyByName(name
);
518 if ( !p
|| !p
->GetChildCount() )
519 return wxNullProperty
;
521 return p
->GetPropertyByName(subname
);
524 // -----------------------------------------------------------------------
526 // Since GetPropertyByName is used *a lot*, this makes sense
527 // since non-virtual method can be called with less code.
528 wxPGProperty
* wxPropertyGridInterface::GetPropertyByName( const wxString
& name
) const
530 wxPGProperty
* p
= DoGetPropertyByName(name
);
534 // Check if its "Property.SubProperty" format
535 int pos
= name
.Find(wxT('.'));
539 return GetPropertyByName(name
.substr(0,pos
),
540 name
.substr(pos
+1,name
.length()-pos
-1));
543 // -----------------------------------------------------------------------
545 bool wxPropertyGridInterface::HideProperty( wxPGPropArg id
, bool hide
, int flags
)
547 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
549 wxPropertyGrid
* pg
= m_pState
->GetGrid();
551 if ( pg
== p
->GetGrid() )
552 return pg
->DoHideProperty(p
, hide
, flags
);
554 m_pState
->DoHideProperty(p
, hide
, flags
);
559 // -----------------------------------------------------------------------
561 bool wxPropertyGridInterface::Collapse( wxPGPropArg id
)
563 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
564 wxPropertyGrid
* pg
= p
->GetGridIfDisplayed();
566 return pg
->DoCollapse(p
);
568 return p
->GetParentState()->DoCollapse(p
);
571 // -----------------------------------------------------------------------
573 bool wxPropertyGridInterface::Expand( wxPGPropArg id
)
575 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
576 wxPropertyGrid
* pg
= p
->GetGridIfDisplayed();
578 return pg
->DoExpand(p
);
580 return p
->GetParentState()->DoExpand(p
);
583 // -----------------------------------------------------------------------
585 void wxPropertyGridInterface::Sort( int flags
)
587 wxPropertyGrid
* pg
= GetPropertyGrid();
589 pg
->DoClearSelection();
591 unsigned int pageIndex
= 0;
595 wxPropertyGridPageState
* page
= GetPageState(pageIndex
);
602 // -----------------------------------------------------------------------
604 void wxPropertyGridInterface::SetPropertyLabel( wxPGPropArg id
, const wxString
& newproplabel
)
606 wxPG_PROP_ARG_CALL_PROLOG()
608 p
->SetLabel( newproplabel
);
610 wxPropertyGridPageState
* state
= p
->GetParentState();
611 wxPropertyGrid
* pg
= state
->GetGrid();
613 if ( pg
->HasFlag(wxPG_AUTO_SORT
) )
614 pg
->SortChildren(p
->GetParent());
616 if ( pg
->GetState() == state
)
618 if ( pg
->HasFlag(wxPG_AUTO_SORT
) )
625 // -----------------------------------------------------------------------
627 bool wxPropertyGridInterface::SetPropertyMaxLength( wxPGPropArg id
, int maxLen
)
629 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
631 wxPropertyGrid
* pg
= m_pState
->GetGrid();
633 p
->m_maxLen
= (short) maxLen
;
635 // Adjust control if selected currently
636 if ( pg
== p
->GetGrid() && p
== m_pState
->GetSelection() )
638 wxWindow
* wnd
= pg
->GetEditorControl();
639 wxTextCtrl
* tc
= wxDynamicCast(wnd
,wxTextCtrl
);
641 tc
->SetMaxLength( maxLen
);
650 // -----------------------------------------------------------------------
653 wxPropertyGridInterface::SetPropertyBackgroundColour( wxPGPropArg id
,
654 const wxColour
& colour
,
657 wxPG_PROP_ARG_CALL_PROLOG()
658 p
->SetBackgroundColour( colour
, recursively
);
659 RefreshProperty( p
);
662 // -----------------------------------------------------------------------
664 void wxPropertyGridInterface::SetPropertyTextColour( wxPGPropArg id
,
665 const wxColour
& colour
,
668 wxPG_PROP_ARG_CALL_PROLOG()
669 p
->SetTextColour( colour
, recursively
);
670 RefreshProperty( p
);
673 // -----------------------------------------------------------------------
675 void wxPropertyGridInterface::SetPropertyColoursToDefault( wxPGPropArg id
)
677 wxPG_PROP_ARG_CALL_PROLOG()
682 // -----------------------------------------------------------------------
684 void wxPropertyGridInterface::SetPropertyCell( wxPGPropArg id
,
686 const wxString
& text
,
687 const wxBitmap
& bitmap
,
688 const wxColour
& fgCol
,
689 const wxColour
& bgCol
)
691 wxPG_PROP_ARG_CALL_PROLOG()
693 wxPGCell
& cell
= p
->GetCell(column
);
694 if ( text
.length() && text
!= wxPG_LABEL
)
697 cell
.SetBitmap(bitmap
);
698 if ( fgCol
!= wxNullColour
)
699 cell
.SetFgCol(fgCol
);
700 if ( bgCol
!= wxNullColour
)
701 cell
.SetBgCol(bgCol
);
704 // -----------------------------------------------------------------------
705 // GetPropertyValueAsXXX methods
707 #define IMPLEMENT_GET_VALUE(T,TRET,BIGNAME,DEFRETVAL) \
708 TRET wxPropertyGridInterface::GetPropertyValueAs##BIGNAME( wxPGPropArg id ) const \
710 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(DEFRETVAL) \
711 wxVariant value = p->GetValue(); \
712 if ( wxStrcmp(value.GetType(), wxPGTypeName_##T) != 0 ) \
714 wxPGGetFailed(p,wxPGTypeName_##T); \
715 return (TRET)DEFRETVAL; \
717 return (TRET)value.Get##BIGNAME(); \
720 // String is different than others.
721 wxString
wxPropertyGridInterface::GetPropertyValueAsString( wxPGPropArg id
) const
723 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxEmptyString
)
724 return p
->GetValueAsString(wxPG_FULL_VALUE
);
727 bool wxPropertyGridInterface::GetPropertyValueAsBool( wxPGPropArg id
) const
729 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
730 wxVariant value
= p
->GetValue();
731 if ( wxStrcmp(value
.GetType(), wxPGTypeName_bool
) == 0 )
733 return value
.GetBool();
735 if ( wxStrcmp(value
.GetType(), wxPGTypeName_long
) == 0 )
737 return value
.GetLong()?true:false;
739 wxPGGetFailed(p
,wxPGTypeName_bool
);
743 IMPLEMENT_GET_VALUE(long,long,Long
,0)
744 IMPLEMENT_GET_VALUE(double,double,Double
,0.0)
746 bool wxPropertyGridInterface::IsPropertyExpanded( wxPGPropArg id
) const
748 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
749 return p
->IsExpanded();
752 // -----------------------------------------------------------------------
753 // wxPropertyGridInterface wrappers
754 // -----------------------------------------------------------------------
756 bool wxPropertyGridInterface::ChangePropertyValue( wxPGPropArg id
, wxVariant newValue
)
758 return GetPropertyGrid()->ChangePropertyValue(id
, newValue
);
761 // -----------------------------------------------------------------------
763 void wxPropertyGridInterface::BeginAddChildren( wxPGPropArg id
)
765 wxPG_PROP_ARG_CALL_PROLOG()
766 wxCHECK_RET( p
->HasFlag(wxPG_PROP_AGGREGATE
), wxT("only call on properties with fixed children") );
767 p
->ClearFlag(wxPG_PROP_AGGREGATE
);
768 p
->SetFlag(wxPG_PROP_MISC_PARENT
);
771 // -----------------------------------------------------------------------
773 bool wxPropertyGridInterface::EditorValidate()
775 return GetPropertyGrid()->DoEditorValidate();
778 // -----------------------------------------------------------------------
780 void wxPropertyGridInterface::EndAddChildren( wxPGPropArg id
)
782 wxPG_PROP_ARG_CALL_PROLOG()
783 wxCHECK_RET( p
->HasFlag(wxPG_PROP_MISC_PARENT
), wxT("only call on properties for which BeginAddChildren was called prior") );
784 p
->ClearFlag(wxPG_PROP_MISC_PARENT
);
785 p
->SetFlag(wxPG_PROP_AGGREGATE
);
788 // -----------------------------------------------------------------------
789 // wxPGVIterator_State
790 // -----------------------------------------------------------------------
792 // Default returned by wxPropertyGridInterface::GetVIterator().
793 class wxPGVIteratorBase_State
: public wxPGVIteratorBase
796 wxPGVIteratorBase_State( wxPropertyGridPageState
* state
, int flags
)
798 m_it
.Init( state
, flags
);
800 virtual ~wxPGVIteratorBase_State() { }
801 virtual void Next() { m_it
.Next(); }
804 wxPGVIterator
wxPropertyGridInterface::GetVIterator( int flags
) const
806 return wxPGVIterator( new wxPGVIteratorBase_State( m_pState
, flags
) );
809 // -----------------------------------------------------------------------
810 // wxPGEditableState related functions
811 // -----------------------------------------------------------------------
813 // EscapeDelimiters() changes ";" into "\;" and "|" into "\|"
814 // in the input string. This is an internal functions which is
815 // used for saving states
816 // NB: Similar function exists in aui/framemanager.cpp
817 static wxString
EscapeDelimiters(const wxString
& s
)
820 result
.Alloc(s
.length());
821 const wxChar
* ch
= s
.c_str();
824 if (*ch
== wxT(';') || *ch
== wxT('|') || *ch
== wxT(','))
832 wxString
wxPropertyGridInterface::SaveEditableState( int includedStates
) const
837 // Save state on page basis
838 unsigned int pageIndex
= 0;
839 wxArrayPtrVoid pageStates
;
843 wxPropertyGridPageState
* page
= GetPageState(pageIndex
);
846 pageStates
.Add(page
);
851 for ( pageIndex
=0; pageIndex
< pageStates
.size(); pageIndex
++ )
853 wxPropertyGridPageState
* pageState
= (wxPropertyGridPageState
*) pageStates
[pageIndex
];
855 if ( includedStates
& SelectionState
)
858 if ( pageState
->GetSelection() )
859 sel
= pageState
->GetSelection()->GetName();
860 result
+= wxS("selection=");
861 result
+= EscapeDelimiters(sel
);
864 if ( includedStates
& ExpandedState
)
866 wxArrayPGProperty ptrs
;
867 wxPropertyGridConstIterator it
=
868 wxPropertyGridConstIterator( pageState
,
869 wxPG_ITERATE_ALL_PARENTS_RECURSIVELY
|wxPG_ITERATE_HIDDEN
,
872 result
+= wxS("expanded=");
878 const wxPGProperty
* p
= it
.GetProperty();
880 if ( !p
->HasFlag(wxPG_PROP_COLLAPSED
) )
881 result
+= EscapeDelimiters(p
->GetName());
886 if ( result
.Last() == wxS(',') )
891 if ( includedStates
& ScrollPosState
)
894 GetPropertyGrid()->GetViewStart(&x
,&y
);
895 result
+= wxString::Format(wxS("scrollpos=%i,%i;"), x
, y
);
897 if ( includedStates
& SplitterPosState
)
899 result
+= wxS("splitterpos=");
901 for ( size_t i
=0; i
<pageState
->GetColumnCount(); i
++ )
902 result
+= wxString::Format(wxS("%i,"), pageState
->DoGetSplitterPosition(i
));
904 result
.RemoveLast(); // Remove last comma
907 if ( includedStates
& PageState
)
909 result
+= wxS("ispageselected=");
911 if ( GetPageState(-1) == pageState
)
916 if ( includedStates
& DescBoxState
)
918 wxVariant v
= GetEditableStateItem(wxS("descboxheight"));
920 result
+= wxString::Format(wxS("descboxheight=%i;"), (int)v
.GetLong());
922 result
.RemoveLast(); // Remove last semicolon
927 if ( result
.length() )
933 bool wxPropertyGridInterface::RestoreEditableState( const wxString
& src
, int restoreStates
)
935 wxPropertyGrid
* pg
= GetPropertyGrid();
936 wxPGProperty
* newSelection
= NULL
;
940 long selectedPage
= -1;
941 bool pgSelectionSet
= false;
945 wxArrayString pageStrings
= ::wxSplit(src
, wxS('|'), wxS('\\'));
947 for ( pageIndex
=0; pageIndex
<pageStrings
.size(); pageIndex
++ )
949 wxPropertyGridPageState
* pageState
= GetPageState(pageIndex
);
953 wxArrayString kvpairStrings
= ::wxSplit(pageStrings
[pageIndex
], wxS(';'), wxS('\\'));
955 for ( size_t i
=0; i
<kvpairStrings
.size(); i
++ )
957 const wxString
& kvs
= kvpairStrings
[i
];
958 int eq_pos
= kvs
.Find(wxS('='));
959 if ( eq_pos
!= wxNOT_FOUND
)
961 wxString key
= kvs
.substr(0, eq_pos
);
962 wxString value
= kvs
.substr(eq_pos
+1);
964 // Further split value by commas
965 wxArrayString values
= ::wxSplit(value
, wxS(','), wxS('\\'));
967 if ( key
== wxS("expanded") )
969 if ( restoreStates
& ExpandedState
)
971 wxPropertyGridIterator it
=
972 wxPropertyGridIterator( pageState
,
976 // First collapse all
977 for ( ; !it
.AtEnd(); it
.Next() )
979 wxPGProperty
* p
= it
.GetProperty();
980 pageState
->DoCollapse(p
);
983 // Then expand those which names are in values
984 for ( size_t n
=0; n
<values
.size(); n
++ )
986 const wxString
& name
= values
[n
];
987 wxPGProperty
* prop
= GetPropertyByName(name
);
989 pageState
->DoExpand(prop
);
993 else if ( key
== wxS("scrollpos") )
995 if ( restoreStates
& ScrollPosState
)
997 if ( values
.size() == 2 )
999 values
[0].ToLong(&vx
);
1000 values
[1].ToLong(&vy
);
1008 else if ( key
== wxS("splitterpos") )
1010 if ( restoreStates
& SplitterPosState
)
1012 for ( size_t n
=1; n
<values
.size(); n
++ )
1015 values
[n
].ToLong(&pos
);
1017 pageState
->DoSetSplitterPosition(pos
, n
);
1021 else if ( key
== wxS("selection") )
1023 if ( restoreStates
& SelectionState
)
1025 if ( values
.size() > 0 )
1027 if ( pageState
->IsDisplayed() )
1029 if ( values
[0].length() )
1030 newSelection
= GetPropertyByName(value
);
1031 pgSelectionSet
= true;
1035 if ( values
[0].length() )
1036 pageState
->DoSetSelection(GetPropertyByName(value
));
1038 pageState
->DoClearSelection();
1043 else if ( key
== wxS("ispageselected") )
1045 if ( restoreStates
& PageState
)
1048 if ( values
.size() == 1 && values
[0].ToLong(&pageSelStatus
) )
1050 if ( pageSelStatus
)
1051 selectedPage
= pageIndex
;
1059 else if ( key
== wxS("descboxheight") )
1061 if ( restoreStates
& DescBoxState
)
1064 if ( values
.size() == 1 && values
[0].ToLong(&descBoxHeight
) )
1066 SetEditableStateItem(wxS("descboxheight"), descBoxHeight
);
1083 // Force recalculation of virtual heights of all pages
1084 // (may be needed on unclean source string).
1086 wxPropertyGridPageState
* pageState
= GetPageState(pageIndex
);
1089 pageState
->VirtualHeightChanged();
1091 pageState
= GetPageState(pageIndex
);
1097 // Selection of visible grid page must be set after Thaw() call
1098 if ( pgSelectionSet
)
1101 pg
->DoSelectProperty(newSelection
);
1103 pg
->DoClearSelection();
1106 if ( selectedPage
!= -1 )
1108 DoSelectPage(selectedPage
);
1119 #endif // wxUSE_PROPGRID