dialog_copper_zones.cpp 22 KB
Newer Older
1 2 3 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
/**
 * @file dialog_copper_zones.cpp
 */

/*
 * This program source code file is part of KiCad, a free EDA CAD application.
 *
 * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
 * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
  * 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
 */
29

30
#include <wx/wx.h>
31 32 33 34 35 36 37
#include <fctsys.h>
#include <appl_wxstruct.h>
#include <confirm.h>
#include <PolyLine.h>
#include <pcbnew.h>
#include <wxPcbStruct.h>
#include <zones.h>
38
#include <base_units.h>
39

40
#include <class_zone.h>
41
#include <class_board.h>
Dick Hollenbeck's avatar
Dick Hollenbeck committed
42
#include <dialog_copper_zones_base.h>
43 44

#include <wx/imaglist.h>    // needed for wx/listctrl.h, in wxGTK 2.8.12
45
#include <wx/listctrl.h>
46
#include <layers_id_colors_and_visibility.h>
47

Dick Hollenbeck's avatar
Dick Hollenbeck committed
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72

/**
 * Class DIALOG_COPPER_ZONE
 * is the derived class from dialog_copper_zone_frame created by wxFormBuilder
 */
class DIALOG_COPPER_ZONE : public DIALOG_COPPER_ZONE_BASE
{
public:
    DIALOG_COPPER_ZONE( PCB_BASE_FRAME* aParent, ZONE_SETTINGS* aSettings );

private:
    PCB_BASE_FRAME* m_Parent;
    wxConfig*       m_Config;               ///< Current config

    ZONE_EDIT_T     m_OnExitCode;           ///< exit code: ZONE_ABORT if no change,
                                            ///< ZONE_OK if new values accepted
                                            ///< ZONE_EXPORT_VALUES if values are exported to others zones

    ZONE_SETTINGS   m_settings;
    ZONE_SETTINGS*  m_ptr;

    bool            m_NetSortingByPadCount; ///< false = alphabetic sort.
                                            ///< true = pad count sort.

    long            m_NetFiltering;
73
    std::vector<LAYER_NUM> m_LayerId;       ///< Handle the real layer number from layer
Dick Hollenbeck's avatar
Dick Hollenbeck committed
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
                                            ///< name position in m_LayerSelectionCtrl

    static wxString m_netNameShowFilter;    ///< the filter to show nets (default * "*").
                                            ///< static to keep this pattern for an entire pcbnew session

    /**
     * Function initDialog
     * fills in the dialog controls using the current settings.
     */
    void initDialog();

    void OnButtonOkClick( wxCommandEvent& event );
    void OnButtonCancelClick( wxCommandEvent& event );
    void OnClose( wxCloseEvent& event );
    void OnCornerSmoothingModeChoice( wxCommandEvent& event );

    /**
     * Function AcceptOptions
     * @param aPromptForErrors is true to prompt user on incorrect params.
     * @param aUseExportableSetupOnly is true to use exportable parametres only (used to export this setup to other zones).
     * @return bool - false if incorrect options, true if ok.
     */
    bool AcceptOptions( bool aPromptForErrors, bool aUseExportableSetupOnly = false );

    void OnNetSortingOptionSelected( wxCommandEvent& event );
    void ExportSetupToOtherCopperZones( wxCommandEvent& event );
    void OnPadsInZoneClick( wxCommandEvent& event );
    void OnRunFiltersButtonClick( wxCommandEvent& event );


    void buildAvailableListOfNets();

    /**
     * Function initListNetsParams
     * initializes m_NetSortingByPadCount and m_NetFiltering values
     * according to m_NetDisplayOption selection.
     */
    void initListNetsParams();

    /**
     * Function makeLayerBitmap
     * creates the colored rectangle bitmaps used in the layer selection widget.
     * @param aColor is the color to fill the rectangle with.
     */
118
    wxBitmap makeLayerBitmap( EDA_COLOR_T aColor );
Dick Hollenbeck's avatar
Dick Hollenbeck committed
119 120 121 122 123
};


#define LAYER_BITMAP_SIZE_X     20
#define LAYER_BITMAP_SIZE_Y     10
124

125 126
// Initialize static member variables
wxString DIALOG_COPPER_ZONE::m_netNameShowFilter( wxT( "*" ) );
127

128

