dialog_pad_properties.cpp 33.3 KB
Newer Older
1 2
/*******************************************************************/
/* dialog_pad_properties.cpp: Pad editing functions and dialog box */
3
/* see also dialog_pad_properties_base.xxx (built with wxFormBuilder)   */
4
/*******************************************************************/
5

6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
/*
 * This program source code file is part of KiCad, a free EDA CAD application.
 *
 * Copyright (C) 2012 Jean-Pierre Charras
 * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, you may find one here:
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * or you may search the http://www.gnu.org website for the version 2 license,
 * or you may write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 */

30 31 32 33 34 35 36 37 38 39
#include <fctsys.h>
#include <common.h>
#include <gr_basic.h>
#include <class_drawpanel.h>
#include <confirm.h>
#include <pcbnew.h>
#include <trigo.h>
#include <macros.h>
#include <wxBasePcbFrame.h>
#include <pcbcommon.h>
40
#include <base_units.h>
41

42
#include <wx/dcbuffer.h>
Dick Hollenbeck's avatar
Dick Hollenbeck committed
43
#include <protos.h>
44

45 46
#include <class_board.h>
#include <class_module.h>
47

48
#include <dialog_pad_properties_base.h>
49
#include <html_messagebox.h>
50 51


Dick Hollenbeck's avatar
Dick Hollenbeck committed
52 53
// list of pad shapes.
static PAD_SHAPE_T CodeShape[] = {
54 55 56 57
    PAD_CIRCLE, PAD_OVAL, PAD_RECT, PAD_TRAPEZOID
};


Dick Hollenbeck's avatar
Dick Hollenbeck committed
58
static PAD_ATTR_T CodeType[] = {
59 60 61
    PAD_STANDARD, PAD_SMD, PAD_CONN, PAD_HOLE_NOT_PLATED
};

Dick Hollenbeck's avatar
Dick Hollenbeck committed
62 63 64
#define NBTYPES     DIM(CodeType)


65
// Default mask layers setup for pads according to the pad type
Dick Hollenbeck's avatar
Dick Hollenbeck committed
66 67
static long Std_Pad_Layers[] = {

68
    // PAD_STANDARD:
charras's avatar
charras committed
69
    PAD_STANDARD_DEFAULT_LAYERS,
70 71

    // PAD_CONN:
charras's avatar
charras committed
72
    PAD_CONN_DEFAULT_LAYERS,
73 74

    // PAD_SMD:
charras's avatar
charras committed
75
    PAD_SMD_DEFAULT_LAYERS,
76 77

    //PAD_HOLE_NOT_PLATED:
charras's avatar
charras committed
78
    PAD_HOLE_NOT_PLATED_DEFAULT_LAYERS
79 80 81
};


82 83 84 85
/**
 * class DIALOG_PAD_PROPERTIES, derived from DIALOG_PAD_PROPERTIES_BASE,
 * created by wxFormBuilder
 */
86
 class DIALOG_PAD_PROPERTIES : public DIALOG_PAD_PROPERTIES_BASE
87 88
{
public:
Dick Hollenbeck's avatar
Dick Hollenbeck committed
89
    DIALOG_PAD_PROPERTIES( PCB_BASE_FRAME* aParent, D_PAD* aPad );
90 91 92 93 94
    ~DIALOG_PAD_PROPERTIES()
    {
        delete m_dummyPad;
    }

95
private:
Dick Hollenbeck's avatar
Dick Hollenbeck committed
96 97 98 99 100 101 102 103 104
    PCB_BASE_FRAME* m_Parent;
    D_PAD*  m_CurrentPad;            // pad currently being edited
    D_PAD*  m_dummyPad;              // a working copy used to show changes
    BOARD*  m_Board;
    D_PAD&  m_Pad_Master;
    bool    m_isFlipped;            // true if the parent footprint (therefore pads) is flipped (mirrored)
                                    // in this case, some Y coordinates values must be negated
    bool    m_canUpdate;

105
    void initValues();
Dick Hollenbeck's avatar
Dick Hollenbeck committed
106

107
    bool padValuesOK();       ///< test if all values are acceptable for the pad
Dick Hollenbeck's avatar
Dick Hollenbeck committed
108 109

    /**
110
     * Function setPadLayersList
Dick Hollenbeck's avatar
Dick Hollenbeck committed
111 112 113
     * updates the CheckBox states in pad layers list,
     * @param layer_mask = pad layer mask (ORed layers bit mask)
     */
114 115 116 117 118 119 120 121 122 123 124 125
    void setPadLayersList( long layer_mask );

    /// Copy values from dialog field to aPad's members
    bool transferDataToPad( D_PAD* aPad );

    // event handlers:

    void OnPadShapeSelection( wxCommandEvent& event );
    void OnDrillShapeSelected( wxCommandEvent& event );

    void PadOrientEvent( wxCommandEvent& event );
    void PadTypeSelected( wxCommandEvent& event );
Dick Hollenbeck's avatar
Dick Hollenbeck committed
126

127
    void OnSetLayers( wxCommandEvent& event );
128 129
    void OnCancelButtonClick( wxCommandEvent& event );
    void OnPaintShowPanel( wxPaintEvent& event );
Dick Hollenbeck's avatar
Dick Hollenbeck committed
130 131 132

    /// Called when a dimension has changed.
    /// Update the graphical pad shown in the panel.
133
    void OnValuesChanged( wxCommandEvent& event );
134 135

    /// Updates the different parameters for the component being edited.
Dick Hollenbeck's avatar
Dick Hollenbeck committed
136
    /// Fired from the OK button click.
137
    void PadPropertiesAccept( wxCommandEvent& event );
138 139 140
};


Dick Hollenbeck's avatar
Dick Hollenbeck committed
141
DIALOG_PAD_PROPERTIES::DIALOG_PAD_PROPERTIES( PCB_BASE_FRAME* aParent, D_PAD* aPad ) :
142
    DIALOG_PAD_PROPERTIES_BASE( aParent ),
143
    // use aParent's parent, which is the original BOARD, not the dummy module editor BOARD,
Dick Hollenbeck's avatar
Dick Hollenbeck committed
144
    // since FOOTPRINT_EDIT_FRAME::GetDesignSettings() is tricked out to use the PCB_EDIT_FRAME's
145 146
    // BOARD, not its own BOARD.
    m_Pad_Master( aParent->GetDesignSettings().m_Pad_Master )
Dick Hollenbeck's avatar
Dick Hollenbeck committed
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
{
    m_canUpdate  = false;
    m_Parent     = aParent;
    m_CurrentPad = aPad;
    m_Board      = m_Parent->GetBoard();
    m_dummyPad   = new D_PAD( (MODULE*) NULL );

    if( aPad )
        m_dummyPad->Copy( aPad );
    else
        m_dummyPad->Copy( &m_Pad_Master );

    initValues();

    m_sdbSizer1OK->SetDefault();
    GetSizer()->SetSizeHints( this );
163 164

    m_PadNumCtrl->SetFocus();
Dick Hollenbeck's avatar
Dick Hollenbeck committed
165 166 167 168
    m_canUpdate = true;
}


