/* accept DRC parameters (min clearance value and min sizes
*/
void DIALOG_DRC_CONTROL::SetDrcParmeters( )
{
    m_BrdSettings.m_TrackMinWidth = ValueFromTextCtrl( *m_SetTrackMinWidthCtrl );
    m_BrdSettings.m_ViasMinSize = ValueFromTextCtrl( *m_SetViaMinSizeCtrl );
    m_BrdSettings.m_MicroViasMinSize = ValueFromTextCtrl( *m_SetMicroViakMinSizeCtrl );

    m_brdEditor->GetBoard()->SetDesignSettings( m_BrdSettings );
}
Exemplo n.º 2
0
wxPoint DIALOG_SET_GRID::getGridOrigin()
{
    wxPoint grid;

    // @todo Some error checking here would be a good thing.
    grid.x = ValueFromTextCtrl( *m_GridOriginXCtrl );
    grid.y = ValueFromTextCtrl( *m_GridOriginYCtrl );

    return grid;
}
Exemplo n.º 3
0
void DIALOG_DESIGN_RULES::CopyGlobalRulesToBoard()
{
    m_BrdSettings->m_BlindBuriedViaAllowed = m_OptViaType->GetSelection() > 0;

    // Update vias minimum values for DRC
    m_BrdSettings->m_ViasMinSize = ValueFromTextCtrl( *m_SetViasMinSizeCtrl );
    m_BrdSettings->m_ViasMinDrill = ValueFromTextCtrl( *m_SetViasMinDrillCtrl );

    m_BrdSettings->m_MicroViasAllowed = m_AllowMicroViaCtrl->GetSelection() == 1;

    // Update microvias minimum values for DRC
    m_BrdSettings->m_MicroViasMinSize = ValueFromTextCtrl( *m_SetMicroViasMinSizeCtrl );
    m_BrdSettings->m_MicroViasMinDrill = ValueFromTextCtrl( *m_SetMicroViasMinDrillCtrl );

    // Update tracks minimum values for DRC
    m_BrdSettings->m_TrackMinWidth = ValueFromTextCtrl( *m_SetTrackMinWidthCtrl );
}
void DIALOG_PLOT_SCHEMATIC::SetHPGLPenWidth()
{
    m_HPGLPenSize = ValueFromTextCtrl( *m_penHPGLWidthCtrl );

    if( m_HPGLPenSize > Millimeter2iu( 2 ) )
        m_HPGLPenSize = Millimeter2iu( 2 );

    if( m_HPGLPenSize < Millimeter2iu( 0.01 ) )
        m_HPGLPenSize = Millimeter2iu( 0.01 );
}
bool DIALOG_MOVE_EXACT::GetTranslationInIU ( wxPoint& val, bool polar )
{
    if( polar )
    {
        const int r = ValueFromTextCtrl( *m_xEntry );
        const double q = DoubleValueFromString( DEGREES, m_yEntry->GetValue() );

        val.x = r * cos( DEG2RAD( q / 10.0 ) );
        val.y = r * sin( DEG2RAD( q / 10.0 ) );
    }
    else
    {
        // direct read
        val.x = ValueFromTextCtrl( *m_xEntry );
        val.y = ValueFromTextCtrl( *m_yEntry );
    }

    // no validation to do here, but in future, you could return false here
    return true;
}
bool DIALOG_GLOBAL_MODULES_FIELDS_EDITION::TransferDataFromWindow()
{
    m_refSelection = m_ReferenceOpt->GetValue();
    m_valueSelection = m_ValueOpt->GetValue();
    m_othersSelection = m_OtherFields->GetValue();
    m_filterString = m_ModuleFilter->GetValue();

    m_brdSettings->m_ModuleTextSize.x = ValueFromTextCtrl( *m_SizeX_Value );
    m_brdSettings->m_ModuleTextSize.y = ValueFromTextCtrl( *m_SizeY_Value );
    m_brdSettings->m_ModuleTextWidth = ValueFromTextCtrl( *m_ThicknessValue );

    // clip m_ModuleTextWidth to the 1/4 of min size, to keep it always readable
    int max_thickness = std::min( m_brdSettings->m_ModuleTextSize.x,
                            m_brdSettings->m_ModuleTextSize.y ) / 4;
    if( m_brdSettings->m_ModuleTextWidth > max_thickness )
        m_brdSettings->m_ModuleTextWidth = max_thickness;

    m_parent->ResetModuleTextSizes( m_filterString, m_refSelection,
                                    m_valueSelection, m_othersSelection );
    return true;
}
void DIALOG_GLOBAL_MODULES_FIELDS_EDITION::OnOKClick( wxCommandEvent& event )
{
    m_refSelection = m_ReferenceOpt->GetValue();
    m_valueSelection = m_ValueOpt->GetValue();
    m_othersSelection = m_OtherFields->GetValue();
    m_filterString = m_ModuleFilter->GetValue();

    m_brdSettings->m_ModuleTextSize.x = ValueFromTextCtrl( *m_SizeX_Value );
    m_brdSettings->m_ModuleTextSize.y = ValueFromTextCtrl( *m_SizeY_Value );
    m_brdSettings->m_ModuleTextWidth = ValueFromTextCtrl( *m_TicknessValue );

    // clip m_ModuleTextWidth to the 1/4 of min size, to keep it always readable
    int minsize = std::min( m_brdSettings->m_ModuleTextSize.x,
                            m_brdSettings->m_ModuleTextSize.y ) / 4;
    if( m_brdSettings->m_ModuleTextWidth > minsize )
        m_brdSettings->m_ModuleTextWidth = minsize;

    m_parent->ResetModuleTextSizes( m_filterString, m_refSelection,
                                    m_valueSelection, m_othersSelection );
    EndModal( wxID_OK );
}
void DIALOG_PRINT_USING_PRINTER::SetPenWidth()
{
    // Get the new pen width value, and verify min et max value
    // NOTE: s_Parameters.m_PenDefaultSize is in internal units

    s_Parameters.m_PenDefaultSize = ValueFromTextCtrl( *m_DialogPenWidth );

    if( s_Parameters.m_PenDefaultSize > PEN_WIDTH_MAX_VALUE )
    {
        s_Parameters.m_PenDefaultSize = PEN_WIDTH_MAX_VALUE;
    }

    if( s_Parameters.m_PenDefaultSize < PEN_WIDTH_MIN_VALUE )
    {
        s_Parameters.m_PenDefaultSize = PEN_WIDTH_MIN_VALUE;
    }

    g_DrawDefaultLineThickness = s_Parameters.m_PenDefaultSize;

    m_DialogPenWidth->SetValue(
        StringFromValue( g_UserUnit, s_Parameters.m_PenDefaultSize ) );
}
void DIALOG_PLOT_SCHEMATIC::getPlotOptions()
{
    m_config->Write( PLOT_MODECOLOR_KEY, getModeColor() );
    m_config->Write( PLOT_FRAME_REFERENCE_KEY, getPlotFrameRef() );
    m_config->Write( PLOT_FORMAT_KEY, (long) GetPlotFileFormat() );
    m_config->Write( PLOT_HPGL_ORIGIN_KEY, GetPlotOriginCenter() );
    m_HPGLPaperSizeSelect = m_HPGLPaperSizeOption->GetSelection();
    m_config->Write( PLOT_HPGL_PAPERSIZE_KEY, m_HPGLPaperSizeSelect );
    // HPGL Pen Size is stored in mm in config
    m_config->Write( PLOT_HPGL_PEN_SIZE_KEY, m_HPGLPenSize/IU_PER_MM );

    m_pageSizeSelect    = m_PaperSizeOption->GetSelection();
    SetDefaultLineThickness( ValueFromTextCtrl( *m_DefaultLineSizeCtrl ) );

    // Plot directory
    wxString path = m_outputDirectoryName->GetValue();
    path.Replace( '\\', '/' );

    if(  m_parent->GetPlotDirectoryName() != path )
        m_configChanged = true;

    m_parent->SetPlotDirectoryName( path );

}
bool DIALOG_PAD_PROPERTIES::transferDataToPad( D_PAD* aPad )
{
    wxString    msg;
    int         x, y;

    if( !Validate() )
        return true;
    if( !m_panelGeneral->Validate() )
        return true;
    if( !m_localSettingsPanel->Validate() )
        return true;

    m_OrientValidator.TransferFromWindow();

    aPad->SetAttribute( code_type[m_PadType->GetSelection()] );
    aPad->SetShape( code_shape[m_PadShape->GetSelection()] );


    // Read pad clearances values:
    aPad->SetLocalClearance( ValueFromTextCtrl( *m_NetClearanceValueCtrl ) );
    aPad->SetLocalSolderMaskMargin( ValueFromTextCtrl( *m_SolderMaskMarginCtrl ) );
    aPad->SetLocalSolderPasteMargin( ValueFromTextCtrl( *m_SolderPasteMarginCtrl ) );
    aPad->SetThermalWidth( ValueFromTextCtrl( *m_ThermalWidthCtrl ) );
    aPad->SetThermalGap( ValueFromTextCtrl( *m_ThermalGapCtrl ) );
    double dtmp = 0.0;
    msg = m_SolderPasteMarginRatioCtrl->GetValue();
    msg.ToDouble( &dtmp );

    // A -50% margin ratio means no paste on a pad, the ratio must be >= -50%
    if( dtmp < -50.0 )
        dtmp = -50.0;
    // A margin ratio is always <= 0
    // 0 means use full pad copper area
    if( dtmp > 0.0 )
        dtmp = 0.0;

    aPad->SetLocalSolderPasteMarginRatio( dtmp / 100 );

    switch( m_ZoneConnectionChoice->GetSelection() )
    {
    default:
    case 0:
        aPad->SetZoneConnection( PAD_ZONE_CONN_INHERITED );
        break;

    case 1:
        aPad->SetZoneConnection( PAD_ZONE_CONN_FULL );
        break;

    case 2:
        aPad->SetZoneConnection( PAD_ZONE_CONN_THERMAL );
        break;

    case 3:
        aPad->SetZoneConnection( PAD_ZONE_CONN_NONE );
        break;
    }

    // Read pad position:
    x = ValueFromTextCtrl( *m_PadPosition_X_Ctrl );
    y = ValueFromTextCtrl( *m_PadPosition_Y_Ctrl );

    aPad->SetPosition( wxPoint( x, y ) );
    aPad->SetPos0( wxPoint( x, y ) );

    // Read pad drill:
    x = ValueFromTextCtrl( *m_PadDrill_X_Ctrl );
    y = ValueFromTextCtrl( *m_PadDrill_Y_Ctrl );

    if( m_DrillShapeCtrl->GetSelection() == 0 )
    {
        aPad->SetDrillShape( PAD_DRILL_SHAPE_CIRCLE );
        y = x;
    }
    else
        aPad->SetDrillShape( PAD_DRILL_SHAPE_OBLONG );

    aPad->SetDrillSize( wxSize( x, y ) );

    // Read pad shape size:
    x = ValueFromTextCtrl( *m_ShapeSize_X_Ctrl );
    y = ValueFromTextCtrl( *m_ShapeSize_Y_Ctrl );

    if( aPad->GetShape() == PAD_SHAPE_CIRCLE )
        y = x;

    aPad->SetSize( wxSize( x, y ) );

    // Read pad length die
    aPad->SetPadToDieLength( ValueFromTextCtrl( *m_LengthPadToDieCtrl ) );

    // For a trapezoid, test delta value (be sure delta is not too large for pad size)
    // remember DeltaSize.x is the Y size variation
    bool   error    = false;

    if( aPad->GetShape() == PAD_SHAPE_TRAPEZOID )
    {
        wxSize delta;

        // For a trapezoid, only one of delta.x or delta.y is not 0, depending on
        // the direction.
        if( m_trapDeltaDirChoice->GetSelection() == 0 )
            delta.x = ValueFromTextCtrl( *m_ShapeDelta_Ctrl );
        else
            delta.y = ValueFromTextCtrl( *m_ShapeDelta_Ctrl );

        if( delta.x < 0 && delta.x <= -aPad->GetSize().y )
        {
            delta.x = -aPad->GetSize().y + 2;
            error = true;
        }

        if( delta.x > 0 && delta.x >= aPad->GetSize().y )
        {
            delta.x = aPad->GetSize().y - 2;
            error = true;
        }

        if( delta.y < 0 && delta.y <= -aPad->GetSize().x )
        {
            delta.y = -aPad->GetSize().x + 2;
            error = true;
        }

        if( delta.y > 0 && delta.y >= aPad->GetSize().x )
        {
            delta.y = aPad->GetSize().x - 2;
            error = true;
        }

        aPad->SetDelta( delta );
    }

    // Read pad shape offset:
    x = ValueFromTextCtrl( *m_ShapeOffset_X_Ctrl );
    y = ValueFromTextCtrl( *m_ShapeOffset_Y_Ctrl );
    aPad->SetOffset( wxPoint( x, y ) );

    aPad->SetOrientation( m_OrientValue * 10.0 );

    msg = m_PadNumCtrl->GetValue().Left( 4 );
    aPad->SetPadName( msg );

    // Check if user has set an existing net name
    const NETINFO_ITEM* netinfo = m_board->FindNet( m_PadNetNameCtrl->GetValue() );

    if( netinfo != NULL )
        aPad->SetNetCode( netinfo->GetNet() );
    else
        aPad->SetNetCode( NETINFO_LIST::UNCONNECTED );

    // Clear some values, according to the pad type and shape
    switch( aPad->GetShape() )
    {
    case PAD_SHAPE_CIRCLE:
        aPad->SetOffset( wxPoint( 0, 0 ) );
        aPad->SetDelta( wxSize( 0, 0 ) );
        x = aPad->GetSize().x;
        aPad->SetSize( wxSize( x, x ) );
        break;

    case PAD_SHAPE_RECT:
        aPad->SetDelta( wxSize( 0, 0 ) );
        break;

    case PAD_SHAPE_OVAL:
        aPad->SetDelta( wxSize( 0, 0 ) );
        break;

    case PAD_SHAPE_TRAPEZOID:
        break;

    case PAD_SHAPE_ROUNDRECT:
        aPad->SetDelta( wxSize( 0, 0 ) );
        break;

    default:
        ;
    }

    switch( aPad->GetAttribute() )
    {
    case PAD_ATTRIB_STANDARD:
        break;

    case PAD_ATTRIB_CONN:
    case PAD_ATTRIB_SMD:
        // SMD and PAD_ATTRIB_CONN has no hole.
        // basically, SMD and PAD_ATTRIB_CONN are same type of pads
        // PAD_ATTRIB_CONN has just a default non technical layers that differs from SMD
        // and are intended to be used in virtual edge board connectors
        // However we can accept a non null offset,
        // mainly to allow complex pads build from a set of basic pad shapes
        aPad->SetDrillSize( wxSize( 0, 0 ) );
        break;

    case PAD_ATTRIB_HOLE_NOT_PLATED:
        // Mechanical purpose only:
        // no offset, no net name, no pad name allowed
        aPad->SetOffset( wxPoint( 0, 0 ) );
        aPad->SetPadName( wxEmptyString );
        aPad->SetNetCode( NETINFO_LIST::UNCONNECTED );
        break;

    default:
        DisplayError( NULL, wxT( "Error: unknown pad type" ) );
        break;
    }

    if( aPad->GetShape() == PAD_SHAPE_ROUNDRECT )
    {
        wxString value = m_tcCornerSizeRatio->GetValue();
        double rrRadiusRatioPercent;

        if( value.ToDouble( &rrRadiusRatioPercent ) )
            aPad->SetRoundRectRadiusRatio( rrRadiusRatioPercent / 100.0 );
    }

    LSET padLayerMask;

    switch( m_rbCopperLayersSel->GetSelection() )
    {
    case 0:
        padLayerMask.set( F_Cu );
        break;

    case 1:
        padLayerMask.set( B_Cu );
        break;

    case 2:
        padLayerMask |= LSET::AllCuMask();
        break;

    case 3:     // No copper layers
        break;
    }

    if( m_PadLayerAdhCmp->GetValue() )
        padLayerMask.set( F_Adhes );

    if( m_PadLayerAdhCu->GetValue() )
        padLayerMask.set( B_Adhes );

    if( m_PadLayerPateCmp->GetValue() )
        padLayerMask.set( F_Paste );

    if( m_PadLayerPateCu->GetValue() )
        padLayerMask.set( B_Paste );

    if( m_PadLayerSilkCmp->GetValue() )
        padLayerMask.set( F_SilkS );

    if( m_PadLayerSilkCu->GetValue() )
        padLayerMask.set( B_SilkS );

    if( m_PadLayerMaskCmp->GetValue() )
        padLayerMask.set( F_Mask );

    if( m_PadLayerMaskCu->GetValue() )
        padLayerMask.set( B_Mask );

    if( m_PadLayerECO1->GetValue() )
        padLayerMask.set( Eco1_User );

    if( m_PadLayerECO2->GetValue() )
        padLayerMask.set( Eco2_User );

    if( m_PadLayerDraft->GetValue() )
        padLayerMask.set( Dwgs_User );

    aPad->SetLayerSet( padLayerMask );

    return error;
}
void DIALOG_MODULE_BOARD_EDITOR::OnOkClick( wxCommandEvent& event )
{
    wxPoint  modpos;
    wxString msg;

    if( m_CurrentModule->GetFlags() == 0 )    // this is a simple edition, we
                                              // must create an undo entry
        m_Parent->SaveCopyInUndoList( m_CurrentModule, UR_CHANGED );

    if( m_DC )
    {
        m_Parent->GetCanvas()->CrossHairOff( m_DC );
        m_CurrentModule->Draw( m_Parent->GetCanvas(), m_DC, GR_XOR );
    }

    // Init Fields (should be first, because they can be moved or/and flipped later):
    m_CurrentModule->Reference().Copy( m_ReferenceCopy );
    m_CurrentModule->Value().Copy( m_ValueCopy );

    // Initialize masks clearances
    m_CurrentModule->SetLocalClearance( ValueFromTextCtrl( *m_NetClearanceValueCtrl ) );
    m_CurrentModule->SetLocalSolderMaskMargin( ValueFromTextCtrl( *m_SolderMaskMarginCtrl ) );
    m_CurrentModule->SetLocalSolderPasteMargin( ValueFromTextCtrl( *m_SolderPasteMarginCtrl ) );

    double dtmp = 0.0;
    msg = m_SolderPasteMarginRatioCtrl->GetValue();
    msg.ToDouble( &dtmp );

    // A -50% margin ratio means no paste on a pad, the ratio must be >= -50%
    if( dtmp < -50.0 )
        dtmp = -50.0;
    // A margin ratio is always <= 0
    // 0 means use full pad copper area
    if( dtmp > 0.0 )
        dtmp = 0.0;

    m_CurrentModule->SetLocalSolderPasteMarginRatio( dtmp / 100 );

    switch( m_ZoneConnectionChoice->GetSelection() )
    {
    default:
    case 0:
        m_CurrentModule->SetZoneConnection( UNDEFINED_CONNECTION );
        break;

    case 1:
        m_CurrentModule->SetZoneConnection( PAD_IN_ZONE );
        break;

    case 2:
        m_CurrentModule->SetZoneConnection( THERMAL_PAD );
        break;

    case 3:
        m_CurrentModule->SetZoneConnection( PAD_NOT_IN_ZONE );
        break;
    }

    // Set Module Position
    modpos.x = ValueFromTextCtrl( *m_ModPositionX );
    modpos.y = ValueFromTextCtrl( *m_ModPositionY );
    m_CurrentModule->SetPosition( modpos );
    m_CurrentModule->SetLocked( m_AutoPlaceCtrl->GetSelection() == 1 );

    switch( m_AttributsCtrl->GetSelection() )
    {
    case 0:
        m_CurrentModule->SetAttributes( 0 );
        break;

    case 1:
        m_CurrentModule->SetAttributes( MOD_CMS );
        break;

    case 2:
        m_CurrentModule->SetAttributes( MOD_VIRTUAL );
        break;
    }

    m_CurrentModule->SetPlacementCost90( m_CostRot90Ctrl->GetValue() );
    m_CurrentModule->SetPlacementCost180( m_CostRot180Ctrl->GetValue() );

    /* Now, set orientation. must be made after others changes,
     * because rotation changes fields positions on board according to the new orientation
     * (relative positions are not modified)
     */
    long orient = 0;
    msg = m_OrientValue->GetValue();
    msg.ToLong( &orient );

    if( m_CurrentModule->GetOrientation() != orient )
        m_CurrentModule->Rotate( m_CurrentModule->GetPosition(),
                                 orient - m_CurrentModule->GetOrientation() );

    // Set component side, that also have effect on the fields positions on board
    bool change_layer = false;
    if( m_LayerCtrl->GetSelection() == 0 )     // layer req = COMPONENT
    {
        if( m_CurrentModule->GetLayer() == LAYER_N_BACK )
            change_layer = true;
    }
    else if( m_CurrentModule->GetLayer() == LAYER_N_FRONT )
        change_layer = true;

    if( change_layer )
        m_CurrentModule->Flip( m_CurrentModule->GetPosition() );

    // Update 3D shape list
    int ii = m_3D_ShapeNameListBox->GetSelection();

    if( ii >= 0 )
        TransfertDisplayTo3DValues( ii  );

    S3D_MASTER* draw3D = m_CurrentModule->Models();

    for( unsigned ii = 0; ii < m_Shapes3D_list.size(); ii++ )
    {
        S3D_MASTER* draw3DCopy = m_Shapes3D_list[ii];

        if( draw3DCopy->GetShape3DName().IsEmpty() )
            continue;

        if( draw3D == NULL )
        {
            draw3D = new S3D_MASTER( draw3D );
            m_CurrentModule->Models().Append( draw3D );
        }

        draw3D->SetShape3DName( draw3DCopy->GetShape3DName() );
        draw3D->m_MatScale    = draw3DCopy->m_MatScale;
        draw3D->m_MatRotation = draw3DCopy->m_MatRotation;
        draw3D->m_MatPosition = draw3DCopy->m_MatPosition;

        draw3D = draw3D->Next();
    }

    // Remove old extra 3D shapes
    S3D_MASTER* nextdraw3D;

    for( ; draw3D != NULL; draw3D = nextdraw3D )
    {
        nextdraw3D = (S3D_MASTER*) draw3D->Next();
        delete m_CurrentModule->Models().Remove( draw3D );
    }

    // Fill shape list with one void entry, if no entry
    if( m_CurrentModule->Models() == NULL )
        m_CurrentModule->Models().PushBack( new S3D_MASTER( m_CurrentModule ) );


    m_CurrentModule->CalculateBoundingBox();

    m_Parent->OnModify();

    EndModal( 1 );

    if( m_DC )
    {
        m_CurrentModule->Draw( m_Parent->GetCanvas(), m_DC, GR_OR );
        m_Parent->GetCanvas()->CrossHairOn( m_DC );
    }
}
void DIALOG_MODULE_MODULE_EDITOR::OnOkClick( wxCommandEvent& event )
{
    // First, test for invalid chars in module name
    wxString footprintName = m_FootprintNameCtrl->GetValue();

    if( ! footprintName.IsEmpty() )
    {
        if( ! MODULE::IsLibNameValid( footprintName ) )
        {
            wxString msg;
            msg.Printf( _( "Error:\none of invalid chars <%s> found\nin <%s>" ),
                        MODULE::StringLibNameInvalidChars( true ),
                        GetChars( footprintName ) );

            DisplayError( NULL, msg );
                return;
        }
    }

    m_parent->SaveCopyInUndoList( m_currentModule, UR_MODEDIT );
    m_currentModule->SetLocked( m_AutoPlaceCtrl->GetSelection() == 1 );

    switch( m_AttributsCtrl->GetSelection() )
    {
    case 0:
        m_currentModule->SetAttributes( 0 );
        break;

    case 1:
        m_currentModule->SetAttributes( MOD_CMS );
        break;

    case 2:
        m_currentModule->SetAttributes( MOD_VIRTUAL );
        break;
    }

    m_currentModule->SetPlacementCost90( m_CostRot90Ctrl->GetValue() );
    m_currentModule->SetPlacementCost180( m_CostRot180Ctrl->GetValue() );
    m_currentModule->SetDescription( m_DocCtrl->GetValue() );
    m_currentModule->SetKeywords( m_KeywordCtrl->GetValue() );

    // Init footprint name in library
    if( ! footprintName.IsEmpty() )
        m_currentModule->SetFPID( FPID( footprintName ) );

    // Init Fields:
    m_currentModule->Reference().Copy( m_referenceCopy );
    m_currentModule->Value().Copy( m_valueCopy );

    // Initialize masks clearances
    m_currentModule->SetLocalClearance( ValueFromTextCtrl( *m_NetClearanceValueCtrl ) );
    m_currentModule->SetLocalSolderMaskMargin( ValueFromTextCtrl( *m_SolderMaskMarginCtrl ) );
    m_currentModule->SetLocalSolderPasteMargin( ValueFromTextCtrl( *m_SolderPasteMarginCtrl ) );
    double   dtmp;
    wxString msg = m_SolderPasteMarginRatioCtrl->GetValue();
    msg.ToDouble( &dtmp );

    // A  -50% margin ratio means no paste on a pad, the ratio must be >= -50 %
    if( dtmp < -50.0 )
        dtmp = -50.0;

    // A margin ratio is always <= 0
    if( dtmp > 0.0 )
        dtmp = 0.0;

    m_currentModule->SetLocalSolderPasteMarginRatio( dtmp / 100 );

    // Update 3D shape list
    int ii = m_3D_ShapeNameListBox->GetSelection();

    if ( ii >= 0 )
        TransfertDisplayTo3DValues( ii );

    S3D_MASTER*   draw3D  = m_currentModule->Models();

    for( unsigned ii = 0; ii < m_shapes3D_list.size(); ii++ )
    {
        S3D_MASTER*   draw3DCopy = m_shapes3D_list[ii];

        if( draw3DCopy->GetShape3DName().IsEmpty() )
            continue;

        if( draw3D == NULL )
        {
            draw3D = new S3D_MASTER( draw3D );
            m_currentModule->Models().Append( draw3D );
        }

        draw3D->SetShape3DName( draw3DCopy->GetShape3DName() );
        draw3D->m_MatScale    = draw3DCopy->m_MatScale;
        draw3D->m_MatRotation = draw3DCopy->m_MatRotation;
        draw3D->m_MatPosition = draw3DCopy->m_MatPosition;

        draw3D = draw3D->Next();
    }

    // Remove old extra 3D shapes
    S3D_MASTER* nextdraw3D;

    for( ; draw3D != NULL; draw3D = nextdraw3D )
    {
        nextdraw3D = (S3D_MASTER*) draw3D->Next();
        delete m_currentModule->Models().Remove( draw3D );
    }

    // Fill shape list with one void entry, if no entry
    if( m_currentModule->Models() == NULL )
        m_currentModule->Models().PushBack( new S3D_MASTER( m_currentModule ) );


    m_currentModule->CalculateBoundingBox();

    m_parent->OnModify();

    EndModal( 1 );
}
bool DIALOG_COPPER_ZONE::AcceptOptions( bool aPromptForErrors, bool aUseExportableSetupOnly )
{
    switch( m_PadInZoneOpt->GetSelection() )
    {
    case 3:
        // Pads are not covered
        m_settings.SetPadConnection( PAD_NOT_IN_ZONE );
        break;

    case 2:
        // Use thermal relief for THT pads
        m_settings.SetPadConnection( THT_THERMAL );
        break;

    case 1:
        // Use thermal relief for pads
        m_settings.SetPadConnection( THERMAL_PAD );
        break;

    case 0:
        // pads are covered by copper
        m_settings.SetPadConnection( PAD_IN_ZONE );
        break;
    }

    switch( m_OutlineAppearanceCtrl->GetSelection() )
    {
    case 0:
        m_settings.m_Zone_HatchingStyle = CPolyLine::NO_HATCH;
        break;

    case 1:
        m_settings.m_Zone_HatchingStyle = CPolyLine::DIAGONAL_EDGE;
        break;

    case 2:
        m_settings.m_Zone_HatchingStyle = CPolyLine::DIAGONAL_FULL;
        break;
    }

    m_settings.m_ArcToSegmentsCount = m_ArcApproximationOpt->GetSelection() == 1 ?
                                           ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF :
                                           ARC_APPROX_SEGMENTS_COUNT_LOW_DEF;

    if( m_Config )
    {
        m_Config->Write( ZONE_NET_OUTLINES_HATCH_OPTION_KEY,
                         (long) m_settings.m_Zone_HatchingStyle );
        wxString filter = m_DoNotShowNetNameFilter->GetValue();
        m_Config->Write( ZONE_NET_FILTER_STRING_KEY, filter );
    }

    m_netNameShowFilter = m_ShowNetNameFilter->GetValue();
    m_settings.m_FillMode = (m_FillModeCtrl->GetSelection() == 0) ? 0 : 1;

    wxString txtvalue = m_ZoneClearanceCtrl->GetValue();
    m_settings.m_ZoneClearance = ValueFromString( g_UserUnit, txtvalue );

    // Test if this is a reasonable value for this parameter
    // A too large value can hang Pcbnew
    #define CLEARANCE_MAX_VALUE ZONE_CLEARANCE_MAX_VALUE_MIL*IU_PER_MILS
    if( m_settings.m_ZoneClearance > CLEARANCE_MAX_VALUE )
    {
        wxString msg;
        msg.Printf( _( "Clearance must be smaller than %f\" / %f mm." ),
            ZONE_CLEARANCE_MAX_VALUE_MIL / 1000.0, ZONE_CLEARANCE_MAX_VALUE_MIL * 0.0254 );
        DisplayError( this, msg );
        return false;
    }

    txtvalue = m_ZoneMinThicknessCtrl->GetValue();
    m_settings.m_ZoneMinThickness = ValueFromString( g_UserUnit, txtvalue );

    if( m_settings.m_ZoneMinThickness < (ZONE_THICKNESS_MIN_VALUE_MIL*IU_PER_MILS) )
    {
        wxString msg;
        msg.Printf( _( "Minimum width must be larger than %f\" / %f mm." ),
            ZONE_THICKNESS_MIN_VALUE_MIL / 1000.0, ZONE_THICKNESS_MIN_VALUE_MIL * 0.0254 );
        DisplayError( this, msg );
        return false;
    }

    m_settings.SetCornerSmoothingType( m_cornerSmoothingChoice->GetSelection() );
    txtvalue = m_cornerSmoothingCtrl->GetValue();
    m_settings.SetCornerRadius( ValueFromString( g_UserUnit, txtvalue ) );

    m_settings.m_ZonePriority = m_PriorityLevelCtrl->GetValue();

    if( m_OrientEdgesOpt->GetSelection() == 0 )
        m_settings.m_Zone_45_Only = false;
    else
        m_settings.m_Zone_45_Only = true;

    m_settings.m_ThermalReliefGap = ValueFromTextCtrl( *m_AntipadSizeValue );
    m_settings.m_ThermalReliefCopperBridge = ValueFromTextCtrl( *m_CopperWidthValue );

    if( m_Config )
    {
        ConfigBaseWriteDouble( m_Config, ZONE_CLEARANCE_WIDTH_STRING_KEY,
                               (double) m_settings.m_ZoneClearance / IU_PER_MILS );

        ConfigBaseWriteDouble( m_Config, ZONE_MIN_THICKNESS_WIDTH_STRING_KEY,
            (double) m_settings.m_ZoneMinThickness / IU_PER_MILS );

        ConfigBaseWriteDouble( m_Config, ZONE_THERMAL_RELIEF_GAP_STRING_KEY,
            (double) m_settings.m_ThermalReliefGap / IU_PER_MILS );

        ConfigBaseWriteDouble( m_Config, ZONE_THERMAL_RELIEF_COPPER_WIDTH_STRING_KEY,
            (double) m_settings.m_ThermalReliefCopperBridge / IU_PER_MILS );
    }

    if( m_settings.m_ThermalReliefCopperBridge <= m_settings.m_ZoneMinThickness )
    {
        DisplayError( this,
                     _( "Thermal relief spoke must be greater than the minimum width." ) );
        return false;
    }

    // If we use only exportable to others zones parameters, exit here:
    if( aUseExportableSetupOnly )
        return true;

    // Get the layer selection for this zone
    int ii = m_LayerSelectionCtrl->GetFirstSelected();

    if( ii < 0 && aPromptForErrors )
    {
        DisplayError( this, _( "No layer selected." ) );
        return false;
    }

    m_settings.m_CurrentZone_Layer = m_LayerId[ii];

    // Get the net name selection for this zone
    ii = m_ListNetNameSelection->GetSelection();

    if( ii < 0 && aPromptForErrors )
    {
        DisplayError( this, _( "No net selected." ) );
        return false;
    }

    if( ii == 0 )   // the not connected option was selected: this is not a good practice: warn:
    {
        if( !IsOK( this, _(
                      "You have chosen the \"not connected\" option. This will create insulated copper islands. Are you sure ?" ) )
            )
            return false;
    }

    wxString net_name = m_ListNetNameSelection->GetString( ii );

    m_settings.m_NetcodeSelection = 0;

    // Search net_code for this net, if a net was selected
    if( m_ListNetNameSelection->GetSelection() > 0 )
    {
        NETINFO_ITEM* net = m_Parent->GetBoard()->FindNet( net_name );
        if( net )
            m_settings.m_NetcodeSelection = net->GetNet();
    }

    return true;
}
Exemplo n.º 14
0
bool DIALOG_DESIGN_RULES::TestDataValidity( wxString* aErrorMsg )
{
    bool     result = true;

    wxString msg;
    wxString errorMsg;

    int      minViaDia = ValueFromTextCtrl( *m_SetViasMinSizeCtrl );
    int      minViaDrill = ValueFromTextCtrl( *m_SetViasMinDrillCtrl );
    int      minUViaDia = ValueFromTextCtrl( *m_SetMicroViasMinSizeCtrl );
    int      minUViaDrill = ValueFromTextCtrl( *m_SetMicroViasMinDrillCtrl );
    int      minTrackWidth = ValueFromTextCtrl( *m_SetTrackMinWidthCtrl );
    int      maxval = 1000 * IU_PER_MILS;   // a max value for tracks and vias sizes (1 inch)

    // @todo Change this code to set the focus to the control where the first error occurs
    //       so the user doesn't have to figure out where the issue is.

    // Test net class parameters.
    for( int row = 0; row < m_grid->GetNumberRows(); row++ )
    {
        int tracksize = ValueFromString( g_UserUnit,
                                         m_grid->GetCellValue( row, GRID_TRACKSIZE ) );
        if( tracksize < minTrackWidth )
        {
            result = false;
            msg.Printf( _( "%s: <b>Track Size</b> &lt; <b>Min Track Size</b><br>" ),
                        GetChars( m_grid->GetRowLabelValue( row ) ) );
            errorMsg += msg;
        }

        // Test vias
        int viadia = ValueFromString( g_UserUnit,
                                      m_grid->GetCellValue( row, GRID_VIASIZE ) );

        if( viadia < minViaDia )
        {
            result = false;
            msg.Printf( _( "%s: <b>Via Diameter</b> &lt; <b>Minimun Via Diameter</b><br>" ),
                        GetChars( m_grid->GetRowLabelValue( row ) ) );
            errorMsg += msg;
        }

        int viadrill = ValueFromString( g_UserUnit,
                                        m_grid->GetCellValue( row, GRID_VIADRILL ) );

        if( viadrill >= viadia )
        {
            result = false;
            msg.Printf( _( "%s: <b>Via Drill</b> &ge; <b>Via Dia</b><br>" ),
                        GetChars( m_grid->GetRowLabelValue( row ) ) );
            errorMsg += msg;
        }

        if( viadrill < minViaDrill )
        {
            result = false;
            msg.Printf( _( "%s: <b>Via Drill</b> &lt; <b>Min Via Drill</b><br>" ),
                        GetChars( m_grid->GetRowLabelValue( row ) ) );
            errorMsg += msg;
        }

        // Test Micro vias
        int muviadia = ValueFromString( g_UserUnit,
                                        m_grid->GetCellValue( row, GRID_uVIASIZE ) );

        if( muviadia < minUViaDia )
        {
            result = false;
            msg.Printf( _( "%s: <b>MicroVia Diameter</b> &lt; <b>MicroVia Min Diameter</b><br>" ),
                        GetChars( m_grid->GetRowLabelValue( row ) ) );
            errorMsg += msg;
        }

        int muviadrill = ValueFromString( g_UserUnit,
                                          m_grid->GetCellValue( row, GRID_uVIADRILL ) );

        if( muviadrill >= muviadia )
        {
            result = false;
            msg.Printf( _( "%s: <b>MicroVia Drill</b> &ge; <b>MicroVia Dia</b><br>" ),
                        GetChars( m_grid->GetRowLabelValue( row ) ) );
            errorMsg += msg;
        }

        if( muviadrill < minUViaDrill )
        {
            result = false;
            msg.Printf( _( "%s: <b>MicroVia Drill</b> &lt; <b>MicroVia Min Drill</b><br>" ),
                        GetChars( m_grid->GetRowLabelValue( row ) ) );
            errorMsg += msg;
        }
    }

    // Test custom tracks
    for( int row = 0; row < m_gridTrackWidthList->GetNumberRows();  ++row )
    {
        wxString tvalue = m_gridTrackWidthList->GetCellValue( row, 0 );

        if( tvalue.IsEmpty() )
            continue;

        int tracksize = ValueFromString( g_UserUnit, tvalue );

        if( tracksize < minTrackWidth )
        {
            result = false;
            msg.Printf( _( "<b>Extra Track %d Size</b> %s &lt; <b>Min Track Size</b><br>" ),
                        row + 1, GetChars( tvalue ) );

            errorMsg += msg;
        }

        if( tracksize > maxval )
        {
            result = false;
            msg.Printf( _( "<b>Extra Track %d Size</b> %s &gt; <b>1 inch!</b><br>" ),
                        row + 1, GetChars( tvalue ) );

            errorMsg += msg;
        }
    }

    // Test custom vias
    for( int row = 0; row < m_gridViaSizeList->GetNumberRows();  ++row )
    {
        wxString tvalue = m_gridViaSizeList->GetCellValue( row, 0 );

        if( tvalue.IsEmpty() )
            continue;

        int viadia = ValueFromString( g_UserUnit, tvalue );

        if( viadia < minViaDia )
        {
            result = false;
            msg.Printf( _( "<b>Extra Via %d Size</b> %s &lt; <b>Min Via Size</b><br>" ),
                        row + 1, GetChars( tvalue ) );
            errorMsg += msg;
        }

        wxString drlvalue = m_gridViaSizeList->GetCellValue( row, 1 );

        if( drlvalue.IsEmpty() )
        {
            result =  false;
            msg.Printf( _( "<b>No via drill size define in row %d</b><br>" ), row + 1 );
            errorMsg += msg;
            continue;
        }

        int viadrill = ValueFromString( g_UserUnit, drlvalue );

        if( viadrill < minViaDrill )
        {
            result = false;
            msg.Printf( _( "<b>Extra Via %d Drill</b> %s &lt; <b>Min Via Drill %s</b><br>" ),
                        row + 1, GetChars( drlvalue ),
                        GetChars( m_SetViasMinDrillCtrl->GetValue() ) );
            errorMsg += msg;
        }

        if( viadia <= viadrill )
        {
            result = false;
            msg.Printf( _( "<b>Extra Via %d Size</b> %s &le; <b> Drill Size</b> %s<br>" ),
                        row + 1, GetChars( tvalue ), GetChars( drlvalue ) );
            errorMsg += msg;
        }

        // Test for a reasonable via size:
        if( viadia > maxval )    // 1 inch!
        {
            result = false;
            msg.Printf( _( "<b>Extra Via %d Size</b>%s &gt; <b>1 inch!</b><br>" ),
                        row + 1, GetChars( tvalue ) );
            errorMsg += msg;
        }
    }

    if( !result && aErrorMsg )
        *aErrorMsg = errorMsg;

    return result;
}