示例#1
0
bool DIALOG_TRACK_VIA_PROPERTIES::Apply( COMMIT& aCommit )
{
    if( !check() )
        return false;

    bool changeLock = m_lockedCbox->Get3StateValue() != wxCHK_UNDETERMINED;
    bool setLock = m_lockedCbox->Get3StateValue() == wxCHK_CHECKED;

    for( auto item : m_items )
    {
        aCommit.Modify( item );

        switch( item->Type() )
        {
            case PCB_TRACE_T:
            {
                assert( m_tracks );
                TRACK* t = static_cast<TRACK*>( item );

                if( m_trackStartX.Valid() || m_trackStartY.Valid() )
                {
                    wxPoint start = t->GetStart();

                    if( m_trackStartX.Valid() )
                        start.x = m_trackStartX.GetValue();

                    if( m_trackStartY.Valid() )
                        start.y = m_trackStartY.GetValue();

                    t->SetStart( start );
                }

                if( m_trackEndX.Valid() || m_trackEndY.Valid() )
                {
                    wxPoint end = t->GetEnd();

                    if( m_trackEndX.Valid() )
                        end.x = m_trackEndX.GetValue();

                    if( m_trackEndY.Valid() )
                        end.y = m_trackEndY.GetValue();

                    t->SetEnd( end );
                }

                if( m_trackNetclass->IsChecked() )
                {
                    t->SetWidth( t->GetNetClass()->GetTrackWidth() );
                }
                else if( m_trackWidth.Valid() )
                {
                    t->SetWidth( m_trackWidth.GetValue() );
                }

                LAYER_NUM layer = m_TrackLayerCtrl->GetLayerSelection();

                if( layer != UNDEFINED_LAYER )
                    t->SetLayer( (LAYER_ID) layer );

                if( changeLock )
                    t->SetLocked( setLock );

                break;
            }

            case PCB_VIA_T:
            {
                assert( m_vias );

                VIA* v = static_cast<VIA*>( item );

                if( m_viaX.Valid() || m_viaY.Valid() )
                {
                    wxPoint pos = v->GetPosition();

                    if( m_viaX.Valid() )
                        pos.x = m_viaX.GetValue();

                    if( m_viaY.Valid() )
                        pos.y = m_viaY.GetValue();

                    v->SetPosition( pos );
                }

                if( m_viaNetclass->IsChecked() )
                {
                    switch( v->GetViaType() )
                    {
                    default:
                        wxFAIL_MSG("Unhandled via type");
                        // fall through

                    case VIA_THROUGH:
                    case VIA_BLIND_BURIED:
                        v->SetWidth( v->GetNetClass()->GetViaDiameter() );
                        v->SetDrill( v->GetNetClass()->GetViaDrill() );
                        break;

                    case VIA_MICROVIA:
                        v->SetWidth( v->GetNetClass()->GetuViaDiameter() );
                        v->SetDrill( v->GetNetClass()->GetuViaDrill() );
                        break;
                    }
                }
                else
                {
                    if( m_viaDiameter.Valid() )
                        v->SetWidth( m_viaDiameter.GetValue() );

                    if( m_viaDrill.Valid() )
                        v->SetDrill( m_viaDrill.GetValue() );
                }

                if( changeLock )
                    v->SetLocked( setLock );

                break;
            }

            default:
                assert( false );
                break;
        }
    }

    return true;
}
bool DIALOG_TRACK_VIA_PROPERTIES::TransferDataFromWindow()
{
    auto connectivity = m_frame->GetBoard()->GetConnectivity();
    int newNetCode = m_netSelector->GetSelectedNetcode();
    std::vector<D_PAD*> changingPads;

    if ( !m_netSelector->IsIndeterminate() )
    {
        std::set<D_PAD*> connectedPads;

        for( auto& item : m_items )
        {
            const KICAD_T ourTypes[] = { PCB_TRACE_T, PCB_PAD_T, PCB_VIA_T, PCB_MODULE_T, EOT };
            auto connectedItems = connectivity->GetConnectedItems( static_cast<BOARD_CONNECTED_ITEM*>( item ), ourTypes, true );
            for ( auto citem : connectedItems )
            {
                if( citem->Type() == PCB_PAD_T )
                {
                    connectedPads.insert( static_cast<D_PAD*>( citem ) );
                }
            }
        }

        for( D_PAD* pad : connectedPads )
        {
            if( pad->GetNetCode() != newNetCode )
                changingPads.push_back( pad );
        }
    }

    // Run validations:

    if( changingPads.size() )
    {
        if( !confirmPadChange( changingPads ) )
            return false;
    }

    if( m_vias )
    {
        if( !m_viaDiameter.Validate( GEOMETRY_MIN_SIZE, INT_MAX )
            || !m_viaDrill.Validate( GEOMETRY_MIN_SIZE, INT_MAX ) )
            return false;

        if( m_ViaDiameterCtrl->IsEnabled() && !m_viaDiameter.IsIndeterminate()
            && m_ViaDrillCtrl->IsEnabled() && !m_viaDrill.IsIndeterminate()
            && m_viaDiameter.GetValue() <= m_viaDrill.GetValue() )
        {
            DisplayError( GetParent(), _( "Via drill size must be smaller than via diameter" ) );
            m_ViaDrillCtrl->SelectAll();
            m_ViaDrillCtrl->SetFocus();
            return false;
        }

        if( m_ViaStartLayer->GetLayerSelection() != UNDEFINED_LAYER &&
            m_ViaStartLayer->GetLayerSelection() == m_ViaEndLayer->GetLayerSelection() )
        {
            DisplayError( GetParent(), _( "Via start layer and end layer cannot be the same" ) );
            return false;
        }
    }

    if( m_tracks )
    {
        if( !m_trackWidth.Validate( GEOMETRY_MIN_SIZE, INT_MAX ) )
            return false;
    }

    // If we survived that, then save the changes:

    bool changeLock = m_lockedCbox->Get3StateValue() != wxCHK_UNDETERMINED;
    bool setLock = m_lockedCbox->Get3StateValue() == wxCHK_CHECKED;

    for( auto item : m_items )
    {
        m_commit.Modify( item );

        switch( item->Type() )
        {
            case PCB_TRACE_T:
            {
                wxASSERT( m_tracks );
                TRACK* t = static_cast<TRACK*>( item );

                if( !m_trackStartX.IsIndeterminate() )
                    t->SetStart( wxPoint( m_trackStartX.GetValue(), t->GetStart().y ) );

                if( !m_trackStartY.IsIndeterminate() )
                    t->SetStart( wxPoint( t->GetStart().x, m_trackStartY.GetValue() ) );

                if( !m_trackEndX.IsIndeterminate() )
                    t->SetEnd( wxPoint( m_trackEndX.GetValue(), t->GetEnd().y ) );

                if( !m_trackEndY.IsIndeterminate() )
                    t->SetEnd( wxPoint( t->GetEnd().x, m_trackEndY.GetValue() ) );

                if( m_trackNetclass->IsChecked() )
                    t->SetWidth( t->GetNetClass()->GetTrackWidth() );
                else if( !m_trackWidth.IsIndeterminate() )
                    t->SetWidth( m_trackWidth.GetValue() );

                LAYER_NUM layer = m_TrackLayerCtrl->GetLayerSelection();

                if( layer != UNDEFINED_LAYER )
                    t->SetLayer( (PCB_LAYER_ID) layer );

                if( changeLock )
                    t->SetLocked( setLock );

                if ( !m_netSelector->IsIndeterminate() )
                    t->SetNetCode( m_netSelector->GetSelectedNetcode() );

                break;
            }

            case PCB_VIA_T:
            {
                wxASSERT( m_vias );
                VIA* v = static_cast<VIA*>( item );

                if( !m_viaX.IsIndeterminate() )
                    v->SetPosition( wxPoint( m_viaX.GetValue(), v->GetPosition().y ) );

                if( !m_viaY.IsIndeterminate() )
                    v->SetPosition( wxPoint( v->GetPosition().x, m_viaY.GetValue() ) );

                if( m_ViaTypeChoice->GetSelection() != 3)
                {
                    switch( m_ViaTypeChoice->GetSelection() )
                    {
                    default:
                    case 0: v->SetViaType( VIA_THROUGH ); v->SanitizeLayers(); break;
                    case 1: v->SetViaType( VIA_MICROVIA );                     break;
                    case 2: v->SetViaType( VIA_BLIND_BURIED );                 break;
                    }
                }

                auto startLayer = static_cast<PCB_LAYER_ID>( m_ViaStartLayer->GetLayerSelection() );
                auto endLayer = static_cast<PCB_LAYER_ID>( m_ViaEndLayer->GetLayerSelection() );

                if (startLayer != UNDEFINED_LAYER )
                    v->SetTopLayer( startLayer );

                if (endLayer != UNDEFINED_LAYER )
                    v->SetBottomLayer( endLayer );

                v->SanitizeLayers();

                if( m_viaNetclass->IsChecked() )
                {
                    switch( v->GetViaType() )
                    {
                    default:
                        wxFAIL_MSG("Unhandled via type");
                        // fall through

                    case VIA_THROUGH:
                    case VIA_BLIND_BURIED:
                        v->SetWidth( v->GetNetClass()->GetViaDiameter() );
                        v->SetDrill( v->GetNetClass()->GetViaDrill() );
                        break;

                    case VIA_MICROVIA:
                        v->SetWidth( v->GetNetClass()->GetuViaDiameter() );
                        v->SetDrill( v->GetNetClass()->GetuViaDrill() );
                        break;
                    }
                }
                else
                {
                    if( !m_viaDiameter.IsIndeterminate() )
                        v->SetWidth( m_viaDiameter.GetValue() );

                    if( !m_viaDrill.IsIndeterminate() )
                        v->SetDrill( m_viaDrill.GetValue() );
                }

                if ( !m_netSelector->IsIndeterminate() )
                    v->SetNetCode( m_netSelector->GetSelectedNetcode() );

                if( changeLock )
                    v->SetLocked( setLock );

                break;
            }

            default:
                wxASSERT( false );
                break;
        }
    }

    if ( !m_netSelector->IsIndeterminate() )
    {
        // Commit::Push() will rebuild connectivitiy propagating nets from connected pads
        // outwards.  We therefore have to update the connected pads in order for the net
        // change to "stick".
        for( D_PAD* pad : changingPads )
        {
            m_commit.Modify( pad );
            pad->SetNetCode( m_netSelector->GetSelectedNetcode() );
        }
    }

    m_commit.Push( _( "Edit track/via properties" ) );

    return true;
}