Exemplo n.º 1
0
void FOOTPRINT_EDIT_FRAME::Edit_Edge_Width( EDGE_MODULE* aEdge )
{
    MODULE* module = GetBoard()->m_Modules;

    SaveCopyInUndoList( module, UR_CHANGED );

    if( aEdge == NULL )
    {
        for( BOARD_ITEM *item = module->GraphicalItemsList(); item; item = item->Next() )
        {
            aEdge = dyn_cast<EDGE_MODULE*>( item );

            if( aEdge )
                aEdge->SetWidth( GetDesignSettings().GetLineThickness( aEdge->GetLayer() ) );
        }
    }
    else
    {
        aEdge->SetWidth( GetDesignSettings().GetLineThickness( aEdge->GetLayer() ) );
    }

    OnModify();
    module->CalculateBoundingBox();
    module->SetLastEditTime();
}
Exemplo n.º 2
0
void FOOTPRINT_EDIT_FRAME::Edit_Edge_Width( EDGE_MODULE* aEdge )
{
    MODULE* module = GetBoard()->m_Modules;

    SaveCopyInUndoList( module, UR_MODEDIT );

    if( aEdge == NULL )
    {
        aEdge = (EDGE_MODULE*) (BOARD_ITEM*) module->m_Drawings;

        for( ; aEdge != NULL; aEdge = aEdge->Next() )
        {
            if( aEdge->Type() != PCB_MODULE_EDGE_T )
                continue;

            aEdge->SetWidth( GetDesignSettings().m_ModuleSegmentWidth );
        }
    }
    else
    {
        aEdge->SetWidth( GetDesignSettings().m_ModuleSegmentWidth );
    }

    OnModify();
    module->CalculateBoundingBox();
    module->m_LastEdit_Time = time( NULL );
}
Exemplo n.º 3
0
MODULE* PCB_BASE_FRAME::Create_1_Module( const wxString& aModuleName )
{
    MODULE*  module;
    wxString moduleName;
    wxPoint  newpos;

    moduleName = aModuleName;

    // Ask for the new module reference
    if( moduleName.IsEmpty() )
    {
        wxTextEntryDialog dlg( this, FMT_MOD_REF, FMT_MOD_CREATE, moduleName );

        if( dlg.ShowModal() != wxID_OK )
            return NULL;    //Aborted by user

        moduleName = dlg.GetValue();
    }

    moduleName.Trim( true );
    moduleName.Trim( false );

    if( moduleName.IsEmpty( ) )
    {
        DisplayInfoMessage( this, FMT_NO_REF_ABORTED );
        return NULL;
    }

    // Creates the new module and add it to the head of the linked list of modules
    module = new MODULE( GetBoard() );

    GetBoard()->Add( module );

    // Update parameters: position, timestamp ...
    newpos = GetScreen()->GetCrossHairPosition();
    module->SetPosition( newpos );
    module->SetLastEditTime();

    // Update its name in lib
    module->m_LibRef = moduleName;

    // Update reference:
    module->m_Reference->m_Text = moduleName;
    module->m_Reference->SetThickness( GetDesignSettings().m_ModuleTextWidth );
    module->m_Reference->SetSize( GetDesignSettings().m_ModuleTextSize );

    // Set the value field to a default value
    module->m_Value->m_Text = wxT( "VAL**" );
    module->m_Value->SetThickness( GetDesignSettings().m_ModuleTextWidth );
    module->m_Value->SetSize( GetDesignSettings().m_ModuleTextSize );
    module->SetPosition( wxPoint( 0, 0 ) );

    SetMsgPanel( module );
    return module;
}
Exemplo n.º 4
0
wxSize D_PAD::GetSolderPasteMargin() const
{
    // The pad inherits the margin only to calculate a default shape,
    // therefore only if it is also a copper layer.
    // Pads defined only on mask layers (and perhaps on other tech layers) use the shape
    // defined by the pad settings only
    bool isOnCopperLayer = ( m_layerMask & LSET::AllCuMask() ).any();

    if( !isOnCopperLayer )
        return wxSize( 0, 0 );

    int     margin = m_LocalSolderPasteMargin;
    double  mratio = m_LocalSolderPasteMarginRatio;

    MODULE* module = GetParent();

    if( module )
    {
        if( margin == 0 )
            margin = module->GetLocalSolderPasteMargin();

        auto brd = GetBoard();

        if( margin == 0 && brd )
        {
                margin = brd->GetDesignSettings().m_SolderPasteMargin;
        }

        if( mratio == 0.0 )
            mratio = module->GetLocalSolderPasteMarginRatio();

        if( mratio == 0.0 && brd )
        {
            mratio = brd->GetDesignSettings().m_SolderPasteMarginRatio;
        }
    }

    wxSize pad_margin;
    pad_margin.x = margin + KiROUND( m_Size.x * mratio );
    pad_margin.y = margin + KiROUND( m_Size.y * mratio );

    // ensure mask have a size always >= 0
    if( pad_margin.x < -m_Size.x / 2 )
        pad_margin.x = -m_Size.x / 2;

    if( pad_margin.y < -m_Size.y / 2 )
        pad_margin.y = -m_Size.y / 2;

    return pad_margin;
}
void ZONE_CONTAINER::TransformSolidAreasShapesToPolygonSet(
        SHAPE_POLY_SET& aCornerBuffer, int aError ) const
{
    if( GetFilledPolysList().IsEmpty() )
        return;

    // add filled areas polygons
    aCornerBuffer.Append( m_FilledPolysList );
    auto board = GetBoard();
    int maxError = ARC_HIGH_DEF;

    if( board )
        maxError = board->GetDesignSettings().m_MaxError;

    // add filled areas outlines, which are drawn with thick lines
    for( int i = 0; i < m_FilledPolysList.OutlineCount(); i++ )
    {
        const SHAPE_LINE_CHAIN& path = m_FilledPolysList.COutline( i );

        for( int j = 0; j < path.PointCount(); j++ )
        {
            const VECTOR2I& a = path.CPoint( j );
            const VECTOR2I& b = path.CPoint( j + 1 );

            TransformRoundedEndsSegmentToPolygon( aCornerBuffer, wxPoint( a.x, a.y ),
                    wxPoint( b.x, b.y ), maxError, GetMinThickness() );
        }
    }
}
Exemplo n.º 6
0
/* Initialize the drawing of a segment of type other than trace.
 */
