DIALOG_TRACK_VIA_PROPERTIES::DIALOG_TRACK_VIA_PROPERTIES( PCB_BASE_FRAME* aParent, const SELECTION& aItems ) :
    DIALOG_TRACK_VIA_PROPERTIES_BASE( aParent ), m_items( aItems ),
    m_trackStartX( aParent, m_TrackStartXCtrl, m_TrackStartXUnit ),
    m_trackStartY( aParent, m_TrackStartYCtrl, m_TrackStartYUnit ),
    m_trackEndX( aParent, m_TrackEndXCtrl, m_TrackEndXUnit ),
    m_trackEndY( aParent, m_TrackEndYCtrl, m_TrackEndYUnit ),
    m_trackWidth( aParent, m_TrackWidthCtrl, m_TrackWidthUnit ),
    m_viaX( aParent, m_ViaXCtrl, m_ViaXUnit ), m_viaY( aParent, m_ViaYCtrl, m_ViaYUnit ),
    m_viaDiameter( aParent, m_ViaDiameterCtrl, m_ViaDiameterUnit ),
    m_viaDrill( aParent, m_ViaDrillCtrl, m_ViaDrillUnit ),
    m_tracks( false ), m_vias( false )
{
    wxASSERT( !m_items.Empty() );

    // This is a way to trick gcc into considering these variables as initialized
    OPT<int> trackStartX = NULLOPT;
    OPT<int> trackStartY = NULLOPT;
    OPT<int> trackEndX = NULLOPT;
    OPT<int> trackEndY = NULLOPT;
    OPT<int> trackWidth = NULLOPT;
    OPT<PCB_LAYER_ID> trackLayer = NULLOPT;
    OPT<int> viaX = NULLOPT;
    OPT<int> viaY = NULLOPT;
    OPT<int> viaDiameter = NULLOPT;
    OPT<int> viaDrill = NULLOPT;

    VIATYPE_T viaType = VIA_NOT_DEFINED;
    PCB_LAYER_ID viaStartLayer = UNDEFINED_LAYER;
    PCB_LAYER_ID viaEndLayer = UNDEFINED_LAYER;

    m_haveUniqueNet = true;
    int prevNet = -1;

    m_NetComboBox->SetBoard( aParent->GetBoard() );
    m_NetComboBox->Enable( true );

    bool hasLocked = false;
    bool hasUnlocked = false;

    for( auto& item : m_items )
    {
        int net = static_cast<BOARD_CONNECTED_ITEM*>(item)->GetNetCode();

        if( prevNet >= 0 && net != prevNet )
        {
            printf("prev %d net %d\n", net, prevNet );
            m_haveUniqueNet = false;
            break;
        }

        prevNet = net;
    }

    if ( m_haveUniqueNet )
    {
        m_NetComboBox->SetSelectedNet( prevNet );
    }
    else
    {
        m_NetComboBox->SetMultiple( true );
    }


    // Look for values that are common for every item that is selected
    for( auto& item : m_items )
    {
        switch( item->Type() )
        {
            case PCB_TRACE_T:
            {
                const TRACK* t = static_cast<const TRACK*>( item );

                if( !m_tracks )     // first track in the list
                {
                    trackStartX = t->GetStart().x;
                    trackStartY = t->GetStart().y;
                    trackEndX   = t->GetEnd().x;
                    trackEndY   = t->GetEnd().y;
                    trackWidth  = t->GetWidth();
                    trackLayer  = t->GetLayer();
                    m_tracks    = true;
                }
                else        // check if values are the same for every selected track
                {
                    if( trackStartX && ( *trackStartX != t->GetStart().x ) )
                        trackStartX = NULLOPT;

                    if( trackStartY && ( *trackStartY != t->GetStart().y ) )
                        trackStartY = NULLOPT;

                    if( trackEndX && ( *trackEndX != t->GetEnd().x ) )
                        trackEndX = NULLOPT;

                    if( trackEndY && ( *trackEndY != t->GetEnd().y ) )
                        trackEndY = NULLOPT;

                    if( trackWidth && ( *trackWidth != t->GetWidth() ) )
                        trackWidth = NULLOPT;

                    if( trackLayer && ( *trackLayer != t->GetLayer() ) )
                        trackLayer = NULLOPT;
                }

                if( t->IsLocked() )
                    hasLocked = true;
                else
                    hasUnlocked = true;

                break;
            }

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

                if( !m_vias )       // first via in the list
                {
                    viaX = v->GetPosition().x;
                    viaY = v->GetPosition().y;
                    viaDiameter = v->GetWidth();
                    viaDrill = v->GetDrillValue();
                    m_vias = true;
                    viaType = v->GetViaType();
                    viaStartLayer = v->TopLayer();
                    viaEndLayer = v->BottomLayer();
                }
                else        // check if values are the same for every selected via
                {
                    if( viaX && ( *viaX != v->GetPosition().x ) )
                        viaX = NULLOPT;

                    if( viaY && ( *viaY != v->GetPosition().y ) )
                        viaY = NULLOPT;

                    if( viaDiameter && ( *viaDiameter != v->GetWidth() ) )
                        viaDiameter = NULLOPT;

                    if( viaDrill && ( *viaDrill != v->GetDrillValue() ) )
                        viaDrill = NULLOPT;

                    if( viaType != v->GetViaType() )
                        viaType = VIA_NOT_DEFINED;

                    if( viaStartLayer != v->TopLayer() )
                        viaStartLayer = UNDEFINED_LAYER;

                    if( viaEndLayer != v->BottomLayer() )
                        viaEndLayer = UNDEFINED_LAYER;
                }

                if( v->IsLocked() )
                    hasLocked = true;
                else
                    hasUnlocked = true;

                break;
            }

            default:
            {
                wxASSERT( false );
                break;
            }
        }
    }

    wxASSERT( m_tracks || m_vias );

    if( m_vias )
    {
        setCommonVal( viaX, m_ViaXCtrl, m_viaX );
        setCommonVal( viaY, m_ViaYCtrl, m_viaY );
        setCommonVal( viaDiameter, m_ViaDiameterCtrl, m_viaDiameter );
        setCommonVal( viaDrill, m_ViaDrillCtrl, m_viaDrill );

        m_DesignRuleViasUnit->SetLabel( GetAbbreviatedUnitsLabel( g_UserUnit ) );

        int viaSelection = wxNOT_FOUND;

        for( unsigned ii = 0; ii < aParent->GetDesignSettings().m_ViasDimensionsList.size(); ii++ )
        {
            VIA_DIMENSION* viaDimension = &aParent->GetDesignSettings().m_ViasDimensionsList[ii];
            wxString msg = StringFromValue( g_UserUnit, viaDimension->m_Diameter, false )
                + " / " + StringFromValue( g_UserUnit, viaDimension->m_Drill, false );
            m_DesignRuleViasCtrl->Append( msg, viaDimension );

            if( viaSelection == wxNOT_FOUND && viaDiameter == viaDimension->m_Diameter
                && viaDrill == viaDimension->m_Drill )
            {
                viaSelection = ii;
            }
        }

        m_DesignRuleViasCtrl->SetSelection( viaSelection );

        m_DesignRuleViasCtrl->Connect( wxEVT_CHOICE, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES::onViaSelect ), NULL, this );
        m_ViaDiameterCtrl->Connect( wxEVT_TEXT, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES::onViaEdit ), NULL, this );
        m_ViaDrillCtrl->Connect( wxEVT_TEXT, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES::onViaEdit ), NULL, this );
        m_ViaTypeChoice->Connect( wxEVT_CHOICE, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES::onViaEdit ), NULL, this );

        m_ViaDiameterCtrl->SetFocus();

        m_ViaTypeChoice->Enable();

        if( viaType == VIA_THROUGH )
            m_ViaTypeChoice->SetSelection( 0 );
        else if( viaType == VIA_MICROVIA )
            m_ViaTypeChoice->SetSelection( 1 );
        else if ( viaType == VIA_BLIND_BURIED )
            m_ViaTypeChoice->SetSelection( 2 );
        else if( viaType == VIA_NOT_DEFINED )
            m_ViaTypeChoice->SetSelection( 3 );


        m_ViaStartLayer->SetLayersHotkeys( false );
        m_ViaStartLayer->SetLayerSet( LSET::AllNonCuMask() );
        m_ViaStartLayer->SetBoardFrame( aParent );
        m_ViaStartLayer->Resync();
        m_ViaEndLayer->SetLayersHotkeys( false );
        m_ViaEndLayer->SetLayerSet( LSET::AllNonCuMask() );
        m_ViaEndLayer->SetBoardFrame( aParent );
        m_ViaEndLayer->Resync();


        m_ViaStartLayer->SetLayerSelection( viaStartLayer );
        m_ViaEndLayer->SetLayerSelection( viaEndLayer );

        m_ViaStartLayer->Enable( false );
        m_ViaEndLayer->Enable( false );

        if( viaType != VIA_THROUGH ) // check if selected type isnt through.
        {
            m_ViaStartLayer->Enable();
            m_ViaEndLayer->Enable();
        }

    }
    else
    {
        m_MainSizer->Hide( m_sbViaSizer, true );
    }

    if( m_tracks )
    {
        setCommonVal( trackStartX, m_TrackStartXCtrl, m_trackStartX );
        setCommonVal( trackStartY, m_TrackStartYCtrl, m_trackStartY );
        setCommonVal( trackEndX, m_TrackEndXCtrl, m_trackEndX );
        setCommonVal( trackEndY, m_TrackEndYCtrl, m_trackEndY );
        setCommonVal( trackWidth, m_TrackWidthCtrl, m_trackWidth );

        for( unsigned ii = 0; ii < aParent->GetDesignSettings().m_TrackWidthList.size(); ii++ )
        {
            int width = aParent->GetDesignSettings().m_TrackWidthList[ii];
            wxString msg = StringFromValue( g_UserUnit, width, false );
            m_TrackWidthCtrl->Append( msg );
        }

        m_TrackLayerCtrl->SetLayersHotkeys( false );
        m_TrackLayerCtrl->SetLayerSet( LSET::AllNonCuMask() );
        m_TrackLayerCtrl->SetBoardFrame( aParent );
        m_TrackLayerCtrl->Resync();

        if( trackLayer )
            m_TrackLayerCtrl->SetLayerSelection( *trackLayer );

        m_TrackWidthCtrl->SetFocus();
    }
    else
    {
        m_MainSizer->Hide( m_sbTrackSizer, true );
    }

    if( hasLocked && hasUnlocked )
    {
         m_lockedCbox->Set3StateValue( wxCHK_UNDETERMINED );
    }
    else if( hasLocked )
    {
        m_lockedCbox->Set3StateValue( wxCHK_CHECKED );
    }
    else
    {
        m_lockedCbox->Set3StateValue( wxCHK_UNCHECKED );
    }


    m_StdButtonsOK->SetDefault();

    // Pressing ENTER when any of the text input fields is active applies changes
    Connect( wxEVT_TEXT_ENTER, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES::onOkClick ),
             NULL, this );
}
Exemple #2
0
DIALOG_TRACK_VIA_PROPERTIES::DIALOG_TRACK_VIA_PROPERTIES( PCB_BASE_FRAME* aParent, const SELECTION& aItems ) :
    DIALOG_TRACK_VIA_PROPERTIES_BASE( aParent ), m_items( aItems ),
    m_trackStartX( aParent, m_TrackStartXCtrl, m_TrackStartXUnit ),
    m_trackStartY( aParent, m_TrackStartYCtrl, m_TrackStartYUnit ),
    m_trackEndX( aParent, m_TrackEndXCtrl, m_TrackEndXUnit ),
    m_trackEndY( aParent, m_TrackEndYCtrl, m_TrackEndYUnit ),
    m_trackWidth( aParent, m_TrackWidthCtrl, m_TrackWidthUnit ),
    m_viaX( aParent, m_ViaXCtrl, m_ViaXUnit ), m_viaY( aParent, m_ViaYCtrl, m_ViaYUnit ),
    m_viaDiameter( aParent, m_ViaDiameterCtrl, m_ViaDiameterUnit ),
    m_viaDrill( aParent, m_ViaDrillCtrl, m_ViaDrillUnit ),
    m_tracks( false ), m_vias( false )
{
    assert( !m_items.Empty() );

    // This is a way to trick gcc into considering these variables as initialized
    boost::optional<int> trackStartX = boost::make_optional<int>( false, 0 );
    boost::optional<int> trackStartY = boost::make_optional<int>( false, 0 );
    boost::optional<int> trackEndX = boost::make_optional<int>( false, 0 );
    boost::optional<int> trackEndY = boost::make_optional<int>( false, 0 );
    boost::optional<int> trackWidth = boost::make_optional<int>( false, 0 );
    boost::optional<LAYER_ID> trackLayer = boost::make_optional<LAYER_ID>( false, (LAYER_ID) 0 );
    boost::optional<int> viaX, viaY, viaDiameter;
    boost::optional<int> viaDrill = boost::make_optional<int>( false, 0 );

    bool hasLocked = false;
    bool hasUnlocked = false;

    // Look for values that are common for every item that is selected
    for( auto& item : m_items )
    {
        switch( item->Type() )
        {
            case PCB_TRACE_T:
            {
                const TRACK* t = static_cast<const TRACK*>( item );

                if( !m_tracks )     // first track in the list
                {
                    trackStartX = t->GetStart().x;
                    trackStartY = t->GetStart().y;
                    trackEndX   = t->GetEnd().x;
                    trackEndY   = t->GetEnd().y;
                    trackWidth  = t->GetWidth();
                    trackLayer  = t->GetLayer();
                    m_tracks    = true;
                }
                else        // check if values are the same for every selected track
                {
                    if( trackStartX && ( *trackStartX != t->GetStart().x ) )
                        trackStartX = boost::none;

                    if( trackStartY && ( *trackStartY != t->GetStart().y ) )
                        trackStartY = boost::none;

                    if( trackEndX && ( *trackEndX != t->GetEnd().x ) )
                        trackEndX = boost::none;

                    if( trackEndY && ( *trackEndY != t->GetEnd().y ) )
                        trackEndY = boost::none;

                    if( trackWidth && ( *trackWidth != t->GetWidth() ) )
                        trackWidth = boost::none;

                    if( trackLayer && ( *trackLayer != t->GetLayer() ) )
                        trackLayer = boost::none;
                }

                if( t->IsLocked() )
                    hasLocked = true;
                else
                    hasUnlocked = true;

                break;
            }

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

                if( !m_vias )       // first via in the list
                {
                    viaX = v->GetPosition().x;
                    viaY = v->GetPosition().y;
                    viaDiameter = v->GetWidth();
                    viaDrill = v->GetDrillValue();
                    m_vias = true;
                }
                else        // check if values are the same for every selected via
                {
                    if( viaX && ( *viaX != v->GetPosition().x ) )
                        viaX = boost::none;

                    if( viaY && ( *viaY != v->GetPosition().y ) )
                        viaY = boost::none;

                    if( viaDiameter && ( *viaDiameter != v->GetWidth() ) )
                        viaDiameter = boost::none;

                    if( viaDrill && ( *viaDrill != v->GetDrillValue() ) )
                        viaDrill = boost::none;
                }

                if( v->IsLocked() )
                    hasLocked = true;
                else
                    hasUnlocked = true;

                break;
            }

            default:
                assert( false );
                break;
        }
    }

    assert( m_tracks || m_vias );

    if( m_vias )
    {
        setCommonVal( viaX, m_ViaXCtrl, m_viaX );
        setCommonVal( viaY, m_ViaYCtrl, m_viaY );
        setCommonVal( viaDiameter, m_ViaDiameterCtrl, m_viaDiameter );
        setCommonVal( viaDrill, m_ViaDrillCtrl, m_viaDrill );
        m_ViaDiameterCtrl->SetFocus();
    }
    else
    {
        m_MainSizer->Hide( m_sbViaSizer, true );
    }

    if( m_tracks )
    {
        setCommonVal( trackStartX, m_TrackStartXCtrl, m_trackStartX );
        setCommonVal( trackStartY, m_TrackStartYCtrl, m_trackStartY );
        setCommonVal( trackEndX, m_TrackEndXCtrl, m_trackEndX );
        setCommonVal( trackEndY, m_TrackEndYCtrl, m_trackEndY );
        setCommonVal( trackWidth, m_TrackWidthCtrl, m_trackWidth );

        m_TrackLayerCtrl->SetLayersHotkeys( false );
        m_TrackLayerCtrl->SetLayerSet( LSET::AllNonCuMask() );
        m_TrackLayerCtrl->SetBoardFrame( aParent );
        m_TrackLayerCtrl->Resync();

        if( trackLayer )
            m_TrackLayerCtrl->SetLayerSelection( *trackLayer );

        m_TrackWidthCtrl->SetFocus();
    }
    else
    {
        m_MainSizer->Hide( m_sbTrackSizer, true );
    }

    if( hasLocked && hasUnlocked )
    {
         m_lockedCbox->Set3StateValue( wxCHK_UNDETERMINED );
    }
    else if( hasLocked )
    {
        m_lockedCbox->Set3StateValue( wxCHK_CHECKED );
    }
    else
    {
        m_lockedCbox->Set3StateValue( wxCHK_UNCHECKED );
    }

    m_StdButtonsOK->SetDefault();

    FixOSXCancelButtonIssue();

    // Pressing ENTER when any of the text input fields is active applies changes
    Connect( wxEVT_TEXT_ENTER, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES::onOkClick ), NULL, this );
}
DIALOG_TRACK_VIA_PROPERTIES::DIALOG_TRACK_VIA_PROPERTIES( PCB_BASE_FRAME* aParent, const SELECTION& aItems ) :
    DIALOG_TRACK_VIA_PROPERTIES_BASE( aParent ), m_items( aItems ),
    m_trackStartX( aParent, m_TrackStartXCtrl, m_TrackStartXUnit ),
    m_trackStartY( aParent, m_TrackStartYCtrl, m_TrackStartYUnit ),
    m_trackEndX( aParent, m_TrackEndXCtrl, m_TrackEndXUnit ),
    m_trackEndY( aParent, m_TrackEndYCtrl, m_TrackEndYUnit ),
    m_trackWidth( aParent, m_TrackWidthCtrl, m_TrackWidthUnit ),
    m_viaX( aParent, m_ViaXCtrl, m_ViaXUnit ), m_viaY( aParent, m_ViaYCtrl, m_ViaYUnit ),
    m_viaDiameter( aParent, m_ViaDiameterCtrl, m_ViaDiameterUnit ),
    m_viaDrill( aParent, m_ViaDrillCtrl, m_ViaDrillUnit ),
    m_tracks( false ), m_vias( false )
{
    assert( !m_items.Empty() );

    boost::optional<int> trackStartX, trackStartY, trackEndX, trackEndY, trackWidth;
    boost::optional<LAYER_ID> trackLayer;
    boost::optional<int> viaX, viaY, viaDiameter, viaDrill;

    // Look for values that are common for every item that is selected
    for( int i = 0; i < m_items.Size(); ++i )
    {
        const BOARD_ITEM* item = m_items.Item<BOARD_ITEM>( i );

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

                if( !m_tracks )     // first track in the list
                {
                    trackStartX = t->GetStart().x;
                    trackStartY = t->GetStart().y;
                    trackEndX   = t->GetEnd().x;
                    trackEndY   = t->GetEnd().y;
                    trackWidth  = t->GetWidth();
                    trackLayer  = t->GetLayer();
                    m_tracks    = true;
                }
                else        // check if values are the same for every selected track
                {
                    if( trackStartX && *trackStartX != t->GetStart().x )
                        trackStartX = boost::none;

                    if( trackStartY && *trackStartY != t->GetStart().y )
                        trackStartY = boost::none;

                    if( trackEndX && *trackEndX != t->GetEnd().x )
                        trackEndX = boost::none;

                    if( trackEndY && *trackEndY != t->GetEnd().y )
                        trackEndY = boost::none;

                    if( trackWidth && *trackWidth != t->GetWidth() )
                        trackWidth = boost::none;

                    if( trackLayer && *trackLayer != t->GetLayer() )
                        trackLayer = boost::none;
                }
                break;
            }

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

                if( !m_vias )       // first via in the list
                {
                    viaX = v->GetPosition().x;
                    viaY = v->GetPosition().y;
                    viaDiameter = v->GetWidth();
                    viaDrill = v->GetDrillValue();
                    m_vias = true;
                }
                else        // check if values are the same for every selected via
                {
                    if( viaX && *viaX != v->GetPosition().x )
                        viaX = boost::none;

                    if( viaY && *viaY != v->GetPosition().y )
                        viaY = boost::none;

                    if( viaDiameter && *viaDiameter != v->GetWidth() )
                        viaDiameter = boost::none;

                    if( viaDrill && *viaDrill != v->GetDrillValue() )
                        viaDrill = boost::none;
                }
                break;
            }

            default:
                assert( false );
                break;
        }
    }

    assert( m_tracks || m_vias );

    if( m_vias )
    {
        setCommonVal( viaX, m_ViaXCtrl, m_viaX );
        setCommonVal( viaY, m_ViaYCtrl, m_viaY );
        setCommonVal( viaDiameter, m_ViaDiameterCtrl, m_viaDiameter );
        setCommonVal( viaDrill, m_ViaDrillCtrl, m_viaDrill );
        m_ViaDiameterCtrl->SetFocus();
    }
    else
    {
        m_MainSizer->Hide( m_sbViaSizer, true );
    }

    if( m_tracks )
    {
        setCommonVal( trackStartX, m_TrackStartXCtrl, m_trackStartX );
        setCommonVal( trackStartY, m_TrackStartYCtrl, m_trackStartY );
        setCommonVal( trackEndX, m_TrackEndXCtrl, m_trackEndX );
        setCommonVal( trackEndY, m_TrackEndYCtrl, m_trackEndY );
        setCommonVal( trackWidth, m_TrackWidthCtrl, m_trackWidth );

        m_TrackLayerCtrl->SetLayersHotkeys( false );
        m_TrackLayerCtrl->SetLayerSet( LSET::AllNonCuMask() );
        m_TrackLayerCtrl->SetBoardFrame( aParent );
        m_TrackLayerCtrl->Resync();

        if( trackLayer )
            m_TrackLayerCtrl->SetLayerSelection( *trackLayer );

        m_TrackWidthCtrl->SetFocus();
    }
    else
    {
        m_MainSizer->Hide( m_sbTrackSizer, true );
    }

    m_StdButtonsOK->SetDefault();

    FixOSXCancelButtonIssue();

    // Now all widgets have the size fixed, call FinishDialogSettings
    FinishDialogSettings();

    // Pressing ENTER when any of the text input fields is active applies changes
    Connect( wxEVT_TEXT_ENTER, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES::onOkClick ), NULL, this );
}