propgrid.cpp

来自「这是一个GPS相关的程序」· C++ 代码 · 共 2,266 行 · 第 1/5 页

CPP
2,266
字号

    unsigned int count = pwc->GetCount();

    if ( !pwc->IsExpanded() || !count )
        return this;

    return pwc->Last()->GetLastVisibleSubItem();
}


bool wxPGProperty::UsesAutoUnspecified() const
{
    if ( GetGrid()->GetExtraStyle() & wxPG_EX_AUTO_UNSPECIFIED_VALUES )
        return true;

    return false;
}


// -----------------------------------------------------------------------
// wxPGPropertyWithChildren
// -----------------------------------------------------------------------


wxPGPropertyClassInfo wxBaseParentPropertyClassInfo = {wxT("wxBaseParentProperty"),
                                                       &wxBasePropertyClassInfo,
                                                       (wxPGPropertyConstructor) NULL};


wxPGPropertyWithChildren::wxPGPropertyWithChildren()
    : wxPGProperty()
{
    m_expanded = 1;
    m_y = -2;
    m_parentingType = -1;
}

wxPGPropertyWithChildren::wxPGPropertyWithChildren( const wxString &label, const wxString& name )
    : wxPGProperty(label,name)
{
    m_expanded = 1;
    m_y = -2;
    m_parentingType = -1;
    m_parentState = (wxPropertyGridState*) NULL;
}


wxPGPropertyWithChildren::~wxPGPropertyWithChildren()
{
    Empty(); // this deletes items
}


// This is used by Insert etc.
void wxPGPropertyWithChildren::AddChild2( wxPGProperty* prop, int index, bool correct_mode )
{
    if ( index < 0 || (size_t)index >= m_children.GetCount() )
    {
        if ( correct_mode ) prop->m_arrIndex = m_children.GetCount();
        m_children.Add( (void*)prop );
    }
    else
    {
        m_children.Insert( (void*)prop, index );
        if ( correct_mode ) FixIndexesOfChildren( index );
    }

    prop->m_parent = this;
}

// This is used by properties that have fixed sub-properties
void wxPGPropertyWithChildren::AddChild( wxPGProperty* prop )
{
    prop->m_arrIndex = m_children.GetCount();
    m_children.Add( (void*)prop );

    int custImgHeight = prop->GetImageSize().y;
    if ( custImgHeight < 0 /*|| custImgHeight > 1*/ )
        prop->m_flags |= wxPG_PROP_CUSTOMIMAGE;

    prop->m_parent = this;

    prop->m_y = -1; // Collapsed
}


void wxPGPropertyWithChildren::FixIndexesOfChildren( size_t starthere )
{
    size_t i;
    for ( i=starthere;i<GetCount();i++)
        Item(i)->m_arrIndex = i;
}


// Returns (direct) child property with given name (or NULL if not found)
wxPGProperty* wxPGPropertyWithChildren::GetPropertyByName( const wxString& name ) const
{
    size_t i;

    for ( i=0; i<GetCount(); i++ )
    {
        wxPGProperty* p = Item(i);
        if ( p->m_name == name )
            return p;
    }

    // Does it have point, then?
    int pos = name.Find(wxT('.'));
    if ( pos <= 0 )
        return (wxPGProperty*) NULL;

    wxPGPropertyWithChildren* pwc =
        (wxPGPropertyWithChildren*) GetPropertyByName(name.substr(0,pos));

    if ( !pwc || !pwc->GetParentingType() )
        return (wxPGProperty*) NULL;

    return pwc->GetPropertyByName(name.substr(pos+1,name.length()-pos-1));
}