DRAWSEGMENT* PCB_EDIT_FRAME::Begin_DrawSegment( DRAWSEGMENT* Segment, STROKE_T shape, wxDC* DC )
{
    int          lineWidth;
    DRAWSEGMENT* DrawItem;

    lineWidth = GetDesignSettings().GetLineThickness( GetActiveLayer() );

    if( Segment == NULL )        // Create new segment.
    {
        SetCurItem( Segment = new DRAWSEGMENT( GetBoard() ) );
        Segment->SetFlags( IS_NEW );
        Segment->SetLayer( GetActiveLayer() );
        Segment->SetWidth( lineWidth );
        Segment->SetShape( shape );
        Segment->SetAngle( 900 );
        Segment->SetStart( GetCrossHairPosition() );
        Segment->SetEnd( GetCrossHairPosition() );
        m_canvas->SetMouseCapture( DrawSegment, Abort_EditEdge );
    }
    else
    {
        // The ending point coordinate Segment->m_End was updated by the function
        // DrawSegment() called on a move mouse event during the segment creation
        if( Segment->GetStart() != Segment->GetEnd() )
        {
            if( Segment->GetShape() == S_SEGMENT )
            {
                SaveCopyInUndoList( Segment, UR_NEW );
                GetBoard()->Add( Segment );

                OnModify();
                Segment->ClearFlags();

                Segment->Draw( m_canvas, DC, GR_OR );

                DrawItem = Segment;

                SetCurItem( Segment = new DRAWSEGMENT( GetBoard() ) );

                Segment->SetFlags( IS_NEW );
                Segment->SetLayer( DrawItem->GetLayer() );
                Segment->SetWidth( lineWidth );
                Segment->SetShape( DrawItem->GetShape() );
                Segment->SetType( DrawItem->GetType() );
                Segment->SetAngle( DrawItem->GetAngle() );
                Segment->SetStart( DrawItem->GetEnd() );
                Segment->SetEnd( DrawItem->GetEnd() );
                DrawSegment( m_canvas, DC, wxDefaultPosition, false );
            }
            else
            {
                End_Edge( Segment, DC );
                Segment = NULL;
            }
        }
    }

    return Segment;
}
void PCB_EDIT_FRAME::OnUpdateSelectTrackWidth( wxUpdateUIEvent& aEvent )
{
    if( aEvent.GetId() == ID_AUX_TOOLBAR_PCB_TRACK_WIDTH )
    {
        if( m_SelTrackWidthBox->GetSelection() != (int) GetDesignSettings().GetTrackWidthIndex() )
            m_SelTrackWidthBox->SetSelection( GetDesignSettings().GetTrackWidthIndex() );
    }
    else
    {
        bool check = ( ( ( ID_POPUP_PCB_SELECT_WIDTH1 +
                           (int) GetDesignSettings().GetTrackWidthIndex() ) == aEvent.GetId() ) &&
                               !GetDesignSettings().m_UseConnectedTrackWidth &&
                               !GetDesignSettings().UseCustomTrackViaSize() );

        aEvent.Check( check );
    }
}
/* Add a new pad to aModule.
 */
void PCB_BASE_FRAME::AddPad( MODULE* aModule, bool draw )
{
    m_Pcb->m_Status_Pcb     = 0;
    aModule->SetLastEditTime();

    D_PAD* pad = new D_PAD( aModule );

    // Add the new pad to end of the module pad list.
    aModule->Pads().PushBack( pad );

    // Update the pad properties,
    // and keep NETINFO_LIST::ORPHANED as net info
    // which is the default when nets cannot be handled.
    Import_Pad_Settings( pad, false );

    pad->SetPosition( GetCrossHairPosition() );

    // Set the relative pad position
    // ( pad position for module orient, 0, and relative to the module position)

    wxPoint pos0 = pad->GetPosition() - aModule->GetPosition();
    RotatePoint( &pos0, -aModule->GetOrientation() );
    pad->SetPos0( pos0 );

    /* NPTH pads take empty pad number (since they can't be connected),
     * other pads get incremented from the last one edited */
    wxString padName;

    if( pad->GetAttribute() != PAD_ATTRIB_HOLE_NOT_PLATED )
    {
        padName = GetNextPadName( GetDesignSettings()
                .m_Pad_Master.GetPadName() );
    }

    pad->SetPadName( padName );
    GetDesignSettings().m_Pad_Master.SetPadName( padName );

    aModule->CalculateBoundingBox();
    SetMsgPanel( pad );

    if( draw )
        m_canvas->RefreshDrawingRect( aModule->GetBoundingBox() );
}
void PCB_EDIT_FRAME::OnUpdateSelectViaSize( wxUpdateUIEvent& aEvent )
{
    wxString msg;

    if( aEvent.GetId() == ID_AUX_TOOLBAR_PCB_VIA_SIZE )
    {
        if( m_SelViaSizeBox->GetSelection() != (int) GetDesignSettings().GetViaSizeIndex() )
            m_SelViaSizeBox->SetSelection( GetDesignSettings().GetViaSizeIndex() );
    }
    else
    {
        bool check = ( ( ( ID_POPUP_PCB_SELECT_VIASIZE1 +
                           (int) GetDesignSettings().GetViaSizeIndex() ) == aEvent.GetId() ) &&
                       !GetDesignSettings().m_UseConnectedTrackWidth &&
                       !GetDesignSettings().UseCustomTrackViaSize() );

        aEvent.Check( check );
    }
}
void PCB_BASE_FRAME::ResetTextSize( BOARD_ITEM* aItem, wxDC* aDC )
{
    wxSize newSize;
    int newThickness;

    if( aItem->Type() == PCB_TEXT_T )
    {
        newSize = GetDesignSettings().m_PcbTextSize;
        newThickness = GetDesignSettings().m_PcbTextWidth;
        TEXTE_PCB* text = static_cast<TEXTE_PCB*>( aItem );

        // Exit if there's nothing to do
        if( text->GetTextSize() == newSize && text->GetThickness() == newThickness )
            return;

        SaveCopyInUndoList( text, UR_CHANGED );
        text->SetTextSize( newSize );
        text->SetThickness( newThickness );
    }

    else if( aItem->Type() ==  PCB_MODULE_TEXT_T )
    {
        newSize = GetDesignSettings().m_ModuleTextSize;
        newThickness = GetDesignSettings().m_ModuleTextWidth;
        TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( aItem );

        // Exit if there's nothing to do
        if( text->GetTextSize() == newSize && text->GetThickness() == newThickness )
            return;

        SaveCopyInUndoList( text->GetParent(), UR_CHANGED );
        text->SetTextSize( newSize );
        text->SetThickness( newThickness );
    }
    else
        return;

    if( aDC )
        m_canvas->Refresh();

    OnModify();
}
bool PCB_EDIT_FRAME::SetCurrentNetClass( const wxString& aNetClassName )
{
    bool change = GetDesignSettings().SetCurrentNetClass( aNetClassName );

    if( change )
    {
        ReCreateAuxiliaryToolbar();
    }

    return change;
}
Exemplo n.º 12
0
/*
 * Exports the current pad settings to board design settings.
 */