169 170 171 172 173
void DIALOG_PAD_PROPERTIES::OnPaintShowPanel( wxPaintEvent& event )
{
    wxPaintDC    dc( m_panelShowPad );
    PAD_DRAWINFO drawInfo;

174
    EDA_COLOR_T color = ColorFromInt( 0 ); // XXX EVIL merge
175

Dick Hollenbeck's avatar
Dick Hollenbeck committed
176
    if( m_dummyPad->GetLayerMask() & LAYER_FRONT )
177 178 179 180
    {
        color = m_Board->GetVisibleElementColor( PAD_FR_VISIBLE );
    }

Dick Hollenbeck's avatar
Dick Hollenbeck committed
181
    if( m_dummyPad->GetLayerMask() & LAYER_BACK )
182
    {
183
        color = ColorFromInt( color | m_Board->GetVisibleElementColor( PAD_BK_VISIBLE ) ); // XXX EVIL merge
184 185 186 187 188 189 190
    }

    if( color == 0 )
        color = LIGHTGRAY;

    drawInfo.m_Color     = color;
    drawInfo.m_HoleColor = DARKGRAY;
Dick Hollenbeck's avatar
Dick Hollenbeck committed
191
    drawInfo.m_Offset    = m_dummyPad->GetPosition();
192 193
    drawInfo.m_Display_padnum  = true;
    drawInfo.m_Display_netname = true;
Dick Hollenbeck's avatar
Dick Hollenbeck committed
194

Dick Hollenbeck's avatar
Dick Hollenbeck committed
195
    if( m_dummyPad->GetAttribute() == PAD_HOLE_NOT_PLATED )
196
        drawInfo.m_ShowNotPlatedHole = true;
197 198

    // Shows the local pad clearance
Dick Hollenbeck's avatar
Dick Hollenbeck committed
199
    drawInfo.m_PadClearance = m_dummyPad->GetLocalClearance();
200 201 202 203 204

    wxSize dc_size = dc.GetSize();
    dc.SetDeviceOrigin( dc_size.x / 2, dc_size.y / 2 );

    // Calculate a suitable scale to fit the available draw area
205
    int dim = m_dummyPad->GetSize().x + std::abs( m_dummyPad->GetDelta().y);
Dick Hollenbeck's avatar
Dick Hollenbeck committed
206 207 208 209 210 211

    if( m_dummyPad->GetLocalClearance() > 0 )
        dim += m_dummyPad->GetLocalClearance() * 2;

    double scale = (double) dc_size.x / dim;

212
    dim = m_dummyPad->GetSize().y + std::abs( m_dummyPad->GetDelta().x);
Dick Hollenbeck's avatar
Dick Hollenbeck committed
213 214 215
    if( m_dummyPad->GetLocalClearance() > 0 )
        dim += m_dummyPad->GetLocalClearance() * 2;

216
    double altscale = (double) dc_size.y / dim;
217
    scale = std::min( scale, altscale );
218 219 220 221 222

    // Give a margin
    scale *= 0.7;
    dc.SetUserScale( scale, scale );

223
    GRResetPenAndBrush( &dc );
224 225
    m_dummyPad->DrawShape( NULL, &dc, drawInfo );

226 227 228 229 230 231 232
    // Draw X and Y axis.
    // this is particularly useful to show the reference position of pads
    // with offset and no hole
    int width = 0;
    GRLine( NULL, &dc, -dim, 0, dim, 0, width, BLUE );   // X axis
    GRLine( NULL, &dc, 0, -dim, 0, dim, width, BLUE );   // Y axis

233 234 235 236
    event.Skip();
}


Dick Hollenbeck's avatar
Dick Hollenbeck committed
237
void PCB_BASE_FRAME::InstallPadOptionsFrame( D_PAD* aPad )
238
{
Dick Hollenbeck's avatar
Dick Hollenbeck committed
239
    DIALOG_PAD_PROPERTIES dlg( this, aPad );
240

241
    dlg.ShowModal();
242 243 244
}


