kicad/pcbnew/dialog_copper_zones.cpp

477 lines
15 KiB
C++
Raw Normal View History

/////////////////////////////////////////////////////////////////////////////
// Name: dialog_copper_zones.cpp
// Author: jean-pierre Charras
// Created: 09/oct/2008
/// Licence: GNU License
/////////////////////////////////////////////////////////////////////////////
#if defined (__GNUG__) && !defined (NO_GCC_PRAGMA)
#pragma implementation "zones.h"
#endif
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "fctsys.h"
#include "wxstruct.h"
#include "common.h"
#include "PolyLine.h"
#include "pcbnew.h"
#include "trigo.h"
#include "autorout.h"
#include "zones.h"
#include "dialog_copper_zones.h"
/************************************************************************************************/
2008-10-23 10:26:06 +00:00
dialog_copper_zone::dialog_copper_zone( WinEDA_PcbFrame* parent, ZONE_SETTING* zone_setting ) :
dialog_copper_zone_frame( parent )
/************************************************************************************************/
{
m_Parent = parent;
2008-10-23 10:26:06 +00:00
m_Zone_Setting = zone_setting;
m_NetSorting = 1; // 0 = alphabetic sort, 1 = pad count sort
if( m_Parent->m_Parent->m_EDA_Config )
{
m_NetSorting = m_Parent->m_Parent->m_EDA_Config->Read( ZONE_NET_SORT_OPTION_KEY, 1l );
}
2008-10-23 10:26:06 +00:00
SetReturnCode( ZONE_ABORT ); // Will be changed on buttons click
}
2008-10-23 10:26:06 +00:00
/*****************************************************************/
void dialog_copper_zone::OnInitDialog( wxInitDialogEvent& event )
/*****************************************************************/
2008-10-23 10:26:06 +00:00
// Initialise all dialog options and values in wxTextCtrl
{
2008-10-23 10:26:06 +00:00
BOARD* board = m_Parent->m_Pcb;
SetFont( *g_DialogFont );
SetFocus(); // Required under wxGTK if we want to demiss the dialog with the ESC key
2008-10-19 18:18:45 +00:00
wxString msg = _( "Zone clearance value:" ) + ReturnUnitSymbol( g_UnitMetric );
m_ClearanceValueTitle->SetLabel( msg );
2008-10-19 18:18:45 +00:00
msg = _( "Grid :" ) + ReturnUnitSymbol( g_UnitMetric );
m_GridCtrl->SetLabel( msg );
2008-10-19 18:18:45 +00:00
msg = ReturnStringFromValue( g_UnitMetric,
2008-10-23 10:26:06 +00:00
m_Zone_Setting->m_ZoneClearance,
m_Parent->m_InternalUnits );
2008-10-19 18:18:45 +00:00
m_ZoneClearanceCtrl->SetValue( msg );
if( g_Zone_45_Only )
m_OrientEdgesOpt->SetSelection( 1 );
static const int GridList[4] = { 25, 50, 100, 250 };
int selection = 0;
2008-10-23 10:26:06 +00:00
int grid_routing = m_Zone_Setting->m_GridFillValue;
for( unsigned ii = 0; ii < 4; ii++ )
{
2008-10-19 18:18:45 +00:00
msg = ReturnStringFromValue( g_UnitMetric,
2008-10-23 10:26:06 +00:00
GridList[ii],
m_Parent->m_InternalUnits );
m_GridCtrl->SetString( ii, msg );
if( grid_routing == GridList[ii] )
selection = ii;
}
2008-10-23 10:26:06 +00:00
if( grid_routing == 0 ) // No Grid: fill with polygons
selection = 4;
m_GridCtrl->SetSelection( selection );
2008-10-23 10:26:06 +00:00
msg = ReturnStringFromValue( g_UnitMetric,
m_Zone_Setting->m_ZoneClearance,
m_Parent->m_InternalUnits );
m_ZoneClearanceCtrl->SetValue( msg );
2008-10-23 10:26:06 +00:00
switch( m_Zone_Setting->m_Zone_Pad_Options )
{
case PAD_NOT_IN_ZONE: // Pads are not covered
m_PadInZoneOpt->SetSelection( 2 );
break;
2008-10-23 10:26:06 +00:00
case THERMAL_PAD: // Use thermal relief for pads
m_PadInZoneOpt->SetSelection( 1 );
break;
2008-10-23 10:26:06 +00:00
case PAD_IN_ZONE: // pads are covered by copper
m_PadInZoneOpt->SetSelection( 0 );
break;
}
2008-10-23 10:26:06 +00:00
if( m_Zone_Setting->m_FilledAreasShowMode == 1 )
m_ShowFilledAreasInSketchOpt->SetValue( true );
2008-10-23 10:26:06 +00:00
if( m_Zone_Setting->m_Zone_Pad_Options != THERMAL_PAD )
{
2008-10-23 10:26:06 +00:00
m_AntipadSizeValue->Enable( false );
m_CopperWidthValue->Enable( false );
}
else
{
2008-10-23 10:26:06 +00:00
m_AntipadSizeValue->Enable( true );
m_CopperWidthValue->Enable( true );
}
AddUnitSymbol( *m_AntipadSizeText, g_UnitMetric );
AddUnitSymbol( *m_CopperBridgeWidthText, g_UnitMetric );
2008-10-23 10:26:06 +00:00
PutValueInLocalUnits( *m_AntipadSizeValue,
m_Zone_Setting->m_ThermalReliefGapValue,
PCB_INTERNAL_UNIT );
PutValueInLocalUnits( *m_CopperWidthValue,
m_Zone_Setting->m_ThermalReliefCopperBridgeValue,
PCB_INTERNAL_UNIT );
switch( m_Zone_Setting->m_Zone_HatchingStyle )
{
case CPolyLine::NO_HATCH:
2008-10-23 10:26:06 +00:00
m_OutlineAppearanceCtrl->SetSelection( 0 );
break;
case CPolyLine::DIAGONAL_EDGE:
2008-10-23 10:26:06 +00:00
m_OutlineAppearanceCtrl->SetSelection( 1 );
break;
case CPolyLine::DIAGONAL_FULL:
2008-10-23 10:26:06 +00:00
m_OutlineAppearanceCtrl->SetSelection( 2 );
break;
}
2008-10-23 10:26:06 +00:00
m_ArcApproximationOpt->SetSelection( m_Zone_Setting->m_ArcToSegmentsCount == 32 ? 1 : 0 );
/* build copper layers list */
int layer_cnt = board->GetCopperLayerCount();
for( int ii = 0; ii < board->GetCopperLayerCount(); ii++ )
{
2008-10-23 10:26:06 +00:00
int layer_number = COPPER_LAYER_N;
if( layer_cnt <= 1 || ii < layer_cnt - 1 )
layer_number = ii;
else if( ii == layer_cnt - 1 )
layer_number = LAYER_CMP_N;
m_LayerId[ii] = layer_number;
msg = board->GetLayerName( layer_number ).Trim();
m_LayerSelectionCtrl->InsertItems( 1, &msg, ii );
2008-10-23 10:26:06 +00:00
if( m_Zone_Setting->m_CurrentZone_Layer == layer_number )
m_LayerSelectionCtrl->SetSelection( ii );
}
2008-10-23 10:26:06 +00:00
m_NetSortingOption->SetSelection( m_NetSorting );
2008-10-23 10:26:06 +00:00
wxString NetNameFilter;
if( m_Parent->m_Parent->m_EDA_Config )
{
2008-10-23 10:26:06 +00:00
NetNameFilter =
m_Parent->m_Parent->m_EDA_Config->Read( ZONE_NET_FILTER_STRING_KEY, wxT( "N_0*" ) );
}
2008-10-23 10:26:06 +00:00
m_NetNameFilter->SetValue( NetNameFilter );
wxArrayString ListNetName;
m_Parent->m_Pcb->ReturnSortedNetnamesList( ListNetName,
m_NetSorting == 0 ? BOARD::ALPHA_SORT : BOARD::PAD_CNT_SORT );
2008-10-23 10:26:06 +00:00
if( m_NetSorting != 0 )
{
2008-10-23 10:26:06 +00:00
wxString Filter = m_NetNameFilter->GetValue();
for( unsigned ii = 0; ii < ListNetName.GetCount(); ii++ )
{
2008-10-23 10:26:06 +00:00
if( ListNetName[ii].Matches( Filter.GetData() ) )
{
2008-10-23 10:26:06 +00:00
ListNetName.RemoveAt( ii );
ii--;
}
}
}
m_ListNetNameSelection->InsertItems( ListNetName, 0 );
// Select net:
2008-10-23 10:26:06 +00:00
int net_select = m_Zone_Setting->m_NetcodeSelection;
if( net_select > 0 )
{
EQUIPOT* equipot = m_Parent->m_Pcb->FindNet( net_select );
if( equipot ) // Search net in list and select it
{
for( unsigned ii = 0; ii < ListNetName.GetCount(); ii++ )
{
if( ListNetName[ii] == equipot->m_Netname )
{
m_ListNetNameSelection->SetSelection( ii );
2008-10-13 12:01:12 +00:00
m_ListNetNameSelection->EnsureVisible( ii );
break;
}
}
}
}
2008-10-23 10:26:06 +00:00
if( GetSizer() )
{
2008-10-23 10:26:06 +00:00
GetSizer()->SetSizeHints( this );
}
Center();
}
/********************************************************************/
void dialog_copper_zone::OnButtonCancelClick( wxCommandEvent& event )
/********************************************************************/
{
EndModal( ZONE_ABORT );
}
/********************************************************************************************/
2008-10-23 10:26:06 +00:00
bool dialog_copper_zone::AcceptOptions( bool aPromptForErrors, bool aUseExportableSetupOnly )
/********************************************************************************************/
2008-10-23 10:26:06 +00:00
/** Function dialog_copper_zone::AcceptOptions(
* @return false if incorrect options, true if Ok.
* @param aPromptForErrors = true to prompt user on incorrectparams
* @param aUseExportableSetupOnly = true to use exportable parametres only (used to export this setup to other zones)
*/
{
switch( m_PadInZoneOpt->GetSelection() )
{
case 2:
2008-10-23 10:26:06 +00:00
m_Zone_Setting->m_Zone_Pad_Options = PAD_NOT_IN_ZONE; // Pads are not covered
break;
case 1:
2008-10-23 10:26:06 +00:00
m_Zone_Setting->m_Zone_Pad_Options = THERMAL_PAD; // Use thermal relief for pads
break;
case 0:
2008-10-23 10:26:06 +00:00
m_Zone_Setting->m_Zone_Pad_Options = PAD_IN_ZONE; // pads are covered by copper
break;
}
2008-10-23 10:26:06 +00:00
switch( m_OutlineAppearanceCtrl->GetSelection() )
{
case 0:
2008-10-23 10:26:06 +00:00
m_Zone_Setting->m_Zone_HatchingStyle = CPolyLine::NO_HATCH;
break;
case 1:
2008-10-23 10:26:06 +00:00
m_Zone_Setting->m_Zone_HatchingStyle = CPolyLine::DIAGONAL_EDGE;
break;
case 2:
2008-10-23 10:26:06 +00:00
m_Zone_Setting->m_Zone_HatchingStyle = CPolyLine::DIAGONAL_FULL;
break;
}
2008-10-23 10:26:06 +00:00
m_Zone_Setting->m_ArcToSegmentsCount = m_ArcApproximationOpt->GetSelection() == 1 ? 32 : 16;
if( m_Parent->m_Parent->m_EDA_Config )
{
2008-10-23 10:26:06 +00:00
m_Parent->m_Parent->m_EDA_Config->Write( ZONE_NET_OUTLINES_HATCH_OPTION_KEY,
(long) m_Zone_Setting->m_Zone_HatchingStyle );
}
switch( m_GridCtrl->GetSelection() )
{
case 0:
2008-10-23 10:26:06 +00:00
m_Zone_Setting->m_GridFillValue = 25;
break;
case 1:
2008-10-23 10:26:06 +00:00
m_Zone_Setting->m_GridFillValue = 50;
break;
default:
case 2:
2008-10-23 10:26:06 +00:00
m_Zone_Setting->m_GridFillValue = 100;
break;
case 3:
2008-10-23 10:26:06 +00:00
m_Zone_Setting->m_GridFillValue = 250;
break;
case 4:
2008-10-23 10:26:06 +00:00
m_Zone_Setting->m_GridFillValue = 0;
DisplayInfo( this, wxT(
2008-10-23 10:26:06 +00:00
"You are using No grid for filling zones\nThis is currently in development and for tests only.\n Do not use for production" ) );
break;
}
wxString txtvalue = m_ZoneClearanceCtrl->GetValue();
2008-10-23 10:26:06 +00:00
m_Zone_Setting->m_ZoneClearance =
ReturnValueFromString( g_UnitMetric, txtvalue, m_Parent->m_InternalUnits );
if( m_OrientEdgesOpt->GetSelection() == 0 )
g_Zone_45_Only = FALSE;
else
g_Zone_45_Only = TRUE;
2008-10-23 10:26:06 +00:00
m_Zone_Setting->m_FilledAreasShowMode = m_ShowFilledAreasInSketchOpt->IsChecked() ? 1 : 0;
2008-10-23 10:26:06 +00:00
m_Zone_Setting->m_ThermalReliefGapValue = ReturnValueFromTextCtrl( *m_AntipadSizeValue,
PCB_INTERNAL_UNIT );
m_Zone_Setting->m_ThermalReliefCopperBridgeValue = ReturnValueFromTextCtrl(
*m_CopperWidthValue,
PCB_INTERNAL_UNIT );
2008-10-23 10:26:06 +00:00
m_Parent->m_Parent->m_EDA_Config->Write( ZONE_THERMAL_RELIEF_GAP_STRING_KEY,
(long) m_Zone_Setting->m_ThermalReliefGapValue );
m_Parent->m_Parent->m_EDA_Config->Write( ZONE_THERMAL_RELIEF_COPPER_WIDTH_STRING_KEY,
(long) m_Zone_Setting->m_ThermalReliefCopperBridgeValue );
// If we use only exportable to others zones parameters, exit here:
2008-10-23 10:26:06 +00:00
if( aUseExportableSetupOnly )
return true;
/* Get the layer selection for this zone */
int ii = m_LayerSelectionCtrl->GetSelection();
if( ii < 0 && aPromptForErrors )
{
DisplayError( this, _( "Error : you must choose a layer" ) );
return false;
}
2008-10-23 10:26:06 +00:00
m_Zone_Setting->m_CurrentZone_Layer = m_LayerId[ii];
/* Get the net name selection for this zone */
ii = m_ListNetNameSelection->GetSelection();
if( ii < 0 && aPromptForErrors )
{
DisplayError( this, _( "Error : you must choose a net name" ) );
return false;
}
wxString net_name = m_ListNetNameSelection->GetString( ii );
/* Search net_code for this net */
EQUIPOT* net;
2008-10-23 10:26:06 +00:00
g_Zone_Default_Setting.m_NetcodeSelection = 0;
for( net = m_Parent->m_Pcb->m_Equipots; net; net = net->Next() )
{
if( net->m_Netname == net_name )
{
2008-10-23 10:26:06 +00:00
g_Zone_Default_Setting.m_NetcodeSelection = net->GetNet();
break;
}
}
return true;
}
2008-10-23 10:26:06 +00:00
/***************************************************************************/
void dialog_copper_zone::OnNetSortingOptionSelected( wxCommandEvent& event )
/***************************************************************************/
{
wxArrayString ListNetName;
2008-10-23 10:26:06 +00:00
m_NetSorting = m_NetSortingOption->GetSelection();
m_Parent->m_Pcb->ReturnSortedNetnamesList( ListNetName,
m_NetSorting == 0 ? BOARD::ALPHA_SORT : BOARD::PAD_CNT_SORT );
2008-10-23 10:26:06 +00:00
if( m_NetSorting != 0 )
{
2008-10-23 10:26:06 +00:00
wxString Filter = m_NetNameFilter->GetValue();
for( unsigned ii = 0; ii < ListNetName.GetCount(); ii++ )
{
2008-10-23 10:26:06 +00:00
if( ListNetName[ii].Matches( Filter.GetData() ) )
{
2008-10-23 10:26:06 +00:00
ListNetName.RemoveAt( ii );
ii--;
}
}
}
m_ListNetNameSelection->Clear();
m_ListNetNameSelection->InsertItems( ListNetName, 0 );
if( m_Parent->m_Parent->m_EDA_Config )
{
m_Parent->m_Parent->m_EDA_Config->Write( ZONE_NET_SORT_OPTION_KEY, (long) m_NetSorting );
2008-10-23 10:26:06 +00:00
m_Parent->m_Parent->m_EDA_Config->Write( ZONE_NET_FILTER_STRING_KEY,
m_NetNameFilter->GetValue() );
}
2008-10-13 12:01:12 +00:00
// Select and isplay current zone net name in listbox:
2008-10-23 10:26:06 +00:00
int net_select = m_Zone_Setting->m_NetcodeSelection;
2008-10-13 12:01:12 +00:00
if( net_select > 0 )
{
EQUIPOT* equipot = m_Parent->m_Pcb->FindNet( net_select );
if( equipot ) // Search net in list and select it
{
for( unsigned ii = 0; ii < ListNetName.GetCount(); ii++ )
{
if( ListNetName[ii] == equipot->m_Netname )
{
m_ListNetNameSelection->SetSelection( ii );
m_ListNetNameSelection->EnsureVisible( ii );
break;
}
}
}
}
}
/*****************************************************************/
void dialog_copper_zone::OnButtonOkClick( wxCommandEvent& event )
/*****************************************************************/
{
2008-10-23 10:26:06 +00:00
if( AcceptOptions( true ) )
EndModal( ZONE_OK );
}
/******************************************************************************/
void dialog_copper_zone::ExportSetupToOtherCopperZones( wxCommandEvent& event )
/******************************************************************************/
{
2008-10-23 10:26:06 +00:00
if( !AcceptOptions( true, true ) )
return;
// Export to others zones:
2008-10-23 10:26:06 +00:00
BOARD* pcb = m_Parent->m_Pcb;
for( int ii = 0; ii < pcb->GetAreaCount(); ii++ )
{
2008-10-23 10:26:06 +00:00
ZONE_CONTAINER* zone = pcb->GetArea( ii );
m_Zone_Setting->ExportSetting( *zone );
m_Parent->GetScreen()->SetModify();
}
}
/******************************************************************/
void dialog_copper_zone::OnPadsInZoneClick( wxCommandEvent& event )
/******************************************************************/
{
2008-10-23 10:26:06 +00:00
switch( m_PadInZoneOpt->GetSelection() )
{
2008-10-23 10:26:06 +00:00
default:
m_AntipadSizeValue->Enable( false );
m_CopperWidthValue->Enable( false );
break;
2008-10-23 10:26:06 +00:00
case 1:
m_AntipadSizeValue->Enable( true );
m_CopperWidthValue->Enable( true );
break;
}
}