void PCB_BASE_FRAME::Export_Pad_Settings( D_PAD* aPad )
{
    if( aPad == NULL )
        return;

    SetMsgPanel( aPad );

    D_PAD& masterPad = GetDesignSettings().m_Pad_Master;

    masterPad.ImportSettingsFromMaster( *aPad );
}
/* Imports the board design settings to aPad
 * - The position, names, and keys are not modifed.
 */
void PCB_BASE_FRAME::Import_Pad_Settings( D_PAD* aPad, bool aDraw )
{
    if( aDraw )
    {
        aPad->SetFlags( DO_NOT_DRAW );
        m_canvas->RefreshDrawingRect( aPad->GetBoundingBox() );
        aPad->ClearFlags( DO_NOT_DRAW );
    }

    D_PAD& mp = GetDesignSettings().m_Pad_Master;

    aPad->SetShape( mp.GetShape() );
    aPad->SetLayerSet( mp.GetLayerSet() );
    aPad->SetAttribute( mp.GetAttribute() );
    aPad->SetOrientation( mp.GetOrientation() + aPad->GetParent()->GetOrientation() );
    aPad->SetSize( mp.GetSize() );
    aPad->SetDelta( wxSize( 0, 0 ) );
    aPad->SetOffset( mp.GetOffset() );
    aPad->SetDrillSize( mp.GetDrillSize() );
    aPad->SetDrillShape( mp.GetDrillShape() );

    switch( mp.GetShape() )
    {
    case PAD_TRAPEZOID:
        aPad->SetDelta( mp.GetDelta() );
        break;

    case PAD_CIRCLE:
        // ensure size.y == size.x
        aPad->SetSize( wxSize( aPad->GetSize().x, aPad->GetSize().x ) );
        break;

    default:
        ;
    }

    switch( mp.GetAttribute() )
    {
    case PAD_SMD:
    case PAD_CONN:
        aPad->SetDrillSize( wxSize( 0, 0 ) );
        aPad->SetOffset( wxPoint( 0, 0 ) );
        break;
    default:
        ;
    }

    if( aDraw )
        m_canvas->RefreshDrawingRect( aPad->GetBoundingBox() );

    aPad->GetParent()->SetLastEditTime();

    OnModify();
}
Exemplo n.º 14
0
void FOOTPRINT_EDIT_FRAME::Enter_Edge_Width( EDGE_MODULE* aEdge )
{
    wxString buffer;

    buffer = StringFromValue( g_UserUnit, GetDesignSettings().m_ModuleSegmentWidth );
    wxTextEntryDialog dlg( this, _( "New Width:" ), _( "Edge Width" ), buffer );

    if( dlg.ShowModal() != wxID_OK )
        return; // canceled by user

    buffer = dlg.GetValue( );
    GetDesignSettings().m_ModuleSegmentWidth = ValueFromString( g_UserUnit, buffer );

    if( aEdge )
    {
        MODULE* module = GetBoard()->m_Modules;
        aEdge->SetWidth( GetDesignSettings().m_ModuleSegmentWidth );
        module->CalculateBoundingBox();
        OnModify();
    }
}
Exemplo n.º 15
0
void PCB_EDIT_FRAME::updateViaSizeSelectBox()
{
    if( m_SelViaSizeBox == NULL )
        return;

    wxString msg;

    m_SelViaSizeBox->Clear();
    bool mmFirst = g_UserUnit != INCHES;

    for( unsigned ii = 0; ii < GetDesignSettings().m_ViasDimensionsList.size(); ii++ )
    {
        int diam = GetDesignSettings().m_ViasDimensionsList[ii].m_Diameter;

        double valueMils = To_User_Unit( INCHES, diam ) * 1000;
        double value_mm = To_User_Unit( MILLIMETRES, diam );

        if( mmFirst )
            msg.Printf( _( "Via: %.2f mm (%.1f mils)" ),
                        value_mm, valueMils );
        else
            msg.Printf( _( "Via: %.1f mils (%.2f mm)" ),
                        valueMils, value_mm );

        int hole = GetDesignSettings().m_ViasDimensionsList[ii].m_Drill;

        if( hole )
        {
            msg  << wxT("/ ");
            wxString hole_str;
            valueMils = To_User_Unit( INCHES, hole ) * 1000;
            value_mm = To_User_Unit( MILLIMETRES, hole );

            if( mmFirst )
                hole_str.Printf( _( "%.2f mm (%.1f mils)" ),
                                 value_mm, valueMils );
            else
                hole_str.Printf( _( "%.1f mils (%.2f mm)" ),
                                 valueMils, value_mm );

            msg += hole_str;
        }

        // Mark the netclass via size value (the first in list)
        if( ii == 0 )
            msg << wxT( " *" );

        m_SelViaSizeBox->Append( msg );
    }

    if( GetDesignSettings().GetViaSizeIndex() >= GetDesignSettings().m_ViasDimensionsList.size() )
        GetDesignSettings().SetViaSizeIndex( 0 );

    m_SelViaSizeBox->SetSelection( GetDesignSettings().GetViaSizeIndex() );
}
void FOOTPRINT_EDIT_FRAME::LoadSettings( wxConfigBase* aCfg )
{
    PCB_BASE_FRAME::LoadSettings( aCfg );
    wxConfigLoadSetups( aCfg, GetConfigurationSettings() );

    // Ensure some params are valid
    BOARD_DESIGN_SETTINGS& settings = GetDesignSettings();

    // Usually, graphic items are drawn on F_SilkS or F_Fab layer
    // Force these layers if not default
    if( ( settings.m_RefDefaultlayer != F_SilkS ) && ( settings.m_RefDefaultlayer != F_Fab ) )
        settings.m_RefDefaultlayer = F_SilkS;

    if( ( settings.m_ValueDefaultlayer != F_SilkS ) && ( settings.m_ValueDefaultlayer != F_Fab ) )
        settings.m_ValueDefaultlayer = F_Fab;
}
Exemplo n.º 17
0
PCB_TARGET* PCB_EDIT_FRAME::CreateTarget( wxDC* DC )
{
    PCB_TARGET* target = new PCB_TARGET( GetBoard() );

    target->SetFlags( IS_NEW );

    GetBoard()->Add( target );

    target->SetLayer( Edge_Cuts );
    target->SetWidth( GetDesignSettings().m_EdgeSegmentWidth );
    target->SetSize( MireDefaultSize );
    target->SetPosition( GetCrossHairPosition() );

    PlaceTarget( target, DC );

    return target;
}
bool PCB_EDIT_FRAME::IsMicroViaAcceptable()
{
    int copperlayercnt = GetBoard()->GetCopperLayerCount( );
    LAYER_ID currLayer = GetActiveLayer();

    if( !GetDesignSettings().m_MicroViasAllowed )
        return false;   // Obvious..

    if( copperlayercnt < 4 )
        return false;   // Only on multilayer boards..

    if( ( currLayer == B_Cu )
       || ( currLayer == F_Cu )
       || ( currLayer == copperlayercnt - 2 )
       || ( currLayer == In1_Cu ) )
        return true;

    return false;
}
Exemplo n.º 19
0
bool PCB_EDIT_FRAME::IsMicroViaAcceptable( void )
{
    int copperlayercnt = GetBoard()->GetCopperLayerCount( );
    LAYER_NUM currLayer = getActiveLayer();

    if( !GetDesignSettings().m_MicroViasAllowed )
        return false;   // Obvious..

    if( copperlayercnt < 4 )
        return false;   // Only on multilayer boards..

    if( ( currLayer == LAYER_N_BACK )
            || ( currLayer == LAYER_N_FRONT )
            || ( currLayer == copperlayercnt - 2 )
            || ( currLayer == LAYER_N_2 ) )
        return true;

    return false;
}
Exemplo n.º 20
0
/*
 * Imports the board design settings to aPad
 * - The position, names, and keys are not modifed.
 * The parameters are expected to be correct (i.e. settings are valid)
 */
