1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/propgrid/property.cpp
3 // Purpose: wxPGProperty and related support classes
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"
34 #include "wx/settings.h"
38 #include <wx/propgrid/propgrid.h>
41 #define PWC_CHILD_SUMMARY_LIMIT 16 // Maximum number of children summarized in a parent property's
44 #define PWC_CHILD_SUMMARY_CHAR_LIMIT 64 // Character limit of summary field when not editing
47 // -----------------------------------------------------------------------
49 static void wxPGDrawFocusRect( wxDC
& dc
, const wxRect
& rect
)
51 #if defined(__WXMSW__) && !defined(__WXWINCE__)
52 // FIXME: Use DrawFocusRect code above (currently it draws solid line
53 // for caption focus but works ok for other stuff).
54 // Also, it seems that this code may not work in future wx versions.
55 dc
.SetLogicalFunction(wxINVERT
);
57 wxPen
pen(*wxBLACK
,1,wxDOT
);
58 pen
.SetCap(wxCAP_BUTT
);
60 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
62 dc
.DrawRectangle(rect
);
64 dc
.SetLogicalFunction(wxCOPY
);
66 dc
.SetLogicalFunction(wxINVERT
);
68 dc
.SetPen(wxPen(*wxBLACK
,1,wxDOT
));
69 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
71 dc
.DrawRectangle(rect
);
73 dc
.SetLogicalFunction(wxCOPY
);
77 // -----------------------------------------------------------------------
79 // -----------------------------------------------------------------------
81 wxSize
wxPGCellRenderer::GetImageSize( const wxPGProperty
* WXUNUSED(property
),
83 int WXUNUSED(item
) ) const
88 void wxPGCellRenderer::DrawText( wxDC
& dc
, const wxRect
& rect
,
89 int xOffset
, const wxString
& text
) const
92 xOffset
+= wxCC_CUSTOM_IMAGE_MARGIN1
+ wxCC_CUSTOM_IMAGE_MARGIN2
;
94 rect
.x
+xOffset
+wxPG_XBEFORETEXT
,
95 rect
.y
+((rect
.height
-dc
.GetCharHeight())/2) );
98 void wxPGCellRenderer::DrawEditorValue( wxDC
& dc
, const wxRect
& rect
,
99 int xOffset
, const wxString
& text
,
100 wxPGProperty
* property
,
101 const wxPGEditor
* editor
) const
104 xOffset
+= wxCC_CUSTOM_IMAGE_MARGIN1
+ wxCC_CUSTOM_IMAGE_MARGIN2
;
106 int yOffset
= ((rect
.height
-dc
.GetCharHeight())/2);
113 rect2
.height
-= yOffset
;
114 editor
->DrawValue( dc
, rect2
, property
, text
);
119 rect
.x
+xOffset
+wxPG_XBEFORETEXT
,
124 void wxPGCellRenderer::DrawCaptionSelectionRect( wxDC
& dc
, int x
, int y
, int w
, int h
) const
126 wxRect
focusRect(x
,y
+((h
-dc
.GetCharHeight())/2),w
,h
);
127 wxPGDrawFocusRect(dc
,focusRect
);
130 int wxPGCellRenderer::PreDrawCell( wxDC
& dc
, const wxRect
& rect
, const wxPGCell
& cell
, int flags
) const
134 if ( !(flags
& Selected
) )
136 // Draw using wxPGCell information, if available
137 wxColour fgCol
= cell
.GetFgCol();
139 dc
.SetTextForeground(fgCol
);
141 wxColour bgCol
= cell
.GetBgCol();
146 dc
.DrawRectangle(rect
);
150 const wxBitmap
& bmp
= cell
.GetBitmap();
152 // In control, do not draw oversized bitmap
153 (!(flags
& Control
) || bmp
.GetHeight() < rect
.height
)
157 rect
.x
+ wxPG_CONTROL_MARGIN
+ wxCC_CUSTOM_IMAGE_MARGIN1
,
158 rect
.y
+ wxPG_CUSTOM_IMAGE_SPACINGY
,
160 imageOffset
= bmp
.GetWidth();
166 // -----------------------------------------------------------------------
167 // wxPGDefaultRenderer
168 // -----------------------------------------------------------------------
170 void wxPGDefaultRenderer::Render( wxDC
& dc
, const wxRect
& rect
,
171 const wxPropertyGrid
* propertyGrid
, wxPGProperty
* property
,
172 int column
, int item
, int flags
) const
174 bool isUnspecified
= property
->IsValueUnspecified();
176 if ( column
== 1 && item
== -1 )
178 int cmnVal
= property
->GetCommonValue();
182 if ( !isUnspecified
)
183 DrawText( dc
, rect
, 0, propertyGrid
->GetCommonValueLabel(cmnVal
) );
188 const wxPGEditor
* editor
= NULL
;
189 const wxPGCell
* cell
= property
->GetCell(column
);
195 if ( column
== 1 && (flags
& Control
) )
197 int selectedIndex
= property
->GetChoiceSelection();
198 if ( selectedIndex
!= wxNOT_FOUND
)
200 const wxPGChoices
& choices
= property
->GetChoices();
201 const wxPGCell
* ccell
= &choices
[selectedIndex
];
203 ( ccell
->GetBitmap().IsOk() || ccell
->GetFgCol().IsOk() || ccell
->GetBgCol().IsOk() )
211 int preDrawFlags
= flags
;
213 if ( propertyGrid
->GetInternalFlags() & wxPG_FL_CELL_OVERRIDES_SEL
)
214 preDrawFlags
= preDrawFlags
& ~(Selected
);
216 imageOffset
= PreDrawCell( dc
, rect
, *cell
, preDrawFlags
);
217 text
= cell
->GetText();
218 if ( text
== wxS("@!") )
221 text
= property
->GetLabel();
222 else if ( column
== 1 )
223 text
= property
->GetValueString();
225 text
= wxEmptyString
;
228 else if ( column
== 0 )
231 DrawText( dc
, rect
, 0, property
->GetLabel() );
233 else if ( column
== 1 )
235 if ( !isUnspecified
)
237 editor
= property
->GetColumnEditor(column
);
239 // Regular property value
241 wxSize imageSize
= propertyGrid
->GetImageSize(property
, item
);
243 wxPGPaintData paintdata
;
244 paintdata
.m_parent
= propertyGrid
;
245 paintdata
.m_choiceItem
= item
;
247 if ( imageSize
.x
> 0 )
249 wxRect
imageRect(rect
.x
+ wxPG_CONTROL_MARGIN
+ wxCC_CUSTOM_IMAGE_MARGIN1
,
250 rect
.y
+wxPG_CUSTOM_IMAGE_SPACINGY
,
251 wxPG_CUSTOM_IMAGE_WIDTH
,
252 rect
.height
-(wxPG_CUSTOM_IMAGE_SPACINGY
*2));
254 /*if ( imageSize.x == wxPG_FULL_CUSTOM_PAINT_WIDTH )
256 imageRect.width = m_width - imageRect.x;
259 dc
.SetPen( wxPen(propertyGrid
->GetCellTextColour(), 1, wxSOLID
) );
261 paintdata
.m_drawnWidth
= imageSize
.x
;
262 paintdata
.m_drawnHeight
= imageSize
.y
;
264 if ( !isUnspecified
)
266 property
->OnCustomPaint( dc
, imageRect
, paintdata
);
270 dc
.SetBrush(*wxWHITE_BRUSH
);
271 dc
.DrawRectangle(imageRect
);
274 imageOffset
= paintdata
.m_drawnWidth
;
277 text
= property
->GetValueString();
280 if ( propertyGrid
->GetColumnCount() <= 2 )
282 wxString unitsString
= property
->GetAttribute(wxPGGlobalVars
->m_strUnits
, wxEmptyString
);
283 if ( unitsString
.length() )
284 text
= wxString::Format(wxS("%s %s"), text
.c_str(), unitsString
.c_str() );
288 if ( text
.length() == 0 )
290 // Try to show inline help if no text
291 wxVariant vInlineHelp
= property
->GetAttribute(wxPGGlobalVars
->m_strInlineHelp
);
292 if ( !vInlineHelp
.IsNull() )
294 text
= vInlineHelp
.GetString();
295 dc
.SetTextForeground(propertyGrid
->GetCellDisabledTextColour());
299 else if ( column
== 2 )
302 if ( !text
.length() )
303 text
= property
->GetAttribute(wxPGGlobalVars
->m_strUnits
, wxEmptyString
);
306 DrawEditorValue( dc
, rect
, imageOffset
, text
, property
, editor
);
308 // active caption gets nice dotted rectangle
309 if ( property
->IsCategory() /*&& column == 0*/ )
311 if ( flags
& Selected
)
313 if ( imageOffset
> 0 )
314 imageOffset
+= wxCC_CUSTOM_IMAGE_MARGIN2
+ 4;
316 DrawCaptionSelectionRect( dc
,
317 rect
.x
+wxPG_XBEFORETEXT
-wxPG_CAPRECTXMARGIN
+imageOffset
,
318 rect
.y
-wxPG_CAPRECTYMARGIN
+1,
319 ((wxPropertyCategory
*)property
)->GetTextExtent(propertyGrid
,
320 propertyGrid
->GetCaptionFont())
321 +(wxPG_CAPRECTXMARGIN
*2),
322 propertyGrid
->GetFontHeight()+(wxPG_CAPRECTYMARGIN
*2) );
327 wxSize
wxPGDefaultRenderer::GetImageSize( const wxPGProperty
* property
,
331 if ( property
&& column
== 1 )
335 wxBitmap
* bmp
= property
->GetValueImage();
337 if ( bmp
&& bmp
->Ok() )
338 return wxSize(bmp
->GetWidth(),bmp
->GetHeight());
344 // -----------------------------------------------------------------------
346 // -----------------------------------------------------------------------
352 wxPGCell::wxPGCell( const wxString
& text
,
353 const wxBitmap
& bitmap
,
354 const wxColour
& fgCol
,
355 const wxColour
& bgCol
)
356 : m_bitmap(bitmap
), m_fgCol(fgCol
), m_bgCol(bgCol
)
361 // -----------------------------------------------------------------------
363 // -----------------------------------------------------------------------
365 IMPLEMENT_ABSTRACT_CLASS(wxPGProperty
, wxObject
)
367 wxString
* wxPGProperty::sm_wxPG_LABEL
= NULL
;
369 void wxPGProperty::Init()
375 m_parentState
= (wxPropertyGridPageState
*) NULL
;
378 m_clientObject
= NULL
;
380 m_customEditor
= (wxPGEditor
*) NULL
;
382 m_validator
= (wxValidator
*) NULL
;
384 m_valueBitmap
= (wxBitmap
*) NULL
;
386 m_maxLen
= 0; // infinite maximum length
388 m_flags
= wxPG_PROP_PROPERTY
;
398 void wxPGProperty::Init( const wxString
& label
, const wxString
& name
)
400 // We really need to check if &label and &name are NULL pointers
401 // (this can if we are called before property grid has been initalized)
403 if ( (&label
) != NULL
&& label
!= wxPG_LABEL
)
406 if ( (&name
) != NULL
&& name
!= wxPG_LABEL
)
409 DoSetName( m_label
);
414 wxPGProperty::wxPGProperty()
421 wxPGProperty::wxPGProperty( const wxString
& label
, const wxString
& name
)
428 wxPGProperty::~wxPGProperty()
430 delete m_clientObject
;
432 Empty(); // this deletes items
434 delete m_valueBitmap
;
441 for ( i
=0; i
<m_cells
.size(); i
++ )
442 delete (wxPGCell
*) m_cells
[i
];
444 // This makes it easier for us to detect dangling pointers
449 bool wxPGProperty::IsSomeParent( wxPGProperty
* candidate
) const
451 wxPGProperty
* parent
= m_parent
;
454 if ( parent
== candidate
)
456 parent
= parent
->m_parent
;
462 wxString
wxPGProperty::GetName() const
464 wxPGProperty
* parent
= GetParent();
466 if ( !m_name
.length() || !parent
|| parent
->IsCategory() || parent
->IsRoot() )
469 return m_parent
->GetName() + wxS(".") + m_name
;
472 wxPropertyGrid
* wxPGProperty::GetGrid() const
474 if ( !m_parentState
)
476 return m_parentState
->GetGrid();
480 void wxPGProperty::UpdateControl( wxWindow
* primary
)
483 GetEditorClass()->UpdateControl(this, primary
);
486 bool wxPGProperty::ValidateValue( wxVariant
& WXUNUSED(value
), wxPGValidationInfo
& WXUNUSED(validationInfo
) ) const
491 void wxPGProperty::OnSetValue()
495 void wxPGProperty::RefreshChildren ()
499 wxString
wxPGProperty::GetColumnText( unsigned int col
) const
501 wxPGCell
* cell
= GetCell(col
);
504 return cell
->GetText();
511 return GetDisplayedString();
513 return GetAttribute(wxPGGlobalVars
->m_strUnits
, wxEmptyString
);
516 return wxEmptyString
;
519 void wxPGProperty::GenerateComposedValue( wxString
& text
, int argFlags
) const
522 int iMax
= m_children
.GetCount();
528 if ( iMax
> PWC_CHILD_SUMMARY_LIMIT
&&
529 !(argFlags
& wxPG_FULL_VALUE
) )
530 iMax
= PWC_CHILD_SUMMARY_LIMIT
;
532 int iMaxMinusOne
= iMax
-1;
534 if ( !IsTextEditable() )
535 argFlags
|= wxPG_UNEDITABLE_COMPOSITE_FRAGMENT
;
537 wxPGProperty
* curChild
= (wxPGProperty
*) m_children
.Item(0);
539 for ( i
= 0; i
< iMax
; i
++ )
542 if ( !curChild
->IsValueUnspecified() )
543 s
= curChild
->GetValueString(argFlags
|wxPG_COMPOSITE_FRAGMENT
);
546 if ( (argFlags
& wxPG_UNEDITABLE_COMPOSITE_FRAGMENT
) && !s
.length() )
549 if ( !curChild
->GetChildCount() || skip
)
552 text
+= wxS("[") + s
+ wxS("]");
554 if ( i
< iMaxMinusOne
)
556 if ( text
.length() > PWC_CHILD_SUMMARY_CHAR_LIMIT
&&
557 !(argFlags
& wxPG_EDITABLE_VALUE
) &&
558 !(argFlags
& wxPG_FULL_VALUE
) )
563 if ( !curChild
->GetChildCount() )
569 curChild
= (wxPGProperty
*) m_children
.Item(i
+1);
573 // Remove superfluous semicolon and space
575 if ( text
.EndsWith(wxS("; "), &rest
) )
578 if ( (unsigned int)i
< m_children
.GetCount() )
579 text
+= wxS("; ...");
582 wxString
wxPGProperty::GetValueAsString( int argFlags
) const
584 wxCHECK_MSG( GetChildCount() > 0,
586 wxT("If user property does not have any children, it must override GetValueAsString") );
589 GenerateComposedValue(text
, argFlags
);
593 wxString
wxPGProperty::GetValueString( int argFlags
) const
595 if ( IsValueUnspecified() )
596 return wxEmptyString
;
598 if ( m_commonValue
== -1 )
599 return GetValueAsString(argFlags
);
602 // Return common value's string representation
603 wxPropertyGrid
* pg
= GetGrid();
604 const wxPGCommonValue
* cv
= pg
->GetCommonValue(m_commonValue
);
606 if ( argFlags
& wxPG_FULL_VALUE
)
608 return cv
->GetLabel();
610 else if ( argFlags
& wxPG_EDITABLE_VALUE
)
612 return cv
->GetEditableText();
616 return cv
->GetLabel();
620 bool wxPGProperty::IntToValue( wxVariant
& variant
, int number
, int WXUNUSED(argFlags
) ) const
622 variant
= (long)number
;
626 // Convert semicolon delimited tokens into child values.
627 bool wxPGProperty::StringToValue( wxVariant
& variant
, const wxString
& text
, int argFlags
) const
629 if ( !GetChildCount() )
632 unsigned int curChild
= 0;
634 unsigned int iMax
= m_children
.GetCount();
636 if ( iMax
> PWC_CHILD_SUMMARY_LIMIT
&&
637 !(argFlags
& wxPG_FULL_VALUE
) )
638 iMax
= PWC_CHILD_SUMMARY_LIMIT
;
640 bool changed
= false;
645 // Its best only to add non-empty group items
646 bool addOnlyIfNotEmpty
= false;
647 const wxChar delimeter
= wxS(';');
649 size_t tokenStart
= 0xFFFFFF;
651 wxVariantList temp_list
;
652 wxVariant
list(temp_list
);
654 int propagatedFlags
= argFlags
& wxPG_REPORT_ERROR
;
657 bool debug_print
= false;
662 wxLogDebug(wxT(">> %s.StringToValue('%s')"),GetLabel().c_str(),text
.c_str());
665 wxString::const_iterator it
= text
.begin();
668 if ( it
!= text
.end() )
675 if ( tokenStart
!= 0xFFFFFF )
678 if ( a
== delimeter
|| a
== 0 )
680 token
= text
.substr(tokenStart
,pos
-tokenStart
);
682 size_t len
= token
.length();
684 if ( !addOnlyIfNotEmpty
|| len
> 0 )
686 const wxPGProperty
* child
= Item(curChild
);
689 wxLogDebug(wxT("token = '%s', child = %s"),token
.c_str(),child
->GetLabel().c_str());
694 bool wasUnspecified
= child
->IsValueUnspecified();
696 wxVariant
variant(child
->GetValueRef());
697 if ( child
->StringToValue(variant
, token
, propagatedFlags
|wxPG_COMPOSITE_FRAGMENT
) )
699 variant
.SetName(child
->GetBaseName());
701 // Clear unspecified flag only if OnSetValue() didn't
703 if ( child
->IsValueUnspecified() &&
704 (wasUnspecified
|| !UsesAutoUnspecified()) )
706 variant
= child
->GetDefaultValue();
709 list
.Append(variant
);
716 // Empty, becomes unspecified
718 variant2
.SetName(child
->GetBaseName());
719 list
.Append(variant2
);
724 if ( curChild
>= iMax
)
728 tokenStart
= 0xFFFFFF;
733 // Token is not running
737 addOnlyIfNotEmpty
= false;
739 // Is this a group of tokens?
744 if ( it
!= text
.end() ) it
++;
746 size_t startPos
= pos
;
748 // Group item - find end
749 while ( it
!= text
.end() && depth
> 0 )
757 else if ( a
== wxS('[') )
761 token
= text
.substr(startPos
,pos
-startPos
-1);
763 if ( !token
.length() )
766 const wxPGProperty
* child
= Item(curChild
);
768 wxVariant oldChildValue
= child
->GetValue();
769 wxVariant
variant(oldChildValue
);
770 bool stvRes
= child
->StringToValue( variant
, token
, propagatedFlags
);
771 if ( stvRes
|| (variant
!= oldChildValue
) )
778 // Failed, becomes unspecified
783 variant
.SetName(child
->GetBaseName());
784 list
.Append(variant
);
787 if ( curChild
>= iMax
)
790 addOnlyIfNotEmpty
= true;
792 tokenStart
= 0xFFFFFF;
798 if ( a
== delimeter
)
811 if ( it
!= text
.end() )
828 bool wxPGProperty::SetValueFromString( const wxString
& text
, int argFlags
)
830 wxVariant
variant(m_value
);
831 bool res
= StringToValue(variant
, text
, argFlags
);
837 bool wxPGProperty::SetValueFromInt( long number
, int argFlags
)
839 wxVariant
variant(m_value
);
840 bool res
= IntToValue(variant
, number
, argFlags
);
846 wxSize
wxPGProperty::OnMeasureImage( int WXUNUSED(item
) ) const
849 return wxSize(m_valueBitmap
->GetWidth(),-1);
854 wxPGCellRenderer
* wxPGProperty::GetCellRenderer( int WXUNUSED(column
) ) const
856 return wxPGGlobalVars
->m_defaultRenderer
;
859 void wxPGProperty::OnCustomPaint( wxDC
& dc
,
863 wxBitmap
* bmp
= m_valueBitmap
;
865 wxCHECK_RET( bmp
&& bmp
->Ok(), wxT("invalid bitmap") );
867 wxCHECK_RET( rect
.x
>= 0, wxT("unexpected measure call") );
869 dc
.DrawBitmap(*bmp
,rect
.x
,rect
.y
);
872 const wxPGEditor
* wxPGProperty::DoGetEditorClass() const
874 return wxPG_EDITOR(TextCtrl
);
877 // Default extra property event handling - that is, none at all.
878 bool wxPGProperty::OnEvent( wxPropertyGrid
*, wxWindow
*, wxEvent
& )
884 void wxPGProperty::SetValue( wxVariant value
, wxVariant
* pList
, int flags
)
886 if ( !value
.IsNull() )
888 wxVariant tempListVariant
;
891 // List variants are reserved a special purpose
892 // as intermediate containers for child values
893 // of properties with children.
894 if ( value
.GetType() == wxPG_VARIANT_TYPE_LIST
)
897 // However, situation is different for composed string properties
898 if ( HasFlag(wxPG_PROP_COMPOSED_VALUE
) )
900 tempListVariant
= value
;
901 pList
= &tempListVariant
;
905 AdaptListToValue(value
, &newValue
);
907 //wxLogDebug(wxT(">> %s.SetValue() adapted list value to type '%s'"),GetName().c_str(),value.GetType().c_str());
910 if ( HasFlag( wxPG_PROP_AGGREGATE
) )
911 flags
|= wxPG_SETVAL_AGGREGATED
;
913 if ( pList
&& !pList
->IsNull() )
915 wxASSERT( pList
->GetType() == wxPG_VARIANT_TYPE_LIST
);
916 wxASSERT( GetChildCount() );
917 wxASSERT( !IsCategory() );
919 wxVariantList
& list
= pList
->GetList();
920 wxVariantList::iterator node
;
923 //wxLogDebug(wxT(">> %s.SetValue() pList parsing"),GetName().c_str());
925 // Children in list can be in any order, but we will give hint to
926 // GetPropertyByNameWH(). This optimizes for full list parsing.
927 for ( node
= list
.begin(); node
!= list
.end(); node
++ )
929 wxVariant
& childValue
= *((wxVariant
*)*node
);
930 wxPGProperty
* child
= GetPropertyByNameWH(childValue
.GetName(), i
);
933 //wxLogDebug(wxT("%i: child = %s, childValue.GetType()=%s"),i,child->GetBaseName().c_str(),childValue.GetType().c_str());
934 if ( childValue
.GetType() == wxPG_VARIANT_TYPE_LIST
)
936 if ( child
->HasFlag(wxPG_PROP_AGGREGATE
) && !(flags
& wxPG_SETVAL_AGGREGATED
) )
938 wxVariant listRefCopy
= childValue
;
939 child
->SetValue(childValue
, &listRefCopy
, flags
|wxPG_SETVAL_FROM_PARENT
);
943 wxVariant oldVal
= child
->GetValue();
944 child
->SetValue(oldVal
, &childValue
, flags
|wxPG_SETVAL_FROM_PARENT
);
947 else if ( child
->GetValue() != childValue
)
949 // For aggregate properties, we will trust RefreshChildren()
950 // to update child values.
951 if ( !HasFlag(wxPG_PROP_AGGREGATE
) )
952 child
->SetValue(childValue
, NULL
, flags
|wxPG_SETVAL_FROM_PARENT
);
953 if ( flags
& wxPG_SETVAL_BY_USER
)
954 child
->SetFlag(wxPG_PROP_MODIFIED
);
961 if ( !value
.IsNull() )
966 if ( !(flags
& wxPG_SETVAL_FROM_PARENT
) )
967 UpdateParentValues();
970 if ( flags
& wxPG_SETVAL_BY_USER
)
971 SetFlag(wxPG_PROP_MODIFIED
);
973 if ( HasFlag(wxPG_PROP_AGGREGATE
) )
978 if ( m_commonValue
!= -1 )
980 wxPropertyGrid
* pg
= GetGrid();
981 if ( !pg
|| m_commonValue
!= pg
->GetUnspecifiedCommonValue() )
987 // Set children to unspecified, but only if aggregate or
988 // value is <composed>
989 if ( AreChildrenComponents() )
992 for ( i
=0; i
<GetChildCount(); i
++ )
993 Item(i
)->SetValue(value
, NULL
, flags
|wxPG_SETVAL_FROM_PARENT
);
998 // Update editor control
1001 // We need to check for these, otherwise GetGrid() may fail.
1002 if ( flags
& wxPG_SETVAL_REFRESH_EDITOR
)
1007 void wxPGProperty::SetValueInEvent( wxVariant value
) const
1009 GetGrid()->ValueChangeInEvent(value
);
1012 void wxPGProperty::SetFlagRecursively( FlagType flag
, bool set
)
1020 for ( i
= 0; i
< GetChildCount(); i
++ )
1021 Item(i
)->SetFlagRecursively(flag
, set
);
1024 void wxPGProperty::RefreshEditor()
1026 if ( m_parent
&& GetParentState() )
1028 wxPropertyGrid
* pg
= GetParentState()->GetGrid();
1029 if ( pg
->GetSelectedProperty() == this )
1031 wxWindow
* editor
= pg
->GetEditorControl();
1033 GetEditorClass()->UpdateControl( this, editor
);
1039 wxVariant
wxPGProperty::GetDefaultValue() const
1041 wxVariant defVal
= GetAttribute(wxS("DefaultValue"));
1042 if ( !defVal
.IsNull() )
1045 wxVariant value
= GetValue();
1047 if ( !value
.IsNull() )
1049 wxString
valueType(value
.GetType());
1051 if ( valueType
== wxPG_VARIANT_TYPE_LONG
)
1052 return wxPGVariant_Zero
;
1053 if ( valueType
== wxPG_VARIANT_TYPE_STRING
)
1054 return wxPGVariant_EmptyString
;
1055 if ( valueType
== wxPG_VARIANT_TYPE_BOOL
)
1056 return wxPGVariant_False
;
1057 if ( valueType
== wxPG_VARIANT_TYPE_DOUBLE
)
1058 return wxVariant(0.0);
1059 if ( valueType
== wxPG_VARIANT_TYPE_ARRSTRING
)
1060 return wxVariant(wxArrayString());
1061 if ( valueType
== wxS("wxLongLong") )
1062 return WXVARIANT(wxLongLong(0));
1063 if ( valueType
== wxS("wxULongLong") )
1064 return WXVARIANT(wxULongLong(0));
1065 if ( valueType
== wxS("wxColour") )
1066 return WXVARIANT(*wxBLACK
);
1068 if ( valueType
== wxPG_VARIANT_TYPE_DATETIME
)
1069 return wxVariant(wxDateTime::Now());
1071 if ( valueType
== wxS("wxFont") )
1072 return WXVARIANT(*wxNORMAL_FONT
);
1073 if ( valueType
== wxS("wxPoint") )
1074 return WXVARIANT(wxPoint(0, 0));
1075 if ( valueType
== wxS("wxSize") )
1076 return WXVARIANT(wxSize(0, 0));
1082 void wxPGProperty::SetCell( int column
, wxPGCell
* cellObj
)
1084 if ( column
>= (int)m_cells
.size() )
1085 m_cells
.SetCount(column
+1, NULL
);
1087 delete (wxPGCell
*) m_cells
[column
];
1088 m_cells
[column
] = cellObj
;
1091 wxPGEditorDialogAdapter
* wxPGProperty::GetEditorDialog() const
1096 bool wxPGProperty::DoSetAttribute( const wxString
& WXUNUSED(name
), wxVariant
& WXUNUSED(value
) )
1101 void wxPGProperty::SetAttribute( const wxString
& name
, wxVariant value
)
1103 if ( DoSetAttribute( name
, value
) )
1105 // Support working without grid, when possible
1106 if ( wxPGGlobalVars
->HasExtraStyle( wxPG_EX_WRITEONLY_BUILTIN_ATTRIBUTES
) )
1110 m_attributes
.Set( name
, value
);
1113 void wxPGProperty::SetAttributes( const wxPGAttributeStorage
& attributes
)
1115 wxPGAttributeStorage::const_iterator it
= attributes
.StartIteration();
1118 while ( attributes
.GetNext(it
, variant
) )
1119 SetAttribute( variant
.GetName(), variant
);
1122 wxVariant
wxPGProperty::DoGetAttribute( const wxString
& WXUNUSED(name
) ) const
1128 wxVariant
wxPGProperty::GetAttribute( const wxString
& name
) const
1130 return m_attributes
.FindValue(name
);
1133 wxString
wxPGProperty::GetAttribute( const wxString
& name
, const wxString
& defVal
) const
1135 wxVariant variant
= m_attributes
.FindValue(name
);
1137 if ( !variant
.IsNull() )
1138 return variant
.GetString();
1143 long wxPGProperty::GetAttributeAsLong( const wxString
& name
, long defVal
) const
1145 wxVariant variant
= m_attributes
.FindValue(name
);
1147 return wxPGVariantToInt(variant
, defVal
);
1150 double wxPGProperty::GetAttributeAsDouble( const wxString
& name
, double defVal
) const
1153 wxVariant variant
= m_attributes
.FindValue(name
);
1155 if ( wxPGVariantToDouble(variant
, &retVal
) )
1161 wxVariant
wxPGProperty::GetAttributesAsList() const
1163 wxVariantList tempList
;
1164 wxVariant
v( tempList
, wxString::Format(wxS("@%s@attr"),m_name
.c_str()) );
1166 wxPGAttributeStorage::const_iterator it
= m_attributes
.StartIteration();
1169 while ( m_attributes
.GetNext(it
, variant
) )
1175 // Slots of utility flags are NULL
1176 const unsigned int gs_propFlagToStringSize
= 14;
1178 static const wxChar
* gs_propFlagToString
[gs_propFlagToStringSize
] = {
1195 wxString
wxPGProperty::GetFlagsAsString( FlagType flagsMask
) const
1198 int relevantFlags
= m_flags
& flagsMask
& wxPG_STRING_STORED_FLAGS
;
1202 for ( i
=0; i
<gs_propFlagToStringSize
; i
++ )
1204 if ( relevantFlags
& a
)
1206 const wxChar
* fs
= gs_propFlagToString
[i
];
1218 void wxPGProperty::SetFlagsFromString( const wxString
& str
)
1222 WX_PG_TOKENIZER1_BEGIN(str
, wxS('|'))
1224 for ( i
=0; i
<gs_propFlagToStringSize
; i
++ )
1226 const wxChar
* fs
= gs_propFlagToString
[i
];
1227 if ( fs
&& str
== fs
)
1233 WX_PG_TOKENIZER1_END()
1235 m_flags
= (m_flags
& ~wxPG_STRING_STORED_FLAGS
) | flags
;
1238 wxValidator
* wxPGProperty::DoGetValidator() const
1240 return (wxValidator
*) NULL
;
1243 int wxPGProperty::InsertChoice( const wxString
& label
, int index
, int value
)
1245 wxPropertyGrid
* pg
= GetGrid();
1246 int sel
= GetChoiceSelection();
1250 if ( index
== wxNOT_FOUND
)
1251 index
= m_choices
.GetCount();
1256 m_choices
.Insert(label
, index
, value
);
1258 if ( sel
!= newSel
)
1259 SetChoiceSelection(newSel
);
1261 if ( this == pg
->GetSelection() )
1262 GetEditorClass()->InsertItem(pg
->GetEditorControl(),label
,index
);
1268 void wxPGProperty::DeleteChoice( int index
)
1270 wxPropertyGrid
* pg
= GetGrid();
1272 int sel
= GetChoiceSelection();
1275 // Adjust current value
1278 SetValueToUnspecified();
1281 else if ( index
< sel
)
1286 m_choices
.RemoveAt(index
);
1288 if ( sel
!= newSel
)
1289 SetChoiceSelection(newSel
);
1291 if ( this == pg
->GetSelection() )
1292 GetEditorClass()->DeleteItem(pg
->GetEditorControl(), index
);
1295 int wxPGProperty::GetChoiceSelection() const
1297 wxVariant value
= GetValue();
1298 wxString valueType
= value
.GetType();
1299 int index
= wxNOT_FOUND
;
1301 if ( IsValueUnspecified() || !m_choices
.GetCount() )
1304 if ( valueType
== wxPG_VARIANT_TYPE_LONG
)
1306 index
= value
.GetLong();
1308 else if ( valueType
== wxPG_VARIANT_TYPE_STRING
)
1310 index
= m_choices
.Index(value
.GetString());
1312 else if ( valueType
== wxPG_VARIANT_TYPE_BOOL
)
1314 index
= value
.GetBool()? 1 : 0;
1320 void wxPGProperty::SetChoiceSelection( int newValue
)
1322 // Changes value of a property with choices, but only
1323 // works if the value type is long or string.
1324 wxString valueType
= GetValue().GetType();
1326 wxCHECK_RET( m_choices
.IsOk(), wxT("invalid choiceinfo") );
1328 if ( valueType
== wxPG_VARIANT_TYPE_STRING
)
1330 SetValue( m_choices
.GetLabel(newValue
) );
1332 else // if ( valueType == wxPG_VARIANT_TYPE_LONG )
1334 SetValue( (long) newValue
);
1338 bool wxPGProperty::SetChoices( wxPGChoices
& choices
)
1340 m_choices
.Assign(choices
);
1343 // This may be needed to trigger some initialization
1344 // (but don't do it if property is somewhat uninitialized)
1345 wxVariant defVal
= GetDefaultValue();
1346 if ( defVal
.IsNull() )
1356 const wxPGEditor
* wxPGProperty::GetEditorClass() const
1358 const wxPGEditor
* editor
;
1360 if ( !m_customEditor
)
1362 editor
= DoGetEditorClass();
1365 editor
= m_customEditor
;
1368 // Maybe override editor if common value specified
1369 if ( GetDisplayedCommonValueCount() )
1371 // TextCtrlAndButton -> ComboBoxAndButton
1372 if ( editor
->IsKindOf(CLASSINFO(wxPGTextCtrlAndButtonEditor
)) )
1373 editor
= wxPG_EDITOR(ChoiceAndButton
);
1375 // TextCtrl -> ComboBox
1376 else if ( editor
->IsKindOf(CLASSINFO(wxPGTextCtrlEditor
)) )
1377 editor
= wxPG_EDITOR(ComboBox
);
1383 bool wxPGProperty::HasVisibleChildren() const
1387 for ( i
=0; i
<GetChildCount(); i
++ )
1389 wxPGProperty
* child
= Item(i
);
1391 if ( !child
->HasFlag(wxPG_PROP_HIDDEN
) )
1398 bool wxPGProperty::PrepareValueForDialogEditing( wxPropertyGrid
* propGrid
)
1400 return propGrid
->EditorValidate();
1404 bool wxPGProperty::RecreateEditor()
1406 wxPropertyGrid
* pg
= GetGrid();
1409 wxPGProperty
* selected
= pg
->GetSelection();
1410 if ( this == selected
)
1412 pg
->DoSelectProperty(this, wxPG_SEL_FORCE
);
1419 void wxPGProperty::SetValueImage( wxBitmap
& bmp
)
1421 delete m_valueBitmap
;
1423 if ( &bmp
&& bmp
.Ok() )
1426 wxSize maxSz
= GetGrid()->GetImageSize();
1427 wxSize
imSz(bmp
.GetWidth(),bmp
.GetHeight());
1429 if ( imSz
.x
!= maxSz
.x
|| imSz
.y
!= maxSz
.y
)
1431 // Create a memory DC
1432 wxBitmap
* bmpNew
= new wxBitmap(maxSz
.x
,maxSz
.y
,bmp
.GetDepth());
1435 dc
.SelectObject(*bmpNew
);
1438 // FIXME: This is ugly - use image or wait for scaling patch.
1439 double scaleX
= (double)maxSz
.x
/ (double)imSz
.x
;
1440 double scaleY
= (double)maxSz
.y
/ (double)imSz
.y
;
1442 dc
.SetUserScale(scaleX
,scaleY
);
1444 dc
.DrawBitmap( bmp
, 0, 0 );
1446 m_valueBitmap
= bmpNew
;
1450 m_valueBitmap
= new wxBitmap(bmp
);
1453 m_flags
|= wxPG_PROP_CUSTOMIMAGE
;
1457 m_valueBitmap
= NULL
;
1458 m_flags
&= ~(wxPG_PROP_CUSTOMIMAGE
);
1463 wxPGProperty
* wxPGProperty::GetMainParent() const
1465 const wxPGProperty
* curChild
= this;
1466 const wxPGProperty
* curParent
= m_parent
;
1468 while ( curParent
&& !curParent
->IsCategory() )
1470 curChild
= curParent
;
1471 curParent
= curParent
->m_parent
;
1474 return (wxPGProperty
*) curChild
;
1478 const wxPGProperty
* wxPGProperty::GetLastVisibleSubItem() const
1481 // Returns last visible sub-item, recursively.
1482 if ( !IsExpanded() || !GetChildCount() )
1485 return Last()->GetLastVisibleSubItem();
1489 bool wxPGProperty::IsVisible() const
1491 const wxPGProperty
* parent
;
1493 if ( HasFlag(wxPG_PROP_HIDDEN
) )
1496 for ( parent
= GetParent(); parent
!= NULL
; parent
= parent
->GetParent() )
1498 if ( !parent
->IsExpanded() || parent
->HasFlag(wxPG_PROP_HIDDEN
) )
1505 wxPropertyGrid
* wxPGProperty::GetGridIfDisplayed() const
1507 wxPropertyGridPageState
* state
= GetParentState();
1508 wxPropertyGrid
* propGrid
= state
->GetGrid();
1509 if ( state
== propGrid
->GetState() )
1515 int wxPGProperty::GetY2( int lh
) const
1517 const wxPGProperty
* parent
;
1518 const wxPGProperty
* child
= this;
1522 for ( parent
= GetParent(); parent
!= NULL
; parent
= child
->GetParent() )
1524 if ( !parent
->IsExpanded() )
1526 y
+= parent
->GetChildrenHeight(lh
, child
->GetIndexInParent());
1531 y
-= lh
; // need to reduce one level
1537 int wxPGProperty::GetY() const
1539 return GetY2(GetGrid()->GetRowHeight());
1542 // This is used by Insert etc.
1543 void wxPGProperty::AddChild2( wxPGProperty
* prop
, int index
, bool correct_mode
)
1545 if ( index
< 0 || (size_t)index
>= m_children
.GetCount() )
1547 if ( correct_mode
) prop
->m_arrIndex
= m_children
.GetCount();
1548 m_children
.Add( prop
);
1552 m_children
.Insert( prop
, index
);
1553 if ( correct_mode
) FixIndexesOfChildren( index
);
1556 prop
->m_parent
= this;
1559 // This is used by properties that have fixed sub-properties
1560 void wxPGProperty::AddChild( wxPGProperty
* prop
)
1562 wxASSERT_MSG( prop
->GetBaseName().length(),
1563 "Property's children must have unique, non-empty names within their scope" );
1565 prop
->m_arrIndex
= m_children
.GetCount();
1566 m_children
.Add( prop
);
1568 int custImgHeight
= prop
->OnMeasureImage().y
;
1569 if ( custImgHeight
< 0 /*|| custImgHeight > 1*/ )
1570 prop
->m_flags
|= wxPG_PROP_CUSTOMIMAGE
;
1572 prop
->m_parent
= this;
1576 void wxPGProperty::AdaptListToValue( wxVariant
& list
, wxVariant
* value
) const
1578 wxASSERT( GetChildCount() );
1579 wxASSERT( !IsCategory() );
1581 *value
= GetValue();
1583 if ( !list
.GetCount() )
1586 wxASSERT( GetChildCount() >= (unsigned int)list
.GetCount() );
1588 bool allChildrenSpecified
;
1590 // Don't fully update aggregate properties unless all children have
1592 if ( HasFlag(wxPG_PROP_AGGREGATE
) )
1593 allChildrenSpecified
= AreAllChildrenSpecified(&list
);
1595 allChildrenSpecified
= true;
1597 wxVariant childValue
= list
[0];
1601 //wxLogDebug(wxT(">> %s.AdaptListToValue()"),GetBaseName().c_str());
1603 for ( i
=0; i
<GetChildCount(); i
++ )
1605 const wxPGProperty
* child
= Item(i
);
1607 if ( childValue
.GetName() == child
->GetBaseName() )
1609 //wxLogDebug(wxT(" %s(n=%i), %s"),childValue.GetName().c_str(),n,childValue.GetType().c_str());
1611 if ( childValue
.GetType() == wxPG_VARIANT_TYPE_LIST
)
1613 wxVariant
cv2(child
->GetValue());
1614 child
->AdaptListToValue(childValue
, &cv2
);
1618 if ( allChildrenSpecified
)
1619 ChildChanged(*value
, i
, childValue
);
1621 if ( n
== (unsigned int)list
.GetCount() )
1623 childValue
= list
[n
];
1629 void wxPGProperty::FixIndexesOfChildren( size_t starthere
)
1632 for ( i
=starthere
;i
<GetChildCount();i
++)
1633 Item(i
)->m_arrIndex
= i
;
1637 // Returns (direct) child property with given name (or NULL if not found)
1638 wxPGProperty
* wxPGProperty::GetPropertyByName( const wxString
& name
) const
1642 for ( i
=0; i
<GetChildCount(); i
++ )
1644 wxPGProperty
* p
= Item(i
);
1645 if ( p
->m_name
== name
)
1649 // Does it have point, then?
1650 int pos
= name
.Find(wxS('.'));
1652 return (wxPGProperty
*) NULL
;
1654 wxPGProperty
* p
= GetPropertyByName(name
. substr(0,pos
));
1656 if ( !p
|| !p
->GetChildCount() )
1659 return p
->GetPropertyByName(name
.substr(pos
+1,name
.length()-pos
-1));
1662 wxPGProperty
* wxPGProperty::GetPropertyByNameWH( const wxString
& name
, unsigned int hintIndex
) const
1664 unsigned int i
= hintIndex
;
1666 if ( i
>= GetChildCount() )
1669 unsigned int lastIndex
= i
- 1;
1671 if ( lastIndex
>= GetChildCount() )
1672 lastIndex
= GetChildCount() - 1;
1676 wxPGProperty
* p
= Item(i
);
1677 if ( p
->m_name
== name
)
1680 if ( i
== lastIndex
)
1684 if ( i
== GetChildCount() )
1691 int wxPGProperty::GetChildrenHeight( int lh
, int iMax_
) const
1693 // Returns height of children, recursively, and
1694 // by taking expanded/collapsed status into account.
1696 // iMax is used when finding property y-positions.
1702 iMax_
= GetChildCount();
1704 unsigned int iMax
= iMax_
;
1706 wxASSERT( iMax
<= GetChildCount() );
1708 if ( !IsExpanded() && GetParent() )
1713 wxPGProperty
* pwc
= (wxPGProperty
*) Item(i
);
1715 if ( !pwc
->HasFlag(wxPG_PROP_HIDDEN
) )
1717 if ( !pwc
->IsExpanded() ||
1718 pwc
->GetChildCount() == 0 )
1721 h
+= pwc
->GetChildrenHeight(lh
) + lh
;
1730 wxPGProperty
* wxPGProperty::GetItemAtY( unsigned int y
, unsigned int lh
, unsigned int* nextItemY
) const
1732 wxASSERT( nextItemY
);
1734 // Linear search at the moment
1736 // nextItemY = y of next visible property, final value will be written back.
1737 wxPGProperty
* result
= NULL
;
1738 wxPGProperty
* current
= NULL
;
1739 unsigned int iy
= *nextItemY
;
1741 unsigned int iMax
= GetChildCount();
1745 wxPGProperty
* pwc
= Item(i
);
1747 if ( !pwc
->HasFlag(wxPG_PROP_HIDDEN
) )
1758 if ( pwc
->IsExpanded() &&
1759 pwc
->GetChildCount() > 0 )
1761 result
= (wxPGProperty
*) pwc
->GetItemAtY( y
, lh
, &iy
);
1773 if ( !result
&& y
< iy
)
1780 wxLogDebug(wxT("%s::GetItemAtY(%i) -> %s"),this->GetLabel().c_str(),y,current->GetLabel().c_str());
1782 wxLogDebug(wxT("%s::GetItemAtY(%i) -> NULL"),this->GetLabel().c_str(),y);
1785 return (wxPGProperty
*) result
;
1788 void wxPGProperty::Empty()
1791 if ( !HasFlag(wxPG_PROP_CHILDREN_ARE_COPIES
) )
1793 for ( i
=0; i
<GetChildCount(); i
++ )
1795 wxPGProperty
* p
= (wxPGProperty
*) Item(i
);
1803 void wxPGProperty::ChildChanged( wxVariant
& WXUNUSED(thisValue
),
1804 int WXUNUSED(childIndex
),
1805 wxVariant
& WXUNUSED(childValue
) ) const
1809 bool wxPGProperty::AreAllChildrenSpecified( wxVariant
* pendingList
) const
1813 const wxVariantList
* pList
= NULL
;
1814 wxVariantList::const_iterator node
;
1818 pList
= &pendingList
->GetList();
1819 node
= pList
->begin();
1822 for ( i
=0; i
<GetChildCount(); i
++ )
1824 wxPGProperty
* child
= Item(i
);
1825 const wxVariant
* listValue
= NULL
;
1830 const wxString
& childName
= child
->GetBaseName();
1832 for ( ; node
!= pList
->end(); node
++ )
1834 const wxVariant
& item
= *((const wxVariant
*)*node
);
1835 if ( item
.GetName() == childName
)
1845 value
= child
->GetValue();
1847 if ( value
.IsNull() )
1850 // Check recursively
1851 if ( child
->GetChildCount() )
1853 const wxVariant
* childList
= NULL
;
1855 if ( listValue
&& listValue
->GetType() == wxPG_VARIANT_TYPE_LIST
)
1856 childList
= listValue
;
1858 if ( !child
->AreAllChildrenSpecified((wxVariant
*)childList
) )
1866 wxPGProperty
* wxPGProperty::UpdateParentValues()
1868 wxPGProperty
* parent
= m_parent
;
1869 if ( parent
&& parent
->HasFlag(wxPG_PROP_COMPOSED_VALUE
) &&
1870 !parent
->IsCategory() && !parent
->IsRoot() )
1873 parent
->GenerateComposedValue(s
, 0);
1874 parent
->m_value
= s
;
1875 return parent
->UpdateParentValues();
1880 bool wxPGProperty::IsTextEditable() const
1882 if ( HasFlag(wxPG_PROP_READONLY
) )
1885 if ( HasFlag(wxPG_PROP_NOEDITOR
) &&
1887 wxString(GetEditorClass()->GetClassInfo()->GetClassName()).EndsWith(wxS("Button")))
1894 // Call for after sub-properties added with AddChild
1895 void wxPGProperty::PrepareSubProperties()
1897 wxPropertyGridPageState
* state
= GetParentState();
1901 if ( !GetChildCount() )
1904 wxByte depth
= m_depth
+ 1;
1905 wxByte depthBgCol
= m_depthBgCol
;
1907 FlagType inheritFlags
= m_flags
& wxPG_INHERITED_PROPFLAGS
;
1909 wxByte bgColIndex
= m_bgColIndex
;
1910 wxByte fgColIndex
= m_fgColIndex
;
1913 // Set some values to the children
1916 wxPGProperty
* nparent
= this;
1918 while ( i
< nparent
->GetChildCount() )
1920 wxPGProperty
* np
= nparent
->Item(i
);
1922 np
->m_parentState
= state
;
1923 np
->m_flags
|= inheritFlags
; // Hideable also if parent.
1924 np
->m_depth
= depth
;
1925 np
->m_depthBgCol
= depthBgCol
;
1926 np
->m_bgColIndex
= bgColIndex
;
1927 np
->m_fgColIndex
= fgColIndex
;
1929 // Also handle children of children
1930 if ( np
->GetChildCount() > 0 )
1936 nparent
->SetParentalType(wxPG_PROP_AGGREGATE
);
1937 nparent
->SetExpanded(false);
1946 // After reaching last sibling, go back to processing
1947 // siblings of the parent
1948 while ( i
>= nparent
->GetChildCount() )
1950 // Exit the loop when top parent hit
1951 if ( nparent
== this )
1956 i
= nparent
->GetArrIndex() + 1;
1957 nparent
= nparent
->GetParent();
1962 // Call after fixed sub-properties added/removed after creation.
1963 // if oldSelInd >= 0 and < new max items, then selection is
1964 // moved to it. Note: oldSelInd -2 indicates that this property
1965 // should be selected.
1966 void wxPGProperty::SubPropsChanged( int oldSelInd
)
1968 wxPropertyGridPageState
* state
= GetParentState();
1969 wxPropertyGrid
* grid
= state
->GetGrid();
1971 PrepareSubProperties();
1973 wxPGProperty
* sel
= (wxPGProperty
*) NULL
;
1974 if ( oldSelInd
>= (int)m_children
.GetCount() )
1975 oldSelInd
= (int)m_children
.GetCount() - 1;
1977 if ( oldSelInd
>= 0 )
1978 sel
= (wxPGProperty
*) m_children
[oldSelInd
];
1979 else if ( oldSelInd
== -2 )
1983 state
->DoSelectProperty(sel
);
1985 if ( state
== grid
->GetState() )
1987 grid
->GetPanel()->Refresh();
1991 // -----------------------------------------------------------------------
1993 // -----------------------------------------------------------------------
1995 WX_PG_IMPLEMENT_PROPERTY_CLASS_PLAIN(wxPGRootProperty
,none
,TextCtrl
)
1996 IMPLEMENT_DYNAMIC_CLASS(wxPGRootProperty
, wxPGProperty
)
1999 wxPGRootProperty::wxPGRootProperty()
2003 m_name
= wxS("<root>");
2010 wxPGRootProperty::~wxPGRootProperty()
2015 // -----------------------------------------------------------------------
2016 // wxPropertyCategory
2017 // -----------------------------------------------------------------------
2019 WX_PG_IMPLEMENT_PROPERTY_CLASS_PLAIN(wxPropertyCategory
,none
,TextCtrl
)
2020 IMPLEMENT_DYNAMIC_CLASS(wxPropertyCategory
, wxPGProperty
)
2022 void wxPropertyCategory::Init()
2024 // don't set colour - prepareadditem method should do this
2025 SetParentalType(wxPG_PROP_CATEGORY
);
2026 m_capFgColIndex
= 1;
2030 wxPropertyCategory::wxPropertyCategory()
2037 wxPropertyCategory::wxPropertyCategory( const wxString
&label
, const wxString
& name
)
2038 : wxPGProperty(label
,name
)
2044 wxPropertyCategory::~wxPropertyCategory()
2049 wxString
wxPropertyCategory::GetValueAsString( int ) const
2051 return wxEmptyString
;
2054 int wxPropertyCategory::GetTextExtent( const wxWindow
* wnd
, const wxFont
& font
) const
2056 if ( m_textExtent
> 0 )
2057 return m_textExtent
;
2059 ((wxWindow
*)wnd
)->GetTextExtent( m_label
, &x
, &y
, 0, 0, &font
);
2063 void wxPropertyCategory::CalculateTextExtent( wxWindow
* wnd
, const wxFont
& font
)
2066 wnd
->GetTextExtent( m_label
, &x
, &y
, 0, 0, &font
);
2070 // -----------------------------------------------------------------------
2071 // wxPGAttributeStorage
2072 // -----------------------------------------------------------------------
2074 wxPGAttributeStorage::wxPGAttributeStorage()
2078 wxPGAttributeStorage::~wxPGAttributeStorage()
2080 wxPGHashMapS2P::iterator it
;
2082 for ( it
= m_map
.begin(); it
!= m_map
.end(); it
++ )
2084 wxVariantData
* data
= (wxVariantData
*) it
->second
;
2089 void wxPGAttributeStorage::Set( const wxString
& name
, const wxVariant
& value
)
2091 wxVariantData
* data
= value
.GetData();
2094 wxPGHashMapS2P::iterator it
= m_map
.find(name
);
2095 if ( it
!= m_map
.end() )
2096 ((wxVariantData
*)it
->second
)->DecRef();
2104 #endif // wxUSE_PROPGRID