245
void DIALOG_PAD_PROPERTIES::initValues()
246
{
Dick Hollenbeck's avatar
Dick Hollenbeck committed
247 248
    wxString    msg;
    double      angle;
249

250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266
    // Setup layers names from board
    // Should be made first, before calling m_rbCopperLayersSel->SetSelection()
    m_rbCopperLayersSel->SetString( 0, m_Board->GetLayerName( LAYER_N_FRONT ) );
    m_rbCopperLayersSel->SetString( 1, m_Board->GetLayerName( LAYER_N_BACK ) );

    m_PadLayerAdhCmp->SetLabel( m_Board->GetLayerName( ADHESIVE_N_FRONT ) );
    m_PadLayerAdhCu->SetLabel( m_Board->GetLayerName( ADHESIVE_N_BACK ) );
    m_PadLayerPateCmp->SetLabel( m_Board->GetLayerName( SOLDERPASTE_N_FRONT ) );
    m_PadLayerPateCu->SetLabel( m_Board->GetLayerName( SOLDERPASTE_N_BACK ) );
    m_PadLayerSilkCmp->SetLabel( m_Board->GetLayerName( SILKSCREEN_N_FRONT ) );
    m_PadLayerSilkCu->SetLabel( m_Board->GetLayerName( SILKSCREEN_N_BACK ) );
    m_PadLayerMaskCmp->SetLabel( m_Board->GetLayerName( SOLDERMASK_N_FRONT ) );
    m_PadLayerMaskCu->SetLabel( m_Board->GetLayerName( SOLDERMASK_N_BACK ) );
    m_PadLayerECO1->SetLabel( m_Board->GetLayerName( ECO1_N ) );
    m_PadLayerECO2->SetLabel( m_Board->GetLayerName( ECO2_N ) );
    m_PadLayerDraft->SetLabel( m_Board->GetLayerName( DRAW_N ) );

267
    m_isFlipped = false;
Dick Hollenbeck's avatar
Dick Hollenbeck committed
268

269 270
    if( m_CurrentPad )
    {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
271 272 273
        MODULE* module = m_CurrentPad->GetParent();

        if( module->GetLayer() == LAYER_N_BACK )
274 275 276 277
        {
            m_isFlipped = true;
            m_staticModuleSideValue->SetLabel( _( "Back side (footprint is mirrored)" ) );
        }
Dick Hollenbeck's avatar
Dick Hollenbeck committed
278 279

        msg.Printf( wxT( "%.1f" ), (double) module->GetOrientation() / 10 );
280 281
        m_staticModuleRotValue->SetLabel( msg );
    }
282

283 284
    if( m_isFlipped )
    {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
285 286 287 288 289 290 291 292 293 294
        wxPoint pt = m_dummyPad->GetOffset();
        NEGATE( pt.y );
        m_dummyPad->SetOffset( pt );

        wxSize sz = m_dummyPad->GetDelta();
        NEGATE( sz.y );
        m_dummyPad->SetDelta( sz );

        // flip pad's layers
        m_dummyPad->SetLayerMask( ChangeSideMaskLayer( m_dummyPad->GetLayerMask() ) );
295
    }
Dick Hollenbeck's avatar
Dick Hollenbeck committed
296

297
    m_staticTextWarningPadFlipped->Show(m_isFlipped);
298

Dick Hollenbeck's avatar
Dick Hollenbeck committed
299
    m_PadNumCtrl->SetValue( m_dummyPad->GetPadName() );
300
    m_PadNetNameCtrl->SetValue( m_dummyPad->GetNetname() );
301

302
    // Display current unit name in dialog:
303 304 305 306 307 308 309 310
    m_PadPosX_Unit->SetLabel( GetUnitsLabel( g_UserUnit ) );
    m_PadPosY_Unit->SetLabel( GetUnitsLabel( g_UserUnit ) );
    m_PadDrill_X_Unit->SetLabel( GetUnitsLabel( g_UserUnit ) );
    m_PadDrill_Y_Unit->SetLabel( GetUnitsLabel( g_UserUnit ) );
    m_PadShapeSizeX_Unit->SetLabel( GetUnitsLabel( g_UserUnit ) );
    m_PadShapeSizeY_Unit->SetLabel( GetUnitsLabel( g_UserUnit ) );
    m_PadShapeOffsetX_Unit->SetLabel( GetUnitsLabel( g_UserUnit ) );
    m_PadShapeOffsetY_Unit->SetLabel( GetUnitsLabel( g_UserUnit ) );
311
    m_PadShapeDelta_Unit->SetLabel( GetUnitsLabel( g_UserUnit ) );
312
    m_PadLengthDie_Unit->SetLabel( GetUnitsLabel( g_UserUnit ) );
313

314
    // Display current pad masks clearances units
315 316 317
    m_NetClearanceUnits->SetLabel( GetUnitsLabel( g_UserUnit ) );
    m_SolderMaskMarginUnits->SetLabel( GetUnitsLabel( g_UserUnit ) );
    m_SolderPasteMarginUnits->SetLabel( GetUnitsLabel( g_UserUnit ) );
318 319
    m_ThermalWidthUnits->SetLabel( GetUnitsLabel( g_UserUnit ) );
    m_ThermalGapUnits->SetLabel( GetUnitsLabel( g_UserUnit ) );
320 321

    // Display current pad parameters units:
322 323
    PutValueInLocalUnits( *m_PadPosition_X_Ctrl, m_dummyPad->GetPosition().x );
    PutValueInLocalUnits( *m_PadPosition_Y_Ctrl, m_dummyPad->GetPosition().y );
324

325 326
    PutValueInLocalUnits( *m_PadDrill_X_Ctrl, m_dummyPad->GetDrillSize().x );
    PutValueInLocalUnits( *m_PadDrill_Y_Ctrl, m_dummyPad->GetDrillSize().y );
327

328 329
    PutValueInLocalUnits( *m_ShapeSize_X_Ctrl, m_dummyPad->GetSize().x );
    PutValueInLocalUnits( *m_ShapeSize_Y_Ctrl, m_dummyPad->GetSize().y );
330

331 332
    PutValueInLocalUnits( *m_ShapeOffset_X_Ctrl, m_dummyPad->GetOffset().x );
    PutValueInLocalUnits( *m_ShapeOffset_Y_Ctrl, m_dummyPad->GetOffset().y );
333

Dick Hollenbeck's avatar
Dick Hollenbeck committed
334
    if( m_dummyPad->GetDelta().x )
335
    {
336
        PutValueInLocalUnits( *m_ShapeDelta_Ctrl, m_dummyPad->GetDelta().x );
337
        m_trapDeltaDirChoice->SetSelection( 0 );
338 339 340
    }
    else
    {
341
        PutValueInLocalUnits( *m_ShapeDelta_Ctrl, m_dummyPad->GetDelta().y );
342
        m_trapDeltaDirChoice->SetSelection( 1 );
343
    }
344

345
    PutValueInLocalUnits( *m_LengthDieCtrl, m_dummyPad->GetDieLength() );
346

347 348 349 350
    PutValueInLocalUnits( *m_NetClearanceValueCtrl, m_dummyPad->GetLocalClearance() );
    PutValueInLocalUnits( *m_SolderMaskMarginCtrl, m_dummyPad->GetLocalSolderMaskMargin() );
    PutValueInLocalUnits( *m_ThermalWidthCtrl, m_dummyPad->GetThermalWidth() );
    PutValueInLocalUnits( *m_ThermalGapCtrl, m_dummyPad->GetThermalGap() );
351

352
    // These 2 parameters are usually < 0, so prepare entering a negative value, if current is 0
353
    PutValueInLocalUnits( *m_SolderPasteMarginCtrl, m_dummyPad->GetLocalSolderPasteMargin() );
Dick Hollenbeck's avatar
Dick Hollenbeck committed
354 355

    if( m_dummyPad->GetLocalSolderPasteMargin() == 0 )
356 357
        m_SolderPasteMarginCtrl->SetValue( wxT( "-" ) + m_SolderPasteMarginCtrl->GetValue() );

Dick Hollenbeck's avatar
Dick Hollenbeck committed
358 359 360 361
    msg.Printf( wxT( "%.1f" ), m_dummyPad->GetLocalSolderPasteMarginRatio() * 100.0 );

    if( m_dummyPad->GetLocalSolderPasteMarginRatio() == 0.0 && msg[0] == '0' )
        // Sometimes Printf adds a sign if the value is small
362
        m_SolderPasteMarginRatioCtrl->SetValue( wxT( "-" ) + msg );
363
    else
364
        m_SolderPasteMarginRatioCtrl->SetValue( msg );
365

366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385
    switch( m_dummyPad->GetZoneConnection() )
    {
    default:
    case UNDEFINED_CONNECTION:
        m_ZoneConnectionChoice->SetSelection( 0 );
        break;

    case PAD_IN_ZONE:
        m_ZoneConnectionChoice->SetSelection( 1 );
        break;

    case THERMAL_PAD:
        m_ZoneConnectionChoice->SetSelection( 2 );
        break;

    case PAD_NOT_IN_ZONE:
        m_ZoneConnectionChoice->SetSelection( 3 );
        break;
    }

386 387
    if( m_CurrentPad )
    {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
388 389 390 391
        MODULE* module = m_CurrentPad->GetParent();

        angle = m_CurrentPad->GetOrientation() - module->GetOrientation();

392
        if( m_isFlipped )
Dick Hollenbeck's avatar
Dick Hollenbeck committed
393 394 395
            NEGATE( angle );

        m_dummyPad->SetOrientation( angle );
396
    }
397

Dick Hollenbeck's avatar
Dick Hollenbeck committed
398
    angle = m_dummyPad->GetOrientation();
399

Dick Hollenbeck's avatar
Dick Hollenbeck committed
400
    NORMALIZE_ANGLE_180( angle );    // ? normalizing is in D_PAD::SetOrientation()
401

Dick Hollenbeck's avatar
Dick Hollenbeck committed
402
    // Set layers used by this pad: :
403
    setPadLayersList( m_dummyPad->GetLayerMask() );
404 405

    // Pad Orient
Dick Hollenbeck's avatar
Dick Hollenbeck committed
406
    switch( int( angle ) )
407 408 409 410 411 412 413 414 415
    {
    case 0:
        m_PadOrient->SetSelection( 0 );
        break;

    case 900:
        m_PadOrient->SetSelection( 1 );
        break;

416
    case -900:
417 418 419 420
        m_PadOrient->SetSelection( 2 );
        break;

    case 1800:
421
    case -1800:
422 423 424 425 426 427 428 429
        m_PadOrient->SetSelection( 3 );
        break;

    default:
        m_PadOrient->SetSelection( 4 );
        break;
    }

Dick Hollenbeck's avatar
Dick Hollenbeck committed
430
    switch( m_dummyPad->GetShape() )
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449
    {
    default:
    case PAD_CIRCLE:
        m_PadShape->SetSelection( 0 );
        break;

    case PAD_OVAL:
        m_PadShape->SetSelection( 1 );
        break;

    case PAD_RECT:
        m_PadShape->SetSelection( 2 );
        break;

    case PAD_TRAPEZOID:
        m_PadShape->SetSelection( 3 );
        break;
    }

Dick Hollenbeck's avatar
Dick Hollenbeck committed
450
    msg.Printf( wxT( "%g" ), angle );
451
    m_PadOrientCtrl->SetValue( msg );
452

453
    // Type of pad selection
454
    m_PadType->SetSelection( 0 );
Dick Hollenbeck's avatar
Dick Hollenbeck committed
455

456
    for( unsigned ii = 0; ii < NBTYPES; ii++ )
457
    {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
458
        if( CodeType[ii] == m_dummyPad->GetAttribute() )
459
        {
460 461
            m_PadType->SetSelection( ii );
            break;
462 463 464
        }
    }

465 466
    // Enable/disable Pad name,and pad length die
    // (disable for NPTH pads (mechanical pads)
Dick Hollenbeck's avatar
Dick Hollenbeck committed
467 468
    bool enable = m_dummyPad->GetAttribute() != PAD_HOLE_NOT_PLATED;

469 470 471 472
    m_PadNumCtrl->Enable( enable );
    m_PadNetNameCtrl->Enable( enable );
    m_LengthDieCtrl->Enable( enable );

Dick Hollenbeck's avatar
Dick Hollenbeck committed
473
    if( m_dummyPad->GetDrillShape() != PAD_OVAL )
474 475 476
        m_DrillShapeCtrl->SetSelection( 0 );
    else
        m_DrillShapeCtrl->SetSelection( 1 );
477

Dick Hollenbeck's avatar
Dick Hollenbeck committed
478
    // Update some dialog widgets state (Enable/disable options):
479
    wxCommandEvent cmd_event;
480
    setPadLayersList( m_dummyPad->GetLayerMask() );
481
    OnDrillShapeSelected( cmd_event );
482
    OnPadShapeSelection( cmd_event );
483 484 485
}