Dick Hollenbeck's avatar
Dick Hollenbeck committed
129 130 131 132 133 134 135 136 137 138 139
ZONE_EDIT_T InvokeCopperZonesEditor( PCB_BASE_FRAME* aCaller, ZONE_SETTINGS* aSettings )
{
    DIALOG_COPPER_ZONE dlg( aCaller, aSettings );

    ZONE_EDIT_T result = ZONE_EDIT_T( dlg.ShowModal() );
    return result;
}


DIALOG_COPPER_ZONE::DIALOG_COPPER_ZONE( PCB_BASE_FRAME* aParent, ZONE_SETTINGS* aSettings ) :
    DIALOG_COPPER_ZONE_BASE( aParent )
140
{
Dick Hollenbeck's avatar
Dick Hollenbeck committed
141
    m_Parent = aParent;
142
    m_Config = wxGetApp().GetSettings();
Dick Hollenbeck's avatar
Dick Hollenbeck committed
143 144 145 146 147

    m_ptr = aSettings;
    m_settings = *aSettings;

    m_NetSortingByPadCount = true;      // false = alphabetic sort, true = pad count sort
148
    m_OnExitCode = ZONE_ABORT;
149

Dick Hollenbeck's avatar
Dick Hollenbeck committed
150
    SetReturnCode( ZONE_ABORT );        // Will be changed on buttons click
151

152 153 154 155 156
    // Fix static text widget minimum width to a suitable value so that
    // resizing the dialog is not necessary when changing the corner smoothing type.
    // Depends on the default text in the widget.
    m_cornerSmoothingTitle->SetMinSize( m_cornerSmoothingTitle->GetSize() );

charras's avatar
charras committed
157
    initDialog();
charras's avatar
charras committed
158

charras's avatar
charras committed
159
    GetSizer()->SetSizeHints( this );
160
    Center();
161 162 163
}


