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/cursor.h"
36 #include "wx/dialog.h"
37 #include "wx/settings.h"
38 #include "wx/msgdlg.h"
39 #include "wx/choice.h"
40 #include "wx/stattext.h"
41 #include "wx/scrolwin.h"
42 #include "wx/dirdlg.h"
43 #include "wx/layout.h"
45 #include "wx/textdlg.h"
46 #include "wx/filedlg.h"
47 #include "wx/statusbr.h"
52 #include <wx/propgrid/property.h>
53 #include <wx/propgrid/propgrid.h>
56 const wxChar
*wxPGTypeName_long
= wxT("long");
57 const wxChar
*wxPGTypeName_bool
= wxT("bool");
58 const wxChar
*wxPGTypeName_double
= wxT("double");
59 const wxChar
*wxPGTypeName_wxString
= wxT("string");
60 const wxChar
*wxPGTypeName_void
= wxT("void*");
61 const wxChar
*wxPGTypeName_wxArrayString
= wxT("arrstring");
64 // ----------------------------------------------------------------------------
66 // ----------------------------------------------------------------------------
68 WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED(wxPoint
, WXDLLIMPEXP_PROPGRID
)
69 WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED(wxSize
, WXDLLIMPEXP_PROPGRID
)
70 WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED_DUMMY_EQ(wxArrayInt
, WXDLLIMPEXP_PROPGRID
)
72 // For wxLongLong and wxULongLong have custom classname << variant
73 // implementation for improved flexibility.
74 WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED_NO_EQ_NO_GETTER(wxLongLong
, WXDLLIMPEXP_PROPGRID
)
75 WX_PG_IMPLEMENT_VARIANT_DATA_EQ(wxLongLong
, WXDLLIMPEXP_PROPGRID
)
76 WXDLLIMPEXP_PROPGRID wxLongLong
& operator << ( wxLongLong
&value
, const wxVariant
&variant
)
79 if ( !wxPGVariantToLongLong(variant
, &ll
) )
81 wxFAIL_MSG("Cannot convert to wxLongLong");
86 WXDLLIMPEXP_PROPGRID wxLongLong_t
& operator << ( wxLongLong_t
&value
, const wxVariant
&variant
)
88 if ( !wxPGVariantToLongLong(variant
, &value
) )
90 wxFAIL_MSG("Cannot convert to wxLongLong");
95 WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED_NO_EQ_NO_GETTER(wxULongLong
, WXDLLIMPEXP_PROPGRID
)
96 WX_PG_IMPLEMENT_VARIANT_DATA_EQ(wxULongLong
, WXDLLIMPEXP_PROPGRID
)
97 WXDLLIMPEXP_PROPGRID wxULongLong
& operator << ( wxULongLong
&value
, const wxVariant
&variant
)
100 if ( !wxPGVariantToULongLong(variant
, &ull
) )
102 wxFAIL_MSG("Cannot convert to wxULongLong");
107 WXDLLIMPEXP_PROPGRID wxULongLong_t
& operator << ( wxULongLong_t
&value
, const wxVariant
&variant
)
109 if ( !wxPGVariantToULongLong(variant
, &value
) )
111 wxFAIL_MSG("Cannot convert to wxULongLong");
116 IMPLEMENT_VARIANT_OBJECT_EXPORTED(wxFont
, WXDLLIMPEXP_PROPGRID
)
118 // -----------------------------------------------------------------------
120 // -----------------------------------------------------------------------
122 long wxPGVariantToInt( const wxVariant
& variant
, long defVal
)
124 if ( variant
.IsNull() )
127 if ( variant
.GetType() == wxS("long") )
128 return variant
.GetLong();
130 if ( variant
.GetType() == wxS("bool") )
131 return variant
.GetBool() ?
1 : 0;
133 if ( variant
.GetType() == wxS("wxLongLong") )
137 if ( ll
>= LONG_MAX
)
139 else if ( ll
<= LONG_MIN
)
146 if ( variant
.GetType() == wxPG_VARIANT_TYPE_STRING
)
147 variant
.GetString().ToLong(&l
, 0);
152 // -----------------------------------------------------------------------
154 bool wxPGVariantToLongLong( const wxVariant
& variant
, wxLongLong_t
* pResult
)
156 if ( variant
.IsNull() )
159 wxString variantType
= variant
.GetType();
161 if ( variantType
== wxPG_VARIANT_TYPE_LONG
)
163 *pResult
= variant
.GetLong();
167 if ( variantType
== wxLongLong_VariantType
)
169 // NOTE: << operator uses this functions, so we can't use it here
170 *pResult
= wxLongLongRefFromVariant(variant
).GetValue();
177 // -----------------------------------------------------------------------
179 bool wxPGVariantToULongLong( const wxVariant
& variant
, wxULongLong_t
* pResult
)
181 if ( variant
.IsNull() )
184 wxString variantType
= variant
.GetType();
186 if ( variantType
== wxPG_VARIANT_TYPE_LONG
)
188 *pResult
= (unsigned long)variant
.GetLong();
192 if ( variantType
== wxULongLong_VariantType
)
194 // NOTE: << operator uses this functions, so we can't use it here
195 *pResult
= wxULongLongRefFromVariant(variant
).GetValue();
202 // -----------------------------------------------------------------------
204 bool wxPGVariantToDouble( const wxVariant
& variant
, double* pResult
)
206 if ( variant
.IsNull() )
209 wxString variantType
= variant
.GetType();
211 if ( variantType
== wxPG_VARIANT_TYPE_DOUBLE
)
213 *pResult
= variant
.GetDouble();
217 if ( variantType
== wxPG_VARIANT_TYPE_LONG
)
219 *pResult
= (double)variant
.GetLong();
223 if ( variantType
== wxLongLong_VariantType
)
227 *pResult
= ll
.ToDouble();
231 if ( variantType
== wxPG_VARIANT_TYPE_STRING
)
232 if ( variant
.GetString().ToDouble(pResult
) )
238 // -----------------------------------------------------------------------
240 // -----------------------------------------------------------------------
242 wxPGProperty
* wxPGPropArgCls
::GetPtr( wxPropertyGridInterface
* iface
) const
244 if ( m_flags
== IsProperty
)
246 wxASSERT_MSG( m_ptr
.property
, wxT("invalid property ptr") );
247 return m_ptr
.property
;
249 else if ( m_flags
& IsWxString
)
250 return iface
->GetPropertyByNameA(*m_ptr
.stringName
);
251 else if ( m_flags
& IsCharPtr
)
252 return iface
->GetPropertyByNameA(m_ptr
.charName
);
254 else if ( m_flags
& IsWCharPtr
)
255 return iface
->GetPropertyByNameA(m_ptr
.wcharName
);
261 // -----------------------------------------------------------------------
262 // wxPropertyGridInterface
263 // -----------------------------------------------------------------------
265 void wxPropertyGridInterface
::RefreshGrid( wxPropertyGridPageState
* state
)
270 wxPropertyGrid
* grid
= state
->GetGrid();
271 if ( grid
->GetState() == state
&& !grid
->IsFrozen() )
277 // -----------------------------------------------------------------------
279 wxPGProperty
* wxPropertyGridInterface
::Append( wxPGProperty
* property
)
281 wxPGProperty
* retp
= m_pState
->DoAppend(property
);
283 wxPropertyGrid
* grid
= m_pState
->GetGrid();
290 // -----------------------------------------------------------------------
292 wxPGProperty
* wxPropertyGridInterface
::AppendIn( wxPGPropArg id
, wxPGProperty
* newproperty
)
294 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty
)
295 wxPGProperty
* pwc
= (wxPGProperty
*) p
;
296 wxPGProperty
* retp
= m_pState
->DoInsert(pwc
, pwc
->GetChildCount(), newproperty
);
300 // -----------------------------------------------------------------------
302 wxPGProperty
* wxPropertyGridInterface
::Insert( wxPGPropArg id
, wxPGProperty
* property
)
304 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty
)
305 wxPGProperty
* retp
= m_pState
->DoInsert(p
->GetParent(), p
->GetArrIndex(), property
);
310 // -----------------------------------------------------------------------
312 wxPGProperty
* wxPropertyGridInterface
::Insert( wxPGPropArg id
, int index
, wxPGProperty
* newproperty
)
314 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty
)
315 wxPGProperty
* retp
= m_pState
->DoInsert((wxPGProperty
*)p
,index
,newproperty
);
320 // -----------------------------------------------------------------------
322 void wxPropertyGridInterface
::DeleteProperty( wxPGPropArg id
)
324 wxPG_PROP_ARG_CALL_PROLOG()
326 wxPropertyGridPageState
* state
= p
->GetParentState();
327 wxPropertyGrid
* grid
= state
->GetGrid();
329 if ( grid
->GetState() == state
)
331 bool selRes
= grid
->DoSelectProperty(NULL
, wxPG_SEL_DELETING
);
332 wxPG_CHECK_RET_DBG( selRes
,
333 wxT("failed to deselect a property (editor probably had invalid value)") );
336 state
->DoDelete( p
);
341 // -----------------------------------------------------------------------
343 wxPGProperty
* wxPropertyGridInterface
::ReplaceProperty( wxPGPropArg id
, wxPGProperty
* property
)
345 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty
)
347 wxPGProperty
* replaced
= p
;
348 wxCHECK_MSG( replaced
&& property
,
350 wxT("NULL property") );
351 wxCHECK_MSG( !replaced
->IsCategory(),
353 wxT("cannot replace this type of property") );
354 wxCHECK_MSG( !m_pState
->IsInNonCatMode(),
356 wxT("cannot replace properties in alphabetic mode") );
358 // Get address to the slot
359 wxPGProperty
* parent
= replaced
->GetParent();
360 int ind
= replaced
->GetIndexInParent();
362 wxPropertyGridPageState
* state
= replaced
->GetParentState();
363 DeleteProperty(replaced
); // Must use generic Delete
364 state
->DoInsert(parent
,ind
,property
);
369 // -----------------------------------------------------------------------
370 // wxPropertyGridInterface property operations
371 // -----------------------------------------------------------------------
373 bool wxPropertyGridInterface
::ClearSelection()
375 wxPropertyGridPageState
* state
= m_pState
;
376 wxPropertyGrid
* pg
= state
->GetGrid();
377 if ( pg
->GetState() == state
)
378 return pg
->DoClearSelection();
380 state
->SetSelection(NULL
);
384 // -----------------------------------------------------------------------
386 void wxPropertyGridInterface
::LimitPropertyEditing( wxPGPropArg id
, bool limit
)
388 wxPG_PROP_ARG_CALL_PROLOG()
390 m_pState
->DoLimitPropertyEditing(p
, limit
);
394 // -----------------------------------------------------------------------
396 bool wxPropertyGridInterface
::EnableProperty( wxPGPropArg id
, bool enable
)
398 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
400 wxPropertyGridPageState
* state
= p
->GetParentState();
401 wxPropertyGrid
* grid
= state
->GetGrid();
405 if ( !(p
->m_flags
& wxPG_PROP_DISABLED
) )
408 // If active, Set active Editor.
409 if ( grid
->GetState() == state
&& p
== grid
->GetSelection() )
410 grid
->DoSelectProperty( p
, wxPG_SEL_FORCE
);
414 if ( p
->m_flags
& wxPG_PROP_DISABLED
)
417 // If active, Disable as active Editor.
418 if ( grid
->GetState() == state
&& p
== grid
->GetSelection() )
419 grid
->DoSelectProperty( p
, wxPG_SEL_FORCE
);
422 state
->DoEnableProperty(p
, enable
);
424 RefreshProperty( p
);
429 // -----------------------------------------------------------------------
431 bool wxPropertyGridInterface
::ExpandAll( bool doExpand
)
433 wxPropertyGridPageState
* state
= m_pState
;
435 if ( !state
->DoGetRoot()->GetChildCount() )
438 wxPropertyGrid
* pg
= state
->GetGrid();
440 if ( GetSelection() && GetSelection() != state
->DoGetRoot() &&
443 if ( !pg
->ClearSelection() )
449 for ( it
= GetVIterator( wxPG_ITERATE_ALL
); !it
.AtEnd(); it
.Next() )
451 wxPGProperty
* p
= (wxPGProperty
*) it
.GetProperty();
452 if ( p
->GetChildCount() )
456 if ( !p
->IsExpanded() )
463 if ( p
->IsExpanded() )
465 state
->DoCollapse(p
);
471 pg
->RecalculateVirtualSize();
478 // -----------------------------------------------------------------------
480 void wxPropertyGridInterface
::SetPropertyValueUnspecified( wxPGPropArg id
)
482 wxPG_PROP_ARG_CALL_PROLOG()
483 wxPropertyGrid
* propGrid
= p
->GetGridIfDisplayed();
485 propGrid
->DoSetPropertyValueUnspecified(p
);
487 p
->GetParentState()->DoSetPropertyValueUnspecified(p
);
490 // -----------------------------------------------------------------------
491 // wxPropertyGridInterface property value setting and getting
492 // -----------------------------------------------------------------------
494 void wxPGGetFailed( const wxPGProperty
* p
, const wxString
& typestr
)
496 wxPGTypeOperationFailed(p
, typestr
, wxS("Get"));
499 // -----------------------------------------------------------------------
501 void wxPGTypeOperationFailed( const wxPGProperty
* p
,
502 const wxString
& typestr
,
505 wxASSERT( p
!= NULL
);
506 wxLogError( _("Type operation \"%s\" failed: Property labeled \"%s\" is of type \"%s\", NOT \"%s\"."),
507 op
.c_str(), p
->GetLabel().c_str(), p
->GetValue().GetType().c_str(), typestr
.c_str() );
510 // -----------------------------------------------------------------------
512 void wxPropertyGridInterface
::SetPropVal( wxPGPropArg id
, wxVariant
& value
)
514 wxPG_PROP_ARG_CALL_PROLOG()
519 wxPropertyGrid
* propGrid
= p
->GetGridIfDisplayed();
521 propGrid
->DrawItemAndValueRelated( p
);
526 // -----------------------------------------------------------------------
528 void wxPropertyGridInterface
::SetPropertyValueString( wxPGPropArg id
, const wxString
& value
)
530 wxPG_PROP_ARG_CALL_PROLOG()
532 if ( m_pState
->DoSetPropertyValueString(p
,value
) )
534 wxPropertyGrid
* propGrid
= p
->GetGridIfDisplayed();
536 propGrid
->DrawItemAndValueRelated( p
);
540 // -----------------------------------------------------------------------
542 void wxPropertyGridInterface
::SetValidationFailureBehavior( int vfbFlags
)
544 GetPropertyGrid()->m_permanentValidationFailureBehavior
= vfbFlags
;
547 // -----------------------------------------------------------------------
549 wxPGProperty
* wxPropertyGridInterface
::GetPropertyByNameA( const wxString
& name
) const
551 wxPGProperty
* p
= GetPropertyByName(name
);
552 wxASSERT_MSG(p
,wxString
::Format(wxT("no property with name '%s'"),name
.c_str()));
556 // ----------------------------------------------------------------------------
558 wxPGProperty
* wxPropertyGridInterface
::GetPropertyByLabel( const wxString
& label
) const
562 for ( it
= GetVIterator( wxPG_ITERATE_PROPERTIES
); !it
.AtEnd(); it
.Next() )
564 if ( it
.GetProperty()->GetLabel() == label
)
565 return it
.GetProperty();
568 return wxNullProperty
;
571 // ----------------------------------------------------------------------------
573 void wxPropertyGridInterface
::DoSetPropertyAttribute( wxPGPropArg id
, const wxString
& name
,
574 wxVariant
& value
, long argFlags
)
576 wxPG_PROP_ARG_CALL_PROLOG()
578 p
->SetAttribute( name
, value
);
580 if ( argFlags
& wxPG_RECURSE
)
583 for ( i
= 0; i
< p
->GetChildCount(); i
++ )
584 DoSetPropertyAttribute(p
->Item(i
), name
, value
, argFlags
);
588 // -----------------------------------------------------------------------
590 void wxPropertyGridInterface
::SetPropertyAttributeAll( const wxString
& attrName
,
593 unsigned int pageIndex
= 0;
597 wxPropertyGridPageState
* page
= GetPageState(pageIndex
);
600 DoSetPropertyAttribute(page
->DoGetRoot(), attrName
, value
, wxPG_RECURSE
);
606 // -----------------------------------------------------------------------
608 void wxPropertyGridInterface
::GetPropertiesWithFlag( wxArrayPGProperty
* targetArr
,
609 wxPGProperty
::FlagType flags
,
611 int iterFlags
) const
613 wxASSERT( targetArr
);
614 wxPGVIterator it
= GetVIterator( iterFlags
);
620 const wxPGProperty
* property
= it
.GetProperty();
624 if ( (property
->GetFlags() & flags
) == flags
)
625 targetArr
->push_back((wxPGProperty
*)property
);
629 if ( (property
->GetFlags() & flags
) != flags
)
630 targetArr
->push_back((wxPGProperty
*)property
);
635 // -----------------------------------------------------------------------
637 void wxPropertyGridInterface
::SetPropertiesFlag( const wxArrayPGProperty
& srcArr
,
638 wxPGProperty
::FlagType flags
,
643 for ( i
=0; i
<srcArr
.size(); i
++ )
645 wxPGProperty
* property
= srcArr
[i
];
648 property
->SetFlag(flags
);
650 property
->ClearFlag(flags
);
653 // If collapsed flag or hidden was manipulated, we need to update virtual
655 wxPropertyGrid
* pg
= GetPropertyGrid();
656 if ( flags
& (wxPG_PROP_COLLAPSED
|wxPG_PROP_HIDDEN
) )
658 GetState()->VirtualHeightChanged();
659 pg
->RecalculateVirtualSize();
663 // -----------------------------------------------------------------------
665 void wxPropertyGridInterface
::SetBoolChoices( const wxString
& trueChoice
,
666 const wxString
& falseChoice
)
668 wxPGGlobalVars
->m_boolChoices
[0] = falseChoice
;
669 wxPGGlobalVars
->m_boolChoices
[1] = trueChoice
;
672 // -----------------------------------------------------------------------
674 wxPGProperty
* wxPropertyGridInterface
::DoGetPropertyByName( const wxString
& name
) const
676 return m_pState
->BaseGetPropertyByName(name
);
679 // -----------------------------------------------------------------------
681 wxPGProperty
* wxPropertyGridInterface
::GetPropertyByName( const wxString
& name
,
682 const wxString
& subname
) const
684 wxPGProperty
* p
= DoGetPropertyByName(name
);
685 if ( !p
|| !p
->GetChildCount() )
686 return wxNullProperty
;
688 return p
->GetPropertyByName(subname
);
691 // -----------------------------------------------------------------------
693 // Since GetPropertyByName is used *a lot*, this makes sense
694 // since non-virtual method can be called with less code.
695 wxPGProperty
* wxPropertyGridInterface
::GetPropertyByName( const wxString
& name
) const
697 wxPGProperty
* p
= DoGetPropertyByName(name
);
701 // Check if its "Property.SubProperty" format
702 int pos
= name
.Find(wxT('.'));
706 return GetPropertyByName(name
.substr(0,pos
),
707 name
.substr(pos
+1,name
.length()-pos
-1));
710 // -----------------------------------------------------------------------
712 bool wxPropertyGridInterface
::HideProperty( wxPGPropArg id
, bool hide
, int flags
)
714 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
716 wxPropertyGrid
* pg
= m_pState
->GetGrid();
718 if ( pg
== p
->GetGrid() )
719 return pg
->DoHideProperty(p
, hide
, flags
);
721 m_pState
->DoHideProperty(p
, hide
, flags
);
726 // -----------------------------------------------------------------------
728 bool wxPropertyGridInterface
::Collapse( wxPGPropArg id
)
730 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
731 wxPropertyGrid
* pg
= p
->GetGridIfDisplayed();
733 return pg
->DoCollapse(p
);
735 return p
->GetParentState()->DoCollapse(p
);
738 // -----------------------------------------------------------------------
740 bool wxPropertyGridInterface
::Expand( wxPGPropArg id
)
742 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
743 wxPropertyGrid
* pg
= p
->GetGridIfDisplayed();
745 return pg
->DoExpand(p
);
747 return p
->GetParentState()->DoExpand(p
);
750 // -----------------------------------------------------------------------
752 void wxPropertyGridInterface
::SetPropertyLabel( wxPGPropArg id
, const wxString
& newproplabel
)
754 wxPG_PROP_ARG_CALL_PROLOG()
756 p
->SetLabel( newproplabel
);
758 wxPropertyGridPageState
* state
= p
->GetParentState();
759 wxPropertyGrid
* pg
= state
->GetGrid();
761 if ( pg
->HasFlag(wxPG_AUTO_SORT
) )
762 pg
->SortChildren(p
->GetParent());
764 if ( pg
->GetState() == state
)
766 if ( pg
->HasFlag(wxPG_AUTO_SORT
) )
773 // -----------------------------------------------------------------------
775 bool wxPropertyGridInterface
::SetPropertyMaxLength( wxPGPropArg id
, int maxLen
)
777 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
779 wxPropertyGrid
* pg
= m_pState
->GetGrid();
781 p
->m_maxLen
= (short) maxLen
;
783 // Adjust control if selected currently
784 if ( pg
== p
->GetGrid() && p
== m_pState
->GetSelection() )
786 wxWindow
* wnd
= pg
->GetEditorControl();
787 wxTextCtrl
* tc
= wxDynamicCast(wnd
,wxTextCtrl
);
789 tc
->SetMaxLength( maxLen
);
798 // -----------------------------------------------------------------------
799 // GetPropertyValueAsXXX methods
801 #define IMPLEMENT_GET_VALUE(T,TRET,BIGNAME,DEFRETVAL) \
802 TRET wxPropertyGridInterface::GetPropertyValueAs##BIGNAME( wxPGPropArg id ) const \
804 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(DEFRETVAL) \
805 wxVariant value = p->GetValue(); \
806 if ( wxStrcmp(value.GetType(), wxPGTypeName_##T) != 0 ) \
808 wxPGGetFailed(p,wxPGTypeName_##T); \
809 return (TRET)DEFRETVAL; \
811 return (TRET)value.Get##BIGNAME(); \
814 // String is different than others.
815 wxString wxPropertyGridInterface
::GetPropertyValueAsString( wxPGPropArg id
) const
817 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxEmptyString
)
818 return p
->GetValueAsString(wxPG_FULL_VALUE
);
821 bool wxPropertyGridInterface
::GetPropertyValueAsBool( wxPGPropArg id
) const
823 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
824 wxVariant value
= p
->GetValue();
825 if ( wxStrcmp(value
.GetType(), wxPGTypeName_bool
) == 0 )
827 return value
.GetBool();
829 if ( wxStrcmp(value
.GetType(), wxPGTypeName_long
) == 0 )
831 return value
.GetLong()?
true:false;
833 wxPGGetFailed(p
,wxPGTypeName_bool
);
837 IMPLEMENT_GET_VALUE(long,long,Long
,0)
838 IMPLEMENT_GET_VALUE(double,double,Double
,0.0)
839 IMPLEMENT_GET_VALUE(void,void*,VoidPtr
,NULL
)
841 bool wxPropertyGridInterface
::IsPropertyExpanded( wxPGPropArg id
) const
843 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
844 return p
->IsExpanded();
847 // -----------------------------------------------------------------------
848 // wxPropertyGridInterface wrappers
849 // -----------------------------------------------------------------------
851 bool wxPropertyGridInterface
::ChangePropertyValue( wxPGPropArg id
, wxVariant newValue
)
853 return GetPropertyGrid()->ChangePropertyValue(id
, newValue
);
856 // -----------------------------------------------------------------------
858 void wxPropertyGridInterface
::BeginAddChildren( wxPGPropArg id
)
860 wxPG_PROP_ARG_CALL_PROLOG()
861 wxCHECK_RET( p
->HasFlag(wxPG_PROP_AGGREGATE
), wxT("only call on properties with fixed children") );
862 p
->ClearFlag(wxPG_PROP_AGGREGATE
);
863 p
->SetFlag(wxPG_PROP_MISC_PARENT
);
866 // -----------------------------------------------------------------------
868 bool wxPropertyGridInterface
::EditorValidate()
870 return GetPropertyGrid()->DoEditorValidate();
873 // -----------------------------------------------------------------------
875 void wxPropertyGridInterface
::EndAddChildren( wxPGPropArg id
)
877 wxPG_PROP_ARG_CALL_PROLOG()
878 wxCHECK_RET( p
->HasFlag(wxPG_PROP_MISC_PARENT
), wxT("only call on properties for which BeginAddChildren was called prior") );
879 p
->ClearFlag(wxPG_PROP_MISC_PARENT
);
880 p
->SetFlag(wxPG_PROP_AGGREGATE
);
883 // -----------------------------------------------------------------------
884 // wxPGVIterator_State
885 // -----------------------------------------------------------------------
887 // Default returned by wxPropertyGridInterface::GetVIterator().
888 class wxPGVIteratorBase_State
: public wxPGVIteratorBase
891 wxPGVIteratorBase_State( wxPropertyGridPageState
* state
, int flags
)
893 m_it
.Init( state
, flags
);
895 virtual ~wxPGVIteratorBase_State() { }
896 virtual void Next() { m_it
.Next(); }
899 wxPGVIterator wxPropertyGridInterface
::GetVIterator( int flags
) const
901 return wxPGVIterator( new wxPGVIteratorBase_State( m_pState
, flags
) );
904 // -----------------------------------------------------------------------
905 // wxPGEditableState related functions
906 // -----------------------------------------------------------------------
908 // EscapeDelimiters() changes ";" into "\;" and "|" into "\|"
909 // in the input string. This is an internal functions which is
910 // used for saving states
911 // NB: Similar function exists in aui/framemanager.cpp
912 static wxString
EscapeDelimiters(const wxString
& s
)
915 result
.Alloc(s
.length());
916 const wxChar
* ch
= s
.c_str();
919 if (*ch
== wxT(';') || *ch
== wxT('|') || *ch
== wxT(','))
927 wxString wxPropertyGridInterface
::SaveEditableState( int includedStates
) const
932 // Save state on page basis
933 unsigned int pageIndex
= 0;
934 wxArrayPtrVoid pageStates
;
938 wxPropertyGridPageState
* page
= GetPageState(pageIndex
);
941 pageStates
.Add(page
);
946 for ( pageIndex
=0; pageIndex
< pageStates
.size(); pageIndex
++ )
948 wxPropertyGridPageState
* pageState
= (wxPropertyGridPageState
*) pageStates
[pageIndex
];
950 if ( includedStates
& SelectionState
)
953 if ( pageState
->GetSelection() )
954 sel
= pageState
->GetSelection()->GetName();
955 result
+= wxS("selection=");
956 result
+= EscapeDelimiters(sel
);
959 if ( includedStates
& ExpandedState
)
961 wxArrayPGProperty ptrs
;
962 wxPropertyGridConstIterator it
=
963 wxPropertyGridConstIterator( pageState
,
964 wxPG_ITERATE_ALL_PARENTS_RECURSIVELY
|wxPG_ITERATE_HIDDEN
,
967 result
+= wxS("expanded=");
973 const wxPGProperty
* p
= it
.GetProperty();
975 if ( !p
->HasFlag(wxPG_PROP_COLLAPSED
) )
976 result
+= EscapeDelimiters(p
->GetName());
981 if ( result
.Last() == wxS(',') )
986 if ( includedStates
& ScrollPosState
)
989 GetPropertyGrid()->GetViewStart(&x
,&y
);
990 result
+= wxString
::Format(wxS("scrollpos=%i,%i;"), x
, y
);
992 if ( includedStates
& SplitterPosState
)
994 result
+= wxS("splitterpos=");
996 for ( size_t i
=0; i
<pageState
->GetColumnCount(); i
++ )
997 result
+= wxString
::Format(wxS("%i,"), pageState
->DoGetSplitterPosition(i
));
999 result
.RemoveLast(); // Remove last comma
1002 if ( includedStates
& PageState
)
1004 result
+= wxS("ispageselected=");
1006 if ( GetPageState(-1) == pageState
)
1007 result
+= wxS("1;");
1009 result
+= wxS("0;");
1011 result
.RemoveLast(); // Remove last semicolon
1016 if ( result
.length() )
1017 result
.RemoveLast();
1022 bool wxPropertyGridInterface
::RestoreEditableState( const wxString
& src
, int restoreStates
)
1024 wxPropertyGrid
* pg
= GetPropertyGrid();
1025 wxPGProperty
* newSelection
= NULL
;
1029 long selectedPage
= -1;
1030 bool pgSelectionSet
= false;
1034 wxArrayString pageStrings
= ::wxSplit(src
, wxS('|'), wxS('\\'));
1036 for ( pageIndex
=0; pageIndex
<pageStrings
.size(); pageIndex
++ )
1038 wxPropertyGridPageState
* pageState
= GetPageState(pageIndex
);
1042 wxArrayString kvpairStrings
= ::wxSplit(pageStrings
[pageIndex
], wxS(';'), wxS('\\'));
1044 for ( size_t i
=0; i
<kvpairStrings
.size(); i
++ )
1046 const wxString
& kvs
= kvpairStrings
[i
];
1047 int eq_pos
= kvs
.Find(wxS('='));
1048 if ( eq_pos
!= wxNOT_FOUND
)
1050 wxString key
= kvs
.substr(0, eq_pos
);
1051 wxString value
= kvs
.substr(eq_pos
+1);
1053 // Further split value by commas
1054 wxArrayString values
= ::wxSplit(value
, wxS(','), wxS('\\'));
1056 if ( key
== wxS("expanded") )
1058 if ( restoreStates
& ExpandedState
)
1060 wxPropertyGridIterator it
=
1061 wxPropertyGridIterator( pageState
,
1065 // First collapse all
1066 for ( ; !it
.AtEnd(); it
.Next() )
1068 wxPGProperty
* p
= it
.GetProperty();
1069 pageState
->DoCollapse(p
);
1072 // Then expand those which names are in values
1073 for ( size_t n
=0; n
<values
.size(); n
++ )
1075 const wxString
& name
= values
[n
];
1076 wxPGProperty
* prop
= GetPropertyByName(name
);
1078 pageState
->DoExpand(prop
);
1082 else if ( key
== wxS("scrollpos") )
1084 if ( restoreStates
& ScrollPosState
)
1086 if ( values
.size() == 2 )
1088 values
[0].ToLong(&vx
);
1089 values
[1].ToLong(&vy
);
1097 else if ( key
== wxS("splitterpos") )
1099 if ( restoreStates
& SplitterPosState
)
1101 for ( size_t n
=1; n
<values
.size(); n
++ )
1104 values
[n
].ToLong(&pos
);
1106 pageState
->DoSetSplitterPosition(pos
, n
);
1110 else if ( key
== wxS("selection") )
1112 if ( restoreStates
& SelectionState
)
1114 if ( values
.size() > 0 )
1116 if ( pageState
->IsDisplayed() )
1118 if ( values
[0].length() )
1119 newSelection
= GetPropertyByName(value
);
1120 pgSelectionSet
= true;
1124 if ( values
[0].length() )
1125 pageState
->SetSelection(GetPropertyByName(value
));
1127 pageState
->DoClearSelection();
1132 else if ( key
== wxS("ispageselected") )
1134 if ( restoreStates
& PageState
)
1137 if ( values
.size() == 1 && values
[0].ToLong(&pageSelStatus
) )
1139 if ( pageSelStatus
)
1140 selectedPage
= pageIndex
;
1157 // Force recalculation of virtual heights of all pages
1158 // (may be needed on unclean source string).
1160 wxPropertyGridPageState
* pageState
= GetPageState(pageIndex
);
1163 pageState
->VirtualHeightChanged();
1165 pageState
= GetPageState(pageIndex
);
1171 // Selection of visible grid page must be set after Thaw() call
1172 if ( pgSelectionSet
)
1175 pg
->SelectProperty(newSelection
);
1177 pg
->ClearSelection();
1180 if ( selectedPage
!= -1 )
1182 DoSelectPage(selectedPage
);
1193 #endif // wxUSE_PROPGRID