486
void DIALOG_PAD_PROPERTIES::OnPadShapeSelection( wxCommandEvent& event )
487 488 489
{
    switch( m_PadShape->GetSelection() )
    {
490
    case 0:     // CIRCLE:
491
        m_ShapeDelta_Ctrl->Enable( false );
492
        m_trapDeltaDirChoice->Enable( false );
493
        m_ShapeSize_Y_Ctrl->Enable( false );
494 495
        m_ShapeOffset_X_Ctrl->Enable( false );
        m_ShapeOffset_Y_Ctrl->Enable( false );
496 497
        break;

498
    case 1:     // OVAL:
499
        m_ShapeDelta_Ctrl->Enable( false );
500
        m_trapDeltaDirChoice->Enable( false );
501
        m_ShapeSize_Y_Ctrl->Enable( true );
502 503
        m_ShapeOffset_X_Ctrl->Enable( true );
        m_ShapeOffset_Y_Ctrl->Enable( true );
504 505 506
        break;

    case 2:     // PAD_RECT:
507
        m_ShapeDelta_Ctrl->Enable( false );
508
        m_trapDeltaDirChoice->Enable( false );
509
        m_ShapeSize_Y_Ctrl->Enable( true );
510 511
        m_ShapeOffset_X_Ctrl->Enable( true );
        m_ShapeOffset_Y_Ctrl->Enable( true );
512 513
        break;

514
    case 3:     // TRAPEZOID:
515
        m_ShapeDelta_Ctrl->Enable( true );
516
        m_trapDeltaDirChoice->Enable( true );
517
        m_ShapeSize_Y_Ctrl->Enable( true );
518 519
        m_ShapeOffset_X_Ctrl->Enable( true );
        m_ShapeOffset_Y_Ctrl->Enable( true );
520 521
        break;
    }
522

523
    transferDataToPad( m_dummyPad );
524
    m_panelShowPad->Refresh();
525 526 527
}


528
void DIALOG_PAD_PROPERTIES::OnDrillShapeSelected( wxCommandEvent& event )
529
{
Dick Hollenbeck's avatar
Dick Hollenbeck committed
530
    if( m_PadType->GetSelection() == 1 || m_PadType->GetSelection() == 2 )
531 532
    {
        // pad type = SMD or CONN: no hole allowed
533 534
        m_PadDrill_X_Ctrl->Enable( false );
        m_PadDrill_Y_Ctrl->Enable( false );
535
    }
536
    else
537
    {
538 539 540 541 542 543 544 545 546 547 548 549
        switch( m_DrillShapeCtrl->GetSelection() )
        {
        case 0:     //CIRCLE:
            m_PadDrill_X_Ctrl->Enable( true );
            m_PadDrill_Y_Ctrl->Enable( false );
            break;

        case 1:     //OVALE:
            m_PadDrill_X_Ctrl->Enable( true );
            m_PadDrill_Y_Ctrl->Enable( true );
            break;
        }
550
    }
551

552
    transferDataToPad( m_dummyPad );
553
    m_panelShowPad->Refresh();
554 555 556
}


