1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/propgrid/propgridiface.cpp
3 // Purpose: wxPropertyGridInterface class
4 // Author: Jaakko Salli
8 // Copyright: (c) Jaakko Salli
9 // Licence: wxWindows licence
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
);
76 else if ( m_flags
& IsWCharPtr
)
77 return iface
->GetPropertyByNameA(m_ptr
.wcharName
);
82 // -----------------------------------------------------------------------
83 // wxPropertyGridInterface
84 // -----------------------------------------------------------------------
86 void wxPropertyGridInterface::RefreshGrid( wxPropertyGridPageState
* state
)
91 wxPropertyGrid
* grid
= state
->GetGrid();
92 if ( grid
->GetState() == state
&& !grid
->IsFrozen() )
98 // -----------------------------------------------------------------------
100 wxPGProperty
* wxPropertyGridInterface::Append( wxPGProperty
* property
)
102 wxPGProperty
* retp
= m_pState
->DoAppend(property
);
104 wxPropertyGrid
* grid
= m_pState
->GetGrid();
111 // -----------------------------------------------------------------------
113 wxPGProperty
* wxPropertyGridInterface::AppendIn( wxPGPropArg id
, wxPGProperty
* newproperty
)
115 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty
)
116 wxPGProperty
* pwc
= (wxPGProperty
*) p
;
117 wxPGProperty
* retp
= m_pState
->DoInsert(pwc
, pwc
->GetChildCount(), newproperty
);
121 // -----------------------------------------------------------------------
123 wxPGProperty
* wxPropertyGridInterface::Insert( wxPGPropArg id
, wxPGProperty
* property
)
125 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty
)
126 wxPGProperty
* retp
= m_pState
->DoInsert(p
->GetParent(), p
->GetIndexInParent(), property
);
131 // -----------------------------------------------------------------------
133 wxPGProperty
* wxPropertyGridInterface::Insert( wxPGPropArg id
, int index
, wxPGProperty
* newproperty
)
135 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty
)
136 wxPGProperty
* retp
= m_pState
->DoInsert((wxPGProperty
*)p
,index
,newproperty
);
141 // -----------------------------------------------------------------------
143 void wxPropertyGridInterface::DeleteProperty( wxPGPropArg id
)
145 wxPG_PROP_ARG_CALL_PROLOG()
147 wxPropertyGridPageState
* state
= p
->GetParentState();
149 state
->DoDelete( p
, true );
154 // -----------------------------------------------------------------------
156 wxPGProperty
* wxPropertyGridInterface::RemoveProperty( wxPGPropArg id
)
158 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty
)
160 wxCHECK( !p
->GetChildCount() || p
->HasFlag(wxPG_PROP_AGGREGATE
),
163 wxPropertyGridPageState
* state
= p
->GetParentState();
165 state
->DoDelete( p
, false );
172 // -----------------------------------------------------------------------
174 wxPGProperty
* wxPropertyGridInterface::ReplaceProperty( wxPGPropArg id
, wxPGProperty
* property
)
176 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty
)
178 wxPGProperty
* replaced
= p
;
179 wxCHECK_MSG( replaced
&& property
,
181 wxT("NULL property") );
182 wxCHECK_MSG( !replaced
->IsCategory(),
184 wxT("cannot replace this type of property") );
185 wxCHECK_MSG( !m_pState
->IsInNonCatMode(),
187 wxT("cannot replace properties in alphabetic mode") );
189 // Get address to the slot
190 wxPGProperty
* parent
= replaced
->GetParent();
191 int ind
= replaced
->GetIndexInParent();
193 wxPropertyGridPageState
* state
= replaced
->GetParentState();
194 DeleteProperty(replaced
); // Must use generic Delete
195 state
->DoInsert(parent
,ind
,property
);
200 // -----------------------------------------------------------------------
201 // wxPropertyGridInterface property operations
202 // -----------------------------------------------------------------------
204 wxPGProperty
* wxPropertyGridInterface::GetSelection() const
206 return m_pState
->GetSelection();
209 // -----------------------------------------------------------------------
211 bool wxPropertyGridInterface::ClearSelection( bool validation
)
213 bool res
= DoClearSelection(validation
, wxPG_SEL_DONT_SEND_EVENT
);
214 wxPropertyGrid
* pg
= GetPropertyGrid();
220 // -----------------------------------------------------------------------
222 bool wxPropertyGridInterface::DoClearSelection( bool validation
,
226 selFlags
|= wxPG_SEL_NOVALIDATE
;
228 wxPropertyGridPageState
* state
= m_pState
;
232 wxPropertyGrid
* pg
= state
->GetGrid();
233 if ( pg
->GetState() == state
)
234 return pg
->DoSelectProperty(NULL
, selFlags
);
236 state
->DoSetSelection(NULL
);
242 // -----------------------------------------------------------------------
244 void wxPropertyGridInterface::LimitPropertyEditing( wxPGPropArg id
, bool limit
)
246 wxPG_PROP_ARG_CALL_PROLOG()
248 m_pState
->DoLimitPropertyEditing(p
, limit
);
252 // -----------------------------------------------------------------------
254 bool wxPropertyGridInterface::EnableProperty( wxPGPropArg id
, bool enable
)
256 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
258 wxPropertyGridPageState
* state
= p
->GetParentState();
259 wxPropertyGrid
* grid
= state
->GetGrid();
263 if ( !(p
->m_flags
& wxPG_PROP_DISABLED
) )
266 // If active, Set active Editor.
267 if ( grid
&& grid
->GetState() == state
&& p
== grid
->GetSelection() )
268 grid
->DoSelectProperty( p
, wxPG_SEL_FORCE
);
272 if ( p
->m_flags
& wxPG_PROP_DISABLED
)
275 // If active, Disable as active Editor.
276 if ( grid
&& grid
->GetState() == state
&& p
== grid
->GetSelection() )
277 grid
->DoSelectProperty( p
, wxPG_SEL_FORCE
);
282 RefreshProperty( p
);
287 // -----------------------------------------------------------------------
289 bool wxPropertyGridInterface::ExpandAll( bool doExpand
)
291 wxPropertyGridPageState
* state
= m_pState
;
293 if ( !state
->DoGetRoot()->GetChildCount() )
296 wxPropertyGrid
* pg
= state
->GetGrid();
298 if ( GetSelection() && GetSelection() != state
->DoGetRoot() &&
301 pg
->DoClearSelection();
306 for ( it
= GetVIterator( wxPG_ITERATE_ALL
); !it
.AtEnd(); it
.Next() )
308 wxPGProperty
* p
= (wxPGProperty
*) it
.GetProperty();
309 if ( p
->GetChildCount() )
313 if ( !p
->IsExpanded() )
320 if ( p
->IsExpanded() )
322 state
->DoCollapse(p
);
328 pg
->RecalculateVirtualSize();
335 // -----------------------------------------------------------------------
337 void wxPropertyGridInterface::ClearModifiedStatus()
339 unsigned int pageIndex
= 0;
343 wxPropertyGridPageState
* page
= GetPageState(pageIndex
);
346 page
->DoGetRoot()->SetFlagRecursively(wxPG_PROP_MODIFIED
, false);
347 page
->m_anyModified
= false;
352 // Update active editor control, if any
353 GetPropertyGrid()->RefreshEditor();
356 bool wxPropertyGridInterface::SetColumnProportion( unsigned int column
,
359 wxCHECK(m_pState
, false);
360 wxPropertyGrid
* pg
= m_pState
->GetGrid();
362 wxCHECK(pg
->HasFlag(wxPG_SPLITTER_AUTO_CENTER
), false);
363 m_pState
->DoSetColumnProportion(column
, proportion
);
367 // -----------------------------------------------------------------------
368 // wxPropertyGridInterface property value setting and getting
369 // -----------------------------------------------------------------------
371 void wxPGGetFailed( const wxPGProperty
* p
, const wxString
& typestr
)
373 wxPGTypeOperationFailed(p
, typestr
, wxS("Get"));
376 // -----------------------------------------------------------------------
378 void wxPGTypeOperationFailed( const wxPGProperty
* p
,
379 const wxString
& typestr
,
382 wxASSERT( p
!= NULL
);
383 wxLogError( _("Type operation \"%s\" failed: Property labeled \"%s\" is of type \"%s\", NOT \"%s\"."),
384 op
.c_str(), p
->GetLabel().c_str(), p
->GetValue().GetType().c_str(), typestr
.c_str() );
387 // -----------------------------------------------------------------------
389 void wxPropertyGridInterface::SetPropVal( wxPGPropArg id
, wxVariant
& value
)
391 wxPG_PROP_ARG_CALL_PROLOG()
397 // -----------------------------------------------------------------------
399 void wxPropertyGridInterface::SetPropertyValueString( wxPGPropArg id
, const wxString
& value
)
401 wxPG_PROP_ARG_CALL_PROLOG()
404 m_pState
->DoSetPropertyValueString(p
, value
);
407 // -----------------------------------------------------------------------
409 void wxPropertyGridInterface::SetValidationFailureBehavior( int vfbFlags
)
411 GetPropertyGrid()->m_permanentValidationFailureBehavior
= vfbFlags
;
414 // -----------------------------------------------------------------------
416 wxPGProperty
* wxPropertyGridInterface::GetPropertyByNameA( const wxString
& name
) const
418 wxPGProperty
* p
= GetPropertyByName(name
);
419 wxASSERT_MSG(p
,wxString::Format(wxT("no property with name '%s'"),name
.c_str()));
423 // ----------------------------------------------------------------------------
425 wxPGProperty
* wxPropertyGridInterface::GetPropertyByLabel( const wxString
& label
) const
429 for ( it
= GetVIterator( wxPG_ITERATE_PROPERTIES
); !it
.AtEnd(); it
.Next() )
431 if ( it
.GetProperty()->GetLabel() == label
)
432 return it
.GetProperty();
435 return wxNullProperty
;
438 // ----------------------------------------------------------------------------
440 void wxPropertyGridInterface::DoSetPropertyAttribute( wxPGPropArg id
, const wxString
& name
,
441 wxVariant
& value
, long argFlags
)
443 wxPG_PROP_ARG_CALL_PROLOG()
445 p
->SetAttribute( name
, value
);
447 if ( argFlags
& wxPG_RECURSE
)
450 for ( i
= 0; i
< p
->GetChildCount(); i
++ )
451 DoSetPropertyAttribute(p
->Item(i
), name
, value
, argFlags
);
455 // -----------------------------------------------------------------------
457 void wxPropertyGridInterface::SetPropertyAttributeAll( const wxString
& attrName
,
460 unsigned int pageIndex
= 0;
464 wxPropertyGridPageState
* page
= GetPageState(pageIndex
);
467 DoSetPropertyAttribute(page
->DoGetRoot(), attrName
, value
, wxPG_RECURSE
);
473 // -----------------------------------------------------------------------
475 void wxPropertyGridInterface::GetPropertiesWithFlag( wxArrayPGProperty
* targetArr
,
476 wxPGProperty::FlagType flags
,
478 int iterFlags
) const
480 wxASSERT( targetArr
);
481 wxPGVIterator it
= GetVIterator( iterFlags
);
487 const wxPGProperty
* property
= it
.GetProperty();
491 if ( (property
->GetFlags() & flags
) == flags
)
492 targetArr
->push_back((wxPGProperty
*)property
);
496 if ( (property
->GetFlags() & flags
) != flags
)
497 targetArr
->push_back((wxPGProperty
*)property
);
502 // -----------------------------------------------------------------------
504 void wxPropertyGridInterface::SetBoolChoices( const wxString
& trueChoice
,
505 const wxString
& falseChoice
)
507 wxPGGlobalVars
->m_boolChoices
[0] = falseChoice
;
508 wxPGGlobalVars
->m_boolChoices
[1] = trueChoice
;
511 // -----------------------------------------------------------------------
513 wxPGProperty
* wxPropertyGridInterface::DoGetPropertyByName( const wxString
& name
) const
515 return m_pState
->BaseGetPropertyByName(name
);
518 // -----------------------------------------------------------------------
520 wxPGProperty
* wxPropertyGridInterface::GetPropertyByName( const wxString
& name
,
521 const wxString
& subname
) const
523 wxPGProperty
* p
= DoGetPropertyByName(name
);
524 if ( !p
|| !p
->GetChildCount() )
525 return wxNullProperty
;
527 return p
->GetPropertyByName(subname
);
530 // -----------------------------------------------------------------------
532 // Since GetPropertyByName is used *a lot*, this makes sense
533 // since non-virtual method can be called with less code.
534 wxPGProperty
* wxPropertyGridInterface::GetPropertyByName( const wxString
& name
) const
536 wxPGProperty
* p
= DoGetPropertyByName(name
);
540 // Check if its "Property.SubProperty" format
541 int pos
= name
.Find(wxT('.'));
545 return GetPropertyByName(name
.substr(0,pos
),
546 name
.substr(pos
+1,name
.length()-pos
-1));
549 // -----------------------------------------------------------------------
551 bool wxPropertyGridInterface::HideProperty( wxPGPropArg id
, bool hide
, int flags
)
553 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
555 wxPropertyGrid
* pg
= m_pState
->GetGrid();
557 if ( pg
== p
->GetGrid() )
558 return pg
->DoHideProperty(p
, hide
, flags
);
560 m_pState
->DoHideProperty(p
, hide
, flags
);
565 // -----------------------------------------------------------------------
567 bool wxPropertyGridInterface::Collapse( wxPGPropArg id
)
569 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
570 wxPropertyGrid
* pg
= p
->GetGridIfDisplayed();
572 return pg
->DoCollapse(p
);
574 return p
->GetParentState()->DoCollapse(p
);
577 // -----------------------------------------------------------------------
579 bool wxPropertyGridInterface::Expand( wxPGPropArg id
)
581 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
582 wxPropertyGrid
* pg
= p
->GetGridIfDisplayed();
584 return pg
->DoExpand(p
);
586 return p
->GetParentState()->DoExpand(p
);
589 // -----------------------------------------------------------------------
591 void wxPropertyGridInterface::Sort( int flags
)
593 wxPropertyGrid
* pg
= GetPropertyGrid();
595 unsigned int pageIndex
= 0;
599 wxPropertyGridPageState
* page
= GetPageState(pageIndex
);
605 // Fix positions of any open editor controls
607 pg
->CorrectEditorWidgetPosY();
610 // -----------------------------------------------------------------------
612 void wxPropertyGridInterface::SetPropertyLabel( wxPGPropArg id
, const wxString
& newproplabel
)
614 wxPG_PROP_ARG_CALL_PROLOG()
616 p
->SetLabel( newproplabel
);
618 wxPropertyGridPageState
* state
= p
->GetParentState();
619 wxPropertyGrid
* pg
= state
->GetGrid();
621 if ( pg
->HasFlag(wxPG_AUTO_SORT
) )
622 pg
->SortChildren(p
->GetParent());
624 if ( pg
->GetState() == state
)
626 if ( pg
->HasFlag(wxPG_AUTO_SORT
) )
633 // -----------------------------------------------------------------------
635 bool wxPropertyGridInterface::SetPropertyMaxLength( wxPGPropArg id
, int maxLen
)
637 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
639 wxPropertyGrid
* pg
= m_pState
->GetGrid();
641 p
->m_maxLen
= (short) maxLen
;
643 // Adjust control if selected currently
644 if ( pg
== p
->GetGrid() && p
== m_pState
->GetSelection() )
646 wxWindow
* wnd
= pg
->GetEditorControl();
647 wxTextCtrl
* tc
= wxDynamicCast(wnd
,wxTextCtrl
);
649 tc
->SetMaxLength( maxLen
);
658 // -----------------------------------------------------------------------
661 wxPropertyGridInterface::SetPropertyBackgroundColour( wxPGPropArg id
,
662 const wxColour
& colour
,
665 wxPG_PROP_ARG_CALL_PROLOG()
666 p
->SetBackgroundColour(colour
, flags
);
670 // -----------------------------------------------------------------------
672 void wxPropertyGridInterface::SetPropertyTextColour( wxPGPropArg id
,
673 const wxColour
& colour
,
676 wxPG_PROP_ARG_CALL_PROLOG()
677 p
->SetTextColour(colour
, flags
);
681 // -----------------------------------------------------------------------
683 void wxPropertyGridInterface::SetPropertyColoursToDefault( wxPGPropArg id
)
685 wxPG_PROP_ARG_CALL_PROLOG()
690 // -----------------------------------------------------------------------
692 void wxPropertyGridInterface::SetPropertyCell( wxPGPropArg id
,
694 const wxString
& text
,
695 const wxBitmap
& bitmap
,
696 const wxColour
& fgCol
,
697 const wxColour
& bgCol
)
699 wxPG_PROP_ARG_CALL_PROLOG()
701 wxPGCell
& cell
= p
->GetCell(column
);
702 if ( text
.length() && text
!= wxPG_LABEL
)
705 cell
.SetBitmap(bitmap
);
706 if ( fgCol
!= wxNullColour
)
707 cell
.SetFgCol(fgCol
);
708 if ( bgCol
!= wxNullColour
)
709 cell
.SetBgCol(bgCol
);
712 // -----------------------------------------------------------------------
713 // GetPropertyValueAsXXX methods
715 #define IMPLEMENT_GET_VALUE(T,TRET,BIGNAME,DEFRETVAL) \
716 TRET wxPropertyGridInterface::GetPropertyValueAs##BIGNAME( wxPGPropArg id ) const \
718 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(DEFRETVAL) \
719 wxVariant value = p->GetValue(); \
720 if ( wxStrcmp(value.GetType(), wxPGTypeName_##T) != 0 ) \
722 wxPGGetFailed(p,wxPGTypeName_##T); \
723 return (TRET)DEFRETVAL; \
725 return (TRET)value.Get##BIGNAME(); \
728 // String is different than others.
729 wxString
wxPropertyGridInterface::GetPropertyValueAsString( wxPGPropArg id
) const
731 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxEmptyString
)
732 return p
->GetValueAsString(wxPG_FULL_VALUE
);
735 bool wxPropertyGridInterface::GetPropertyValueAsBool( wxPGPropArg id
) const
737 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
738 wxVariant value
= p
->GetValue();
739 if ( wxStrcmp(value
.GetType(), wxPGTypeName_bool
) == 0 )
741 return value
.GetBool();
743 if ( wxStrcmp(value
.GetType(), wxPGTypeName_long
) == 0 )
745 return value
.GetLong()?true:false;
747 wxPGGetFailed(p
,wxPGTypeName_bool
);
751 IMPLEMENT_GET_VALUE(long,long,Long
,0)
752 IMPLEMENT_GET_VALUE(double,double,Double
,0.0)
754 bool wxPropertyGridInterface::IsPropertyExpanded( wxPGPropArg id
) const
756 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
757 return p
->IsExpanded();
760 // -----------------------------------------------------------------------
761 // wxPropertyGridInterface wrappers
762 // -----------------------------------------------------------------------
764 bool wxPropertyGridInterface::ChangePropertyValue( wxPGPropArg id
, wxVariant newValue
)
766 return GetPropertyGrid()->ChangePropertyValue(id
, newValue
);
769 // -----------------------------------------------------------------------
771 void wxPropertyGridInterface::BeginAddChildren( wxPGPropArg id
)
773 wxPG_PROP_ARG_CALL_PROLOG()
774 wxCHECK_RET( p
->HasFlag(wxPG_PROP_AGGREGATE
), wxT("only call on properties with fixed children") );
775 p
->ClearFlag(wxPG_PROP_AGGREGATE
);
776 p
->SetFlag(wxPG_PROP_MISC_PARENT
);
779 // -----------------------------------------------------------------------
781 bool wxPropertyGridInterface::EditorValidate()
783 return GetPropertyGrid()->DoEditorValidate();
786 // -----------------------------------------------------------------------
788 void wxPropertyGridInterface::EndAddChildren( wxPGPropArg id
)
790 wxPG_PROP_ARG_CALL_PROLOG()
791 wxCHECK_RET( p
->HasFlag(wxPG_PROP_MISC_PARENT
), wxT("only call on properties for which BeginAddChildren was called prior") );
792 p
->ClearFlag(wxPG_PROP_MISC_PARENT
);
793 p
->SetFlag(wxPG_PROP_AGGREGATE
);
796 // -----------------------------------------------------------------------
797 // wxPGVIterator_State
798 // -----------------------------------------------------------------------
800 // Default returned by wxPropertyGridInterface::GetVIterator().
801 class wxPGVIteratorBase_State
: public wxPGVIteratorBase
804 wxPGVIteratorBase_State( wxPropertyGridPageState
* state
, int flags
)
806 m_it
.Init( state
, flags
);
808 virtual ~wxPGVIteratorBase_State() { }
809 virtual void Next() { m_it
.Next(); }
812 wxPGVIterator
wxPropertyGridInterface::GetVIterator( int flags
) const
814 return wxPGVIterator( new wxPGVIteratorBase_State( m_pState
, flags
) );
817 // -----------------------------------------------------------------------
818 // wxPGEditableState related functions
819 // -----------------------------------------------------------------------
821 // EscapeDelimiters() changes ";" into "\;" and "|" into "\|"
822 // in the input string. This is an internal functions which is
823 // used for saving states
824 // NB: Similar function exists in aui/framemanager.cpp
825 static wxString
EscapeDelimiters(const wxString
& s
)
828 result
.Alloc(s
.length());
829 const wxChar
* ch
= s
.c_str();
832 if (*ch
== wxT(';') || *ch
== wxT('|') || *ch
== wxT(','))
840 wxString
wxPropertyGridInterface::SaveEditableState( int includedStates
) const
845 // Save state on page basis
846 unsigned int pageIndex
= 0;
847 wxArrayPtrVoid pageStates
;
851 wxPropertyGridPageState
* page
= GetPageState(pageIndex
);
854 pageStates
.Add(page
);
859 for ( pageIndex
=0; pageIndex
< pageStates
.size(); pageIndex
++ )
861 wxPropertyGridPageState
* pageState
= (wxPropertyGridPageState
*) pageStates
[pageIndex
];
863 if ( includedStates
& SelectionState
)
866 if ( pageState
->GetSelection() )
867 sel
= pageState
->GetSelection()->GetName();
868 result
+= wxS("selection=");
869 result
+= EscapeDelimiters(sel
);
872 if ( includedStates
& ExpandedState
)
874 wxArrayPGProperty ptrs
;
875 wxPropertyGridConstIterator it
=
876 wxPropertyGridConstIterator( pageState
,
877 wxPG_ITERATE_ALL_PARENTS_RECURSIVELY
|wxPG_ITERATE_HIDDEN
,
880 result
+= wxS("expanded=");
886 const wxPGProperty
* p
= it
.GetProperty();
888 if ( !p
->HasFlag(wxPG_PROP_COLLAPSED
) )
889 result
+= EscapeDelimiters(p
->GetName());
894 if ( result
.Last() == wxS(',') )
899 if ( includedStates
& ScrollPosState
)
902 GetPropertyGrid()->GetViewStart(&x
,&y
);
903 result
+= wxString::Format(wxS("scrollpos=%i,%i;"), x
, y
);
905 if ( includedStates
& SplitterPosState
)
907 result
+= wxS("splitterpos=");
909 for ( size_t i
=0; i
<pageState
->GetColumnCount(); i
++ )
910 result
+= wxString::Format(wxS("%i,"), pageState
->DoGetSplitterPosition(i
));
912 result
.RemoveLast(); // Remove last comma
915 if ( includedStates
& PageState
)
917 result
+= wxS("ispageselected=");
919 if ( GetPageState(-1) == pageState
)
924 if ( includedStates
& DescBoxState
)
926 wxVariant v
= GetEditableStateItem(wxS("descboxheight"));
928 result
+= wxString::Format(wxS("descboxheight=%i;"), (int)v
.GetLong());
930 result
.RemoveLast(); // Remove last semicolon
935 if ( result
.length() )
941 bool wxPropertyGridInterface::RestoreEditableState( const wxString
& src
, int restoreStates
)
943 wxPropertyGrid
* pg
= GetPropertyGrid();
944 wxPGProperty
* newSelection
= NULL
;
948 long selectedPage
= -1;
949 bool pgSelectionSet
= false;
953 wxArrayString pageStrings
= ::wxSplit(src
, wxS('|'), wxS('\\'));
955 for ( pageIndex
=0; pageIndex
<pageStrings
.size(); pageIndex
++ )
957 wxPropertyGridPageState
* pageState
= GetPageState(pageIndex
);
961 wxArrayString kvpairStrings
= ::wxSplit(pageStrings
[pageIndex
], wxS(';'), wxS('\\'));
963 for ( size_t i
=0; i
<kvpairStrings
.size(); i
++ )
965 const wxString
& kvs
= kvpairStrings
[i
];
966 int eq_pos
= kvs
.Find(wxS('='));
967 if ( eq_pos
!= wxNOT_FOUND
)
969 wxString key
= kvs
.substr(0, eq_pos
);
970 wxString value
= kvs
.substr(eq_pos
+1);
972 // Further split value by commas
973 wxArrayString values
= ::wxSplit(value
, wxS(','), wxS('\\'));
975 if ( key
== wxS("expanded") )
977 if ( restoreStates
& ExpandedState
)
979 wxPropertyGridIterator it
=
980 wxPropertyGridIterator( pageState
,
984 // First collapse all
985 for ( ; !it
.AtEnd(); it
.Next() )
987 wxPGProperty
* p
= it
.GetProperty();
988 pageState
->DoCollapse(p
);
991 // Then expand those which names are in values
992 for ( size_t n
=0; n
<values
.size(); n
++ )
994 const wxString
& name
= values
[n
];
995 wxPGProperty
* prop
= GetPropertyByName(name
);
997 pageState
->DoExpand(prop
);
1001 else if ( key
== wxS("scrollpos") )
1003 if ( restoreStates
& ScrollPosState
)
1005 if ( values
.size() == 2 )
1007 values
[0].ToLong(&vx
);
1008 values
[1].ToLong(&vy
);
1016 else if ( key
== wxS("splitterpos") )
1018 if ( restoreStates
& SplitterPosState
)
1020 for ( size_t n
=1; n
<values
.size(); n
++ )
1023 values
[n
].ToLong(&pos
);
1025 pageState
->DoSetSplitterPosition(pos
, n
);
1029 else if ( key
== wxS("selection") )
1031 if ( restoreStates
& SelectionState
)
1033 if ( values
.size() > 0 )
1035 if ( pageState
->IsDisplayed() )
1037 if ( values
[0].length() )
1038 newSelection
= GetPropertyByName(value
);
1039 pgSelectionSet
= true;
1043 if ( values
[0].length() )
1044 pageState
->DoSetSelection(GetPropertyByName(value
));
1046 pageState
->DoClearSelection();
1051 else if ( key
== wxS("ispageselected") )
1053 if ( restoreStates
& PageState
)
1056 if ( values
.size() == 1 && values
[0].ToLong(&pageSelStatus
) )
1058 if ( pageSelStatus
)
1059 selectedPage
= pageIndex
;
1067 else if ( key
== wxS("descboxheight") )
1069 if ( restoreStates
& DescBoxState
)
1072 if ( values
.size() == 1 && values
[0].ToLong(&descBoxHeight
) )
1074 SetEditableStateItem(wxS("descboxheight"), descBoxHeight
);
1091 // Force recalculation of virtual heights of all pages
1092 // (may be needed on unclean source string).
1094 wxPropertyGridPageState
* pageState
= GetPageState(pageIndex
);
1097 pageState
->VirtualHeightChanged();
1099 pageState
= GetPageState(pageIndex
);
1105 // Selection of visible grid page must be set after Thaw() call
1106 if ( pgSelectionSet
)
1109 pg
->DoSelectProperty(newSelection
);
1111 pg
->DoClearSelection();
1114 if ( selectedPage
!= -1 )
1116 DoSelectPage(selectedPage
);
1127 #endif // wxUSE_PROPGRID