1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/propgrid/propgridiface.cpp
3 // Purpose: wxPropertyGridInterface class
4 // Author: Jaakko Salli
7 // Copyright: (c) Jaakko Salli
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // For compilers that support precompilation, includes "wx/wx.h".
12 #include "wx/wxprec.h"
22 #include "wx/object.h"
24 #include "wx/string.h"
27 #include "wx/window.h"
30 #include "wx/dcmemory.h"
31 #include "wx/button.h"
34 #include "wx/settings.h"
39 #include "wx/propgrid/property.h"
40 #include "wx/propgrid/propgrid.h"
43 const wxChar
*wxPGTypeName_long
= wxT("long");
44 const wxChar
*wxPGTypeName_bool
= wxT("bool");
45 const wxChar
*wxPGTypeName_double
= wxT("double");
46 const wxChar
*wxPGTypeName_wxString
= wxT("string");
47 const wxChar
*wxPGTypeName_void
= wxT("void*");
48 const wxChar
*wxPGTypeName_wxArrayString
= wxT("arrstring");
51 // ----------------------------------------------------------------------------
53 // ----------------------------------------------------------------------------
55 WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED(wxPoint
, WXDLLIMPEXP_PROPGRID
)
56 WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED(wxSize
, WXDLLIMPEXP_PROPGRID
)
57 WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED_DUMMY_EQ(wxArrayInt
, WXDLLIMPEXP_PROPGRID
)
58 IMPLEMENT_VARIANT_OBJECT_EXPORTED(wxFont
, WXDLLIMPEXP_PROPGRID
)
60 // -----------------------------------------------------------------------
62 // -----------------------------------------------------------------------
64 wxPGProperty
* wxPGPropArgCls::GetPtr( wxPropertyGridInterface
* iface
) const
66 if ( m_flags
== IsProperty
)
68 wxASSERT_MSG( m_ptr
.property
, wxT("invalid property ptr") );
69 return m_ptr
.property
;
71 else if ( m_flags
& IsWxString
)
72 return iface
->GetPropertyByNameA(*m_ptr
.stringName
);
73 else if ( m_flags
& IsCharPtr
)
74 return iface
->GetPropertyByNameA(m_ptr
.charName
);
75 else if ( m_flags
& IsWCharPtr
)
76 return iface
->GetPropertyByNameA(m_ptr
.wcharName
);
81 // -----------------------------------------------------------------------
82 // wxPropertyGridInterface
83 // -----------------------------------------------------------------------
85 void wxPropertyGridInterface::RefreshGrid( wxPropertyGridPageState
* state
)
90 wxPropertyGrid
* grid
= state
->GetGrid();
91 if ( grid
->GetState() == state
&& !grid
->IsFrozen() )
97 // -----------------------------------------------------------------------
99 wxPGProperty
* wxPropertyGridInterface::Append( wxPGProperty
* property
)
101 wxPGProperty
* retp
= m_pState
->DoAppend(property
);
103 wxPropertyGrid
* grid
= m_pState
->GetGrid();
110 // -----------------------------------------------------------------------
112 wxPGProperty
* wxPropertyGridInterface::AppendIn( wxPGPropArg id
, wxPGProperty
* newproperty
)
114 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty
)
115 wxPGProperty
* pwc
= (wxPGProperty
*) p
;
116 wxPGProperty
* retp
= m_pState
->DoInsert(pwc
, pwc
->GetChildCount(), newproperty
);
120 // -----------------------------------------------------------------------
122 wxPGProperty
* wxPropertyGridInterface::Insert( wxPGPropArg id
, wxPGProperty
* property
)
124 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty
)
125 wxPGProperty
* retp
= m_pState
->DoInsert(p
->GetParent(), p
->GetIndexInParent(), property
);
130 // -----------------------------------------------------------------------
132 wxPGProperty
* wxPropertyGridInterface::Insert( wxPGPropArg id
, int index
, wxPGProperty
* newproperty
)
134 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty
)
135 wxPGProperty
* retp
= m_pState
->DoInsert((wxPGProperty
*)p
,index
,newproperty
);
140 // -----------------------------------------------------------------------
142 void wxPropertyGridInterface::DeleteProperty( wxPGPropArg id
)
144 wxPG_PROP_ARG_CALL_PROLOG()
146 wxPropertyGridPageState
* state
= p
->GetParentState();
148 state
->DoDelete( p
, true );
153 // -----------------------------------------------------------------------
155 wxPGProperty
* wxPropertyGridInterface::RemoveProperty( wxPGPropArg id
)
157 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty
)
159 wxCHECK( !p
->GetChildCount() || p
->HasFlag(wxPG_PROP_AGGREGATE
),
162 wxPropertyGridPageState
* state
= p
->GetParentState();
164 state
->DoDelete( p
, false );
171 // -----------------------------------------------------------------------
173 wxPGProperty
* wxPropertyGridInterface::ReplaceProperty( wxPGPropArg id
, wxPGProperty
* property
)
175 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty
)
177 wxPGProperty
* replaced
= p
;
178 wxCHECK_MSG( replaced
&& property
,
180 wxT("NULL property") );
181 wxCHECK_MSG( !replaced
->IsCategory(),
183 wxT("cannot replace this type of property") );
184 wxCHECK_MSG( !m_pState
->IsInNonCatMode(),
186 wxT("cannot replace properties in alphabetic mode") );
188 // Get address to the slot
189 wxPGProperty
* parent
= replaced
->GetParent();
190 int ind
= replaced
->GetIndexInParent();
192 wxPropertyGridPageState
* state
= replaced
->GetParentState();
193 DeleteProperty(replaced
); // Must use generic Delete
194 state
->DoInsert(parent
,ind
,property
);
199 // -----------------------------------------------------------------------
200 // wxPropertyGridInterface property operations
201 // -----------------------------------------------------------------------
203 wxPGProperty
* wxPropertyGridInterface::GetSelection() const
205 return m_pState
->GetSelection();
208 // -----------------------------------------------------------------------
210 bool wxPropertyGridInterface::ClearSelection( bool validation
)
212 bool res
= DoClearSelection(validation
, wxPG_SEL_DONT_SEND_EVENT
);
213 wxPropertyGrid
* pg
= GetPropertyGrid();
219 // -----------------------------------------------------------------------
221 bool wxPropertyGridInterface::DoClearSelection( bool validation
,
225 selFlags
|= wxPG_SEL_NOVALIDATE
;
227 wxPropertyGridPageState
* state
= m_pState
;
231 wxPropertyGrid
* pg
= state
->GetGrid();
232 if ( pg
->GetState() == state
)
233 return pg
->DoSelectProperty(NULL
, selFlags
);
235 state
->DoSetSelection(NULL
);
241 // -----------------------------------------------------------------------
243 void wxPropertyGridInterface::LimitPropertyEditing( wxPGPropArg id
, bool limit
)
245 wxPG_PROP_ARG_CALL_PROLOG()
247 m_pState
->DoLimitPropertyEditing(p
, limit
);
251 // -----------------------------------------------------------------------
253 bool wxPropertyGridInterface::EnableProperty( wxPGPropArg id
, bool enable
)
255 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
257 wxPropertyGridPageState
* state
= p
->GetParentState();
258 wxPropertyGrid
* grid
= state
->GetGrid();
262 if ( !(p
->m_flags
& wxPG_PROP_DISABLED
) )
265 // If active, Set active Editor.
266 if ( grid
&& grid
->GetState() == state
&& p
== grid
->GetSelection() )
267 grid
->DoSelectProperty( p
, wxPG_SEL_FORCE
);
271 if ( p
->m_flags
& wxPG_PROP_DISABLED
)
274 // If active, Disable as active Editor.
275 if ( grid
&& grid
->GetState() == state
&& p
== grid
->GetSelection() )
276 grid
->DoSelectProperty( p
, wxPG_SEL_FORCE
);
281 RefreshProperty( p
);
286 // -----------------------------------------------------------------------
288 bool wxPropertyGridInterface::ExpandAll( bool doExpand
)
290 wxPropertyGridPageState
* state
= m_pState
;
292 if ( !state
->DoGetRoot()->GetChildCount() )
295 wxPropertyGrid
* pg
= state
->GetGrid();
297 if ( GetSelection() && GetSelection() != state
->DoGetRoot() &&
300 pg
->DoClearSelection();
305 for ( it
= GetVIterator( wxPG_ITERATE_ALL
); !it
.AtEnd(); it
.Next() )
307 wxPGProperty
* p
= (wxPGProperty
*) it
.GetProperty();
308 if ( p
->GetChildCount() )
312 if ( !p
->IsExpanded() )
319 if ( p
->IsExpanded() )
321 state
->DoCollapse(p
);
327 pg
->RecalculateVirtualSize();
334 // -----------------------------------------------------------------------
336 void wxPropertyGridInterface::ClearModifiedStatus()
338 unsigned int pageIndex
= 0;
342 wxPropertyGridPageState
* page
= GetPageState(pageIndex
);
345 page
->DoGetRoot()->SetFlagRecursively(wxPG_PROP_MODIFIED
, false);
346 page
->m_anyModified
= false;
351 // Update active editor control, if any
352 GetPropertyGrid()->RefreshEditor();
355 bool wxPropertyGridInterface::SetColumnProportion( unsigned int column
,
358 wxCHECK(m_pState
, false);
359 wxPropertyGrid
* pg
= m_pState
->GetGrid();
361 wxCHECK(pg
->HasFlag(wxPG_SPLITTER_AUTO_CENTER
), false);
362 m_pState
->DoSetColumnProportion(column
, proportion
);
366 // -----------------------------------------------------------------------
367 // wxPropertyGridInterface property value setting and getting
368 // -----------------------------------------------------------------------
370 void wxPGGetFailed( const wxPGProperty
* p
, const wxString
& typestr
)
372 wxPGTypeOperationFailed(p
, typestr
, wxS("Get"));
375 // -----------------------------------------------------------------------
377 void wxPGTypeOperationFailed( const wxPGProperty
* p
,
378 const wxString
& typestr
,
381 wxASSERT( p
!= NULL
);
382 wxLogError( _("Type operation \"%s\" failed: Property labeled \"%s\" is of type \"%s\", NOT \"%s\"."),
383 op
.c_str(), p
->GetLabel().c_str(), p
->GetValue().GetType().c_str(), typestr
.c_str() );
386 // -----------------------------------------------------------------------
388 void wxPropertyGridInterface::SetPropVal( wxPGPropArg id
, wxVariant
& value
)
390 wxPG_PROP_ARG_CALL_PROLOG()
396 // -----------------------------------------------------------------------
398 void wxPropertyGridInterface::SetPropertyValueString( wxPGPropArg id
, const wxString
& value
)
400 wxPG_PROP_ARG_CALL_PROLOG()
403 m_pState
->DoSetPropertyValueString(p
, value
);
406 // -----------------------------------------------------------------------
408 void wxPropertyGridInterface::SetValidationFailureBehavior( int vfbFlags
)
410 GetPropertyGrid()->m_permanentValidationFailureBehavior
= vfbFlags
;
413 // -----------------------------------------------------------------------
415 wxPGProperty
* wxPropertyGridInterface::GetPropertyByNameA( const wxString
& name
) const
417 wxPGProperty
* p
= GetPropertyByName(name
);
418 wxASSERT_MSG(p
,wxString::Format(wxT("no property with name '%s'"),name
.c_str()));
422 // ----------------------------------------------------------------------------
424 wxPGProperty
* wxPropertyGridInterface::GetPropertyByLabel( const wxString
& label
) const
428 for ( it
= GetVIterator( wxPG_ITERATE_PROPERTIES
); !it
.AtEnd(); it
.Next() )
430 if ( it
.GetProperty()->GetLabel() == label
)
431 return it
.GetProperty();
434 return wxNullProperty
;
437 // ----------------------------------------------------------------------------
439 void wxPropertyGridInterface::DoSetPropertyAttribute( wxPGPropArg id
, const wxString
& name
,
440 wxVariant
& value
, long argFlags
)
442 wxPG_PROP_ARG_CALL_PROLOG()
444 p
->SetAttribute( name
, value
);
446 if ( argFlags
& wxPG_RECURSE
)
449 for ( i
= 0; i
< p
->GetChildCount(); i
++ )
450 DoSetPropertyAttribute(p
->Item(i
), name
, value
, argFlags
);
454 // -----------------------------------------------------------------------
456 void wxPropertyGridInterface::SetPropertyAttributeAll( const wxString
& attrName
,
459 unsigned int pageIndex
= 0;
463 wxPropertyGridPageState
* page
= GetPageState(pageIndex
);
466 DoSetPropertyAttribute(page
->DoGetRoot(), attrName
, value
, wxPG_RECURSE
);
472 // -----------------------------------------------------------------------
474 void wxPropertyGridInterface::GetPropertiesWithFlag( wxArrayPGProperty
* targetArr
,
475 wxPGProperty::FlagType flags
,
477 int iterFlags
) const
479 wxASSERT( targetArr
);
480 wxPGVIterator it
= GetVIterator( iterFlags
);
486 const wxPGProperty
* property
= it
.GetProperty();
490 if ( (property
->GetFlags() & flags
) == flags
)
491 targetArr
->push_back((wxPGProperty
*)property
);
495 if ( (property
->GetFlags() & flags
) != flags
)
496 targetArr
->push_back((wxPGProperty
*)property
);
501 // -----------------------------------------------------------------------
503 void wxPropertyGridInterface::SetBoolChoices( const wxString
& trueChoice
,
504 const wxString
& falseChoice
)
506 wxPGGlobalVars
->m_boolChoices
[0] = falseChoice
;
507 wxPGGlobalVars
->m_boolChoices
[1] = trueChoice
;
510 // -----------------------------------------------------------------------
512 wxPGProperty
* wxPropertyGridInterface::DoGetPropertyByName( const wxString
& name
) const
514 return m_pState
->BaseGetPropertyByName(name
);
517 // -----------------------------------------------------------------------
519 wxPGProperty
* wxPropertyGridInterface::GetPropertyByName( const wxString
& name
,
520 const wxString
& subname
) const
522 wxPGProperty
* p
= DoGetPropertyByName(name
);
523 if ( !p
|| !p
->GetChildCount() )
524 return wxNullProperty
;
526 return p
->GetPropertyByName(subname
);
529 // -----------------------------------------------------------------------
531 // Since GetPropertyByName is used *a lot*, this makes sense
532 // since non-virtual method can be called with less code.
533 wxPGProperty
* wxPropertyGridInterface::GetPropertyByName( const wxString
& name
) const
535 wxPGProperty
* p
= DoGetPropertyByName(name
);
539 // Check if its "Property.SubProperty" format
540 int pos
= name
.Find(wxT('.'));
544 return GetPropertyByName(name
.substr(0,pos
),
545 name
.substr(pos
+1,name
.length()-pos
-1));
548 // -----------------------------------------------------------------------
550 bool wxPropertyGridInterface::HideProperty( wxPGPropArg id
, bool hide
, int flags
)
552 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
554 wxPropertyGrid
* pg
= m_pState
->GetGrid();
556 if ( pg
== p
->GetGrid() )
557 return pg
->DoHideProperty(p
, hide
, flags
);
559 m_pState
->DoHideProperty(p
, hide
, flags
);
564 // -----------------------------------------------------------------------
566 bool wxPropertyGridInterface::Collapse( wxPGPropArg id
)
568 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
569 wxPropertyGrid
* pg
= p
->GetGridIfDisplayed();
571 return pg
->DoCollapse(p
);
573 return p
->GetParentState()->DoCollapse(p
);
576 // -----------------------------------------------------------------------
578 bool wxPropertyGridInterface::Expand( wxPGPropArg id
)
580 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
581 wxPropertyGrid
* pg
= p
->GetGridIfDisplayed();
583 return pg
->DoExpand(p
);
585 return p
->GetParentState()->DoExpand(p
);
588 // -----------------------------------------------------------------------
590 void wxPropertyGridInterface::Sort( int flags
)
592 wxPropertyGrid
* pg
= GetPropertyGrid();
594 unsigned int pageIndex
= 0;
598 wxPropertyGridPageState
* page
= GetPageState(pageIndex
);
604 // Fix positions of any open editor controls
606 pg
->CorrectEditorWidgetPosY();
609 // -----------------------------------------------------------------------
611 void wxPropertyGridInterface::SetPropertyLabel( wxPGPropArg id
, const wxString
& newproplabel
)
613 wxPG_PROP_ARG_CALL_PROLOG()
615 p
->SetLabel( newproplabel
);
617 wxPropertyGridPageState
* state
= p
->GetParentState();
618 wxPropertyGrid
* pg
= state
->GetGrid();
620 if ( pg
->HasFlag(wxPG_AUTO_SORT
) )
621 pg
->SortChildren(p
->GetParent());
623 if ( pg
->GetState() == state
)
625 if ( pg
->HasFlag(wxPG_AUTO_SORT
) )
632 // -----------------------------------------------------------------------
634 bool wxPropertyGridInterface::SetPropertyMaxLength( wxPGPropArg id
, int maxLen
)
636 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
638 wxPropertyGrid
* pg
= m_pState
->GetGrid();
640 p
->m_maxLen
= (short) maxLen
;
642 // Adjust control if selected currently
643 if ( pg
== p
->GetGrid() && p
== m_pState
->GetSelection() )
645 wxWindow
* wnd
= pg
->GetEditorControl();
646 wxTextCtrl
* tc
= wxDynamicCast(wnd
,wxTextCtrl
);
648 tc
->SetMaxLength( maxLen
);
657 // -----------------------------------------------------------------------
660 wxPropertyGridInterface::SetPropertyBackgroundColour( wxPGPropArg id
,
661 const wxColour
& colour
,
664 wxPG_PROP_ARG_CALL_PROLOG()
665 p
->SetBackgroundColour(colour
, flags
);
669 // -----------------------------------------------------------------------
671 void wxPropertyGridInterface::SetPropertyTextColour( wxPGPropArg id
,
672 const wxColour
& colour
,
675 wxPG_PROP_ARG_CALL_PROLOG()
676 p
->SetTextColour(colour
, flags
);
680 // -----------------------------------------------------------------------
682 void wxPropertyGridInterface::SetPropertyColoursToDefault( wxPGPropArg id
)
684 wxPG_PROP_ARG_CALL_PROLOG()
689 // -----------------------------------------------------------------------
691 void wxPropertyGridInterface::SetPropertyCell( wxPGPropArg id
,
693 const wxString
& text
,
694 const wxBitmap
& bitmap
,
695 const wxColour
& fgCol
,
696 const wxColour
& bgCol
)
698 wxPG_PROP_ARG_CALL_PROLOG()
700 wxPGCell
& cell
= p
->GetCell(column
);
701 if ( !text
.empty() && text
!= wxPG_LABEL
)
704 cell
.SetBitmap(bitmap
);
705 if ( fgCol
!= wxNullColour
)
706 cell
.SetFgCol(fgCol
);
707 if ( bgCol
!= wxNullColour
)
708 cell
.SetBgCol(bgCol
);
711 // -----------------------------------------------------------------------
712 // GetPropertyValueAsXXX methods
714 #define IMPLEMENT_GET_VALUE(T,TRET,BIGNAME,DEFRETVAL) \
715 TRET wxPropertyGridInterface::GetPropertyValueAs##BIGNAME( wxPGPropArg id ) const \
717 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(DEFRETVAL) \
718 wxVariant value = p->GetValue(); \
719 if ( wxStrcmp(value.GetType(), wxPGTypeName_##T) != 0 ) \
721 wxPGGetFailed(p,wxPGTypeName_##T); \
722 return (TRET)DEFRETVAL; \
724 return (TRET)value.Get##BIGNAME(); \
727 // String is different than others.
728 wxString
wxPropertyGridInterface::GetPropertyValueAsString( wxPGPropArg id
) const
730 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxEmptyString
)
731 return p
->GetValueAsString(wxPG_FULL_VALUE
);
734 bool wxPropertyGridInterface::GetPropertyValueAsBool( wxPGPropArg id
) const
736 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
737 wxVariant value
= p
->GetValue();
738 if ( wxStrcmp(value
.GetType(), wxPGTypeName_bool
) == 0 )
740 return value
.GetBool();
742 if ( wxStrcmp(value
.GetType(), wxPGTypeName_long
) == 0 )
744 return value
.GetLong()?true:false;
746 wxPGGetFailed(p
,wxPGTypeName_bool
);
750 IMPLEMENT_GET_VALUE(long,long,Long
,0)
751 IMPLEMENT_GET_VALUE(double,double,Double
,0.0)
753 bool wxPropertyGridInterface::IsPropertyExpanded( wxPGPropArg id
) const
755 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
756 return p
->IsExpanded();
759 // -----------------------------------------------------------------------
760 // wxPropertyGridInterface wrappers
761 // -----------------------------------------------------------------------
763 bool wxPropertyGridInterface::ChangePropertyValue( wxPGPropArg id
, wxVariant newValue
)
765 return GetPropertyGrid()->ChangePropertyValue(id
, newValue
);
768 // -----------------------------------------------------------------------
770 void wxPropertyGridInterface::BeginAddChildren( wxPGPropArg id
)
772 wxPG_PROP_ARG_CALL_PROLOG()
773 wxCHECK_RET( p
->HasFlag(wxPG_PROP_AGGREGATE
), wxT("only call on properties with fixed children") );
774 p
->ClearFlag(wxPG_PROP_AGGREGATE
);
775 p
->SetFlag(wxPG_PROP_MISC_PARENT
);
778 // -----------------------------------------------------------------------
780 bool wxPropertyGridInterface::EditorValidate()
782 return GetPropertyGrid()->DoEditorValidate();
785 // -----------------------------------------------------------------------
787 void wxPropertyGridInterface::EndAddChildren( wxPGPropArg id
)
789 wxPG_PROP_ARG_CALL_PROLOG()
790 wxCHECK_RET( p
->HasFlag(wxPG_PROP_MISC_PARENT
), wxT("only call on properties for which BeginAddChildren was called prior") );
791 p
->ClearFlag(wxPG_PROP_MISC_PARENT
);
792 p
->SetFlag(wxPG_PROP_AGGREGATE
);
795 // -----------------------------------------------------------------------
796 // wxPGVIterator_State
797 // -----------------------------------------------------------------------
799 // Default returned by wxPropertyGridInterface::GetVIterator().
800 class wxPGVIteratorBase_State
: public wxPGVIteratorBase
803 wxPGVIteratorBase_State( wxPropertyGridPageState
* state
, int flags
)
805 m_it
.Init( state
, flags
);
807 virtual ~wxPGVIteratorBase_State() { }
808 virtual void Next() { m_it
.Next(); }
811 wxPGVIterator
wxPropertyGridInterface::GetVIterator( int flags
) const
813 return wxPGVIterator( new wxPGVIteratorBase_State( m_pState
, flags
) );
816 // -----------------------------------------------------------------------
817 // wxPGEditableState related functions
818 // -----------------------------------------------------------------------
820 // EscapeDelimiters() changes ";" into "\;" and "|" into "\|"
821 // in the input string. This is an internal functions which is
822 // used for saving states
823 // NB: Similar function exists in aui/framemanager.cpp
824 static wxString
EscapeDelimiters(const wxString
& s
)
827 result
.Alloc(s
.length());
828 const wxChar
* ch
= s
.c_str();
831 if (*ch
== wxT(';') || *ch
== wxT('|') || *ch
== wxT(','))
839 wxString
wxPropertyGridInterface::SaveEditableState( int includedStates
) const
844 // Save state on page basis
845 unsigned int pageIndex
= 0;
846 wxArrayPtrVoid pageStates
;
850 wxPropertyGridPageState
* page
= GetPageState(pageIndex
);
853 pageStates
.Add(page
);
858 for ( pageIndex
=0; pageIndex
< pageStates
.size(); pageIndex
++ )
860 wxPropertyGridPageState
* pageState
= (wxPropertyGridPageState
*) pageStates
[pageIndex
];
862 if ( includedStates
& SelectionState
)
865 if ( pageState
->GetSelection() )
866 sel
= pageState
->GetSelection()->GetName();
867 result
+= wxS("selection=");
868 result
+= EscapeDelimiters(sel
);
871 if ( includedStates
& ExpandedState
)
873 wxArrayPGProperty ptrs
;
874 wxPropertyGridConstIterator it
=
875 wxPropertyGridConstIterator( pageState
,
876 wxPG_ITERATE_ALL_PARENTS_RECURSIVELY
|wxPG_ITERATE_HIDDEN
,
879 result
+= wxS("expanded=");
885 const wxPGProperty
* p
= it
.GetProperty();
887 if ( !p
->HasFlag(wxPG_PROP_COLLAPSED
) )
888 result
+= EscapeDelimiters(p
->GetName());
893 if ( result
.Last() == wxS(',') )
898 if ( includedStates
& ScrollPosState
)
901 GetPropertyGrid()->GetViewStart(&x
,&y
);
902 result
+= wxString::Format(wxS("scrollpos=%i,%i;"), x
, y
);
904 if ( includedStates
& SplitterPosState
)
906 result
+= wxS("splitterpos=");
908 for ( size_t i
=0; i
<pageState
->GetColumnCount(); i
++ )
909 result
+= wxString::Format(wxS("%i,"), pageState
->DoGetSplitterPosition(i
));
911 result
.RemoveLast(); // Remove last comma
914 if ( includedStates
& PageState
)
916 result
+= wxS("ispageselected=");
918 if ( GetPageState(-1) == pageState
)
923 if ( includedStates
& DescBoxState
)
925 wxVariant v
= GetEditableStateItem(wxS("descboxheight"));
927 result
+= wxString::Format(wxS("descboxheight=%i;"), (int)v
.GetLong());
929 result
.RemoveLast(); // Remove last semicolon
934 if ( !result
.empty() )
940 bool wxPropertyGridInterface::RestoreEditableState( const wxString
& src
, int restoreStates
)
942 wxPropertyGrid
* pg
= GetPropertyGrid();
943 wxPGProperty
* newSelection
= NULL
;
947 long selectedPage
= -1;
948 bool pgSelectionSet
= false;
952 wxArrayString pageStrings
= ::wxSplit(src
, wxS('|'), wxS('\\'));
954 for ( pageIndex
=0; pageIndex
<pageStrings
.size(); pageIndex
++ )
956 wxPropertyGridPageState
* pageState
= GetPageState(pageIndex
);
960 wxArrayString kvpairStrings
= ::wxSplit(pageStrings
[pageIndex
], wxS(';'), wxS('\\'));
962 for ( size_t i
=0; i
<kvpairStrings
.size(); i
++ )
964 const wxString
& kvs
= kvpairStrings
[i
];
965 int eq_pos
= kvs
.Find(wxS('='));
966 if ( eq_pos
!= wxNOT_FOUND
)
968 wxString key
= kvs
.substr(0, eq_pos
);
969 wxString value
= kvs
.substr(eq_pos
+1);
971 // Further split value by commas
972 wxArrayString values
= ::wxSplit(value
, wxS(','), wxS('\\'));
974 if ( key
== wxS("expanded") )
976 if ( restoreStates
& ExpandedState
)
978 wxPropertyGridIterator it
=
979 wxPropertyGridIterator( pageState
,
983 // First collapse all
984 for ( ; !it
.AtEnd(); it
.Next() )
986 wxPGProperty
* p
= it
.GetProperty();
987 pageState
->DoCollapse(p
);
990 // Then expand those which names are in values
991 for ( size_t n
=0; n
<values
.size(); n
++ )
993 const wxString
& name
= values
[n
];
994 wxPGProperty
* prop
= GetPropertyByName(name
);
996 pageState
->DoExpand(prop
);
1000 else if ( key
== wxS("scrollpos") )
1002 if ( restoreStates
& ScrollPosState
)
1004 if ( values
.size() == 2 )
1006 values
[0].ToLong(&vx
);
1007 values
[1].ToLong(&vy
);
1015 else if ( key
== wxS("splitterpos") )
1017 if ( restoreStates
& SplitterPosState
)
1019 for ( size_t n
=1; n
<values
.size(); n
++ )
1022 values
[n
].ToLong(&pos
);
1024 pageState
->DoSetSplitterPosition(pos
, n
);
1028 else if ( key
== wxS("selection") )
1030 if ( restoreStates
& SelectionState
)
1032 if ( values
.size() > 0 )
1034 if ( pageState
->IsDisplayed() )
1036 if ( !values
[0].empty() )
1037 newSelection
= GetPropertyByName(value
);
1038 pgSelectionSet
= true;
1042 if ( !values
[0].empty() )
1043 pageState
->DoSetSelection(GetPropertyByName(value
));
1045 pageState
->DoClearSelection();
1050 else if ( key
== wxS("ispageselected") )
1052 if ( restoreStates
& PageState
)
1055 if ( values
.size() == 1 && values
[0].ToLong(&pageSelStatus
) )
1057 if ( pageSelStatus
)
1058 selectedPage
= pageIndex
;
1066 else if ( key
== wxS("descboxheight") )
1068 if ( restoreStates
& DescBoxState
)
1071 if ( values
.size() == 1 && values
[0].ToLong(&descBoxHeight
) )
1073 SetEditableStateItem(wxS("descboxheight"), descBoxHeight
);
1090 // Force recalculation of virtual heights of all pages
1091 // (may be needed on unclean source string).
1093 wxPropertyGridPageState
* pageState
= GetPageState(pageIndex
);
1096 pageState
->VirtualHeightChanged();
1098 pageState
= GetPageState(pageIndex
);
1104 // Selection of visible grid page must be set after Thaw() call
1105 if ( pgSelectionSet
)
1108 pg
->DoSelectProperty(newSelection
);
1110 pg
->DoClearSelection();
1113 if ( selectedPage
!= -1 )
1115 DoSelectPage(selectedPage
);
1126 #endif // wxUSE_PROPGRID