557
void DIALOG_PAD_PROPERTIES::PadOrientEvent( wxCommandEvent& event )
558 559 560 561
{
    switch( m_PadOrient->GetSelection() )
    {
    case 0:
Dick Hollenbeck's avatar
Dick Hollenbeck committed
562
        m_dummyPad->SetOrientation( 0 );
563 564 565
        break;

    case 1:
Dick Hollenbeck's avatar
Dick Hollenbeck committed
566
        m_dummyPad->SetOrientation( 900 );
567 568 569
        break;

    case 2:
Dick Hollenbeck's avatar
Dick Hollenbeck committed
570
        m_dummyPad->SetOrientation( -900 );
571 572 573
        break;

    case 3:
Dick Hollenbeck's avatar
Dick Hollenbeck committed
574
        m_dummyPad->SetOrientation( 1800 );
575 576 577 578 579
        break;

    default:
        break;
    }
580 581

    wxString msg;
582
    msg.Printf( wxT( "%g" ), m_dummyPad->GetOrientation() );
583 584
    m_PadOrientCtrl->SetValue( msg );

585
    transferDataToPad( m_dummyPad );
586
    m_panelShowPad->Refresh();
587 588 589
}


590
void DIALOG_PAD_PROPERTIES::PadTypeSelected( wxCommandEvent& event )
591
{
592 593
    long        layer_mask;
    unsigned    ii = m_PadType->GetSelection();
594

595
    if( ii >= NBTYPES ) // catches < 0 also
596 597 598
        ii = 0;

    layer_mask = Std_Pad_Layers[ii];
599
    setPadLayersList( layer_mask );
600 601

    // Enable/disable drill dialog items:
602
    event.SetId( m_DrillShapeCtrl->GetSelection() );
603
    OnDrillShapeSelected( event );
Dick Hollenbeck's avatar
Dick Hollenbeck committed
604

605 606 607 608
    if( ii == 0 || ii == NBTYPES-1 )
        m_DrillShapeCtrl->Enable( true );
    else
        m_DrillShapeCtrl->Enable( false );
609 610 611 612 613 614 615

    // Enable/disable Pad name,and pad length die
    // (disable for NPTH pads (mechanical pads)
    bool enable = ii != 3;
    m_PadNumCtrl->Enable( enable );
    m_PadNetNameCtrl->Enable( enable );
    m_LengthDieCtrl->Enable( enable );
616 617 618
}


619
void DIALOG_PAD_PROPERTIES::setPadLayersList( long layer_mask )
620
{
621
    if( ( layer_mask & ALL_CU_LAYERS ) == LAYER_FRONT )
622 623 624
        m_rbCopperLayersSel->SetSelection(0);
    else if( ( layer_mask & ALL_CU_LAYERS ) == LAYER_BACK)
        m_rbCopperLayersSel->SetSelection(1);
625
    else if( ( layer_mask & ALL_CU_LAYERS ) != 0 )
626 627 628
        m_rbCopperLayersSel->SetSelection(2);
    else
        m_rbCopperLayersSel->SetSelection(3);
629

Dick Hollenbeck's avatar
Dick Hollenbeck committed
630 631
    m_PadLayerAdhCmp->SetValue( bool( layer_mask & ADHESIVE_LAYER_FRONT ) );
    m_PadLayerAdhCu->SetValue( bool( layer_mask & ADHESIVE_LAYER_BACK ) );
632

Dick Hollenbeck's avatar
Dick Hollenbeck committed
633 634
    m_PadLayerPateCmp->SetValue( bool( layer_mask & SOLDERPASTE_LAYER_FRONT ) );
    m_PadLayerPateCu->SetValue( bool( layer_mask & SOLDERPASTE_LAYER_BACK ) );
635

Dick Hollenbeck's avatar
Dick Hollenbeck committed
636 637
    m_PadLayerSilkCmp->SetValue( bool( layer_mask & SILKSCREEN_LAYER_FRONT ) );
    m_PadLayerSilkCu->SetValue( bool( layer_mask & SILKSCREEN_LAYER_BACK ) );
638

Dick Hollenbeck's avatar
Dick Hollenbeck committed
639 640
    m_PadLayerMaskCmp->SetValue( bool( layer_mask & SOLDERMASK_LAYER_FRONT ) );
    m_PadLayerMaskCu->SetValue( bool( layer_mask & SOLDERMASK_LAYER_BACK ) );
641

Dick Hollenbeck's avatar
Dick Hollenbeck committed
642 643
    m_PadLayerECO1->SetValue( bool( layer_mask & ECO1_LAYER ) );
    m_PadLayerECO2->SetValue( bool( layer_mask & ECO2_LAYER ) );
644

Dick Hollenbeck's avatar
Dick Hollenbeck committed
645
    m_PadLayerDraft->SetValue( bool( layer_mask & DRAW_LAYER ) );
646 647 648
}


649
// Called when select/deselect a layer.
650
void DIALOG_PAD_PROPERTIES::OnSetLayers( wxCommandEvent& event )
651
{
652
    transferDataToPad( m_dummyPad );
653 654 655
    m_panelShowPad->Refresh();
}

Dick Hollenbeck's avatar
Dick Hollenbeck committed
656

657
// test if all values are acceptable for the pad
658
bool DIALOG_PAD_PROPERTIES::padValuesOK()
659
{
660
    bool error = transferDataToPad( m_dummyPad );
661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691

    wxArrayString error_msgs;
    wxString msg;

    // Test for incorrect values
    if( (m_dummyPad->GetSize().x < m_dummyPad->GetDrillSize().x) ||
        (m_dummyPad->GetSize().y < m_dummyPad->GetDrillSize().y) )
    {
        error_msgs.Add(  _( "Incorrect value for pad drill: pad drill bigger than pad size" ) );
    }

    int padlayers_mask = m_dummyPad->GetLayerMask();
    if( ( padlayers_mask == 0 ) && ( m_dummyPad->GetAttribute() != PAD_HOLE_NOT_PLATED ) )
        error_msgs.Add( _( "Error: pad has no layer and is not a mechanical pad" ) );

    padlayers_mask &= (LAYER_BACK | LAYER_FRONT);
    if( padlayers_mask == 0 )
    {
        if( m_dummyPad->GetDrillSize().x || m_dummyPad->GetDrillSize().y )
        {
            msg = _( "Error: pad is not on a copper layer and has a hole" );
            if( m_dummyPad->GetAttribute() == PAD_HOLE_NOT_PLATED )
            {
                msg += wxT("\n");
                msg += _( "For NPTH pad, set pad drill value to pad size value,\n\
if you do not want this pad plotted in gerber files");
            }
            error_msgs.Add( msg );
        }
    }

692
    wxPoint max_size;
693 694
    max_size.x = std::abs( m_dummyPad->GetOffset().x );
    max_size.y = std::abs( m_dummyPad->GetOffset().y );
695 696
    max_size.x += m_dummyPad->GetDrillSize().x / 2;
    max_size.y += m_dummyPad->GetDrillSize().y / 2;
697 698
    if( ( m_dummyPad->GetSize().x / 2 < max_size.x ) ||
        ( m_dummyPad->GetSize().y / 2 < max_size.y ) )
699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732
    {
        error_msgs.Add( _( "Incorrect value for pad offset" ) );
    }

    if( error )
    {
        error_msgs.Add(  _( "Too large value for pad delta size" ) );
    }

    switch( m_dummyPad->GetAttribute() )
    {
        case PAD_STANDARD :     // Pad through hole, a hole is expected
            if( m_dummyPad->GetDrillSize().x <= 0 )
                error_msgs.Add( _( "Incorrect value for pad drill (too small value)" ) );
            break;

        case PAD_SMD:     // SMD and Connector pads (One external copper layer only)
        case PAD_CONN:
            if( (padlayers_mask & LAYER_BACK) && (padlayers_mask & LAYER_FRONT) )
                error_msgs.Add( _( "Error: only one copper layer allowed for this pad" ) );
            break;

        case PAD_HOLE_NOT_PLATED:     // Not plated
            break;
    }

    if( error_msgs.GetCount() )
    {
        HTML_MESSAGE_BOX dlg( this, _("Pad setup errors list" ) );
        dlg.ListSet( error_msgs );
        dlg.ShowModal();
    }
    return error_msgs.GetCount() == 0;
}
733