void PCB_BASE_FRAME::Import_Pad_Settings( D_PAD* aPad, bool aDraw )
{
    if( aDraw )
    {
        aPad->SetFlags( DO_NOT_DRAW );
        m_canvas->RefreshDrawingRect( aPad->GetBoundingBox() );
        aPad->ClearFlags( DO_NOT_DRAW );
    }

    const D_PAD& mp = GetDesignSettings().m_Pad_Master;

    aPad->ImportSettingsFromMaster( mp );

    if( aDraw )
        m_canvas->RefreshDrawingRect( aPad->GetBoundingBox() );

    aPad->GetParent()->SetLastEditTime();

    OnModify();
}
Exemplo n.º 21
0
void PCB_EDIT_FRAME::Begin_Self( wxDC* DC )
{
    if( s_inductor_pattern.m_Flag )
    {
        m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
        m_canvas->SetMouseCapture( NULL, NULL );

        wxString errorMessage;

        // Prepare parameters for inductor
        // s_inductor_pattern.m_Start is already initialized,
        // when s_inductor_pattern.m_Flag == false
        s_inductor_pattern.m_Width = GetDesignSettings().GetCurrentTrackWidth();
        s_inductor_pattern.m_End = GetCrossHairPosition();

        MODULE* footprint = CreateMicrowaveInductor( this, errorMessage );

        if( footprint )
        {
            SetMsgPanel( footprint );
            footprint->Draw( m_canvas, DC, GR_OR );
        }

        else if( !errorMessage.IsEmpty() )
            DisplayError( this, errorMessage );

        return;
    }

    s_inductor_pattern.m_Start = GetCrossHairPosition();
    s_inductor_pattern.m_End   = s_inductor_pattern.m_Start;

    s_inductor_pattern.m_Flag = true;

    // Update the initial coordinates.
    GetScreen()->m_O_Curseur = GetCrossHairPosition();
    UpdateStatusBar();

    m_canvas->SetMouseCapture( ShowBoundingBoxMicroWaveInductor, Exit_Self );
    m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
}
/* Merge all basic shapes, converted to a polygon in one polygon,
 * return true if OK, false in there is more than one polygon
 * in aMergedPolygon
 */
bool D_PAD::MergePrimitivesAsPolygon( SHAPE_POLY_SET* aMergedPolygon )
{
    auto board = GetBoard();
    int maxError = ARC_HIGH_DEF;

    if( board )
        maxError = board->GetDesignSettings().m_MaxError;

    // if aMergedPolygon == NULL, use m_customShapeAsPolygon as target

    if( !aMergedPolygon )
        aMergedPolygon = &m_customShapeAsPolygon;

    aMergedPolygon->RemoveAllContours();

    // Add the anchor pad shape in aMergedPolygon, others in aux_polyset:
    // The anchor pad is always at 0,0
    switch( GetAnchorPadShape() )
    {
    default:
    case PAD_SHAPE_CIRCLE:
        TransformCircleToPolygon( *aMergedPolygon, wxPoint( 0, 0 ), GetSize().x / 2, maxError );
        break;

    case PAD_SHAPE_RECT:
    {
        SHAPE_RECT rect( -GetSize().x / 2, -GetSize().y / 2, GetSize().x, GetSize().y );
        aMergedPolygon->AddOutline( rect.Outline() );

        break;
    }
    }

    if( !buildCustomPadPolygon( aMergedPolygon, maxError ) )
        return false;

    m_boundingRadius = -1;  // The current bouding radius is no more valid.

    return aMergedPolygon->OutlineCount() <= 1;
}
Exemplo n.º 23
0
MODULE* PCB_EDIT_FRAME::CreateMuWaveBaseFootprint( const wxString& aValue,
                                                   int aTextSize, int aPadCount )
{
    MODULE* module = CreateNewModule( aValue );

    if( aTextSize > 0 )
    {
        module->Reference().SetSize( wxSize( aTextSize, aTextSize ) );
        module->Reference().SetThickness( aTextSize/5 );
        module->Value().SetSize( wxSize( aTextSize, aTextSize ) );
        module->Value().SetThickness( aTextSize/5 );
    }

    // Create 2 pads used in gaps and stubs.  The gap is between these 2 pads
    // the stub is the pad 2
    wxString Line;
    int pad_num = 1;

    while( aPadCount-- )
    {
        D_PAD* pad = new D_PAD( module );

        module->Pads().PushFront( pad );

        int tw = GetDesignSettings().GetCurrentTrackWidth();
        pad->SetSize( wxSize( tw, tw ) );

        pad->SetPosition( module->GetPosition() );
        pad->SetShape( PAD_SHAPE_RECT );
        pad->SetAttribute( PAD_ATTRIB_SMD );
        pad->SetLayerSet( F_Cu );

        Line.Printf( wxT( "%d" ), pad_num );
        pad->SetPadName( Line );
        pad_num++;
    }

    return module;
}
/* Exports the current pad settings to board design settings.
 */