164
void DIALOG_COPPER_ZONE::initDialog()
165
{
166
    BOARD* board = m_Parent->GetBoard();
167

168
    wxString msg;
169

Dick Hollenbeck's avatar
Dick Hollenbeck committed
170
    if( m_settings.m_Zone_45_Only )
171 172
        m_OrientEdgesOpt->SetSelection( 1 );

Dick Hollenbeck's avatar
Dick Hollenbeck committed
173
    m_FillModeCtrl->SetSelection( m_settings.m_FillMode ? 1 : 0 );
174

175
    AddUnitSymbol( *m_ClearanceValueTitle, g_UserUnit );
176
    msg = ReturnStringFromValue( g_UserUnit, m_settings.m_ZoneClearance );
177 178
    m_ZoneClearanceCtrl->SetValue( msg );

179
    AddUnitSymbol( *m_MinThicknessValueTitle, g_UserUnit );
180
    msg = ReturnStringFromValue( g_UserUnit, m_settings.m_ZoneMinThickness );
181 182
    m_ZoneMinThicknessCtrl->SetValue( msg );

183
    switch( m_settings.GetPadConnection() )
184
    {
185
    case THT_THERMAL:               // Thermals only for THT pads
186 187 188
        m_PadInZoneOpt->SetSelection( 2 );
        break;

189 190 191 192
    case PAD_NOT_IN_ZONE:           // Pads are not covered
        m_PadInZoneOpt->SetSelection( 3 );
        break;

193
    default:
194 195 196 197 198 199 200 201 202
    case THERMAL_PAD:               // Use thermal relief for pads
        m_PadInZoneOpt->SetSelection( 1 );
        break;

    case PAD_IN_ZONE:               // pads are covered by copper
        m_PadInZoneOpt->SetSelection( 0 );
        break;
    }

203 204 205
    // Antipad and spokes are significant only for thermals
    if( m_settings.GetPadConnection() != THERMAL_PAD &&
        m_settings.GetPadConnection() != THT_THERMAL )
206 207 208 209 210 211 212 213 214 215
    {
        m_AntipadSizeValue->Enable( false );
        m_CopperWidthValue->Enable( false );
    }
    else
    {
        m_AntipadSizeValue->Enable( true );
        m_CopperWidthValue->Enable( true );
    }

Dick Hollenbeck's avatar
Dick Hollenbeck committed
216
    m_PriorityLevelCtrl->SetValue( m_settings.m_ZonePriority );
217

218 219
    AddUnitSymbol( *m_AntipadSizeText, g_UserUnit );
    AddUnitSymbol( *m_CopperBridgeWidthText, g_UserUnit );
220 221
    PutValueInLocalUnits( *m_AntipadSizeValue, m_settings.m_ThermalReliefGap );
    PutValueInLocalUnits( *m_CopperWidthValue, m_settings.m_ThermalReliefCopperBridge );
222

Dick Hollenbeck's avatar
Dick Hollenbeck committed
223
    m_cornerSmoothingChoice->SetSelection( m_settings.GetCornerSmoothingType() );
224

225
    PutValueInLocalUnits( *m_cornerSmoothingCtrl, m_settings.GetCornerRadius() );
226

Dick Hollenbeck's avatar
Dick Hollenbeck committed
227
    switch( m_settings.m_Zone_HatchingStyle )
228 229 230 231 232 233 234 235 236 237 238 239 240 241
    {
    case CPolyLine::NO_HATCH:
        m_OutlineAppearanceCtrl->SetSelection( 0 );
        break;

    case CPolyLine::DIAGONAL_EDGE:
        m_OutlineAppearanceCtrl->SetSelection( 1 );
        break;

    case CPolyLine::DIAGONAL_FULL:
        m_OutlineAppearanceCtrl->SetSelection( 2 );
        break;
    }

242
    m_ArcApproximationOpt->SetSelection(
Dick Hollenbeck's avatar
Dick Hollenbeck committed
243
        m_settings.m_ArcToSegmentsCount == ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF ? 1 : 0 );
244

245
    // Create one column in m_LayerSelectionCtrl
246 247 248
    wxListItem column0;
    column0.SetId( 0 );
    m_LayerSelectionCtrl->InsertColumn( 0, column0 );
249 250 251 252
    // Build copper layer list and append to layer widget
    int layerCount = board->GetCopperLayerCount();
    wxImageList* imageList = new wxImageList( LAYER_BITMAP_SIZE_X, LAYER_BITMAP_SIZE_Y );
    m_LayerSelectionCtrl->AssignImageList( imageList, wxIMAGE_LIST_SMALL );
253
    int ctrlWidth = 0;  // Min width for m_LayerSelectionCtrl to show the layers names
254
    for( LAYER_NUM ii = FIRST_LAYER; ii < layerCount; ++ii )
255
    {
256
        LAYER_NUM layerNumber = LAYER_N_BACK;
257

258 259 260 261
        if( layerCount <= 1 || ii < layerCount - 1 )
            layerNumber = ii;
        else if( ii == layerCount - 1 )
            layerNumber = LAYER_N_FRONT;
262

263
        m_LayerId.insert( m_LayerId.begin(), layerNumber );
264

265
        msg = board->GetLayerName( layerNumber ).Trim();
266
        EDA_COLOR_T layerColor = board->GetLayerColor( layerNumber );
267
        imageList->Add( makeLayerBitmap( layerColor ) );
268
        int itemIndex = m_LayerSelectionCtrl->InsertItem( 0, msg, ii );
269

Dick Hollenbeck's avatar
Dick Hollenbeck committed
270
        if( m_settings.m_CurrentZone_Layer == layerNumber )
271
            m_LayerSelectionCtrl->Select( itemIndex );
272 273 274

        wxSize tsize( GetTextSize( msg, m_LayerSelectionCtrl ) );
        ctrlWidth = std::max( ctrlWidth, tsize.x );
275 276
    }

277 278 279 280 281 282 283 284
    // The most easy way to ensure the right size is to use wxLIST_AUTOSIZE
    // unfortunately this option does not work well both on
    // wxWidgets 2.8 ( column witdth too small), and
    // wxWidgets 2.9 ( column witdth too large)
    ctrlWidth += LAYER_BITMAP_SIZE_X + 16;      // Add bitmap width + margin between bitmap and text
    m_LayerSelectionCtrl->SetColumnWidth( 0, ctrlWidth );
    ctrlWidth += 4;     // add small margin between text and window borders
    m_LayerSelectionCtrl->SetMinSize( wxSize(ctrlWidth, -1));
285

286
    wxString netNameDoNotShowFilter = wxT( "Net-*" );
287
    if( m_Config )
288
    {
289 290 291
        int opt = m_Config->Read( ZONE_NET_SORT_OPTION_KEY, 1l );
        m_NetDisplayOption->SetSelection( opt );
        m_Config->Read( ZONE_NET_FILTER_STRING_KEY, netNameDoNotShowFilter );
292
    }
293 294
    else
        m_NetDisplayOption->SetSelection( 1 );
295

296
    m_ShowNetNameFilter->SetValue( m_netNameShowFilter );
297
    initListNetsParams();
298

299 300 301
    // Build list of nets:
    m_DoNotShowNetNameFilter->SetValue( netNameDoNotShowFilter );
    buildAvailableListOfNets();
302 303 304

    wxCommandEvent event;
    OnCornerSmoothingModeChoice( event );
305 306 307
}