734

Dick Hollenbeck's avatar
Dick Hollenbeck committed
735
void DIALOG_PAD_PROPERTIES::PadPropertiesAccept( wxCommandEvent& event )
736
{
737
    if( !padValuesOK() )
738 739
        return;

740 741 742
    bool rastnestIsChanged = false;
    int  isign = m_isFlipped ? -1 : 1;

743
    transferDataToPad( &m_Pad_Master );
744 745 746

    if( m_CurrentPad )   // Set current Pad parameters
    {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
747 748 749 750
        wxSize  size;
        MODULE* module = m_CurrentPad->GetParent();

        m_Parent->SaveCopyInUndoList( module, UR_CHANGED );
751
        module->SetLastEditTime();
752 753

        // redraw the area where the pad was, without pad (delete pad on screen)
754
        m_CurrentPad->SetFlags( DO_NOT_DRAW );
755
        m_Parent->GetCanvas()->RefreshDrawingRect( m_CurrentPad->GetBoundingBox() );
756
        m_CurrentPad->ClearFlags( DO_NOT_DRAW );
757 758

        // Update values
Dick Hollenbeck's avatar
Dick Hollenbeck committed
759 760
        m_CurrentPad->SetShape( m_Pad_Master.GetShape() );
        m_CurrentPad->SetAttribute( m_Pad_Master.GetAttribute() );
761

Dick Hollenbeck's avatar
Dick Hollenbeck committed
762
        if( m_CurrentPad->GetPosition() != m_Pad_Master.GetPosition() )
763
        {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
764 765
            m_CurrentPad->SetPosition( m_Pad_Master.GetPosition() );
            rastnestIsChanged = true;
766 767
        }

Dick Hollenbeck's avatar
Dick Hollenbeck committed
768 769 770 771 772 773 774 775 776 777
        // compute the pos 0 value, i.e. pad position for module with orientation = 0
        // i.e. relative to module origin (module position)
        wxPoint pt = m_CurrentPad->GetPosition() - module->GetPosition();

        RotatePoint( &pt, -module->GetOrientation() );

        m_CurrentPad->SetPos0( pt );

        m_CurrentPad->SetOrientation( m_Pad_Master.GetOrientation() * isign + module->GetOrientation() );

778
        m_CurrentPad->SetSize( m_Pad_Master.GetSize() );
779

Dick Hollenbeck's avatar
Dick Hollenbeck committed
780 781 782
        size = m_Pad_Master.GetDelta();
        size.y *= isign;
        m_CurrentPad->SetDelta( size );
783

Dick Hollenbeck's avatar
Dick Hollenbeck committed
784 785
        m_CurrentPad->SetDrillSize( m_Pad_Master.GetDrillSize() );
        m_CurrentPad->SetDrillShape( m_Pad_Master.GetDrillShape() );
786

Dick Hollenbeck's avatar
Dick Hollenbeck committed
787 788 789 790 791 792 793
        wxPoint offset = m_Pad_Master.GetOffset();
        offset.y *= isign;
        m_CurrentPad->SetOffset( offset );

        m_CurrentPad->SetDieLength( m_Pad_Master.GetDieLength() );

        if( m_CurrentPad->GetLayerMask() != m_Pad_Master.GetLayerMask() )
794 795
        {
            rastnestIsChanged = true;
Dick Hollenbeck's avatar
Dick Hollenbeck committed
796
            m_CurrentPad->SetLayerMask( m_Pad_Master.GetLayerMask() );
797
        }
Dick Hollenbeck's avatar
Dick Hollenbeck committed
798

799
        if( m_isFlipped )
Dick Hollenbeck's avatar
Dick Hollenbeck committed
800
            m_CurrentPad->SetLayerMask( ChangeSideMaskLayer( m_CurrentPad->GetLayerMask() ) );
801

Dick Hollenbeck's avatar
Dick Hollenbeck committed
802
        m_CurrentPad->SetPadName( m_Pad_Master.GetPadName() );
803

Dick Hollenbeck's avatar
Dick Hollenbeck committed
804
        if( m_CurrentPad->GetNetname() != m_Pad_Master.GetNetname() )
805
        {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
806
            if( m_Pad_Master.GetNetname().IsEmpty() )
807 808 809 810 811 812 813
            {
                rastnestIsChanged = true;
                m_CurrentPad->SetNet( 0 );
                m_CurrentPad->SetNetname( wxEmptyString );
            }
            else
            {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
814
                const NETINFO_ITEM* net = m_Parent->GetBoard()->FindNet( m_Pad_Master.GetNetname() );
815 816 817
                if( net )
                {
                    rastnestIsChanged = true;
Dick Hollenbeck's avatar
Dick Hollenbeck committed
818
                    m_CurrentPad->SetNetname( m_Pad_Master.GetNetname() );
819 820 821 822 823 824 825
                    m_CurrentPad->SetNet( net->GetNet() );
                }
                else
                    DisplayError( NULL, _( "Unknown netname, netname not changed" ) );
            }
        }

Dick Hollenbeck's avatar
Dick Hollenbeck committed
826 827 828 829
        m_CurrentPad->SetLocalClearance( m_Pad_Master.GetLocalClearance() );
        m_CurrentPad->SetLocalSolderMaskMargin( m_Pad_Master.GetLocalSolderMaskMargin() );
        m_CurrentPad->SetLocalSolderPasteMargin( m_Pad_Master.GetLocalSolderPasteMargin() );
        m_CurrentPad->SetLocalSolderPasteMarginRatio( m_Pad_Master.GetLocalSolderPasteMarginRatio() );
830
        m_CurrentPad->SetZoneConnection( m_Pad_Master.GetZoneConnection() );
831 832
        m_CurrentPad->SetThermalWidth( m_Pad_Master.GetThermalWidth() );
        m_CurrentPad->SetThermalGap( m_Pad_Master.GetThermalGap() );
833

Dick Hollenbeck's avatar
Dick Hollenbeck committed
834
        module->CalculateBoundingBox();
835 836 837
        m_CurrentPad->DisplayInfo( m_Parent );

        // redraw the area where the pad was
838
        m_Parent->GetCanvas()->RefreshDrawingRect( m_CurrentPad->GetBoundingBox() );
839 840 841 842 843 844 845 846 847
        m_Parent->OnModify();
    }

    EndModal( wxID_OK );

    if( rastnestIsChanged )  // The net ratsnest must be recalculated
        m_Parent->GetBoard()->m_Status_Pcb = 0;
}