void PCB_BASE_FRAME::Export_Pad_Settings( D_PAD* aPad )
{
    if( aPad == NULL )
        return;

    SetMsgPanel( aPad );

    D_PAD& mp = GetDesignSettings().m_Pad_Master;

    mp.SetShape( aPad->GetShape() );
    mp.SetAttribute( aPad->GetAttribute() );
    mp.SetLayerSet( aPad->GetLayerSet() );

    mp.SetOrientation( aPad->GetOrientation() - aPad->GetParent()->GetOrientation() );

    mp.SetSize( aPad->GetSize() );
    mp.SetDelta( aPad->GetDelta() );

    mp.SetOffset( aPad->GetOffset() );
    mp.SetDrillSize( aPad->GetDrillSize() );
    mp.SetDrillShape( aPad->GetDrillShape() );
}
/*
 * FOOTPRINT_EDIT_FRAME::Function DlgGlobalChange_PadSettings
 * Function to change pad caracteristics for the given footprint
 * or alls footprints which look like the given footprint
 * Options are set by the opened dialog.
 * aPad is the pattern. The given footprint is the parent of this pad
 */
void FOOTPRINT_EDIT_FRAME::DlgGlobalChange_PadSettings( D_PAD* aPad )
{
    int     diag;

    if( aPad == NULL )
        aPad = &GetDesignSettings().m_Pad_Master;

    MODULE* module = aPad->GetParent();

    if( module == NULL )
    {
        DisplayError( this, wxT( "Global_Import_Pad_Settings() Error: NULL module" ) );
        return;
    }

    SetMsgPanel( module );

    {
        DIALOG_GLOBAL_PADS_EDITION dlg( this, aPad );

        dlg.m_buttonIdModules->Enable( false );

        diag = dlg.ShowModal();
    }

    if( diag == -1 )
        return;

    bool edit_Same_Modules = false;
    if( diag == 1 )
        edit_Same_Modules = true;

    GlobalChange_PadSettings( aPad, edit_Same_Modules,
                              DIALOG_GLOBAL_PADS_EDITION::m_Pad_Shape_Filter,
                              DIALOG_GLOBAL_PADS_EDITION::m_Pad_Orient_Filter,
                              DIALOG_GLOBAL_PADS_EDITION::m_Pad_Layer_Filter,
                              true, false );
}
/* Add a new graphical text to the active module (footprint)
 *  Note there always are 2 mandatory texts: reference and value.
 *  New texts have the member TEXTE_MODULE.GetType() set to TEXT_is_DIVERS
 */