wxPGProperty* wxPGPropertyWithChildren::GetItemAtY( unsigned int y, unsigned int lh )
{
    // Linear search.
    unsigned int i = 0;
    unsigned int iMax = GetCount();
    unsigned long py = 0xFFFFFFFF;
    wxPGProperty* p = (wxPGProperty*) NULL;

    while ( i < iMax )
    {
        p = Item(i);
        if ( p->m_y >= 0 )
        {
            py = (unsigned long)p->m_y;
            if ( (py+lh) > y )
                break;
        }
        i++;
    }
    if ( py <= y && i < iMax )
    {
        // perfectly this item
        wxASSERT_MSG( p, wxT("invalid property id") );
        return p;
    }
    else
    {

        // If no visible children, we must retract our steps
        // (should not really happen, so right now we check that it
        // really doesn't).
        if ( py == 0xFFFFFFFF )
        {
            wxLogDebug(wxT("wxPropertyGrid: \"%s\" (y=%i) did not have visible children (it should)."),m_label.c_str(),(int)m_y);
            return (wxPGProperty*) NULL;
        }

        // We are about to return a child of previous' visible item.

    #ifdef __WXDEBUG__
        if ( i < 1 )
        {
            wxLogDebug( wxT("WARNING: \"%s\"->GetItemAtY: (i <= 0)"), m_label.c_str() );
            wxLogDebug( wxT(" \\--> y = %i, py = %i"), (int)y, (int)py );
            if ( p )
                wxLogDebug( wxT(" \\--> p = \"%s\""), p->GetLabel().c_str() );
            else
                wxLogDebug( wxT(" \\--> p = None") );
            return (wxPGProperty*) NULL;
        }
    #endif

        // Get previous *visible* parent.
        wxPGPropertyWithChildren* pwc;
        do
        {
            wxASSERT( i > 0 );
            i--;
            pwc = (wxPGPropertyWithChildren*)Item(i);
        } while ( pwc->m_y < 0 );

        if ( pwc->GetParentingType() != 0 )
        {
        #ifdef __WXDEBUG__
            if ( !pwc->m_expanded || pwc->m_y < 0 )
            {
                wxLogDebug(wxT("WARNING: wxPGPropertyWithChildren::GetItemAtY: Item %s should have been visible and expanded."),pwc->m_label.c_str());
                wxLogDebug(wxT("    (%s[%i]: %s)"),pwc->m_parent->m_label.c_str(),pwc->m_arrIndex,pwc->m_label.c_str());
                //wxLogDebug(wxT("    py=%i"),(int)py);
                return (wxPGProperty*) NULL;
            }
        #endif
            return pwc->GetItemAtY(y,lh);
        }
    }
    return (wxPGProperty*) NULL;
}


void wxPGPropertyWithChildren::Empty()
{
    size_t i;
    if ( m_expanded != wxPG_EXP_OF_COPYARRAY )
    {
        for ( i=0; i<GetCount(); i++ )
        {
            wxPGProperty* p = (wxPGProperty*) Item(i);
            delete p;
        }
    }

    m_children.Empty();
}


void wxPGPropertyWithChildren::ChildChanged( wxPGProperty* WXUNUSED(p) )
{
}


wxString wxPGPropertyWithChildren::GetValueAsString( int argFlags ) const
{
    wxCHECK_MSG( GetCount() > 0,
                 wxString(),
                 wxT("If user property does not have any children, it must override GetValueAsString.") );

    wxString text;

    int i;
    int iMax = m_children.GetCount();
    int iMaxMinusOne = iMax-1;

    wxPGProperty* curChild = (wxPGProperty*) m_children.Item(0);

    for ( i = 0; i < iMax; i++ )
    {
        wxString s;
        if ( !(curChild->m_flags & wxPG_PROP_UNSPECIFIED) )
            s = curChild->GetValueAsString(argFlags);

        if ( curChild->GetParentingType() == 0 )
            text += s;
        else
            text += wxT("[") + s + wxT("]");

        if ( i < iMaxMinusOne )
        {
            curChild = (wxPGProperty*) m_children.Item(i+1);

            if ( curChild->GetParentingType() == 0 )
                text += wxT("; ");
            else
                text += wxT(" ");
        }
    }

    return text;
}