Dick Hollenbeck's avatar
Dick Hollenbeck committed
848

849
bool DIALOG_PAD_PROPERTIES::transferDataToPad( D_PAD* aPad )
850
{
Dick Hollenbeck's avatar
Dick Hollenbeck committed
851 852 853
    long        padLayerMask;
    wxString    msg;
    int         x, y;
854

Dick Hollenbeck's avatar
Dick Hollenbeck committed
855 856
    aPad->SetAttribute( CodeType[m_PadType->GetSelection()] );
    aPad->SetShape( CodeShape[m_PadShape->GetSelection()] );
857 858

    // Read pad clearances values:
859 860 861 862 863
    aPad->SetLocalClearance( ReturnValueFromTextCtrl( *m_NetClearanceValueCtrl ) );
    aPad->SetLocalSolderMaskMargin( ReturnValueFromTextCtrl( *m_SolderMaskMarginCtrl ) );
    aPad->SetLocalSolderPasteMargin( ReturnValueFromTextCtrl( *m_SolderPasteMarginCtrl ) );
    aPad->SetThermalWidth( ReturnValueFromTextCtrl( *m_ThermalWidthCtrl ) );
    aPad->SetThermalGap( ReturnValueFromTextCtrl( *m_ThermalGapCtrl ) );
864
    double dtmp = 0.0;
865 866
    msg = m_SolderPasteMarginRatioCtrl->GetValue();
    msg.ToDouble( &dtmp );
867

868 869 870 871 872 873 874
    // 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;
Dick Hollenbeck's avatar
Dick Hollenbeck committed
875 876

    aPad->SetLocalSolderPasteMarginRatio( dtmp / 100 );
877

878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897
    switch( m_ZoneConnectionChoice->GetSelection() )
    {
    default:
    case 0:
        aPad->SetZoneConnection( UNDEFINED_CONNECTION );
        break;

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

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

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

898
    // Read pad position:
899 900
    x = ReturnValueFromTextCtrl( *m_PadPosition_X_Ctrl );
    y = ReturnValueFromTextCtrl( *m_PadPosition_Y_Ctrl );
Dick Hollenbeck's avatar
Dick Hollenbeck committed
901 902 903

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

    // Read pad drill:
906 907
    x = ReturnValueFromTextCtrl( *m_PadDrill_X_Ctrl );
    y = ReturnValueFromTextCtrl( *m_PadDrill_Y_Ctrl );
Dick Hollenbeck's avatar
Dick Hollenbeck committed
908

909 910
    if( m_DrillShapeCtrl->GetSelection() == 0 )
    {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
911 912
        aPad->SetDrillShape( PAD_CIRCLE );
        y = x;
913 914
    }
    else
Dick Hollenbeck's avatar
Dick Hollenbeck committed
915 916 917
        aPad->SetDrillShape( PAD_OVAL );

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

    // Read pad shape size:
920 921
    x = ReturnValueFromTextCtrl( *m_ShapeSize_X_Ctrl );
    y = ReturnValueFromTextCtrl( *m_ShapeSize_Y_Ctrl );
Dick Hollenbeck's avatar
Dick Hollenbeck committed
922 923 924 925 926 927
    if( aPad->GetShape() == PAD_CIRCLE )
        y = x;

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

    // Read pad length die
928
    aPad->SetDieLength( ReturnValueFromTextCtrl( *m_LengthDieCtrl ) );
929 930

    // Read pad shape delta size:
931
    // m_DeltaSize.x or m_DeltaSize.y must be NULL. for a trapezoid.
932
    wxSize delta;
Dick Hollenbeck's avatar
Dick Hollenbeck committed
933

934
    if( m_trapDeltaDirChoice->GetSelection() == 0 )
935
        delta.x = ReturnValueFromTextCtrl( *m_ShapeDelta_Ctrl );
936
    else
937
        delta.y = ReturnValueFromTextCtrl( *m_ShapeDelta_Ctrl );
938

Dick Hollenbeck's avatar
Dick Hollenbeck committed
939
    // Test bad values (be sure delta values are not too large)
940
    // remember DeltaSize.x is the Y size variation
941
    bool   error    = false;
Dick Hollenbeck's avatar
Dick Hollenbeck committed
942 943

    if( delta.x < 0 && delta.x <= -aPad->GetSize().y )
944
    {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
945
        delta.x = -aPad->GetSize().y + 2;
946 947
        error = true;
    }
Dick Hollenbeck's avatar
Dick Hollenbeck committed
948 949

    if( delta.x > 0 && delta.x >= aPad->GetSize().y )
950
    {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
951
        delta.x = aPad->GetSize().y - 2;
952 953
        error = true;
    }
Dick Hollenbeck's avatar
Dick Hollenbeck committed
954 955

    if( delta.y < 0 && delta.y <= -aPad->GetSize().x )
956
    {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
957
        delta.y = -aPad->GetSize().x + 2;
958 959
        error = true;
    }
Dick Hollenbeck's avatar
Dick Hollenbeck committed
960 961

    if( delta.y > 0 && delta.y >= aPad->GetSize().x )
962
    {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
963
        delta.y = aPad->GetSize().x - 2;
964 965
        error = true;
    }
966

Dick Hollenbeck's avatar
Dick Hollenbeck committed
967 968
    aPad->SetDelta( delta );

969
    // Read pad shape offset:
970 971
    x = ReturnValueFromTextCtrl( *m_ShapeOffset_X_Ctrl );
    y = ReturnValueFromTextCtrl( *m_ShapeOffset_Y_Ctrl );
Dick Hollenbeck's avatar
Dick Hollenbeck committed
972
    aPad->SetOffset( wxPoint( x, y ) );
973

974
    double orient_value = 0;
975
    msg = m_PadOrientCtrl->GetValue();
976 977 978
    msg.ToDouble( &orient_value );

    aPad->SetOrientation( orient_value );
979

980 981 982
    msg = m_PadNumCtrl->GetValue().Left( 4 );
    aPad->SetPadName( msg );
    aPad->SetNetname( m_PadNetNameCtrl->GetValue() );
983

charras's avatar
charras committed
984
    // Clear some values, according to the pad type and shape
Dick Hollenbeck's avatar
Dick Hollenbeck committed
985
    switch( aPad->GetShape() )
charras's avatar
charras committed
986 987
    {
    case PAD_CIRCLE:
Dick Hollenbeck's avatar
Dick Hollenbeck committed
988 989 990 991
        aPad->SetOffset( wxPoint( 0, 0 ) );
        aPad->SetDelta( wxSize( 0, 0 ) );
        x = aPad->GetSize().x;
        aPad->SetSize( wxSize( x, x ) );
charras's avatar
charras committed
992 993 994
        break;

    case PAD_RECT:
Dick Hollenbeck's avatar
Dick Hollenbeck committed
995
        aPad->SetDelta( wxSize( 0, 0 ) );
charras's avatar
charras committed
996 997 998
        break;

    case PAD_OVAL:
Dick Hollenbeck's avatar
Dick Hollenbeck committed
999
        aPad->SetDelta( wxSize( 0, 0 ) );
charras's avatar
charras committed
1000 1001 1002 1003
        break;

    case PAD_TRAPEZOID:
        break;
Dick Hollenbeck's avatar
Dick Hollenbeck committed
1004 1005 1006

    default:
        ;
charras's avatar
charras committed
1007 1008
    }

Dick Hollenbeck's avatar
Dick Hollenbeck committed
1009
    switch( aPad->GetAttribute() )
charras's avatar
charras committed
1010 1011 1012 1013 1014 1015
    {
    case PAD_STANDARD:
        break;

    case PAD_CONN:
    case PAD_SMD:
1016 1017 1018 1019 1020 1021
        // SMD and PAD_CONN has no hole.
        // basically, SMD and PAD_CONN are same type of pads
        // PAD_CONN has just a default non technical layers that differs frm 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 from basic pad shapes
Dick Hollenbeck's avatar
Dick Hollenbeck committed
1022
        aPad->SetDrillSize( wxSize( 0, 0 ) );
charras's avatar
charras committed
1023 1024 1025
        break;

    case PAD_HOLE_NOT_PLATED:
1026 1027
        // Mechanical purpose only:
        // no offset, no net name, no pad name allowed
Dick Hollenbeck's avatar
Dick Hollenbeck committed
1028
        aPad->SetOffset( wxPoint( 0, 0 ) );
1029 1030
        aPad->SetPadName( wxEmptyString );
        aPad->SetNetname( wxEmptyString );
charras's avatar
charras committed
1031 1032 1033
        break;

    default:
1034
        DisplayError( NULL, wxT( "Error: unknown pad type" ) );
charras's avatar
charras committed
1035 1036 1037
        break;
    }

Dick Hollenbeck's avatar
Dick Hollenbeck committed
1038 1039
    padLayerMask = 0;

1040 1041
    switch( m_rbCopperLayersSel->GetSelection() )
    {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
1042 1043 1044
    case 0:
        padLayerMask |= LAYER_FRONT;
        break;
1045

Dick Hollenbeck's avatar
Dick Hollenbeck committed
1046 1047 1048
    case 1:
        padLayerMask |= LAYER_BACK;
        break;
1049

Dick Hollenbeck's avatar
Dick Hollenbeck committed
1050 1051 1052
    case 2:
        padLayerMask |= ALL_CU_LAYERS;
        break;
1053

Dick Hollenbeck's avatar
Dick Hollenbeck committed
1054 1055
    case 3:     // No copper layers
        break;
1056 1057
    }

1058
    if( m_PadLayerAdhCmp->GetValue() )
Dick Hollenbeck's avatar
Dick Hollenbeck committed
1059
        padLayerMask |= ADHESIVE_LAYER_FRONT;
1060
    if( m_PadLayerAdhCu->GetValue() )
Dick Hollenbeck's avatar
Dick Hollenbeck committed
1061
        padLayerMask |= ADHESIVE_LAYER_BACK;
1062
    if( m_PadLayerPateCmp->GetValue() )
Dick Hollenbeck's avatar
Dick Hollenbeck committed
1063
        padLayerMask |= SOLDERPASTE_LAYER_FRONT;
1064
    if( m_PadLayerPateCu->GetValue() )
Dick Hollenbeck's avatar
Dick Hollenbeck committed
1065
        padLayerMask |= SOLDERPASTE_LAYER_BACK;
1066
    if( m_PadLayerSilkCmp->GetValue() )
Dick Hollenbeck's avatar
Dick Hollenbeck committed
1067
        padLayerMask |= SILKSCREEN_LAYER_FRONT;
1068
    if( m_PadLayerSilkCu->GetValue() )
Dick Hollenbeck's avatar
Dick Hollenbeck committed
1069
        padLayerMask |= SILKSCREEN_LAYER_BACK;
1070
    if( m_PadLayerMaskCmp->GetValue() )
Dick Hollenbeck's avatar
Dick Hollenbeck committed
1071
        padLayerMask |= SOLDERMASK_LAYER_FRONT;
1072
    if( m_PadLayerMaskCu->GetValue() )
Dick Hollenbeck's avatar
Dick Hollenbeck committed
1073
        padLayerMask |= SOLDERMASK_LAYER_BACK;
1074
    if( m_PadLayerECO1->GetValue() )
Dick Hollenbeck's avatar
Dick Hollenbeck committed
1075
        padLayerMask |= ECO1_LAYER;
1076
    if( m_PadLayerECO2->GetValue() )
Dick Hollenbeck's avatar
Dick Hollenbeck committed
1077
        padLayerMask |= ECO2_LAYER;
1078
    if( m_PadLayerDraft->GetValue() )
Dick Hollenbeck's avatar
Dick Hollenbeck committed
1079
        padLayerMask |= DRAW_LAYER;
1080

Dick Hollenbeck's avatar
Dick Hollenbeck committed
1081
    aPad->SetLayerMask( padLayerMask );
charras's avatar
charras committed
1082

1083
    return error;
1084
}
1085

1086

1087 1088 1089 1090
void DIALOG_PAD_PROPERTIES::OnValuesChanged( wxCommandEvent& event )
{
    if( m_canUpdate )
    {
1091
        transferDataToPad( m_dummyPad );
1092
        m_panelShowPad->Refresh();
1093 1094
    }
}
1095

1096

1097
void DIALOG_PAD_PROPERTIES::OnCancelButtonClick( wxCommandEvent& event )
1098
{
1099
    EndModal( wxID_CANCEL );
1100
}