TEXTE_MODULE* FOOTPRINT_EDIT_FRAME::CreateTextModule( MODULE* aModule, wxDC* aDC )
{
    TEXTE_MODULE* text = new TEXTE_MODULE( aModule );

    text->SetFlags( IS_NEW );

    GetDesignSettings().m_ModuleTextWidth = Clamp_Text_PenSize( GetDesignSettings().m_ModuleTextWidth,
            std::min( GetDesignSettings().m_ModuleTextSize.x, GetDesignSettings().m_ModuleTextSize.y ), true );
    text->SetTextSize( GetDesignSettings().m_ModuleTextSize );
    text->SetThickness( GetDesignSettings().m_ModuleTextWidth );
    text->SetPosition( GetCrossHairPosition() );

    if( LSET::AllTechMask().test( GetActiveLayer() ) )    // i.e. a possible layer for a text
        text->SetLayer( GetActiveLayer() );

    InstallTextModOptionsFrame( text, NULL );

    m_canvas->MoveCursorToCrossHair();

    if( text->GetText().IsEmpty() )
    {
        delete text;
        return NULL;
    }

    // Add the new text object to the beginning of the footprint draw list.
    if( aModule )
        aModule->GraphicalItems().PushFront( text );

    text->ClearFlags();

    if( aDC )
        text->Draw( m_canvas, aDC, GR_OR );

    SetMsgPanel( text );

    return text;
}
Exemplo n.º 27
0
void PCB_EDIT_FRAME::updateTraceWidthSelectBox()
{
    if( m_SelTrackWidthBox == NULL )
        return;

    wxString msg;
    bool mmFirst = g_UserUnit != INCHES;

    m_SelTrackWidthBox->Clear();

    for( unsigned ii = 0; ii < GetDesignSettings().m_TrackWidthList.size(); ii++ )
    {
        int size = GetDesignSettings().m_TrackWidthList[ii];

        double valueMils = To_User_Unit( INCHES, size ) * 1000;
        double value_mm = To_User_Unit( MILLIMETRES, size );

        if( mmFirst )
            msg.Printf( _( "Track: %.3f mm (%.2f mils)" ),
                        value_mm, valueMils );
        else
            msg.Printf( _( "Track: %.2f mils (%.3f mm)" ),
                        valueMils, value_mm );

        // Mark the netclass track width value (the first in list)
        if( ii == 0 )
            msg << wxT( " *" );

        m_SelTrackWidthBox->Append( msg );
    }

    if( GetDesignSettings().GetTrackWidthIndex() >= GetDesignSettings().m_TrackWidthList.size() )
        GetDesignSettings().SetTrackWidthIndex( 0 );

    m_SelTrackWidthBox->SetSelection( GetDesignSettings().GetTrackWidthIndex() );
}
void PCB_BASE_FRAME::ResetModuleTextSizes( const wxString & aFilter, bool aRef,
                                           bool aValue, bool aOthers )
{
    BOARD_COMMIT commit( this );

    int modTextWidth = GetDesignSettings().m_ModuleTextWidth;
    const wxSize& modTextSize = GetDesignSettings().m_ModuleTextSize;
    bool modified = false;

    // Change fields of footprints with fpid matching the filter
    for( MODULE* module = GetBoard()->m_Modules; module; module = module->Next() )
    {
        if( !aFilter.IsEmpty() )
        {
            if( ! WildCompareString( aFilter, FROM_UTF8( module->GetFPID().Format().c_str() ),
                                     false ) )
                continue;
        }


        if( aRef )
        {
            TEXTE_MODULE* item = &module->Reference();

            if( item->GetTextSize() != GetDesignSettings().m_ModuleTextSize ||
                item->GetThickness() != GetDesignSettings().m_ModuleTextWidth )
            {
                commit.Modify( item );
                item->SetThickness( modTextWidth );
                item->SetTextSize( modTextSize );
                modified = true;
            }
        }

        if( aValue )
        {
            TEXTE_MODULE* item = &module->Value();

            if( item->GetTextSize() != GetDesignSettings().m_ModuleTextSize ||
                item->GetThickness() != GetDesignSettings().m_ModuleTextWidth )
            {
                commit.Modify( item );
                item->SetThickness( modTextWidth );
                item->SetTextSize( modTextSize );
                modified = true;
            }
        }

        if( aOthers )
        {
            // Go through all other module text fields
            for( BOARD_ITEM* boardItem = module->GraphicalItemsList(); boardItem; boardItem = boardItem->Next() )
            {
                if( boardItem->Type() == PCB_MODULE_TEXT_T )
                {
                    TEXTE_MODULE* item = static_cast<TEXTE_MODULE*>( boardItem );

                    if( item->GetTextSize() != GetDesignSettings().m_ModuleTextSize
                        || item->GetThickness() != GetDesignSettings().m_ModuleTextWidth )
                    {
                        commit.Modify( item );
                        item->SetThickness( modTextWidth );
                        item->SetTextSize( modTextSize );
                        modified = true;
                    }
                }
            }
        }
    }

    if( modified )
    {
        commit.Push( "Reset module text size" );
        GetCanvas()->Refresh();
    }
}
Exemplo n.º 29
0
bool PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosition,
                               EDA_ITEM* aItem )
{
    if( aHotkeyCode == 0 )
        return false;

    bool itemCurrentlyEdited = GetCurItem() && GetCurItem()->GetFlags();
    MODULE* module = NULL;
    int evt_type = 0;       //Used to post a wxCommandEvent on demand
    PCB_SCREEN* screen = GetScreen();
    auto displ_opts = (PCB_DISPLAY_OPTIONS*)GetDisplayOptions();

    /* Convert lower to upper case
     * (the usual toupper function has problem with non ascii codes like function keys
     */
    if( (aHotkeyCode >= 'a') && (aHotkeyCode <= 'z') )
        aHotkeyCode += 'A' - 'a';

    EDA_HOTKEY* HK_Descr = GetDescriptorFromHotkey( aHotkeyCode, common_Hotkey_List );

    if( HK_Descr == NULL )
        HK_Descr = GetDescriptorFromHotkey( aHotkeyCode, board_edit_Hotkey_List );

    if( HK_Descr == NULL )
        return false;

    int hk_id = HK_Descr->m_Idcommand;

    // Create a wxCommandEvent that will be posted in some hot keys functions
    wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
    cmd.SetEventObject( this );

    LAYER_NUM  ll;

    switch( hk_id )
    {
    default:
    case HK_NOT_FOUND:
        return false;

    case HK_LEFT_CLICK:
        OnLeftClick( aDC, aPosition );
        break;

    case HK_LEFT_DCLICK:    // Simulate a double left click: generate 2 events
        OnLeftClick( aDC, aPosition );
        OnLeftDClick( aDC, aPosition );
        break;

    case HK_SWITCH_TRACK_WIDTH_TO_NEXT:
        if( GetCanvas()->IsMouseCaptured() )
            GetCanvas()->CallMouseCapture( aDC, wxDefaultPosition, false );

        if( GetDesignSettings().GetTrackWidthIndex() < GetDesignSettings().m_TrackWidthList.size() - 1 )
            GetDesignSettings().SetTrackWidthIndex( GetDesignSettings().GetTrackWidthIndex() + 1 );
        else
            GetDesignSettings().SetTrackWidthIndex( 0 );

        if( GetCanvas()->IsMouseCaptured() )
            GetCanvas()->CallMouseCapture( aDC, wxDefaultPosition, false );

        break;

    case HK_SWITCH_TRACK_WIDTH_TO_PREVIOUS:
        if( GetCanvas()->IsMouseCaptured() )
            GetCanvas()->CallMouseCapture( aDC, wxDefaultPosition, false );

        if( GetDesignSettings().GetTrackWidthIndex() <= 0 )
            GetDesignSettings().SetTrackWidthIndex( GetDesignSettings().m_TrackWidthList.size() -1 );
        else
            GetDesignSettings().SetTrackWidthIndex( GetDesignSettings().GetTrackWidthIndex() - 1 );

        if( GetCanvas()->IsMouseCaptured() )
            GetCanvas()->CallMouseCapture( aDC, wxDefaultPosition, false );

        break;

    case HK_SWITCH_GRID_TO_FASTGRID1:
        SetFastGrid1();
        break;

    case HK_SWITCH_GRID_TO_FASTGRID2:
        SetFastGrid2();
        break;

    case HK_SWITCH_GRID_TO_NEXT:
        evt_type = ID_POPUP_GRID_NEXT;
        break;

    case HK_SWITCH_GRID_TO_PREVIOUS:
        evt_type = ID_POPUP_GRID_PREV;
        break;

    case HK_SWITCH_LAYER_TO_PREVIOUS:
        ll = GetActiveLayer();

        if( !IsCopperLayer( ll ) )
            break;

        if( ll == F_Cu )
            ll = B_Cu;
        else if( ll == B_Cu )
            ll = ToLAYER_ID( GetBoard()->GetCopperLayerCount() - 2 );
        else
            ll = ll - 1;

        SwitchLayer( aDC, ToLAYER_ID( ll ) );
        break;

    case HK_SWITCH_LAYER_TO_NEXT:
        ll = GetActiveLayer();

        if( !IsCopperLayer( ll ) )
            break;

        if( ll == B_Cu )
            ll = F_Cu;
        else if( ++ll >= GetBoard()->GetCopperLayerCount() - 1 )
            ll = B_Cu;

        SwitchLayer( aDC, ToLAYER_ID( ll ) );
        break;

    case HK_SWITCH_LAYER_TO_COMPONENT:
        SwitchLayer( aDC, F_Cu );
        break;

    case HK_SWITCH_LAYER_TO_COPPER:
        SwitchLayer( aDC, B_Cu );
        break;

    case HK_SWITCH_LAYER_TO_INNER1:
        SwitchLayer( aDC, In1_Cu );
        break;

    case HK_SWITCH_LAYER_TO_INNER2:
        SwitchLayer( aDC, In2_Cu );
        break;

    case HK_SWITCH_LAYER_TO_INNER3:
        SwitchLayer( aDC, In3_Cu );
        break;

    case HK_SWITCH_LAYER_TO_INNER4:
        SwitchLayer( aDC, In4_Cu );
        break;

    case HK_SWITCH_LAYER_TO_INNER5:
        SwitchLayer( aDC, In5_Cu );
        break;

    case HK_SWITCH_LAYER_TO_INNER6:
        SwitchLayer( aDC, In6_Cu );
        break;

    case HK_HELP: // Display Current hotkey list
        DisplayHotkeyList( this, g_Board_Editor_Hotkeys_Descr );
        break;

    case HK_PREFERENCES:
        evt_type = wxID_PREFERENCES;
        break;

    case HK_ZOOM_IN:
        evt_type = ID_KEY_ZOOM_IN;
        break;

    case HK_ZOOM_OUT:
        evt_type = ID_KEY_ZOOM_OUT;
        break;

    case HK_ZOOM_REDRAW:
        evt_type = ID_ZOOM_REDRAW;
        break;

    case HK_ZOOM_AUTO:
        evt_type = ID_ZOOM_PAGE;
        break;

    case HK_ZOOM_CENTER:
        evt_type = ID_POPUP_ZOOM_CENTER;
        break;

    case HK_ZOOM_SELECTION:
        evt_type = ID_ZOOM_SELECTION;
        break;

    case HK_ADD_MODULE:
        evt_type = ID_PCB_MODULE_BUTT;
        break;

    case HK_UNDO:
    case HK_REDO:
        if( !itemCurrentlyEdited )
        {
            wxCommandEvent event( wxEVT_COMMAND_TOOL_CLICKED, HK_Descr->m_IdMenuEvent );
            wxPostEvent( this, event );
        }

        break;

    case HK_RESET_LOCAL_COORD:  // Set the relative coord
        GetScreen()->m_O_Curseur = GetCrossHairPosition();
        break;

    case HK_SET_GRID_ORIGIN:
        PCBNEW_CONTROL::SetGridOrigin( GetGalCanvas()->GetView(), this,
                                       new KIGFX::ORIGIN_VIEWITEM( GetGridOrigin(), UR_TRANSIENT ),
                                       GetCrossHairPosition() );
        m_canvas->Refresh();
        break;

    case HK_RESET_GRID_ORIGIN:
        PCBNEW_CONTROL::SetGridOrigin( GetGalCanvas()->GetView(), this,
                                       new KIGFX::ORIGIN_VIEWITEM( GetGridOrigin(), UR_TRANSIENT ),
                                       wxPoint( 0, 0 ) );
        m_canvas->Refresh();
        break;

    case HK_SWITCH_UNITS:
        evt_type = (GetUserUnits() == INCHES) ?
                    ID_TB_OPTIONS_SELECT_UNIT_MM : ID_TB_OPTIONS_SELECT_UNIT_INCH;
        break;

    case HK_SWITCH_TRACK_DISPLAY_MODE:
        displ_opts->m_DisplayPcbTrackFill = !displ_opts->m_DisplayPcbTrackFill;
        m_canvas->Refresh();
        break;

    case HK_DELETE:
        OnHotkeyDeleteItem( aDC );
        break;

    case HK_BACK_SPACE:
        if( IsCopperLayer( GetActiveLayer() ) )
        {
            if( !itemCurrentlyEdited )
            {
                // no track is currently being edited - select a segment and remove it.
                // @todo: possibly? pass the HK command code to PcbGeneralLocateAndDisplay()
                // so it can restrict its search to specific item types.
                BOARD_ITEM * item = PcbGeneralLocateAndDisplay();

                // don't let backspace delete modules!!
                if( item && item->IsTrack() )
                {
                    Delete_Segment( aDC, (TRACK*) item );
                    SetCurItem( NULL );
                }

                OnModify();
            }
            else if( GetCurItem()->IsTrack() )
            {
                // then an element is being edited - remove the last segment.
                // simple lines for debugger:
                TRACK* track = (TRACK*) GetCurItem();
                track = Delete_Segment( aDC, track );
                SetCurItem( track );
                OnModify();
            }
        }

        break;

    case HK_GET_AND_MOVE_FOOTPRINT:
        if( !itemCurrentlyEdited )
            evt_type = ID_POPUP_PCB_GET_AND_MOVE_MODULE_REQUEST;

        break;

    case HK_FIND_ITEM:
        if( !itemCurrentlyEdited )
            evt_type = ID_FIND_ITEMS;

        break;

    case HK_OPEN:
        if( !itemCurrentlyEdited )
            evt_type = ID_LOAD_FILE ;

        break;

    case HK_SAVE:
        if( !itemCurrentlyEdited )
            evt_type = ID_SAVE_BOARD;

        break;

    case HK_ADD_MICROVIA: // Place a micro via if a track is in progress
        if( GetToolId() != ID_TRACK_BUTT )
            return true;

        if( !itemCurrentlyEdited )                         // no track in progress: nothing to do
            break;

        if( GetCurItem()->Type() != PCB_TRACE_T )           // Should not occur
            return true;

        if( !GetCurItem()->IsNew() )
            return true;

        // place micro via and switch layer
        if( IsMicroViaAcceptable() )
            evt_type = ID_POPUP_PCB_PLACE_MICROVIA;

        break;

    case HK_ADD_BLIND_BURIED_VIA:
    case HK_ADD_THROUGH_VIA: // Switch to alternate layer and Place a via if a track is in progress
        if( GetBoard()->GetDesignSettings().m_BlindBuriedViaAllowed &&
            hk_id == HK_ADD_BLIND_BURIED_VIA  )
            GetBoard()->GetDesignSettings().m_CurrentViaType = VIA_BLIND_BURIED;
        else
            GetBoard()->GetDesignSettings().m_CurrentViaType = VIA_THROUGH;

        if( !itemCurrentlyEdited ) // no track in progress: switch layer only
        {
            Other_Layer_Route( NULL, aDC );
            if( displ_opts->m_ContrastModeDisplay )
                m_canvas->Refresh();
            break;
        }

        if( GetToolId() != ID_TRACK_BUTT )
            return true;

        if( GetCurItem()->Type() != PCB_TRACE_T )
            return true;

        if( !GetCurItem()->IsNew() )
            return true;

        evt_type = hk_id == HK_ADD_BLIND_BURIED_VIA ?
            ID_POPUP_PCB_PLACE_BLIND_BURIED_VIA : ID_POPUP_PCB_PLACE_THROUGH_VIA;
        break;

    case HK_SEL_LAYER_AND_ADD_THROUGH_VIA:
    case HK_SEL_LAYER_AND_ADD_BLIND_BURIED_VIA:
        if( GetCurItem() == NULL || !GetCurItem()->IsNew() ||
            GetCurItem()->Type() != PCB_TRACE_T )
            break;

        evt_type = hk_id == HK_SEL_LAYER_AND_ADD_BLIND_BURIED_VIA ?
            ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_BLIND_BURIED_VIA :
            ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_THROUGH_VIA;
        break;

    case HK_SWITCH_TRACK_POSTURE:
        /* change the position of initial segment when creating new tracks
         * switch from _/  to -\ .
         */
        evt_type = ID_POPUP_PCB_SWITCH_TRACK_POSTURE ;
        break;

    case HK_DRAG_TRACK_KEEP_SLOPE:
        OnHotkeyMoveItem( HK_DRAG_TRACK_KEEP_SLOPE );
        break;

    case HK_PLACE_ITEM:
        OnHotkeyPlaceItem( aDC );
        break;

    case HK_ADD_NEW_TRACK: // Start new track, if possible
        OnHotkeyBeginRoute( aDC );
        break;

    case HK_EDIT_ITEM:      // Edit board item
        OnHotkeyEditItem( HK_EDIT_ITEM );
        break;

    case HK_EDIT_MODULE_WITH_MODEDIT:      // Edit module with module editor
        OnHotkeyEditItem( HK_EDIT_MODULE_WITH_MODEDIT );
        break;

    case HK_LOCK_UNLOCK_FOOTPRINT: // toggle module "MODULE_is_LOCKED" status:
        // get any module, locked or not locked and toggle its locked status
        if( !itemCurrentlyEdited )
        {
            wxPoint pos = RefPos( true );
            module = GetBoard()->GetFootprint( pos, screen->m_Active_Layer, true );
        }
        else if( GetCurItem()->Type() == PCB_MODULE_T )
        {
            module = (MODULE*) GetCurItem();
        }

        if( module )
        {
            SetCurItem( module );
            module->SetLocked( !module->IsLocked() );
            OnModify();
            SetMsgPanel( module );
        }
        break;

    case HK_DRAG_ITEM:    // Start drag module or track segment
        OnHotkeyMoveItem( HK_DRAG_ITEM );
        break;

    case HK_MOVE_ITEM:                  // Start move item
        OnHotkeyMoveItem( HK_MOVE_ITEM );
        break;

    case HK_COPY_ITEM:
        evt_type = OnHotkeyCopyItem();
        break;

    case HK_ROTATE_ITEM:        // Rotation
        OnHotkeyRotateItem( HK_ROTATE_ITEM );
        break;

    case HK_FLIP_ITEM:
        OnHotkeyFlipItem( HK_FLIP_ITEM );
        break;

    case HK_MOVE_ITEM_EXACT:
    case HK_DUPLICATE_ITEM:
    case HK_DUPLICATE_ITEM_AND_INCREMENT:
    case HK_CREATE_ARRAY:
        OnHotkeyDuplicateOrArrayItem( HK_Descr->m_Idcommand );
        break;

    case HK_SWITCH_HIGHCONTRAST_MODE: // switch to high contrast mode and refresh the canvas
        displ_opts->m_ContrastModeDisplay = !displ_opts->m_ContrastModeDisplay;
        m_canvas->Refresh();
        break;

    case HK_CANVAS_CAIRO:
        evt_type = ID_MENU_CANVAS_CAIRO;
        break;

    case HK_CANVAS_OPENGL:
        evt_type = ID_MENU_CANVAS_OPENGL;
        break;

    case HK_CANVAS_LEGACY:
        evt_type = ID_MENU_CANVAS_LEGACY;
        break;

    case HK_ZONE_FILL_OR_REFILL:
        evt_type = ID_POPUP_PCB_FILL_ALL_ZONES;
        break;

    case HK_ZONE_REMOVE_FILLED:
        evt_type = ID_POPUP_PCB_REMOVE_FILLED_AREAS_IN_ALL_ZONES;
        break;
    }

    if( evt_type != 0 )
    {
        wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED );
        evt.SetEventObject( this );
        evt.SetId( evt_type );
        GetEventHandler()->ProcessEvent( evt );
    }

    return true;
}
/**
 * Function SetTrackSegmentWidth
 *  Modify one track segment width or one via diameter and drill (using DRC control).
 *  Basic routine used by other routines when editing tracks or vias
 * @param aTrackItem = the track segment or via to modify
 * @param aItemsListPicker = the list picker to use for an undo command (can be NULL)
 * @param aUseNetclassValue = true to use NetClass value, false to use BOARD::m_designSettings value
 * @return  true if done, false if no not change (because DRC error)
 */