308
void DIALOG_COPPER_ZONE::OnButtonCancelClick( wxCommandEvent& event )
309 310 311 312
{
    Close( true );
}

Dick Hollenbeck's avatar
Dick Hollenbeck committed
313 314 315 316 317 318
void DIALOG_COPPER_ZONE::OnButtonOkClick( wxCommandEvent& event )
{
    m_netNameShowFilter = m_ShowNetNameFilter->GetValue();

    if( AcceptOptions( true ) )
    {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
319
        *m_ptr = m_settings;
Dick Hollenbeck's avatar
Dick Hollenbeck committed
320 321 322 323
        EndModal( ZONE_OK );
    }
}

324

Dick Hollenbeck's avatar
Dick Hollenbeck committed
325
// called on system close button
326
void DIALOG_COPPER_ZONE::OnClose( wxCloseEvent& event )
327
{
Dick Hollenbeck's avatar
Dick Hollenbeck committed
328 329 330
    if( m_OnExitCode != ZONE_ABORT )
        *m_ptr = m_settings;

331
    EndModal( m_OnExitCode );
332 333 334
}


335
bool DIALOG_COPPER_ZONE::AcceptOptions( bool aPromptForErrors, bool aUseExportableSetupOnly )
336 337 338
{
    switch( m_PadInZoneOpt->GetSelection() )
    {
339
    case 3:
Dick Hollenbeck's avatar
Dick Hollenbeck committed
340
        // Pads are not covered
341
        m_settings.SetPadConnection( PAD_NOT_IN_ZONE );
342 343
        break;

344 345 346 347 348
    case 2:
        // Use thermal relief for THT pads
        m_settings.SetPadConnection( THT_THERMAL );
        break;

349
    case 1:
Dick Hollenbeck's avatar
Dick Hollenbeck committed
350
        // Use thermal relief for pads
351
        m_settings.SetPadConnection( THERMAL_PAD );
352 353 354
        break;

    case 0:
Dick Hollenbeck's avatar
Dick Hollenbeck committed
355
        // pads are covered by copper
356
        m_settings.SetPadConnection( PAD_IN_ZONE );
357 358 359 360 361 362
        break;
    }

    switch( m_OutlineAppearanceCtrl->GetSelection() )
    {
    case 0:
Dick Hollenbeck's avatar
Dick Hollenbeck committed
363
        m_settings.m_Zone_HatchingStyle = CPolyLine::NO_HATCH;
364 365 366
        break;

    case 1:
Dick Hollenbeck's avatar
Dick Hollenbeck committed
367
        m_settings.m_Zone_HatchingStyle = CPolyLine::DIAGONAL_EDGE;
368 369 370
        break;

    case 2:
Dick Hollenbeck's avatar
Dick Hollenbeck committed
371
        m_settings.m_Zone_HatchingStyle = CPolyLine::DIAGONAL_FULL;
372 373 374
        break;
    }

Dick Hollenbeck's avatar
Dick Hollenbeck committed
375
    m_settings.m_ArcToSegmentsCount = m_ArcApproximationOpt->GetSelection() == 1 ?
376 377
                                           ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF :
                                           ARC_APPROX_SEGMENTS_COUNT_LOW_DEF;
378

379
    if( m_Config )
380
    {
381
        m_Config->Write( ZONE_NET_OUTLINES_HATCH_OPTION_KEY,
Dick Hollenbeck's avatar
Dick Hollenbeck committed
382 383 384
                         (long) m_settings.m_Zone_HatchingStyle );
        wxString filter = m_DoNotShowNetNameFilter->GetValue();
        m_Config->Write( ZONE_NET_FILTER_STRING_KEY, filter );
385 386
    }

387
    m_netNameShowFilter = m_ShowNetNameFilter->GetValue();
Dick Hollenbeck's avatar
Dick Hollenbeck committed
388
    m_settings.m_FillMode = (m_FillModeCtrl->GetSelection() == 0) ? 0 : 1;
389 390

    wxString txtvalue = m_ZoneClearanceCtrl->GetValue();
391
    m_settings.m_ZoneClearance = ReturnValueFromString( g_UserUnit, txtvalue );
392

393
    // Test if this is a reasonable value for this parameter
394
    // A too large value can hang Pcbnew
395
    #define CLEARANCE_MAX_VALUE ZONE_CLEARANCE_MAX_VALUE_MIL*IU_PER_MILS
Dick Hollenbeck's avatar
Dick Hollenbeck committed
396
    if( m_settings.m_ZoneClearance > CLEARANCE_MAX_VALUE )
397
    {
398 399 400 401
        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 );
402 403 404
        return false;
    }

