int PCB_EDIT_FRAME::SetTrackSegmentWidth( TRACK*             aTrackItem,
                                          PICKED_ITEMS_LIST* aItemsListPicker,
                                          bool               aUseNetclassValue )
{
    int           return_code = TRACK_ACTION_NONE;
    int           initial_width;
    int           new_width;
    int           initial_drill = -1;
    int           new_drill = -1;
    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 );

        // Micro vias have a size only defined in their netclass
        // (no specific values defined by a table of specific value)
        // Ensure the netclass is accessible:
        if( via->GetViaType() == VIA_MICROVIA && net == NULL )
            net = aTrackItem->GetNet();

        // Get the draill value, regardless it is default or specific
        initial_drill = via->GetDrillValue();

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

        if( via->GetViaType() == VIA_MICROVIA )
        {
            if( net )
            {
                new_width = net->GetMicroViaSize();
                new_drill = net->GetMicroViaDrillSize();
            }
            else
            {
                // Should not occur
            }
        }

        // Old versions set a drill value <= 0, when the default netclass it used
        // but it could be better to set the drill value to the actual value
        // to avoid issues for existing vias, if the default drill value is modified
        // in the netclass, and not in current vias.
        if( via->GetDrill() <= 0 )      // means default netclass drill value used
        {
            initial_drill  = -1;        // Force drill vias re-initialization
        }
    }

    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;
        return_code = TRACK_ACTION_SUCCESS;

        if( Settings().m_legacyDrcOn )
            diagdrc = m_drc->DrcOnCreatingTrack( aTrackItem, GetBoard()->m_Track );

        if( diagdrc != OK_DRC )
            return_code = TRACK_ACTION_DRC_ERROR;
    }
    else if( initial_width > new_width )
    {
        return_code = TRACK_ACTION_SUCCESS;
    }
    else if( (aTrackItem->Type() == PCB_VIA_T) )
    {
        // if a via has its drill value changed, force change
        if( initial_drill != new_drill )
            return_code = TRACK_ACTION_SUCCESS;
    }

    if( return_code == TRACK_ACTION_SUCCESS )
    {
        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 return_code;
}
/**
 * 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;
}
bool PCB_EDIT_FRAME::SetTrackSegmentWidth( TRACK*             aTrackItem,
                                           PICKED_ITEMS_LIST* aItemsListPicker,
                                           bool               aUseNetclassValue )
{
    /* Modify one track segment width or one via diameter and drill (using DRC control).
     * Basic function used by other routines when editing tracks or vias
     * aTrackItem = the track segment or via to modify
     * aItemsListPicker = the list picker to use for an undo command (can be NULL)
     * aUseNetclassValue = true to use NetClass value, false to use BOARD::m_designSettings value
     * return  true if done, false if no not change (due to DRC error)
     */
    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 );

        // Micro vias have a size only defined in their netclass
        // (no specific values defined by a table of specific value)
        // Ensure the netclass is accessible:
        if( via->GetViaType() == VIA_MICROVIA && net == NULL )
            net = aTrackItem->GetNet();

        // Get the draill value, regardless it is default or specific
        initial_drill = via->GetDrillValue();

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

        if( via->GetViaType() == VIA_MICROVIA )
        {
            if( net )
            {
                new_width = net->GetMicroViaSize();
                new_drill = net->GetMicroViaDrillSize();
            }
            else
            {
                // Should not occur
            }
        }

        // Old versions set a drill value <= 0, when the default netclass it used
        // but it could be better to set the drill value to the actual value
        // to avoid issues for existing vias, if the default drill value is modified
        // in the netclass, and not in current vias.
        if( via->GetDrill() <= 0 )      // means default netclass drill value used
        {
            initial_drill  = -1;        // Force drill vias re-initialization
        }
    }

    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) )
    {
        // if a via has its drill value changed, force change
        if( initial_drill != new_drill )
            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;
}