bool PCB_EDIT_FRAME::SetTrackSegmentWidth( TRACK*             aTrackItem,
                                           PICKED_ITEMS_LIST* aItemsListPicker,
                                           bool               aUseNetclassValue )
{
    int           initial_width, new_width;
    int           initial_drill = -1,new_drill = -1;
    bool          change_ok = false;
    NETINFO_ITEM* net = NULL;

    if( aUseNetclassValue )
        net = aTrackItem->GetNet();

    initial_width = aTrackItem->GetWidth();

    if( net )
        new_width = net->GetTrackWidth();
    else
        new_width = GetDesignSettings().GetCurrentTrackWidth();

    if( aTrackItem->Type() == PCB_VIA_T )
    {
        const VIA *via = static_cast<const VIA *>( aTrackItem );

        if( !via->IsDrillDefault() )
            initial_drill = via->GetDrillValue();

        if( net )
        {
            new_width = net->GetViaSize();
        }
        else
        {
            new_width = GetDesignSettings().GetCurrentViaSize();
            new_drill = GetDesignSettings().GetCurrentViaDrill();
        }

        if( via->GetViaType() == VIA_MICROVIA )
        {
            if( net )
                new_width = net->GetMicroViaSize();
            else
                new_width = GetDesignSettings().GetCurrentMicroViaSize();
        }
    }

    aTrackItem->SetWidth( new_width );

    // make a DRC test because the new size is bigger than the old size
    if( initial_width < new_width )
    {
        int diagdrc = OK_DRC;

        if( g_Drc_On )
            diagdrc = m_drc->Drc( aTrackItem, GetBoard()->m_Track );

        if( diagdrc == OK_DRC )
            change_ok = true;
    }
    else if( initial_width > new_width )
    {
        change_ok = true;
    }
    else if( (aTrackItem->Type() == PCB_VIA_T) && (initial_drill != new_drill) )
    {
        // if new width == initial_width: do nothing, unless a via has its drill value changed
        change_ok = true;
    }

    if( change_ok )
    {
        OnModify();

        if( aItemsListPicker )
        {
            aTrackItem->SetWidth( initial_width );
            ITEM_PICKER picker( aTrackItem, UR_CHANGED );
            picker.SetLink( aTrackItem->Clone() );
            aItemsListPicker->PushItem( picker );
            aTrackItem->SetWidth( new_width );

            if( aTrackItem->Type() == PCB_VIA_T )
            {
                // Set new drill value. Note: currently microvias have only a default drill value
                VIA *via = static_cast<VIA *>( aTrackItem );
                if( new_drill > 0 )
                    via->SetDrill( new_drill );
                else
                    via->SetDrillDefault();
            }
        }
    }
    else
    {
        aTrackItem->SetWidth( initial_width );
    }

    return change_ok;
}