405
    txtvalue = m_ZoneMinThicknessCtrl->GetValue();
406 407
    m_settings.m_ZoneMinThickness = ReturnValueFromString( g_UserUnit, txtvalue );

408
    if( m_settings.m_ZoneMinThickness < (ZONE_THICKNESS_MIN_VALUE_MIL*IU_PER_MILS) )
409
    {
410 411 412 413
        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 );
414 415
        return false;
    }
416

Dick Hollenbeck's avatar
Dick Hollenbeck committed
417
    m_settings.SetCornerSmoothingType( m_cornerSmoothingChoice->GetSelection() );
418
    txtvalue = m_cornerSmoothingCtrl->GetValue();
419
    m_settings.SetCornerRadius( ReturnValueFromString( g_UserUnit, txtvalue ) );
420

Dick Hollenbeck's avatar
Dick Hollenbeck committed
421
    m_settings.m_ZonePriority = m_PriorityLevelCtrl->GetValue();
422

423
    if( m_OrientEdgesOpt->GetSelection() == 0 )
Dick Hollenbeck's avatar
Dick Hollenbeck committed
424
        m_settings.m_Zone_45_Only = false;
425
    else
Dick Hollenbeck's avatar
Dick Hollenbeck committed
426 427
        m_settings.m_Zone_45_Only = true;

428 429
    m_settings.m_ThermalReliefGap = ReturnValueFromTextCtrl( *m_AntipadSizeValue );
    m_settings.m_ThermalReliefCopperBridge = ReturnValueFromTextCtrl( *m_CopperWidthValue );
430

431 432
    if( m_Config )
    {
433 434
        ConfigBaseWriteDouble( m_Config, ZONE_CLEARANCE_WIDTH_STRING_KEY,
                               (double) m_settings.m_ZoneClearance / IU_PER_MILS );
435

436
        ConfigBaseWriteDouble( m_Config, ZONE_MIN_THICKNESS_WIDTH_STRING_KEY,
437
            (double) m_settings.m_ZoneMinThickness / IU_PER_MILS );
charras's avatar
charras committed
438

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

442
        ConfigBaseWriteDouble( m_Config, ZONE_THERMAL_RELIEF_COPPER_WIDTH_STRING_KEY,
443 444
            (double) m_settings.m_ThermalReliefCopperBridge / IU_PER_MILS );
    }
Dick Hollenbeck's avatar
Dick Hollenbeck committed
445 446

    if( m_settings.m_ThermalReliefCopperBridge <= m_settings.m_ZoneMinThickness )
charras's avatar
charras committed
447
    {
448
        DisplayError( this,
449
                     _( "Thermal relief spoke width is smaller than the minimum width." ) );
charras's avatar
charras committed
450 451
        return false;
    }
452 453 454 455 456

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

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

460 461
    if( ii < 0 && aPromptForErrors )
    {
462
        DisplayError( this, _( "No layer selected." ) );
463 464 465
        return false;
    }

Dick Hollenbeck's avatar
Dick Hollenbeck committed
466
    m_settings.m_CurrentZone_Layer = m_LayerId[ii];
467

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

471 472
    if( ii < 0 && aPromptForErrors )
    {
473
        DisplayError( this, _( "No net selected." ) );
474 475 476
        return false;
    }

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

