Pcbnew: add a board layer stack manager

This is a new feature.
This commit is contained in:
jean-pierre charras 2019-07-27 21:09:43 +02:00
parent e7c07501c5
commit f3f0e20a67
25 changed files with 3576 additions and 268 deletions

View File

@ -364,6 +364,12 @@ double DoubleValueFromString( EDA_UNITS_T aUnits, const wxString& aTextValue, bo
aUnits = INCHES;
aUseMils = true;
}
else if( unit == "oz" ) // 1 oz = 1.37 mils
{
aUnits = INCHES;
aUseMils = true;
dtmp *= 1.37;
}
}
else if( aUnits == DEGREES )
{

View File

@ -40,22 +40,26 @@ attr
autoplace_cost90
autoplace_cost180
aux_axis_origin
bevelled
blind
blind_buried_vias_allowed
bold
bottom
bottom_left
bottom_right
castellated_pads
center
chamfer
chamfer_ratio
circle
clearance
color
comment
company
connect
connect_pads
copperpour
copper_finish
crossbar
custom
outline
@ -67,6 +71,7 @@ date
defaults
descr
die_length
dielectric_constraints
dimension
diff_pair_width
diff_pair_gap
@ -75,9 +80,12 @@ drill
edge
edge_clearance
edge_cuts_line_width
edge_connector
edge_plating
edge_width
effects
end
epsilon_r
feature1
feature2
fill
@ -119,7 +127,9 @@ layers
left
links
locked
loss_tangent
max_error
material
micro
min_thickness
mirror
@ -148,7 +158,6 @@ pads
pad_drill
pad_size
pad_to_mask_clearance
solder_mask_min_width
pad_to_paste_clearance
pad_to_paste_clearance_ratio
page
@ -182,9 +191,11 @@ size
smd
smoothing
solder_mask_margin
solder_mask_min_width
solder_paste_margin
solder_paste_margin_ratio
solder_paste_ratio
stackup
start
status
tags
@ -208,6 +219,7 @@ thru
thru_hole
thru_hole_only
tstamp
type
unlocked
user
user_diff_pair

View File

@ -184,6 +184,8 @@ endif()
set( PCBNEW_BRDSTACKUP_MGR
board_stackup_manager/stackup_predefined_prms.cpp
board_stackup_manager/panel_board_stackup.cpp
board_stackup_manager/panel_board_stackup_base.cpp
)
set( PCBNEW_IMPORT_GFX

View File

@ -28,25 +28,22 @@
#include <i18n_utility.h> // For _HKI definition
#include "stackup_predefined_prms.h"
// A reasonable thickness for copper layers:
const int copperDefaultThickness = Millimeter2iu( 0.035 );
// A reasonable thickness for solder mask:
const int maskDefaultThickness = Millimeter2iu( 0.01 );
BOARD_STACKUP_ITEM::BOARD_STACKUP_ITEM( BOARD_STACKUP_ITEM_TYPE aType )
{
m_LayerId = UNDEFINED_LAYER;
m_Type = aType;
m_Enabled = true;
m_DielectricLayerId = 0;
m_EpsilonR = 0;
m_LossTangent = 0.0;
m_ThicknessLocked = false;
// Initialize parameters to a usual value for allowed types:
switch( m_Type )
{
case BS_ITEM_TYPE_COPPER:
m_TypeName = "copper";
m_Thickness = copperDefaultThickness;
m_Thickness = GetCopperDefaultThickness();
break;
case BS_ITEM_TYPE_DIELECTRIC:
@ -66,7 +63,7 @@ BOARD_STACKUP_ITEM::BOARD_STACKUP_ITEM( BOARD_STACKUP_ITEM_TYPE aType )
case BS_ITEM_TYPE_SOLDERMASK:
m_TypeName = "soldermask";
m_Color = NOT_SPECIFIED;
m_Thickness = maskDefaultThickness;
m_Thickness = GetMaskDefaultThickness();
m_EpsilonR = 3.5;
m_LossTangent = 0.0;
break;
@ -88,16 +85,32 @@ BOARD_STACKUP_ITEM::BOARD_STACKUP_ITEM( BOARD_STACKUP_ITEM& aOther )
{
m_LayerId = aOther.m_LayerId;
m_Type = aOther.m_Type;
m_Enabled = aOther.m_Enabled;
m_DielectricLayerId = aOther.m_DielectricLayerId;
m_TypeName = aOther.m_TypeName;
m_Material = aOther.m_Material;
m_Color = aOther.m_Color;
m_Thickness = aOther.m_Thickness;
m_ThicknessLocked = aOther.m_ThicknessLocked;
m_EpsilonR = aOther.m_EpsilonR;
m_LossTangent = aOther.m_LossTangent;
}
int BOARD_STACKUP_ITEM::GetCopperDefaultThickness()
{
// A reasonable thickness for copper layers:
return Millimeter2iu( 0.035 );
}
int BOARD_STACKUP_ITEM::GetMaskDefaultThickness()
{
// A reasonable thickness for solder mask:
return Millimeter2iu( 0.01 );
}
bool BOARD_STACKUP_ITEM::HasEpsilonRValue()
{
return m_Type == BS_ITEM_TYPE_DIELECTRIC || m_Type == BS_ITEM_TYPE_SOLDERMASK;
@ -227,7 +240,7 @@ int BOARD_STACKUP::BuildBoardTicknessFromStackup() const
for( auto item : m_list )
{
if( item->IsThicknessEditable() )
if( item->IsThicknessEditable() && item->m_Enabled )
thickness += item->m_Thickness;
}
@ -308,17 +321,32 @@ bool BOARD_STACKUP::SynchronizeWithBoard( BOARD_DESIGN_SETTINGS* aSettings )
}
void BOARD_STACKUP::BuildDefaultStackupList( BOARD_DESIGN_SETTINGS* aSettings )
void BOARD_STACKUP::BuildDefaultStackupList( BOARD_DESIGN_SETTINGS* aSettings,
int aActiveCopperLayersCount )
{
// Creates a default stackup, according to the current BOARD_DESIGN_SETTINGS settings.
// Note: the m_TypeName string is made translatable using _HKI marker, but is not
// translated when building the stackup.
// It will be used as this in files, and can be translated only in dialog
LSET enabledLayer = aSettings->GetEnabledLayers();
int copperLayerCount = aSettings->GetCopperLayerCount();
double diel_thickness = aSettings->GetBoardThickness()
- (copperDefaultThickness * copperLayerCount);
diel_thickness /= copperLayerCount - 1;
// if aSettings == NULL, build a full stackup (with 32 copper layers)
LSET enabledLayer = aSettings ? aSettings->GetEnabledLayers() : StackupAllowedBrdLayers();
int copperLayerCount = aSettings ? aSettings->GetCopperLayerCount() : B_Cu+1;
// We need to calculate a suitable dielectric layer thickness.
// If no settings, and if aActiveCopperLayersCount is given, use it
// (If no settings, and no aActiveCopperLayersCount, the full 32 layers are used)
int activeCuLayerCount = copperLayerCount;
if( aSettings == nullptr && aActiveCopperLayersCount > 0 )
activeCuLayerCount = aActiveCopperLayersCount;
int brd__thickness = aSettings ? aSettings->GetBoardThickness() : Millimeter2iu( 1.6 );
int diel_thickness = brd__thickness -
( BOARD_STACKUP_ITEM::GetCopperDefaultThickness() * activeCuLayerCount );
// Take in account the solder mask thickness:
int sm_count = ( enabledLayer & LSET( 2, F_Mask, B_Mask) ).count();
diel_thickness -= BOARD_STACKUP_ITEM::GetMaskDefaultThickness() * sm_count;
int dielectric_idx = 0;
@ -407,12 +435,15 @@ void BOARD_STACKUP::BuildDefaultStackupList( BOARD_DESIGN_SETTINGS* aSettings )
}
// Transfer other stackup settings from aSettings
BOARD_STACKUP& source_stackup = aSettings->GetStackupDescriptor();
m_HasDielectricConstrains = source_stackup.m_HasDielectricConstrains;
m_EdgeConnectorConstraints = source_stackup.m_EdgeConnectorConstraints;
m_CastellatedPads = source_stackup.m_CastellatedPads;
m_EdgePlating = source_stackup.m_EdgePlating;
m_FinishType = source_stackup.m_FinishType;
if( aSettings )
{
BOARD_STACKUP& source_stackup = aSettings->GetStackupDescriptor();
m_HasDielectricConstrains = source_stackup.m_HasDielectricConstrains;
m_EdgeConnectorConstraints = source_stackup.m_EdgeConnectorConstraints;
m_CastellatedPads = source_stackup.m_CastellatedPads;
m_EdgePlating = source_stackup.m_EdgePlating;
m_FinishType = source_stackup.m_FinishType;
}
}
@ -425,7 +456,7 @@ void BOARD_STACKUP::FormatBoardStackup( OUTPUTFORMATTER* aFormatter,
if( m_list.empty() )
return;
aFormatter->Print( aNestLevel, "(board_stackup\n" );
aFormatter->Print( aNestLevel, "(stackup\n" );
int nest_level = aNestLevel+1;
for( BOARD_STACKUP_ITEM* item: m_list )
@ -444,8 +475,14 @@ void BOARD_STACKUP::FormatBoardStackup( OUTPUTFORMATTER* aFormatter,
aFormatter->Quotew( item->m_TypeName ).c_str() );
if( item->IsThicknessEditable() )
aFormatter->Print( 0, " (thickness %s)",
FormatInternalUnits( (int)item->m_Thickness ).c_str() );
{
if( item->m_Type == BS_ITEM_TYPE_DIELECTRIC && item->m_ThicknessLocked )
aFormatter->Print( 0, " (thickness %s locked)",
FormatInternalUnits( (int)item->m_Thickness ).c_str() );
else
aFormatter->Print( 0, " (thickness %s)",
FormatInternalUnits( (int)item->m_Thickness ).c_str() );
}
if( item->m_Type == BS_ITEM_TYPE_DIELECTRIC )
aFormatter->Print( 0, " (material %s)",
@ -455,7 +492,7 @@ void BOARD_STACKUP::FormatBoardStackup( OUTPUTFORMATTER* aFormatter,
aFormatter->Print( 0, " (epsilon_r %g)", item->m_EpsilonR );
if( item->HasLossTangentValue() )
aFormatter->Print( 0, " (loss %s)",
aFormatter->Print( 0, " (loss_tangent %s)",
Double2Str(item->m_LossTangent ).c_str() );
if( item->IsColorEditable() && !item->m_Color.IsEmpty()
@ -471,7 +508,7 @@ void BOARD_STACKUP::FormatBoardStackup( OUTPUTFORMATTER* aFormatter,
aFormatter->Print( nest_level, "(copper_finish %s)\n",
aFormatter->Quotew( m_FinishType ).c_str() );
aFormatter->Print( nest_level, "(dielectric_constrains %s)\n",
aFormatter->Print( nest_level, "(dielectric_constraints %s)\n",
m_HasDielectricConstrains ? "yes" : "no" );
if( m_EdgeConnectorConstraints > 0 )

View File

@ -35,7 +35,7 @@ class OUTPUTFORMATTER;
// A enum to manage the different layers inside the stackup layers.
// Note the stackup layers include both dielectric and some layers handled by the board editor
// Therfore a stackup layer item is not exactely like a board layer
// Therefore a stackup layer item is not exactely like a board layer
enum BOARD_STACKUP_ITEM_TYPE
{
BS_ITEM_TYPE_UNDEFINED, // For not yet initialized BOARD_STACKUP_ITEM item
@ -66,11 +66,16 @@ public:
BOARD_STACKUP_ITEM( BOARD_STACKUP_ITEM& aOther );
BOARD_STACKUP_ITEM_TYPE m_Type;
bool m_Enabled; /// true if this stackup item must be taken in account,
/// false to ignore it. Mainly used in dialog stackup editor.
wxString m_TypeName; /// type name of layer (copper, silk screen, core, prepreg ...)
wxString m_Material; /// type of material (has meaning only for dielectric
int m_DielectricLayerId;/// the "layer" id for dielectric layers, from 1 (top) to 32 (bottom)
int m_DielectricLayerId;/// the "layer" id for dielectric layers,
/// from 1 (top) to 31 (bottom)
wxString m_Color; /// mainly for silkscreen and solder mask
int m_Thickness; /// the physical layer thickness in internal units
bool m_ThicknessLocked; /// true for dielectric layers with a fixed thickness
/// (for impendace controled purposes), unused for other layers
double m_EpsilonR; /// For dielectric (and solder mask) the dielectric constant
double m_LossTangent; /// For dielectric (and solder mask) the dielectric loss
PCB_LAYER_ID m_LayerId; /// the layer id (F.Cu to B.Cu, F.Silk, B.silk, F.Mask, B.Mask)
@ -93,6 +98,12 @@ public:
/// @return true if Thickness is editable
bool IsThicknessEditable();
/// @return a reasonable default value for a copper layer thickness
static int GetCopperDefaultThickness();
/// @return a reasonable default value for a solder mask layer thickness
static int GetMaskDefaultThickness();
};
@ -150,6 +161,16 @@ public:
/// @return a reference to the layer aIndex, or nullptr if not exists
BOARD_STACKUP_ITEM* GetStackupLayer( int aIndex );
/** @return the board layers full mask allowed in the stackup list
* i.e. the SilkS, Mask, Paste and all copper layers
*/
static LSET StackupAllowedBrdLayers()
{
return LSET( 6, F_SilkS, F_Mask, F_Paste, B_SilkS, B_Mask, B_Paste )
| LSET::ExternalCuMask() | LSET::InternalCuMask();
}
/// Delete all items in list and clear the list
void RemoveAll();
@ -174,8 +195,12 @@ public:
/**
* Creates a default stackup, according to the current BOARD_DESIGN_SETTINGS settings.
* @param aSettings is the current board setting.
* if nullptr, build a full stackup (with 32 copper layers)
* @param aActiveCopperLayersCount is used only if aSettings == nullptr is the number
* of copper layers to use to calculate a default dielectric thickness.
* ((<= 0 to use all copper layers)
*/
void BuildDefaultStackupList( BOARD_DESIGN_SETTINGS* aSettings );
void BuildDefaultStackupList( BOARD_DESIGN_SETTINGS* aSettings, int aActiveCopperLayersCount = 0 );
/**
* Writes the stackup info on board file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,197 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2009-2019 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
*/
#ifndef PANEL_SETUP_BOARD_STACKUP_H
#define PANEL_SETUP_BOARD_STACKUP_H
#include <fctsys.h>
#include <pcbnew.h>
#include <class_board.h>
#include <widgets/unit_binder.h>
#include "panel_board_stackup_base.h"
#include "class_board_stackup.h"
class wxBitmapComboBox;
class PANEL_SETUP_LAYERS;
#if 0
// Indexes of columns of the grid to show a layer setup
enum LAYER_COLUMN_INDEX
{
LCOL_IDX_BITMAP, // The column displaying the material color
LCOL_IDX_BRD_LAYERNAME, // The column displaying the layer name from the board editor
LCOL_IDX_LAYERTYPENAME, // The column displaying the layer type name
LCOL_IDX_LAYER_MATERIAL, // The column displaying the name of the material
LCOL_IDX_LAYER_THICKNESS,
LCOL_IDX_LAYER_THICKNESS_LOCK,
LCOL_IDX_LAYER_COLOR,
LCOL_IDX_LAYER_EPSILON_R,
LCOL_IDX_LAYER_DIELECTRIC_LOSS,
LCOL_COUNT_MAX // Sentinel
};
#endif
// A helper class to handle UI items managed by m_fgGridSizer
// in PANEL_SETUP_BOARD_STACKUP
// these items are shown or not in m_fgGridSizer, depending on
// the enabled layers in the current board.
// So we need to store the list of these UI items int m_fgGridSizer
// row by row
struct BOARD_STACKUP_ROW_UI_ITEM
{
bool m_isEnabled; // True if the row is in board
// false if not (this row is not shown on the panel)
wxStaticBitmap* m_Icon; // Color icon in first column (column 1)
wxStaticText* m_LayerName; // string shown in column 2
wxControl* m_LayerTypeCtrl; // control shown in column 3
wxControl* m_MaterialCtrl; // control shown in column 4
wxControl* m_ThicknessCtrl; // control shown in column 5
wxControl* m_ThicknessLockCtrl;// control shown in column 6
wxControl* m_ColorCtrl; // control shown in column 7
wxControl* m_EpsilonCtrl; // control shown in column 8
wxControl* m_LossTgCtrl; // control shown in column 9
BOARD_STACKUP_ROW_UI_ITEM() :
m_isEnabled( true ), m_Icon( nullptr ), m_LayerName( nullptr ),
m_LayerTypeCtrl( nullptr ), m_MaterialCtrl( nullptr ),
m_ThicknessCtrl( nullptr ), m_ThicknessLockCtrl( nullptr ),
m_EpsilonCtrl( nullptr ), m_LossTgCtrl( nullptr )
{}
};
class PANEL_SETUP_BOARD_STACKUP : public PANEL_SETUP_BOARD_STACKUP_BASE
{
public:
PANEL_SETUP_BOARD_STACKUP( PAGED_DIALOG* aParent, PCB_EDIT_FRAME* aFrame, PANEL_SETUP_LAYERS* aPanelLayers );
~PANEL_SETUP_BOARD_STACKUP();
void ImportSettingsFrom( BOARD* aBoard );
// Must be called if the copper layers count has changed
// or solder mask, solder paste or silkscreen layers are
// enabled or disabled
// Rebuild the Layer Stack Panel if the new layer set differs
// from the current layet set
void OnLayersOptionsChanged( LSET aNewLayerSet );
BOARD_STACKUP_ITEM* GetStackupItem( int aIndex );
/// Return the color currently selected for the row aRow
wxColor GetSelectedColor( int aRow ) const;
BOARD_STACKUP& GetStackup() { return m_stackup; }
int GetPcbTickness();
bool TransferDataFromWindow() override;
std::vector<wxColor> m_UserColors; // the list of user colors for each grid row
// other colors are defined colors, and are not stored
private:
/** Populate m_fgGridSizer with items to handle stackup parameters
* This is a full list:
* all copper layers and all tech layers that are supported by the stackup
* items not in the current board stackup will be not shown, but they are
* existing in list
*/
void buildLayerStackPanel();
/** Show or do not show items in m_fgGridSizer according to the stackup of the
* current board and optionally update the stackup params (thickness, color ... )
* @param aFullSync = true to update stackup params, false to only update the list
* of shown items
*/
void synchronizeWithBoard( bool aFullSync );
/** Populate m_fgGridSizer with items to handle stackup parameters
* If previous items are in list, remove old items
*/
void RebuildLayerStackPanel();
void onUpdateThicknessValue( wxUpdateUIEvent& event ) override;
void onCalculateDielectricThickness( wxCommandEvent& event ) override;
void onColorSelected( wxCommandEvent& event );
void onMaterialChange( wxCommandEvent& event );
void onThicknessChange( wxCommandEvent& event );
/** Update the icons color (swatches in first grid column)
* @param aRow is the row (index in m_rowUiItemsList) that manages the icon to update.
* if -1 all icons will be updated
*/
void updateIconColor( int aRow = -1 );
/** @return the color of the BOARD_STACKUP_ITEM at row aRow,
* to draw a bitmap color according to the selected color
* or the best default color (for dielectric or copper item)
* @param aRow is the row index to find the color.
*/
wxColor getColorIconItem( int aRow );
/** creates a bitmap combobox to select a layer color
* @return the created wxBitmapComboBox
* @param aStackupItem = the BOARD_STACKUP_ITEM realted to the bitmap combobox
* (to set the user color, if any)
* can be nullptr
* @param aRow = the row index in the wxFlexGridSizer (used to build a wxWidget unique id)
*/
wxBitmapComboBox* createBmComboBox( BOARD_STACKUP_ITEM* aStackupItem, int aRow );
/**
* disconnect event handlers connected to wxControl items
* found in list m_controlItemsList
*/
void disconnectEvents();
BOARD_STACKUP m_stackup;
PANEL_SETUP_LAYERS* m_panelLayers; // The associated PANEL_SETUP_LAYERS, to know
// enabled layers and copper layer names
LSET m_enabledLayers; // the current enabled layers in this panel
// restricted to allowed layers in stackup.
// when do not match the enabled layers
// in PANEL_SETUP_LAYERS the stackup is not up to date
std::vector<BOARD_STACKUP_ROW_UI_ITEM> m_rowUiItemsList; // List of items in m_fgGridSizer
BOARD* m_board;
BOARD_DESIGN_SETTINGS* m_brdSettings;
EDA_UNITS_T m_units;
PCB_EDIT_FRAME* m_frame;
wxSize m_numericTextCtrlSize; // Best size to enter values with units in wxTextCtrl
wxSize m_numericFieldsSize; // Best size to enter double values in wxTextCtrl
wxArrayString m_core_prepreg_choice; // Used to display the option list in dialog
wxSize m_colorSwatchesSize; // the size of color swatches in the wxBitmapComboBox.
// this is the size of the "XX" string to give
// a reasonable size to color swatches
wxSize m_colorIconsSize; // the size of color swatches in grid, left column.
// this is the size of the "XXXXXX" string to give
// a reasonable size to color swatches (icons)
// The list of controls (wxChoice, wxBitmapComboBox, wxTextCtrl) added to the panel
// when building the BOARD_STACKUP_ITEM list editor and connected to command events
// Used to disconnect event handlers
std::vector<wxControl*> m_controlItemsList;
};
#endif // #ifndef PANEL_SETUP_BOARD_STACKUP_H

View File

@ -0,0 +1,192 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Jul 10 2019)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "panel_board_stackup_base.h"
///////////////////////////////////////////////////////////////////////////
PANEL_SETUP_BOARD_STACKUP_BASE::PANEL_SETUP_BOARD_STACKUP_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : wxPanel( parent, id, pos, size, style, name )
{
wxBoxSizer* bMainSizer;
bMainSizer = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* bSizerBrdThickness;
bSizerBrdThickness = new wxBoxSizer( wxHORIZONTAL );
m_thicknessLabel = new wxStaticText( this, wxID_ANY, _("Board thickness:"), wxDefaultPosition, wxDefaultSize, 0 );
m_thicknessLabel->Wrap( -1 );
bSizerBrdThickness->Add( m_thicknessLabel, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
m_thicknessCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
bSizerBrdThickness->Add( m_thicknessCtrl, 0, wxALL, 5 );
bSizerBrdThickness->Add( 20, 0, 0, 0, 5 );
m_staticTextCT = new wxStaticText( this, wxID_ANY, _("Current thickness from stackup:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextCT->Wrap( -1 );
bSizerBrdThickness->Add( m_staticTextCT, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
m_tcCTValue = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY );
bSizerBrdThickness->Add( m_tcCTValue, 0, wxALL, 5 );
bSizerBrdThickness->Add( 5, 0, 0, 0, 5 );
m_buttonSetDielectricThickness = new wxButton( this, wxID_ANY, _("Set Dielectric Thickness"), wxDefaultPosition, wxDefaultSize, 0 );
m_buttonSetDielectricThickness->SetToolTip( _("Set thickness of all not locked dielectric layers.\nThe thickness will be the same for all not locked dielectric layers.") );
bSizerBrdThickness->Add( m_buttonSetDielectricThickness, 0, wxALL, 5 );
bMainSizer->Add( bSizerBrdThickness, 0, wxEXPAND, 5 );
m_staticline = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
bMainSizer->Add( m_staticline, 0, wxALL|wxEXPAND, 5 );
wxBoxSizer* bSizerStackup;
bSizerStackup = new wxBoxSizer( wxHORIZONTAL );
wxBoxSizer* bSizer5;
bSizer5 = new wxBoxSizer( wxVERTICAL );
m_scGridWin = new wxScrolledWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxVSCROLL );
m_scGridWin->SetScrollRate( 5, 5 );
m_fgGridSizer = new wxFlexGridSizer( 0, 9, 0, 0 );
m_fgGridSizer->SetFlexibleDirection( wxBOTH );
m_fgGridSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_staticText7 = new wxStaticText( m_scGridWin, wxID_ANY, _("Layer"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText7->Wrap( -1 );
m_staticText7->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) );
m_fgGridSizer->Add( m_staticText7, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
m_staticText8 = new wxStaticText( m_scGridWin, wxID_ANY, _("Name"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText8->Wrap( -1 );
m_staticText8->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) );
m_fgGridSizer->Add( m_staticText8, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
m_staticText9 = new wxStaticText( m_scGridWin, wxID_ANY, _("Type"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText9->Wrap( -1 );
m_staticText9->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) );
m_fgGridSizer->Add( m_staticText9, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
m_staticText10 = new wxStaticText( m_scGridWin, wxID_ANY, _("Material"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText10->Wrap( -1 );
m_staticText10->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) );
m_fgGridSizer->Add( m_staticText10, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
m_staticText101 = new wxStaticText( m_scGridWin, wxID_ANY, _("Thickness"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText101->Wrap( -1 );
m_staticText101->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) );
m_fgGridSizer->Add( m_staticText101, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
m_staticTextLock = new wxStaticText( m_scGridWin, wxID_ANY, _("Lock"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextLock->Wrap( -1 );
m_staticTextLock->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) );
m_staticTextLock->SetToolTip( _("If lock is enabled, the dielectric thickness calculation will not change the thickness") );
m_fgGridSizer->Add( m_staticTextLock, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
m_staticText102 = new wxStaticText( m_scGridWin, wxID_ANY, _("Color"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText102->Wrap( -1 );
m_staticText102->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) );
m_fgGridSizer->Add( m_staticText102, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
m_staticText103 = new wxStaticText( m_scGridWin, wxID_ANY, _("Epsilon R"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText103->Wrap( -1 );
m_staticText103->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) );
m_fgGridSizer->Add( m_staticText103, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
m_staticText104 = new wxStaticText( m_scGridWin, wxID_ANY, _("Loss tg"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText104->Wrap( -1 );
m_staticText104->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) );
m_fgGridSizer->Add( m_staticText104, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
m_scGridWin->SetSizer( m_fgGridSizer );
m_scGridWin->Layout();
m_fgGridSizer->Fit( m_scGridWin );
bSizer5->Add( m_scGridWin, 1, wxEXPAND | wxALL, 5 );
bSizerStackup->Add( bSizer5, 1, wxEXPAND, 5 );
wxBoxSizer* bSizerRight;
bSizerRight = new wxBoxSizer( wxVERTICAL );
wxString m_rbDielectricConstraintChoices[] = { _("No constraint"), _("Impedance controlled") };
int m_rbDielectricConstraintNChoices = sizeof( m_rbDielectricConstraintChoices ) / sizeof( wxString );
m_rbDielectricConstraint = new wxRadioBox( this, wxID_ANY, _("Impedance Control"), wxDefaultPosition, wxDefaultSize, m_rbDielectricConstraintNChoices, m_rbDielectricConstraintChoices, 1, wxRA_SPECIFY_COLS );
m_rbDielectricConstraint->SetSelection( 0 );
m_rbDielectricConstraint->SetToolTip( _("If Impedance Controlled option is set,\nLoss tangent and EpsilonR will be added to constraints.") );
bSizerRight->Add( m_rbDielectricConstraint, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 );
wxStaticBoxSizer* sbSizerBrdOptions;
sbSizerBrdOptions = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Board Finish") ), wxVERTICAL );
m_cbCastellatedPads = new wxCheckBox( sbSizerBrdOptions->GetStaticBox(), wxID_ANY, _("Has castellated pads"), wxDefaultPosition, wxDefaultSize, 0 );
sbSizerBrdOptions->Add( m_cbCastellatedPads, 0, wxALL, 5 );
m_cbEgdesPlated = new wxCheckBox( sbSizerBrdOptions->GetStaticBox(), wxID_ANY, _("Plated board edge"), wxDefaultPosition, wxDefaultSize, 0 );
sbSizerBrdOptions->Add( m_cbEgdesPlated, 0, wxALL, 5 );
m_staticTextFinish = new wxStaticText( sbSizerBrdOptions->GetStaticBox(), wxID_ANY, _("Copper finish:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextFinish->Wrap( -1 );
sbSizerBrdOptions->Add( m_staticTextFinish, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
wxArrayString m_choiceFinishChoices;
m_choiceFinish = new wxChoice( sbSizerBrdOptions->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceFinishChoices, 0 );
m_choiceFinish->SetSelection( 0 );
sbSizerBrdOptions->Add( m_choiceFinish, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
m_staticTextEdgeConn = new wxStaticText( sbSizerBrdOptions->GetStaticBox(), wxID_ANY, _("Edge card connectors:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextEdgeConn->Wrap( -1 );
sbSizerBrdOptions->Add( m_staticTextEdgeConn, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
wxString m_choiceEdgeConnChoices[] = { _("None"), _("Yes"), _("Yes, bevelled") };
int m_choiceEdgeConnNChoices = sizeof( m_choiceEdgeConnChoices ) / sizeof( wxString );
m_choiceEdgeConn = new wxChoice( sbSizerBrdOptions->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceEdgeConnNChoices, m_choiceEdgeConnChoices, 0 );
m_choiceEdgeConn->SetSelection( 0 );
m_choiceEdgeConn->SetToolTip( _("Options for edge card connectors.") );
sbSizerBrdOptions->Add( m_choiceEdgeConn, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
bSizerRight->Add( sbSizerBrdOptions, 0, wxEXPAND, 5 );
bSizerStackup->Add( bSizerRight, 0, wxEXPAND, 5 );
bMainSizer->Add( bSizerStackup, 1, wxEXPAND, 5 );
this->SetSizer( bMainSizer );
this->Layout();
// Connect Events
m_thicknessCtrl->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( PANEL_SETUP_BOARD_STACKUP_BASE::onUpdateThicknessValue ), NULL, this );
m_buttonSetDielectricThickness->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_BOARD_STACKUP_BASE::onCalculateDielectricThickness ), NULL, this );
}
PANEL_SETUP_BOARD_STACKUP_BASE::~PANEL_SETUP_BOARD_STACKUP_BASE()
{
// Disconnect Events
m_thicknessCtrl->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( PANEL_SETUP_BOARD_STACKUP_BASE::onUpdateThicknessValue ), NULL, this );
m_buttonSetDielectricThickness->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_BOARD_STACKUP_BASE::onCalculateDielectricThickness ), NULL, this );
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,80 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Jul 10 2019)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#pragma once
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
#include <wx/string.h>
#include <wx/stattext.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/textctrl.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/button.h>
#include <wx/sizer.h>
#include <wx/statline.h>
#include <wx/scrolwin.h>
#include <wx/radiobox.h>
#include <wx/checkbox.h>
#include <wx/choice.h>
#include <wx/statbox.h>
#include <wx/panel.h>
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// Class PANEL_SETUP_BOARD_STACKUP_BASE
///////////////////////////////////////////////////////////////////////////////
class PANEL_SETUP_BOARD_STACKUP_BASE : public wxPanel
{
private:
protected:
wxStaticText* m_thicknessLabel;
wxTextCtrl* m_thicknessCtrl;
wxStaticText* m_staticTextCT;
wxTextCtrl* m_tcCTValue;
wxButton* m_buttonSetDielectricThickness;
wxStaticLine* m_staticline;
wxScrolledWindow* m_scGridWin;
wxFlexGridSizer* m_fgGridSizer;
wxStaticText* m_staticText7;
wxStaticText* m_staticText8;
wxStaticText* m_staticText9;
wxStaticText* m_staticText10;
wxStaticText* m_staticText101;
wxStaticText* m_staticTextLock;
wxStaticText* m_staticText102;
wxStaticText* m_staticText103;
wxStaticText* m_staticText104;
wxRadioBox* m_rbDielectricConstraint;
wxCheckBox* m_cbCastellatedPads;
wxCheckBox* m_cbEgdesPlated;
wxStaticText* m_staticTextFinish;
wxChoice* m_choiceFinish;
wxStaticText* m_staticTextEdgeConn;
wxChoice* m_choiceEdgeConn;
// Virtual event handlers, overide them in your derived class
virtual void onUpdateThicknessValue( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void onCalculateDielectricThickness( wxCommandEvent& event ) { event.Skip(); }
public:
PANEL_SETUP_BOARD_STACKUP_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 673,317 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxEmptyString );
~PANEL_SETUP_BOARD_STACKUP_BASE();
};

View File

@ -32,11 +32,13 @@
#include <layers_id_colors_and_visibility.h>
#include <board_design_settings.h>
#include <i18n_utility.h> // _HKI definition
#include <macros.h>
#include "stackup_predefined_prms.h"
// A list of copper finish standard type names
// They are standard names in .gbdjob files, so avoid changing them or
// ensure they are compatible with .gbrjob file spec.
// These names are in fact usual copper finish names.
static wxString CopperFinishType[] =
{
_HKI( NOT_SPECIFIED ), // Not specified, not in .gbrjob file
@ -51,7 +53,7 @@ static wxString CopperFinishType[] =
_HKI("Immersion gold"), // used in .gbrjob file
_HKI("HT_OSP"), // used in .gbrjob file
_HKI("OSP"), // used in .gbrjob file
_HKI("None"), // used in .gbrjob file
_HKI("None"), // used in .gbrjob file
_HKI("User defined") // keep this option at end
};
@ -59,17 +61,18 @@ static wxString CopperFinishType[] =
// A list of available colors for solder mask and silkscreen
// These names are used in .gbrjob file, so they are not fully free.
// Use only what is allowed in .gbrjob files.
// for other colors (user defined), the defined value is the html color syntax.
static FAB_LAYER_COLOR solderMaskColors[] =
{
{ _HKI( NOT_SPECIFIED ), wxColor( 0, 128, 0 ) }, // Not specified, not in .gbrjob file
{ _HKI( "Green" ), wxColor( 0, 128, 0 ) }, // used in .gbrjob file
{ _HKI( NOT_SPECIFIED ), wxColor( 80, 80, 80 ) }, // Not specified, not in .gbrjob file
{ _HKI( "Green" ), wxColor( 60, 150, 80 ) }, // used in .gbrjob file
{ _HKI( "Red" ), wxColor( 128, 0, 0 ) }, // used in .gbrjob file
{ _HKI( "Blue" ), wxColor( 0, 0, 128 ) }, // used in .gbrjob file
{ _HKI( "Black" ), wxColor( 20, 20, 20 ) }, // used in .gbrjob file
{ _HKI( "White" ), wxColor( 200, 200, 200 ) }, // used in .gbrjob file
{ _HKI( "Yellow" ), wxColor( 128, 128, 0 ) }, // used in .gbrjob file
{ _HKI( "Purple" ), wxColor( 100, 0, 100 ) }, // used in .gbrjob file
{ _HKI( "user defined" ), wxColor( 128, 128, 128 ) }, //free
{ _HKI( "user defined" ), wxColor( 128, 128, 128 ) }, //free. the name is a dummy name here
{ "", wxColor( 0, 0, 0 ) } // Sentinel
};
@ -77,6 +80,7 @@ static FAB_LAYER_COLOR solderMaskColors[] =
// A list of available substrate material
// These names are used in .gbrjob file, so they are not fully free.
// Use only what is allowed in .gbrjob files.
// These names are in fact usual substrate names.
static FAB_SUBSTRATE substrateMaterial[] =
{
{ _HKI( NOT_SPECIFIED ), 0.0, 0.0 }, // Not specified, not in .gbrjob file
@ -109,6 +113,18 @@ const FAB_LAYER_COLOR* GetColorStandardList()
}
int GetColorStandardListCount()
{
return arrayDim( solderMaskColors ) - 1;
}
int GetColorUserDefinedListIdx()
{
return GetColorStandardListCount() - 1;
}
const FAB_SUBSTRATE* GetSubstrateMaterialStandardList()
{
return substrateMaterial;

View File

@ -44,7 +44,13 @@
struct FAB_LAYER_COLOR
{
wxString m_ColorName; // the name (in job file) of the color
// User values are the HTML coding #rrggbb hexa value.
wxColor m_Color; // the color in r,g,b values (0..255)
FAB_LAYER_COLOR() {}
FAB_LAYER_COLOR( const wxString& aColorName, const wxColor& aColor )
: m_ColorName( aColorName ), m_Color( aColor )
{}
};
@ -69,6 +75,16 @@ wxArrayString GetCopperFinishStandardList( bool aTranslate );
*/
const FAB_LAYER_COLOR* GetColorStandardList();
/**
* @return the count of colors in ColorStandardList
*/
int GetColorStandardListCount();
/**
* @return the index of the user defined color in ColorStandardList
*/
int GetColorUserDefinedListIdx();
/**
* @return a list of standard material items for dielectric.
*/

View File

@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2017-2018 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2017-2019 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
@ -23,6 +23,7 @@
#include <panel_setup_netclasses.h>
#include <panel_setup_tracks_and_vias.h>
#include <panel_setup_mask_and_paste.h>
#include <../board_stackup_manager/panel_board_stackup.h>
#include <kiface_i.h>
#include "dialog_import_settings.h"
@ -38,13 +39,17 @@ DIALOG_BOARD_SETUP::DIALOG_BOARD_SETUP( PCB_EDIT_FRAME* aFrame ) :
m_netclasses = new PANEL_SETUP_NETCLASSES( this, aFrame, m_constraints );
m_tracksAndVias = new PANEL_SETUP_TRACKS_AND_VIAS( this, aFrame, m_constraints );
m_maskAndPaste = new PANEL_SETUP_MASK_AND_PASTE( this, aFrame );
m_physicalStackup = new PANEL_SETUP_BOARD_STACKUP( this, aFrame, m_layers );
/*
* WARNING: If you change page names you MUST update calls to DoShowBoardSetupDialog().
*/
m_treebook->AddPage( new wxPanel( this ), _( "Board Stack-up" ) );
m_treebook->AddSubPage( m_layers, _( "Layers" ) );
m_treebook->AddPage( new wxPanel( this ), _( "Board Stackup" ) );
m_treebook->AddSubPage( m_layers, _( "Board Editor Layers" ) );
m_treebook->AddSubPage( m_physicalStackup, _( "Physical Stackup" ) );
// Change this value if m_physicalStackup is not the page 2 of m_treebook
m_physicalStackupPage = 2; // The page number (from 0) to select the m_physicalStackup panel
m_treebook->AddPage( new wxPanel( this ), _( "Defaults" ) );
m_treebook->AddSubPage( m_textAndGraphics, _( "Text & Graphics" ) );
@ -54,6 +59,24 @@ DIALOG_BOARD_SETUP::DIALOG_BOARD_SETUP( PCB_EDIT_FRAME* aFrame ) :
m_treebook->AddPage( new wxPanel( this ), _( "Design Rules" ) );
m_treebook->AddSubPage( m_constraints, _( "Constraints" ) );
m_treebook->AddSubPage( m_netclasses, _( "Net Classes" ) );
// Connect Events
m_treebook->Connect( wxEVT_TREEBOOK_PAGE_CHANGED,
wxBookCtrlEventHandler( DIALOG_BOARD_SETUP::OnPageChange ), NULL, this );
}
DIALOG_BOARD_SETUP::~DIALOG_BOARD_SETUP()
{
m_treebook->Disconnect( wxEVT_TREEBOOK_PAGE_CHANGED,
wxBookCtrlEventHandler( DIALOG_BOARD_SETUP::OnPageChange ), NULL, this );
}
void DIALOG_BOARD_SETUP::OnPageChange( wxBookCtrlEvent& event )
{
if( event.GetSelection() == m_physicalStackupPage )
m_physicalStackup->OnLayersOptionsChanged( m_layers->GetUILayerMask() );
}
@ -90,6 +113,16 @@ void DIALOG_BOARD_SETUP::OnAuxiliaryAction( wxCommandEvent& event )
if( importDlg.m_MaskAndPasteOpt->GetValue() )
m_maskAndPaste->ImportSettingsFrom( dummyBoard );
// If layers options are imported, import also the stackup
// layers options and stackup are linked, so they cannot be imported
// separately, and stackup can be imported only after layers options
//
// Note also currently only the list of enabled layers can be imported, because
// we import settings from a .pro project file, not the settings inside
// a board, and info only living in the board is not imported.
if( importDlg.m_LayersOpt->GetValue() )
m_physicalStackup->ImportSettingsFrom( dummyBoard );
delete dummyBoard;
delete cfg;
}

View File

@ -30,12 +30,14 @@ class PANEL_SETUP_TEXT_AND_GRAPHICS;
class PANEL_SETUP_NETCLASSES;
class PANEL_SETUP_TRACKS_AND_VIAS;
class PANEL_SETUP_MASK_AND_PASTE;
class PANEL_SETUP_BOARD_STACKUP;
class DIALOG_BOARD_SETUP : public PAGED_DIALOG
{
public:
DIALOG_BOARD_SETUP( PCB_EDIT_FRAME* aFrame );
~DIALOG_BOARD_SETUP();
protected:
void OnAuxiliaryAction( wxCommandEvent& event ) override;
@ -48,6 +50,13 @@ protected:
PANEL_SETUP_NETCLASSES* m_netclasses;
PANEL_SETUP_TRACKS_AND_VIAS* m_tracksAndVias;
PANEL_SETUP_MASK_AND_PASTE* m_maskAndPaste;
PANEL_SETUP_BOARD_STACKUP* m_physicalStackup;
// event handlers
void OnPageChange( wxBookCtrlEvent& event );
private:
int m_physicalStackupPage; // the page index of the PANEL_SETUP_BOARD_STACKUP page
};

View File

@ -136,11 +136,9 @@ static const LSET presets[] =
PANEL_SETUP_LAYERS::PANEL_SETUP_LAYERS( PAGED_DIALOG* aParent, PCB_EDIT_FRAME* aFrame ) :
PANEL_SETUP_LAYERS_BASE( aParent->GetTreebook() ),
m_Parent( aParent ), m_frame( aFrame ),
m_pcbThickness( aFrame, m_thicknessLabel, m_thicknessCtrl, m_thicknessUnits, true )
m_Parent( aParent ), m_frame( aFrame )
{
m_pcb = aFrame->GetBoard();
m_LayersListPanel->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_LISTBOX) );
}
@ -237,7 +235,6 @@ bool PANEL_SETUP_LAYERS::TransferDataToWindow()
showCopperChoice( m_pcb->GetCopperLayerCount() );
setCopperLayerCheckBoxes( m_pcb->GetCopperLayerCount() );
m_pcbThickness.SetValue( m_pcb->GetDesignSettings().GetBoardThickness() );
showBoardLayerNames();
showSelectedLayerCheckBoxes( m_enabledLayers );
@ -340,7 +337,7 @@ void PANEL_SETUP_LAYERS::showLayerTypes()
}
LSET PANEL_SETUP_LAYERS::getUILayerMask()
LSET PANEL_SETUP_LAYERS::GetUILayerMask()
{
LSET layerMaskResult;
@ -408,7 +405,7 @@ void PANEL_SETUP_LAYERS::setCopperLayerCheckBoxes( int copperCount )
void PANEL_SETUP_LAYERS::OnCheckBox( wxCommandEvent& event )
{
m_enabledLayers = getUILayerMask();
m_enabledLayers = GetUILayerMask();
showPresets( m_enabledLayers );
}
@ -444,7 +441,7 @@ void PANEL_SETUP_LAYERS::DenyChangeCheckBox( wxCommandEvent& event )
if( source == mandatory )
{
msg.Printf( _( "The %s layer is mandatory." ), getLayerName( layer ) );
msg.Printf( _( "The %s layer is mandatory." ), GetLayerName( layer ) );
DisplayError( this, msg );
mandatory->SetValue( true );
return;
@ -479,7 +476,7 @@ void PANEL_SETUP_LAYERS::OnPresetsChoice( wxCommandEvent& event )
void PANEL_SETUP_LAYERS::OnCopperLayersChoice( wxCommandEvent& event )
{
setCopperLayerCheckBoxes( m_CopperLayersChoice->GetCurrentSelection() * 2 + 2 );
m_enabledLayers = getUILayerMask();
m_enabledLayers = GetUILayerMask();
showPresets( m_enabledLayers );
}
@ -491,8 +488,6 @@ bool PANEL_SETUP_LAYERS::TransferDataFromWindow()
wxString msg;
int thickness = m_pcbThickness.GetValue();
// Check for removed layers with items which will get deleted from the board.
LSEQ removedLayers = getRemovedLayersWithItems();
@ -545,7 +540,7 @@ bool PANEL_SETUP_LAYERS::TransferDataFromWindow()
}
}
m_enabledLayers = getUILayerMask();
m_enabledLayers = GetUILayerMask();
if( m_enabledLayers != m_pcb->GetEnabledLayers() )
{
@ -564,14 +559,12 @@ bool PANEL_SETUP_LAYERS::TransferDataFromWindow()
if( m_enabledLayers[layer] )
{
m_pcb->SetLayerName( layer, getLayerName( layer ) );
m_pcb->SetLayerName( layer, GetLayerName( layer ) );
LAYER_T t = (LAYER_T) getLayerTypeIndex( layer );
m_pcb->SetLayerType( layer, t );
}
}
m_pcb->GetDesignSettings().SetBoardThickness( thickness );
// If some board items are deleted: rebuild the connectivity,
// because it is likely some tracks and vias where removed
if( hasRemovedBoardItems )
@ -593,7 +586,7 @@ int PANEL_SETUP_LAYERS::getLayerTypeIndex( LAYER_NUM aLayer )
}
wxString PANEL_SETUP_LAYERS::getLayerName( LAYER_NUM aLayer )
wxString PANEL_SETUP_LAYERS::GetLayerName( LAYER_NUM aLayer )
{
wxControl* control = getName( aLayer );
@ -629,7 +622,7 @@ bool PANEL_SETUP_LAYERS::testLayerNames()
if( !m_enabledLayers[layer] )
continue;
wxString name = getLayerName( layer );
wxString name = GetLayerName( layer );
ctl = (wxTextCtrl*) getName( layer );
@ -683,7 +676,7 @@ bool PANEL_SETUP_LAYERS::testLayerNames()
LSEQ PANEL_SETUP_LAYERS::getRemovedLayersWithItems()
{
LSEQ removedLayers;
LSET newLayers = getUILayerMask();
LSET newLayers = GetUILayerMask();
LSET curLayers = m_pcb->GetEnabledLayers();
if( newLayers == curLayers ) // return a empty list if no change
@ -712,7 +705,7 @@ LSEQ PANEL_SETUP_LAYERS::getNonRemovableLayers()
{
//Build the list of non copper layers in use in footprints.
LSEQ inUseLayers;
LSET newLayers = getUILayerMask();
LSET newLayers = GetUILayerMask();
LSET curLayers = m_pcb->GetEnabledLayers();
if( newLayers == curLayers ) // return a empty list if no change

View File

@ -59,13 +59,17 @@ public:
void ImportSettingsFrom( BOARD* aBoard );
///> @return the selected layer mask within the UI checkboxes
LSET GetUILayerMask();
///> @return the layer name within the UI wxTextCtrl
wxString GetLayerName( LAYER_NUM layer );
private:
PAGED_DIALOG* m_Parent;
PCB_EDIT_FRAME* m_frame;
BOARD* m_pcb;
LSET m_enabledLayers;
UNIT_BINDER m_pcbThickness;
void setLayerCheckBox( LAYER_NUM layer, bool isChecked );
void setCopperLayerCheckBoxes( int copperCount );
@ -77,9 +81,6 @@ private:
void showLayerTypes();
void showPresets( LSET enabledLayerMask );
/** Return the selected layer mask within the UI checkboxes */
LSET getUILayerMask();
wxString getLayerName( LAYER_NUM layer );
int getLayerTypeIndex( LAYER_NUM layer );
void OnCheckBox( wxCommandEvent& event ) override;

View File

@ -42,17 +42,6 @@ PANEL_SETUP_LAYERS_BASE::PANEL_SETUP_LAYERS_BASE( wxWindow* parent, wxWindowID i
bSizerLayerCnt->Add( 15, 0, 0, 0, 5 );
m_thicknessLabel = new wxStaticText( this, wxID_ANY, _("PCB thickness:"), wxDefaultPosition, wxDefaultSize, 0 );
m_thicknessLabel->Wrap( -1 );
bSizerLayerCnt->Add( m_thicknessLabel, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
m_thicknessCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
bSizerLayerCnt->Add( m_thicknessCtrl, 0, wxEXPAND|wxALL, 3 );
m_thicknessUnits = new wxStaticText( this, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_thicknessUnits->Wrap( -1 );
bSizerLayerCnt->Add( m_thicknessUnits, 0, wxALL|wxALIGN_CENTER_VERTICAL, 3 );
bSizerMargins->Add( bSizerLayerCnt, 0, wxEXPAND, 5 );

View File

@ -285,192 +285,6 @@
<property name="width">15</property>
</object>
</object>
<object class="sizeritem" expanded="0">
<property name="border">3</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">PCB thickness:</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_thicknessLabel</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
</object>
</object>
<object class="sizeritem" expanded="0">
<property name="border">3</property>
<property name="flag">wxEXPAND|wxALL</property>
<property name="proportion">0</property>
<object class="wxTextCtrl" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="maxlength"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size">-1,-1</property>
<property name="moveable">1</property>
<property name="name">m_thicknessCtrl</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="value"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="0">
<property name="border">3</property>
<property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">mm</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_thicknessUnits</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
</object>
</object>
</object>
</object>
<object class="sizeritem" expanded="1">

View File

@ -17,10 +17,10 @@
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/stattext.h>
#include <wx/textctrl.h>
#include <wx/sizer.h>
#include <wx/statline.h>
#include <wx/checkbox.h>
#include <wx/textctrl.h>
#include <wx/scrolwin.h>
#include <wx/panel.h>
@ -186,9 +186,6 @@ class PANEL_SETUP_LAYERS_BASE : public wxPanel
wxChoice* m_PresetsChoice;
wxStaticText* m_staticTextCopperLayers;
wxChoice* m_CopperLayersChoice;
wxStaticText* m_thicknessLabel;
wxTextCtrl* m_thicknessCtrl;
wxStaticText* m_thicknessUnits;
wxStaticLine* m_staticline2;
wxScrolledWindow* m_LayersListPanel;
wxFlexGridSizer* m_LayerListFlexGridSizer;

View File

@ -688,7 +688,7 @@ void GERBER_JOBFILE_WRITER::addJSONMaterialStackup()
if( uptodate ) // We can add the dielectric variant ("core" "prepreg" ...):
note << wxString::Format( " \"Type: %s", layer_name.c_str() );
note << wxString::Format( " \"(from %s to %s)\"\n",
note << wxString::Format( " (from %s to %s)\"\n",
formatStringFromUTF32( m_pcb->GetLayerName( last_copper_layer ) ),
formatStringFromUTF32( m_pcb->GetLayerName( next_copper_layer ) ) );

View File

@ -466,6 +466,7 @@ void PCB_IO::formatLayer( const BOARD_ITEM* aItem ) const
m_out->Print( 0, " (layer %s)", m_out->Quotew( aItem->GetLayerName() ).c_str() );
}
void PCB_IO::formatSetup( BOARD* aBoard, int aNestLevel ) const
{
const BOARD_DESIGN_SETTINGS& dsnSettings = aBoard->GetDesignSettings();
@ -473,6 +474,12 @@ void PCB_IO::formatSetup( BOARD* aBoard, int aNestLevel ) const
// Setup
m_out->Print( aNestLevel, "(setup\n" );
// Save the board physical stackup structure
BOARD_STACKUP& stackup = aBoard->GetDesignSettings().GetStackupDescriptor();
if( aBoard->GetDesignSettings().m_HasStackup )
stackup.FormatBoardStackup( m_out,aBoard, aNestLevel+1 );
// Save current default track width, for compatibility with older Pcbnew version;
m_out->Print( aNestLevel+1, "(last_trace_width %s)\n",
FormatInternalUnits( dsnSettings.GetCurrentTrackWidth() ).c_str() );
@ -741,10 +748,12 @@ void PCB_IO::formatNetInformation( BOARD* aBoard, int aNestLevel ) const
void PCB_IO::formatHeader( BOARD* aBoard, int aNestLevel ) const
{
formatGeneral( aBoard, aNestLevel );
// Layers.
// Layers list.
formatBoardLayers( aBoard, aNestLevel );
// Setup
formatSetup( aBoard, aNestLevel );
// Save net codes and names
formatNetInformation( aBoard, aNestLevel );
}

View File

@ -61,7 +61,8 @@ class TEXTE_PCB;
//#define SEXPR_BOARD_FILE_VERSION 20190331 // hatched zones and chamfered round rect pads
//#define SEXPR_BOARD_FILE_VERSION 20190421 // curves in custom pads
//#define SEXPR_BOARD_FILE_VERSION 20190516 // Remove segment count from zones
#define SEXPR_BOARD_FILE_VERSION 20190605 // Add layer defaults
//#define SEXPR_BOARD_FILE_VERSION 20190605 // Add layer defaults
#define SEXPR_BOARD_FILE_VERSION 20190825 // Add board physical stackup info in setup section
#define CTL_STD_LAYER_NAMES (1 << 0) ///< Use English Standard layer names
#define CTL_OMIT_NETS (1 << 1) ///< Omit pads net names (useless in library)

View File

@ -112,6 +112,27 @@ void PCB_PARSER::init()
}
void PCB_PARSER::skipCurrent()
{
int curr_level = 0;
T token;
while( ( token = NextTok() ) != T_EOF )
{
if( token == T_LEFT )
curr_level--;
if( token == T_RIGHT )
{
curr_level++;
if( curr_level > 0 )
return;
}
}
}
void PCB_PARSER::pushValueIntoMap( int aIndex, int aValue )
{
// Add aValue in netcode mapping (m_netCodes) at index aNetCode
@ -123,6 +144,7 @@ void PCB_PARSER::pushValueIntoMap( int aIndex, int aValue )
m_netCodes[aIndex] = aValue;
}
double PCB_PARSER::parseDouble()
{
char* tmp;
@ -952,6 +974,182 @@ void PCB_PARSER::parseLayer( LAYER* aLayer )
}
void PCB_PARSER::parseBoardStackup()
{
T token;
wxString name;
int dielectric_idx = 1; // the index of dielectric layers
BOARD_STACKUP& stackup = m_board->GetDesignSettings().GetStackupDescriptor();
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
if( CurTok() != T_LEFT )
Expecting( T_LEFT );
token = NextTok();
if( token != T_layer )
{
switch( token )
{
case T_copper_finish:
NeedSYMBOL();
stackup.m_FinishType = FromUTF8();
NeedRIGHT();
break;
case T_edge_plating:
token = NextTok();
stackup.m_EdgePlating = token == T_yes;
NeedRIGHT();
break;
case T_dielectric_constraints:
token = NextTok();
stackup.m_HasDielectricConstrains = token == T_yes;
NeedRIGHT();
break;
case T_edge_connector:
token = NextTok();
stackup.m_EdgeConnectorConstraints = BS_EDGE_CONNECTOR_NONE;
if( token == T_yes )
stackup.m_EdgeConnectorConstraints = BS_EDGE_CONNECTOR_IN_USE;
else if( token == T_bevelled )
stackup.m_EdgeConnectorConstraints = BS_EDGE_CONNECTOR_BEVELLED;
NeedRIGHT();
break;
case T_castellated_pads:
token = NextTok();
stackup.m_CastellatedPads = token == T_yes;
NeedRIGHT();
break;
default:
// Currently, skip this item if not defined, because the stackup def
// is a moving target
//Expecting( "copper_finish, edge_plating, dielectric_constrains, edge_connector, castellated_pads" );
skipCurrent();
break;
}
continue;
}
NeedSYMBOL();
name = FromUTF8();
// init the layer id. For dielectric, layer id = UNDEFINED_LAYER
PCB_LAYER_ID layerId = m_board->GetLayerID( name );
// Init the type
BOARD_STACKUP_ITEM_TYPE type = BS_ITEM_TYPE_UNDEFINED;
if( layerId == F_SilkS || layerId == B_SilkS )
type = BS_ITEM_TYPE_SILKSCREEN;
else if( layerId == F_Mask || layerId == B_Mask )
type = BS_ITEM_TYPE_SOLDERMASK;
else if( layerId == F_Paste || layerId == B_Paste )
type = BS_ITEM_TYPE_SOLDERPASTE;
else if( layerId == UNDEFINED_LAYER )
type = BS_ITEM_TYPE_DIELECTRIC;
else if( layerId >= F_Cu && layerId <= B_Cu )
type = BS_ITEM_TYPE_COPPER;
BOARD_STACKUP_ITEM* item = nullptr;
if( type != BS_ITEM_TYPE_UNDEFINED )
{
item = new BOARD_STACKUP_ITEM( type );
item->m_LayerId = layerId;
if( type == BS_ITEM_TYPE_DIELECTRIC )
item->m_DielectricLayerId = dielectric_idx++;
stackup.Add( item );
}
else
Expecting( "layer_name" );
// Dielectric thickness can be locked (for impedance controled layers)
bool thickness_locked = false;
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
if( token == T_LEFT )
{
token = NextTok();
switch( token )
{
case T_type:
NeedSYMBOL();
item->m_TypeName = FromUTF8();
NeedRIGHT();
break;
case T_thickness:
item->m_Thickness = parseBoardUnits( T_thickness );
token = NextTok();
if( token == T_LEFT )
break;
if( token == T_locked )
{
thickness_locked = true;
NeedRIGHT();
}
break;
case T_material:
NeedSYMBOL();
item->m_Material = FromUTF8();
NeedRIGHT();
break;
case T_epsilon_r:
NextTok();
item->m_EpsilonR = parseDouble();
NeedRIGHT();
break;
case T_loss_tangent:
NextTok();
item->m_LossTangent = parseDouble();
NeedRIGHT();
break;
case T_color:
NeedSYMBOL();
item->m_Color = FromUTF8();
NeedRIGHT();
break;
default:
// Currently, skip this item if not defined, because the stackup def
// is a moving target
//Expecting( "type, thickness, material, epsilon_r, loss_tangent, color" );
skipCurrent();
}
}
}
if( type == BS_ITEM_TYPE_DIELECTRIC && thickness_locked )
item->m_ThicknessLocked = true;
}
if( token != T_RIGHT )
{
Expecting( ")" );
}
// Success:
m_board->GetDesignSettings().m_HasStackup = true;
}
void PCB_PARSER::createOldLayerMapping( std::unordered_map< std::string, std::string >& aMap )
{
// N.B. This mapping only includes Italian, Polish and French as they were the only languages that
@ -1193,9 +1391,7 @@ void PCB_PARSER::parseSetup()
T token;
NETCLASSPTR defaultNetClass = m_board->GetDesignSettings().GetDefault();
// TODO Orson: is it really necessary to first operate on a copy and then apply it?
// would not it be better to use reference here and apply all the changes instantly?
BOARD_DESIGN_SETTINGS designSettings = m_board->GetDesignSettings();
BOARD_DESIGN_SETTINGS& designSettings = m_board->GetDesignSettings();
ZONE_SETTINGS zoneSettings = m_board->GetZoneSettings();
// Missing soldermask min width value means that the user has set the value to 0 and
@ -1211,6 +1407,10 @@ void PCB_PARSER::parseSetup()
switch( token )
{
case T_stackup:
parseBoardStackup();
break;
case T_last_trace_width: // not used now
/* lastTraceWidth =*/ parseBoardUnits( T_last_trace_width );
NeedRIGHT();
@ -1370,7 +1570,7 @@ void PCB_PARSER::parseSetup()
break;
case T_pad_to_mask_clearance:
designSettings.m_SolderMaskMargin = parseBoardUnits( T_pad_to_mask_clearance );
designSettings.m_SolderMaskMargin = parseBoardUnits( T_pad_to_mask_clearance );
NeedRIGHT();
break;
@ -1444,7 +1644,7 @@ void PCB_PARSER::parseSetup()
}
}
m_board->SetDesignSettings( designSettings );
//m_board->SetDesignSettings( designSettings );
m_board->SetZoneSettings( zoneSettings );
}

View File

@ -113,6 +113,13 @@ class PCB_PARSER : public PCB_LEXER
*/
void createOldLayerMapping( std::unordered_map< std::string, std::string >& aMap );
/**
* Function skipCurrent
* Skip the current token level, i.e
* search for the RIGHT parenthesis which closes the current description
*/
void skipCurrent();
void parseHeader();
void parseGeneralSection();
void parsePAGE_INFO();
@ -121,6 +128,8 @@ class PCB_PARSER : public PCB_LEXER
void parseLayers();
void parseLayer( LAYER* aLayer );
void parseBoardStackup();
void parseSetup();
void parseDefaults( BOARD_DESIGN_SETTINGS& aSettings );
void parseDefaultTextDims( BOARD_DESIGN_SETTINGS& aSettings, int aLayer );

View File

@ -224,7 +224,8 @@ void PCB_PLOT_PARAMS::Format( OUTPUTFORMATTER* aFormatter,
m_scaleSelection );
aFormatter->Print( aNestLevel+1, "(%s \"%s\")", getTokenName( T_outputdirectory ),
(const char*) m_outputDirectory.utf8_str() );
aFormatter->Print( 0, ")\n" );
aFormatter->Print( 0, "\n" );
aFormatter->Print( aNestLevel, ")\n" );
}