X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/4b6a582bef796b43ad4cf0a96bd40bfd631460c6..728799ae114463b67bccc753877af851ab1666fd:/src/propgrid/property.cpp diff --git a/src/propgrid/property.cpp b/src/propgrid/property.cpp index dcda1ef198..bafa791fc4 100644 --- a/src/propgrid/property.cpp +++ b/src/propgrid/property.cpp @@ -4,9 +4,8 @@ // Author: Jaakko Salli // Modified by: // Created: 2008-08-23 -// RCS-ID: $Id$ // Copyright: (c) Jaakko Salli -// Licence: wxWindows license +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// // For compilers that support precompilation, includes "wx/wx.h". @@ -24,6 +23,7 @@ #include "wx/hash.h" #include "wx/string.h" #include "wx/log.h" + #include "wx/math.h" #include "wx/event.h" #include "wx/window.h" #include "wx/panel.h" @@ -35,6 +35,8 @@ #include "wx/intl.h" #endif +#include "wx/image.h" + #include "wx/propgrid/propgrid.h" @@ -45,7 +47,7 @@ #if wxPG_COMPATIBILITY_1_4 -// Used to establish backwards compatiblity +// Used to establish backwards compatibility const char* g_invalidStringContent = "@__TOTALLY_INVALID_STRING__@"; #endif @@ -108,7 +110,7 @@ void wxPGCellRenderer::DrawEditorValue( wxDC& dc, const wxRect& rect, if ( editor ) { - wxRect rect2(rect); + wxRect rect2(rect); rect2.x += xOffset; rect2.y += yOffset; rect2.height -= yOffset; @@ -135,8 +137,9 @@ int wxPGCellRenderer::PreDrawCell( wxDC& dc, const wxRect& rect, const wxPGCell& // If possible, use cell colours if ( !(flags & DontUseCellBgCol) ) { - dc.SetPen(cell.GetBgCol()); - dc.SetBrush(cell.GetBgCol()); + const wxColour& bgCol = cell.GetBgCol(); + dc.SetPen(bgCol); + dc.SetBrush(bgCol); } if ( !(flags & DontUseCellFgCol) ) @@ -149,8 +152,13 @@ int wxPGCellRenderer::PreDrawCell( wxDC& dc, const wxRect& rect, const wxPGCell& if ( !(flags & (Control|ChoicePopup)) ) dc.DrawRectangle(rect); + // Use cell font, if provided + const wxFont& font = cell.GetFont(); + if ( font.IsOk() ) + dc.SetFont(font); + const wxBitmap& bmp = cell.GetBitmap(); - if ( bmp.Ok() && + if ( bmp.IsOk() && // Do not draw oversized bitmap outside choice popup ((flags & ChoicePopup) || bmp.GetHeight() < rect.height ) ) @@ -165,14 +173,29 @@ int wxPGCellRenderer::PreDrawCell( wxDC& dc, const wxRect& rect, const wxPGCell& return imageWidth; } +void wxPGCellRenderer::PostDrawCell( wxDC& dc, + const wxPropertyGrid* propGrid, + const wxPGCell& cell, + int WXUNUSED(flags) ) const +{ + // Revert font + const wxFont& font = cell.GetFont(); + if ( font.IsOk() ) + dc.SetFont(propGrid->GetFont()); +} + // ----------------------------------------------------------------------- // wxPGDefaultRenderer // ----------------------------------------------------------------------- -void wxPGDefaultRenderer::Render( wxDC& dc, const wxRect& rect, +bool wxPGDefaultRenderer::Render( wxDC& dc, const wxRect& rect, const wxPropertyGrid* propertyGrid, wxPGProperty* property, int column, int item, int flags ) const { + const wxPGEditor* editor = NULL; + const wxPGCell* cell = NULL; + + wxString text; bool isUnspecified = property->IsValueUnspecified(); if ( column == 1 && item == -1 ) @@ -182,17 +205,19 @@ void wxPGDefaultRenderer::Render( wxDC& dc, const wxRect& rect, { // Common Value if ( !isUnspecified ) - DrawText( dc, rect, 0, propertyGrid->GetCommonValueLabel(cmnVal) ); - return; + { + text = propertyGrid->GetCommonValueLabel(cmnVal); + DrawText( dc, rect, 0, text ); + if ( !text.empty() ) + return true; + } + return false; } } - const wxPGEditor* editor = NULL; - const wxPGCell* cell = NULL; - - wxString text; int imageWidth = 0; int preDrawFlags = flags; + bool res = false; property->GetDisplayInfo(column, item, flags, &text, &cell); @@ -200,10 +225,10 @@ void wxPGDefaultRenderer::Render( wxDC& dc, const wxRect& rect, if ( column == 1 ) { + editor = property->GetColumnEditor(column); + if ( !isUnspecified ) { - editor = property->GetColumnEditor(column); - // Regular property value wxSize imageSize = propertyGrid->GetImageSize(property, item); @@ -235,21 +260,31 @@ void wxPGDefaultRenderer::Render( wxDC& dc, const wxRect& rect, if ( propertyGrid->GetColumnCount() <= 2 ) { wxString unitsString = property->GetAttribute(wxPGGlobalVars->m_strUnits, wxEmptyString); - if ( unitsString.length() ) + if ( !unitsString.empty() ) text = wxString::Format(wxS("%s %s"), text.c_str(), unitsString.c_str() ); } } - if ( text.length() == 0 ) + if ( text.empty() ) { - // Try to show inline help if no text - wxVariant vInlineHelp = property->GetAttribute(wxPGGlobalVars->m_strInlineHelp); - if ( !vInlineHelp.IsNull() ) + text = property->GetHintText(); + if ( !text.empty() ) { - text = vInlineHelp.GetString(); - dc.SetTextForeground(propertyGrid->GetCellDisabledTextColour()); + res = true; + + const wxColour& hCol = + propertyGrid->GetCellDisabledTextColour(); + dc.SetTextForeground(hCol); + + // Must make the editor NULL to override its own rendering + // code. + editor = NULL; } } + else + { + res = true; + } } int imageOffset = property->GetImageOffset(imageWidth); @@ -257,14 +292,14 @@ void wxPGDefaultRenderer::Render( wxDC& dc, const wxRect& rect, DrawEditorValue( dc, rect, imageOffset, text, property, editor ); // active caption gets nice dotted rectangle - if ( property->IsCategory() /*&& column == 0*/ ) + if ( property->IsCategory() && column == 0 ) { if ( flags & Selected ) { - if ( imageWidth > 0 ) + if ( imageOffset > 0 ) { imageOffset -= DEFAULT_IMAGE_OFFSET_INCREMENT; - imageWidth += wxCC_CUSTOM_IMAGE_MARGIN2 + 4; + imageOffset += wxCC_CUSTOM_IMAGE_MARGIN2 + 4; } DrawCaptionSelectionRect( dc, @@ -276,6 +311,10 @@ void wxPGDefaultRenderer::Render( wxDC& dc, const wxRect& rect, propertyGrid->GetFontHeight()+(wxPG_CAPRECTYMARGIN*2) ); } } + + PostDrawCell(dc, propertyGrid, *cell, preDrawFlags); + + return res; } wxSize wxPGDefaultRenderer::GetImageSize( const wxPGProperty* property, @@ -288,7 +327,7 @@ wxSize wxPGDefaultRenderer::GetImageSize( const wxPGProperty* property, { wxBitmap* bmp = property->GetValueImage(); - if ( bmp && bmp->Ok() ) + if ( bmp && bmp->IsOk() ) return wxSize(bmp->GetWidth(),bmp->GetHeight()); } } @@ -362,6 +401,13 @@ void wxPGCell::SetFgCol( const wxColour& col ) GetData()->SetFgCol(col); } +void wxPGCell::SetFont( const wxFont& font ) +{ + AllocExclusive(); + + GetData()->SetFont(font); +} + void wxPGCell::SetBgCol( const wxColour& col ) { AllocExclusive(); @@ -388,6 +434,12 @@ void wxPGCell::MergeFrom( const wxPGCell& srcCell ) data->SetBitmap(srcCell.GetBitmap()); } +void wxPGCell::SetEmptyData() +{ + AllocExclusive(); +} + + // ----------------------------------------------------------------------- // wxPGProperty // ----------------------------------------------------------------------- @@ -447,7 +499,24 @@ void wxPGProperty::InitAfterAdded( wxPropertyGridPageState* pageState, // (so propgrid can be NULL, too). wxPGProperty* parent = m_parent; - bool parentIsRoot = parent->IsKindOf(CLASSINFO(wxPGRootProperty)); + bool parentIsRoot = parent->IsKindOf(wxCLASSINFO(wxPGRootProperty)); + + // + // Convert invalid cells to default ones in this grid + for ( unsigned int i=0; iGetPropertyDefaultCell(); + const wxPGCell& catDefCell = propgrid->GetCategoryDefaultCell(); + + if ( !HasFlag(wxPG_PROP_CATEGORY) ) + cell = propDefCell; + else + cell = catDefCell; + } + } m_parentState = pageState; @@ -571,6 +640,27 @@ void wxPGProperty::InitAfterAdded( wxPropertyGridPageState* pageState, } } +void wxPGProperty::OnDetached(wxPropertyGridPageState* WXUNUSED(state), + wxPropertyGrid* propgrid) +{ + if ( propgrid ) + { + const wxPGCell& propDefCell = propgrid->GetPropertyDefaultCell(); + const wxPGCell& catDefCell = propgrid->GetCategoryDefaultCell(); + + // Make default cells invalid + for ( unsigned int i=0; iSetPropertyName(this, newName); + else + DoSetName(newName); +} wxString wxPGProperty::GetName() const { wxPGProperty* parent = GetParent(); - if ( !m_name.length() || !parent || parent->IsCategory() || parent->IsRoot() ) + if ( m_name.empty() || !parent || parent->IsCategory() || parent->IsRoot() ) return m_name; return m_parent->GetName() + wxS(".") + m_name; @@ -633,12 +732,7 @@ wxPropertyGrid* wxPGProperty::GetGrid() const int wxPGProperty::Index( const wxPGProperty* p ) const { - for ( unsigned int i = 0; iGetUnspecifiedValueAppearance(); + } + if ( cell->HasText() ) { *pString = cell->GetText(); @@ -712,7 +815,7 @@ void wxPGProperty::GetDisplayInfo( unsigned int column, /* wxString wxPGProperty::GetColumnText( unsigned int col, int choiceIndex ) const { - + if ( col != 1 || choiceIndex == wxNOT_FOUND ) { const wxPGCell& cell = GetCell(col); @@ -818,12 +921,12 @@ void wxPGProperty::DoGenerateComposedValue( wxString& text, argFlags|wxPG_COMPOSITE_FRAGMENT); } } - + if ( childResults && curChild->GetChildCount() ) (*childResults)[curChild->GetName()] = s; bool skip = false; - if ( (argFlags & wxPG_UNEDITABLE_COMPOSITE_FRAGMENT) && !s.length() ) + if ( (argFlags & wxPG_UNEDITABLE_COMPOSITE_FRAGMENT) && s.empty() ) skip = true; if ( !curChild->GetChildCount() || skip ) @@ -890,8 +993,10 @@ wxString wxPGProperty::GetValueAsString( int argFlags ) const } #endif + wxPropertyGrid* pg = GetGrid(); + if ( IsValueUnspecified() ) - return wxEmptyString; + return pg->GetUnspecifiedValueText(argFlags); if ( m_commonValue == -1 ) { @@ -901,7 +1006,6 @@ wxString wxPGProperty::GetValueAsString( int argFlags ) const // // Return common value's string representation - wxPropertyGrid* pg = GetGrid(); const wxPGCommonValue* cv = pg->GetCommonValue(m_commonValue); if ( argFlags & wxPG_FULL_VALUE ) @@ -930,7 +1034,7 @@ bool wxPGProperty::IntToValue( wxVariant& variant, int number, int WXUNUSED(argF } // Convert semicolon delimited tokens into child values. -bool wxPGProperty::StringToValue( wxVariant& variant, const wxString& text, int argFlags ) const +bool wxPGProperty::StringToValue( wxVariant& v, const wxString& text, int argFlags ) const { if ( !GetChildCount() ) return false; @@ -998,7 +1102,8 @@ bool wxPGProperty::StringToValue( wxVariant& variant, const wxString& text, int // Add only if editable or setting programmatically if ( (argFlags & wxPG_PROGRAMMATIC_VALUE) || - !child->HasFlag(wxPG_PROP_DISABLED|wxPG_PROP_READONLY) ) + (!child->HasFlag(wxPG_PROP_DISABLED) && + !child->HasFlag(wxPG_PROP_READONLY)) ) { if ( len > 0 ) { @@ -1069,7 +1174,7 @@ bool wxPGProperty::StringToValue( wxVariant& variant, const wxString& text, int token = text.substr(startPos,pos-startPos-1); - if ( !token.length() ) + if ( token.empty() ) break; const wxPGProperty* child = Item(curChild); @@ -1078,7 +1183,8 @@ bool wxPGProperty::StringToValue( wxVariant& variant, const wxString& text, int wxVariant variant(oldChildValue); if ( (argFlags & wxPG_PROGRAMMATIC_VALUE) || - !child->HasFlag(wxPG_PROP_DISABLED|wxPG_PROP_READONLY) ) + (!child->HasFlag(wxPG_PROP_DISABLED) && + !child->HasFlag(wxPG_PROP_READONLY)) ) { wxString childName = child->GetBaseName(); @@ -1133,7 +1239,7 @@ bool wxPGProperty::StringToValue( wxVariant& variant, const wxString& text, int } if ( changed ) - variant = list; + v = list; return changed; } @@ -1191,7 +1297,7 @@ void wxPGProperty::OnCustomPaint( wxDC& dc, { wxBitmap* bmp = m_valueBitmap; - wxCHECK_RET( bmp && bmp->Ok(), wxT("invalid bitmap") ); + wxCHECK_RET( bmp && bmp->IsOk(), wxT("invalid bitmap") ); wxCHECK_RET( rect.x >= 0, wxT("unexpected measure call") ); @@ -1293,6 +1399,12 @@ void wxPGProperty::SetValue( wxVariant value, wxVariant* pList, int flags ) } i++; } + + // Always call OnSetValue() for a parent property (do not call it + // here if the value is non-null because it will then be called + // below) + if ( value.IsNull() ) + OnSetValue(); } if ( !value.IsNull() ) @@ -1332,16 +1444,23 @@ void wxPGProperty::SetValue( wxVariant value, wxVariant* pList, int flags ) UpdateParentValues(); // - // Update editor control - // - - // We need to check for these, otherwise GetGrid() may fail. + // Update editor control. if ( flags & wxPG_SETVAL_REFRESH_EDITOR ) { - RefreshEditor(); wxPropertyGrid* pg = GetGridIfDisplayed(); if ( pg ) + { + wxPGProperty* selected = pg->GetSelectedProperty(); + + // Only refresh the control if this was selected, or + // this was some parent of selected, or vice versa) + if ( selected && (selected == this || + selected->IsSomeParent(this) || + this->IsSomeParent(selected)) ) + RefreshEditor(); + pg->DrawItemAndValueRelated(this); + } } } @@ -1351,12 +1470,9 @@ void wxPGProperty::SetValueInEvent( wxVariant value ) const GetGrid()->ValueChangeInEvent(value); } -void wxPGProperty::SetFlagRecursively( FlagType flag, bool set ) +void wxPGProperty::SetFlagRecursively( wxPGPropertyFlags flag, bool set ) { - if ( set ) - SetFlag(flag); - else - ClearFlag(flag); + ChangeFlag(flag, set); unsigned int i; for ( i = 0; i < GetChildCount(); i++ ) @@ -1375,7 +1491,7 @@ void wxPGProperty::RefreshEditor() wxVariant wxPGProperty::GetDefaultValue() const { - wxVariant defVal = GetAttribute(wxS("DefaultValue")); + wxVariant defVal = GetAttribute(wxPG_ATTR_DEFAULT_VALUE); if ( !defVal.IsNull() ) return defVal; @@ -1416,6 +1532,31 @@ wxVariant wxPGProperty::GetDefaultValue() const return wxVariant(); } +void wxPGProperty::Enable( bool enable ) +{ + wxPropertyGrid* pg = GetGrid(); + + // Preferably call the version in the owning wxPropertyGrid, + // since it handles the editor de-activation. + if ( pg ) + pg->EnableProperty(this, enable); + else + DoEnable(enable); +} + +void wxPGProperty::DoEnable( bool enable ) +{ + if ( enable ) + ClearFlag(wxPG_PROP_DISABLED); + else + SetFlag(wxPG_PROP_DISABLED); + + // Apply same to sub-properties as well + unsigned int i; + for ( i = 0; i < GetChildCount(); i++ ) + Item(i)->DoEnable( enable ); +} + void wxPGProperty::EnsureCells( unsigned int column ) { if ( column >= m_cells.size() ) @@ -1424,10 +1565,17 @@ void wxPGProperty::EnsureCells( unsigned int column ) wxPropertyGrid* pg = GetGrid(); wxPGCell defaultCell; - if ( !HasFlag(wxPG_PROP_CATEGORY) ) - defaultCell = pg->GetPropertyDefaultCell(); - else - defaultCell = pg->GetCategoryDefaultCell(); + if ( pg ) + { + // Work around possible VC6 bug by using intermediate variables + const wxPGCell& propDefCell = pg->GetPropertyDefaultCell(); + const wxPGCell& catDefCell = pg->GetCategoryDefaultCell(); + + if ( !HasFlag(wxPG_PROP_CATEGORY) ) + defaultCell = propDefCell; + else + defaultCell = catDefCell; + } // TODO: Replace with resize() call unsigned int cellCountMax = column+1; @@ -1505,16 +1653,17 @@ const wxPGCell& wxPGProperty::GetCell( unsigned int column ) const return pg->GetPropertyDefaultCell(); } -wxPGCell& wxPGProperty::GetCell( unsigned int column ) +wxPGCell& wxPGProperty::GetOrCreateCell( unsigned int column ) { EnsureCells(column); return m_cells[column]; } void wxPGProperty::SetBackgroundColour( const wxColour& colour, - bool recursively ) + int flags ) { wxPGProperty* firstProp = this; + bool recursively = flags & wxPG_RECURSE ? true : false; // // If category is tried to set recursively, skip it and only @@ -1547,9 +1696,10 @@ void wxPGProperty::SetBackgroundColour( const wxColour& colour, } void wxPGProperty::SetTextColour( const wxColour& colour, - bool recursively ) + int flags ) { wxPGProperty* firstProp = this; + bool recursively = flags & wxPG_RECURSE ? true : false; // // If category is tried to set recursively, skip it and only @@ -1637,18 +1787,20 @@ long wxPGProperty::GetAttributeAsLong( const wxString& name, long defVal ) const { wxVariant variant = m_attributes.FindValue(name); - return wxPGVariantToInt(variant, defVal); + if ( variant.IsNull() ) + return defVal; + + return variant.GetLong(); } double wxPGProperty::GetAttributeAsDouble( const wxString& name, double defVal ) const { - double retVal; wxVariant variant = m_attributes.FindValue(name); - if ( wxPGVariantToDouble(variant, &retVal) ) - return retVal; + if ( variant.IsNull() ) + return defVal; - return defVal; + return variant.GetDouble(); } wxVariant wxPGProperty::GetAttributesAsList() const @@ -1668,7 +1820,7 @@ wxVariant wxPGProperty::GetAttributesAsList() const // Slots of utility flags are NULL const unsigned int gs_propFlagToStringSize = 14; -static const wxChar* gs_propFlagToString[gs_propFlagToStringSize] = { +static const wxChar* const gs_propFlagToString[gs_propFlagToStringSize] = { NULL, wxT("DISABLED"), wxT("HIDDEN"), @@ -1698,7 +1850,7 @@ wxString wxPGProperty::GetFlagsAsString( FlagType flagsMask ) const { const wxChar* fs = gs_propFlagToString[i]; wxASSERT(fs); - if ( s.length() ) + if ( !s.empty() ) s << wxS("|"); s << fs; } @@ -1828,8 +1980,14 @@ void wxPGProperty::SetChoiceSelection( int newValue ) } } -bool wxPGProperty::SetChoices( wxPGChoices& choices ) +bool wxPGProperty::SetChoices( const wxPGChoices& choices ) { + // Property must be de-selected first (otherwise choices in + // the control would be de-synced with true choices) + wxPropertyGrid* pg = GetGrid(); + if ( pg && pg->GetSelection() == this ) + pg->ClearSelection(); + m_choices.Assign(choices); { @@ -1862,17 +2020,43 @@ const wxPGEditor* wxPGProperty::GetEditorClass() const if ( GetDisplayedCommonValueCount() ) { // TextCtrlAndButton -> ComboBoxAndButton - if ( editor->IsKindOf(CLASSINFO(wxPGTextCtrlAndButtonEditor)) ) + if ( wxDynamicCast(editor, wxPGTextCtrlAndButtonEditor) ) editor = wxPGEditor_ChoiceAndButton; // TextCtrl -> ComboBox - else if ( editor->IsKindOf(CLASSINFO(wxPGTextCtrlEditor)) ) + else if ( wxDynamicCast(editor, wxPGTextCtrlEditor) ) editor = wxPGEditor_ComboBox; } return editor; } +bool wxPGProperty::Hide( bool hide, int flags ) +{ + wxPropertyGrid* pg = GetGrid(); + if ( pg ) + return pg->HideProperty(this, hide, flags); + + return DoHide( hide, flags ); +} + +bool wxPGProperty::DoHide( bool hide, int flags ) +{ + if ( !hide ) + ClearFlag( wxPG_PROP_HIDDEN ); + else + SetFlag( wxPG_PROP_HIDDEN ); + + if ( flags & wxPG_RECURSE ) + { + unsigned int i; + for ( i = 0; i < GetChildCount(); i++ ) + Item(i)->DoHide(hide, flags | wxPG_RECURSE_STARTS); + } + + return true; +} + bool wxPGProperty::HasVisibleChildren() const { unsigned int i; @@ -1907,7 +2091,7 @@ void wxPGProperty::SetValueImage( wxBitmap& bmp ) { delete m_valueBitmap; - if ( &bmp && bmp.Ok() ) + if ( &bmp && bmp.IsOk() ) { // Resize the image wxSize maxSz = GetGrid()->GetImageSize(); @@ -1915,19 +2099,23 @@ void wxPGProperty::SetValueImage( wxBitmap& bmp ) if ( imSz.y != maxSz.y ) { - // Create a memory DC + #if wxUSE_IMAGE + // Here we use high-quality wxImage scaling functions available + wxImage img = bmp.ConvertToImage(); + double scaleY = (double)maxSz.y / (double)imSz.y; + img.Rescale(wxRound(bmp.GetWidth()*scaleY), + wxRound(bmp.GetHeight()*scaleY), + wxIMAGE_QUALITY_HIGH); + wxBitmap* bmpNew = new wxBitmap(img, 32); + #else + // This is the old, deprecated method of scaling the image wxBitmap* bmpNew = new wxBitmap(maxSz.x,maxSz.y,bmp.GetDepth()); - wxMemoryDC dc; dc.SelectObject(*bmpNew); - - // Scale - // FIXME: This is ugly - use image or wait for scaling patch. double scaleY = (double)maxSz.y / (double)imSz.y; - dc.SetUserScale(scaleY, scaleY); - dc.DrawBitmap(bmp, 0, 0); + #endif m_valueBitmap = bmpNew; } @@ -2010,7 +2198,7 @@ int wxPGProperty::GetY2( int lh ) const for ( parent = GetParent(); parent != NULL; parent = child->GetParent() ) { if ( !parent->IsExpanded() ) - return -1; + return parent->GetY2(lh); y += parent->GetChildrenHeight(lh, child->GetIndexInParent()); y += lh; child = parent; @@ -2117,7 +2305,7 @@ void wxPGProperty::RemoveChild( wxPGProperty* p ) { if ( *it == p ) { - m_children.erase(it); + children.erase(it); break; } } @@ -2144,9 +2332,9 @@ void wxPGProperty::AdaptListToValue( wxVariant& list, wxVariant* value ) const else allChildrenSpecified = true; - wxVariant childValue = list[0]; unsigned int i; unsigned int n = 0; + wxVariant childValue = list[n]; //wxLogDebug(wxT(">> %s.AdaptListToValue()"),GetBaseName().c_str()); @@ -2166,7 +2354,10 @@ void wxPGProperty::AdaptListToValue( wxVariant& list, wxVariant* value ) const } if ( allChildrenSpecified ) - ChildChanged(*value, i, childValue); + { + *value = ChildChanged(*value, i, childValue); + } + n++; if ( n == (unsigned int)list.GetCount() ) break; @@ -2277,7 +2468,9 @@ int wxPGProperty::GetChildrenHeight( int lh, int iMax_ ) const return h; } -wxPGProperty* wxPGProperty::GetItemAtY( unsigned int y, unsigned int lh, unsigned int* nextItemY ) const +wxPGProperty* wxPGProperty::GetItemAtY( unsigned int y, + unsigned int lh, + unsigned int* nextItemY ) const { wxASSERT( nextItemY ); @@ -2327,9 +2520,13 @@ wxPGProperty* wxPGProperty::GetItemAtY( unsigned int y, unsigned int lh, unsigne /* if ( current ) + { wxLogDebug(wxT("%s::GetItemAtY(%i) -> %s"),this->GetLabel().c_str(),y,current->GetLabel().c_str()); + } else + { wxLogDebug(wxT("%s::GetItemAtY(%i) -> NULL"),this->GetLabel().c_str(),y); + } */ return (wxPGProperty*) result; @@ -2349,21 +2546,53 @@ void wxPGProperty::Empty() m_children.clear(); } +wxPGProperty* wxPGProperty::GetItemAtY( unsigned int y ) const +{ + unsigned int nextItem; + return GetItemAtY( y, GetGrid()->GetRowHeight(), &nextItem); +} + void wxPGProperty::DeleteChildren() { wxPropertyGridPageState* state = m_parentState; - while ( GetChildCount() ) + if ( !GetChildCount() ) + return; + + // Because deletion is sometimes deferred, we have to use + // this sort of code for enumerating the child properties. + unsigned int i = GetChildCount(); + while ( i > 0 ) { - wxPGProperty* child = Item(GetChildCount()-1); - state->DoDelete(child, true); + i--; + state->DoDelete(Item(i), true); } } -void wxPGProperty::ChildChanged( wxVariant& WXUNUSED(thisValue), - int WXUNUSED(childIndex), - wxVariant& WXUNUSED(childValue) ) const +bool wxPGProperty::IsChildSelected( bool recursive ) const { + size_t i; + for ( i = 0; i < GetChildCount(); i++ ) + { + wxPGProperty* child = Item(i); + + // Test child + if ( m_parentState->DoIsPropertySelected( child ) ) + return true; + + // Test sub-childs + if ( recursive && child->IsChildSelected( recursive ) ) + return true; + } + + return false; +} + +wxVariant wxPGProperty::ChildChanged( wxVariant& WXUNUSED(thisValue), + int WXUNUSED(childIndex), + wxVariant& WXUNUSED(childValue) ) const +{ + return wxNullVariant; } bool wxPGProperty::AreAllChildrenSpecified( wxVariant* pendingList ) const @@ -2546,22 +2775,44 @@ wxPropertyCategory::~wxPropertyCategory() wxString wxPropertyCategory::ValueToString( wxVariant& WXUNUSED(value), int WXUNUSED(argFlags) ) const { + if ( m_value.GetType() == wxPG_VARIANT_TYPE_STRING ) + return m_value.GetString(); return wxEmptyString; } +wxString wxPropertyCategory::GetValueAsString( int argFlags ) const +{ +#if wxPG_COMPATIBILITY_1_4 + // This is backwards compatibility test + // That is, to make sure this function is not overridden + // (instead, ValueToString() should be). + if ( argFlags == 0xFFFF ) + { + // Do not override! (for backwards compliancy) + return g_invalidStringContent; + } +#endif + + // Unspecified value is always empty string + if ( IsValueUnspecified() ) + return wxEmptyString; + + return wxPGProperty::GetValueAsString(argFlags); +} + int wxPropertyCategory::GetTextExtent( const wxWindow* wnd, const wxFont& font ) const { if ( m_textExtent > 0 ) return m_textExtent; int x = 0, y = 0; - ((wxWindow*)wnd)->GetTextExtent( m_label, &x, &y, 0, 0, &font ); + ((wxWindow*)wnd)->GetTextExtent( m_label, &x, &y, 0, 0, &font ); return x; } void wxPropertyCategory::CalculateTextExtent( wxWindow* wnd, const wxFont& font ) { int x = 0, y = 0; - wnd->GetTextExtent( m_label, &x, &y, 0, 0, &font ); + wnd->GetTextExtent( m_label, &x, &y, 0, 0, &font ); m_textExtent = x; } @@ -2629,12 +2880,12 @@ wxPGChoiceEntry& wxPGChoices::AddAsSorted( const wxString& label, int value ) // ----------------------------------------------------------------------- -void wxPGChoices::Add( const wxChar** labels, const ValArrItem* values ) +void wxPGChoices::Add( const wxChar* const* labels, const ValArrItem* values ) { AllocExclusive(); unsigned int itemcount = 0; - const wxChar** p = &labels[0]; + const wxChar* const* p = &labels[0]; while ( *p ) { p++; itemcount++; } unsigned int i; @@ -2673,7 +2924,7 @@ void wxPGChoices::RemoveAt(size_t nIndex, size_t count) { AllocExclusive(); - wxASSERT( m_data->m_refCount != 0xFFFFFFF ); + wxASSERT( m_data->GetRefCount() != -1 ); m_data->m_items.erase(m_data->m_items.begin()+nIndex, m_data->m_items.begin()+nIndex+count); } @@ -2789,7 +3040,7 @@ void wxPGChoices::AllocExclusive() { EnsureData(); - if ( m_data->m_refCount != 1 ) + if ( m_data->GetRefCount() != 1 ) { wxPGChoicesData* data = new wxPGChoicesData(); data->CopyDataFrom(m_data); @@ -2807,7 +3058,7 @@ void wxPGChoices::AssignData( wxPGChoicesData* data ) if ( data != wxPGChoicesEmptyData ) { m_data = data; - data->m_refCount++; + data->IncRef(); } }