485 486
    wxString net_name = m_ListNetNameSelection->GetString( ii );

Dick Hollenbeck's avatar
Dick Hollenbeck committed
487
    m_settings.m_NetcodeSelection = 0;
488

489
    // Search net_code for this net, if a net was selected
490
    if( m_ListNetNameSelection->GetSelection() > 0 )
491
    {
492
        NETINFO_ITEM* net = m_Parent->GetBoard()->FindNet( net_name );
493
        if( net )
Dick Hollenbeck's avatar
Dick Hollenbeck committed
494
            m_settings.m_NetcodeSelection = net->GetNet();
495 496 497 498 499
    }

    return true;
}

Dick Hollenbeck's avatar
Dick Hollenbeck committed
500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524
void DIALOG_COPPER_ZONE::OnCornerSmoothingModeChoice( wxCommandEvent& event )
{
    int selection = m_cornerSmoothingChoice->GetSelection();

    switch( selection )
    {
    case ZONE_SETTINGS::SMOOTHING_NONE:
        m_cornerSmoothingTitle->Enable( false );
        m_cornerSmoothingCtrl->Enable( false );
        break;
    case ZONE_SETTINGS::SMOOTHING_CHAMFER:
        m_cornerSmoothingTitle->Enable( true );
        m_cornerSmoothingCtrl->Enable( true );
        m_cornerSmoothingTitle->SetLabel( _( "Chamfer distance" ) );
        AddUnitSymbol( *m_cornerSmoothingTitle, g_UserUnit );
        break;
    case ZONE_SETTINGS::SMOOTHING_FILLET:
        m_cornerSmoothingTitle->Enable( true );
        m_cornerSmoothingCtrl->Enable( true );
        m_cornerSmoothingTitle->SetLabel( _( "Fillet radius" ) );
        AddUnitSymbol( *m_cornerSmoothingTitle, g_UserUnit );
        break;
    }
}

525

526
void DIALOG_COPPER_ZONE::OnNetSortingOptionSelected( wxCommandEvent& event )
527
{
528 529
    initListNetsParams();
    buildAvailableListOfNets();
530

531
    m_netNameShowFilter = m_ShowNetNameFilter->GetValue();
532
    if( m_Config )
533
    {
534 535
        m_Config->Write( ZONE_NET_SORT_OPTION_KEY, (long) m_NetDisplayOption->GetSelection() );
        wxString Filter = m_DoNotShowNetNameFilter->GetValue();
536
        m_Config->Write( ZONE_NET_FILTER_STRING_KEY, Filter );
537 538 539 540
    }
}


541
void DIALOG_COPPER_ZONE::ExportSetupToOtherCopperZones( wxCommandEvent& event )
542 543 544 545
{
    if( !AcceptOptions( true, true ) )
        return;

546
    // Export settings ( but layer and netcode ) to others copper zones
547
    BOARD* pcb = m_Parent->GetBoard();
548 549 550
    for( int ii = 0; ii < pcb->GetAreaCount(); ii++ )
    {
        ZONE_CONTAINER* zone = pcb->GetArea( ii );
551 552 553 554 555

        // Cannot export settings from a copper zone
        // to a zone keepout:
        if( zone->GetIsKeepout() )
            continue;
Dick Hollenbeck's avatar
Dick Hollenbeck committed
556
        m_settings.ExportSetting( *zone, false );  // false = partial export
557
        m_Parent->OnModify();
558
    }
559

560
    m_OnExitCode = ZONE_EXPORT_VALUES;     // values are exported to others zones
561 562 563
}


564
void DIALOG_COPPER_ZONE::OnPadsInZoneClick( wxCommandEvent& event )
565 566 567 568 569 570 571 572
{
    switch( m_PadInZoneOpt->GetSelection() )
    {
    default:
        m_AntipadSizeValue->Enable( false );
        m_CopperWidthValue->Enable( false );
        break;

573
    case 2:
574 575 576 577 578 579
    case 1:
        m_AntipadSizeValue->Enable( true );
        m_CopperWidthValue->Enable( true );
        break;
    }
}
580 581