// Convert semicolon delimited tokens into child values.
bool wxPGPropertyWithChildren::SetValueFromString( const wxString& text, int )
{
    if ( !GetCount() )
        return false;

    unsigned int curChild = 0;

    bool changed = false;

    wxString token;
    size_t pos = 0;

    // Its best only to add non-empty group items
    bool addOnlyIfNotEmpty = false;
    const wxChar delimeter = wxT(';');
    wxChar a;

    size_t lastPos = text.length();
    size_t tokenStart = 0xFFFFFF;

    do
    {
        a = text[pos];

        if ( tokenStart != 0xFFFFFF )
        {
            // Token is running
            if ( a == delimeter || a == 0 )
            {
                token = text.substr(tokenStart,pos-tokenStart);
                token.Trim(true);
                size_t len = token.length();

                if ( !addOnlyIfNotEmpty || len > 0 )
                {
                    wxPGProperty* child = Item(curChild);

                    if ( len > 0 )
                    {
                        bool wasUnspecified = child->IsValueUnspecified();
                        if ( child->SetValueFromString( token, wxPG_REPORT_ERROR ) )
                        {
                            // If modified, set mod flag and store value back to parent
                            child->SetFlag( wxPG_PROP_MODIFIED );

                            // Clear unspecified flag only if SetValueFromString didn't
                            // affect it.
                            if ( child->IsValueUnspecified() &&
                                 (wasUnspecified || !UsesAutoUnspecified()) )
                                child->ClearFlag( wxPG_PROP_UNSPECIFIED );

                            ChildChanged( child );
                            changed = true;
                        }

                    }
                    else
                    {
                        child->SetFlag( wxPG_PROP_UNSPECIFIED );
                        changed = true;
                    }

                    curChild++;
                    if ( curChild >= GetCount() )
                        break;
                }

                tokenStart = 0xFFFFFF;
            }
        }
        else
        {
            // Token is not running
            if ( a != wxT(' ') )
            {

                addOnlyIfNotEmpty = false;

                // Is this a group of tokens?
                if ( a == wxT('[') )
                {
                    int depth = 1;

                    pos++;
                    size_t startPos = pos;

                    // Group item - find end
                    do
                    {
                        a = text[pos];
                        pos++;

                        if ( a == wxT(']') )
                            depth--;
                        else if ( a == wxT('[') )
                            depth++;

                    } while ( depth > 0 && a );

                    token = text.substr(startPos,pos-startPos-1);

                    if ( !token.length() )
                        break;

                    wxPGProperty* child = Item(curChild);

                    wxLogDebug(wxT("child(1) %i: %s"),curChild,token.c_str());

                    if ( child->SetValueFromString( token, wxPG_REPORT_ERROR ) )
                    {
                        // If modified, set mod flag and store value back to parent
                        child->SetFlag( wxPG_PROP_MODIFIED );
                        ChildChanged( child );
                        changed = true;
                    }

                    curChild++;
                    if ( curChild >= GetCount() )
                        break;

                    addOnlyIfNotEmpty = true;

                    tokenStart = 0xFFFFFF;
                }
                else
                {
                    tokenStart = pos;

                    if ( a == delimeter )
                    {
                        pos--;
                    }
                }
            }

        }
        pos++;

    }
    while ( pos <= lastPos );

    // This ensures that the last item is set unspecified even
    // if the blank had no terminating delimiter.
    if ( curChild < GetCount() )
    {
        wxPGProperty* child = Item(curChild);

        child->SetFlag( wxPG_PROP_UNSPECIFIED );
        changed = true;
    }

    return changed;
}


void wxPGPropertyWithChildren::RefreshChildren ()
{
}


// -----------------------------------------------------------------------
// wxParentProperty
// -----------------------------------------------------------------------

wxPGProperty* wxParentProperty( const wxString& label, const wxString& name )
{
    return new wxParentPropertyClass(label,name);
}


WX_PG_IMPLEMENT_PROPERTY_CLASS_PLAIN(wxParentProperty,none,TextCtrl)
WX_PG_IMPLEMENT_CLASSINFO(wxParentProperty,wxBaseParentPropertyClass)


wxParentPropertyClass::wxParentPropertyClass( const wxString& label, const wxString& name )
    : wxPGPropertyWithChildren(label,name)
{
    m_parentingType = PT_CUSTOMPROPERTY;
}


wxParentPropertyClass::~wxParentPropertyClass() { }


void wxParentPropertyClass::DoSetValue( wxPGVariant value )
{
    const wxString& str = wxPGVariantToString(value);
    m_string = str;
    SetValueFromString(str,wxPG_REPORT_ERROR);
}


⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?