1
/////////////////////////////////////////////////////////////////////////////
2
// Name: src/propgrid/propgridiface.cpp
3
// Purpose: wxPropertyGridInterface class
4
// Author: Jaakko Salli
7
// RCS-ID: $Id: propgridiface.cpp 66728 2011-01-22 14:38:36Z DS $
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.empty() && 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.empty() )
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].empty() )
1038
newSelection = GetPropertyByName(value);
1039
pgSelectionSet = true;
1043
if ( !values[0].empty() )
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