582
void DIALOG_COPPER_ZONE::initListNetsParams()
583 584 585 586
{
    switch( m_NetDisplayOption->GetSelection() )
    {
    case 0:
587
        m_NetSortingByPadCount = false;
588 589 590 591
        m_NetFiltering = false;
        break;

    case 1:
592
        m_NetSortingByPadCount = true;
593 594 595 596
        m_NetFiltering = false;
        break;

    case 2:
597
        m_NetSortingByPadCount = false;
598 599 600 601
        m_NetFiltering = true;
        break;

    case 3:
602
        m_NetSortingByPadCount = true;
603 604 605 606 607 608
        m_NetFiltering = true;
        break;
    }
}


609
void DIALOG_COPPER_ZONE::OnRunFiltersButtonClick( wxCommandEvent& event )
610 611
{
    m_netNameShowFilter = m_ShowNetNameFilter->GetValue();
612

613
    // Ensure filtered option for nets
614 615 616 617 618 619 620 621 622
    if( m_NetDisplayOption->GetSelection() == 0 )
        m_NetDisplayOption->SetSelection( 2 );
    else if( m_NetDisplayOption->GetSelection() == 1 )
        m_NetDisplayOption->SetSelection( 3 );
    initListNetsParams();
    buildAvailableListOfNets();
}


623
void DIALOG_COPPER_ZONE::buildAvailableListOfNets()
624
{
625
    wxArrayString   listNetName;
626

627
    m_Parent->GetBoard()->ReturnSortedNetnamesList( listNetName, m_NetSortingByPadCount );
628 629 630 631 632

    if( m_NetFiltering )
    {
        wxString doNotShowFilter = m_DoNotShowNetNameFilter->GetValue();
        wxString ShowFilter = m_ShowNetNameFilter->GetValue();
633

634 635 636 637 638 639 640 641 642 643 644 645 646 647
        for( unsigned ii = 0; ii < listNetName.GetCount(); ii++ )
        {
            if( listNetName[ii].Matches( doNotShowFilter ) )
            {
                listNetName.RemoveAt( ii );
                ii--;
            }
            else if( !listNetName[ii].Matches( ShowFilter ) )
            {
                listNetName.RemoveAt( ii );
                ii--;
            }
        }
    }
648

649 650
    listNetName.Insert( wxT( "<no net>" ), 0 );

651 652
    // Ensure currently selected net for the zone is visible, regardless of filters
    int selectedNetListNdx = -1;
Dick Hollenbeck's avatar
Dick Hollenbeck committed
653
    int net_select = m_settings.m_NetcodeSelection;
654

655 656 657
    if( net_select > 0 )
    {
        NETINFO_ITEM* equipot = m_Parent->GetBoard()->FindNet( net_select );
658
        if( equipot )
659
        {
660 661 662
            selectedNetListNdx = listNetName.Index( equipot->GetNetname() );

            if( wxNOT_FOUND == selectedNetListNdx )
663
            {
664 665 666
                // the currently selected net must *always* be visible.
                listNetName.Insert( equipot->GetNetname(), 0 );
                selectedNetListNdx = 0;
667 668 669
            }
        }
    }
670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685
    else if( net_select == 0 )
        selectedNetListNdx = 0;     // SetSelection() on "<no net>"
    else
    {
        // selectedNetListNdx remains -1, no net selected.
    }

    m_ListNetNameSelection->Clear();
    m_ListNetNameSelection->InsertItems( listNetName, 0 );
    m_ListNetNameSelection->SetSelection( 0 );

    if( selectedNetListNdx >= 0 )
    {
        m_ListNetNameSelection->SetSelection( selectedNetListNdx );
        m_ListNetNameSelection->EnsureVisible( selectedNetListNdx );
    }
686
}
687 688


689
wxBitmap DIALOG_COPPER_ZONE::makeLayerBitmap( EDA_COLOR_T aColor )
690 691 692 693 694 695 696 697 698 699 700 701 702
{
    wxBitmap    bitmap( LAYER_BITMAP_SIZE_X, LAYER_BITMAP_SIZE_Y );
    wxBrush     brush;
    wxMemoryDC  iconDC;

    iconDC.SelectObject( bitmap );
    brush.SetColour( MakeColour( aColor ) );
    brush.SetStyle( wxSOLID );
    iconDC.SetBrush( brush );
    iconDC.DrawRectangle( 0, 0, LAYER_BITMAP_SIZE_X, LAYER_BITMAP_SIZE_Y );

    return bitmap;
}