diff --git a/common/common_plotGERBER_functions.cpp b/common/common_plotGERBER_functions.cpp index c0b1d418c3..99e47c27bf 100644 --- a/common/common_plotGERBER_functions.cpp +++ b/common/common_plotGERBER_functions.cpp @@ -67,6 +67,12 @@ bool GERBER_PLOTTER::StartPlot() if( outputFile == NULL ) return false; + if( !attribFunction.IsEmpty() ) + { + fputs( "%TF.GerberVersion,J1*%\n", outputFile ); + fprintf( outputFile, "%%TF.FileFunction,%s*%%\n", TO_UTF8( attribFunction ) ); + } + /* Set coordinate format to 3.4 absolute, leading zero omitted */ fputs( "%FSLAX34Y34*%\n", outputFile ); fputs( "G04 Gerber Fmt 3.4, Leading zero omitted, Abs format*\n", outputFile ); diff --git a/common/pcb_plot_params.keywords b/common/pcb_plot_params.keywords index 972afcb313..96e756c6d2 100644 --- a/common/pcb_plot_params.keywords +++ b/common/pcb_plot_params.keywords @@ -27,3 +27,4 @@ true useauxorigin usegerberextensions viasonmask +usegerberattributes diff --git a/include/plot_common.h b/include/plot_common.h index 3f0aee4e75..1a259fa378 100644 --- a/include/plot_common.h +++ b/include/plot_common.h @@ -282,7 +282,12 @@ public: */ virtual void SetTextMode( PlotTextMode mode ) { - // NOP for most plotters + // NOP for most plotters + } + + virtual void SetLayerAttribFunction( const wxString& function ) + { + // NOP for most plotters } protected: @@ -769,6 +774,7 @@ public: workFile = 0; finalFile = 0; currentAperture = apertures.end(); + attribFunction = wxEmptyString; } virtual PlotFormat GetPlotterType() const @@ -813,6 +819,11 @@ public: virtual void SetLayerPolarity( bool aPositive ); + virtual void SetLayerAttribFunction( const wxString& function ) + { + attribFunction = function; + } + protected: void selectAperture( const wxSize& size, APERTURE::APERTURE_TYPE type ); void emitDcode( const DPOINT& pt, int dcode ); @@ -828,6 +839,8 @@ protected: std::vector apertures; std::vector::iterator currentAperture; + + wxString attribFunction; /* the layer "function", it is linked with the layer id */ }; diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index b9321922a8..96d35e4bc8 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -107,7 +107,7 @@ protected: #ifdef KICAD_SCRIPTING_WXPYTHON // Panel used to let user talk with internal scripting wxWindow* m_pythonPanel; - bool m_pythonPanelHidden; + bool m_pythonPanelShow; ///< Visibility flag for Python Console #endif PCB_LAYER_WIDGET* m_Layers; @@ -1524,7 +1524,9 @@ public: * Function ScriptingConsoleEnableDisable * enables or disabled the scripting console */ - void ScriptingConsoleEnableDisable( wxCommandEvent& event ); + void ScriptingConsoleEnableDisable( wxCommandEvent& aEvent ); + + void OnUpdateScriptingConsoleState( wxUpdateUIEvent& aEvent ); void OnSelectAutoPlaceMode( wxCommandEvent& aEvent ); diff --git a/pcbnew/dialogs/dialog_SVG_print.cpp b/pcbnew/dialogs/dialog_SVG_print.cpp index 5fb3757479..a24fde6d18 100644 --- a/pcbnew/dialogs/dialog_SVG_print.cpp +++ b/pcbnew/dialogs/dialog_SVG_print.cpp @@ -334,7 +334,9 @@ bool DIALOG_SVG_PRINT::CreateSVGFile( const wxString& aFullFileName ) LOCALE_IO toggle; SVG_PLOTTER* plotter = (SVG_PLOTTER*) StartPlotBoard( m_board, - &m_plotOpts, aFullFileName, + &m_plotOpts, + UNDEFINED_LAYER, + aFullFileName, wxEmptyString ); if( plotter ) diff --git a/pcbnew/dialogs/dialog_plot.cpp b/pcbnew/dialogs/dialog_plot.cpp index 230f170b65..cc8ccbda45 100644 --- a/pcbnew/dialogs/dialog_plot.cpp +++ b/pcbnew/dialogs/dialog_plot.cpp @@ -171,6 +171,9 @@ void DIALOG_PLOT::Init_Dialog() // Option for using proper Gerber extensions m_useGerberExtensions->SetValue( m_plotOpts.GetUseGerberExtensions() ); + // Option for including Gerber attributes (from Gerber X2 format) in the output + m_useGerberAttributes->SetValue( m_plotOpts.GetUseGerberAttributes() ); + // Option for excluding contents of "Edges Pcb" layer m_excludeEdgeLayerOpt->SetValue( m_plotOpts.GetExcludeEdgeLayer() ); @@ -379,6 +382,8 @@ void DIALOG_PLOT::SetPlotFormat( wxCommandEvent& event ) m_subtractMaskFromSilk->SetValue( false ); m_useGerberExtensions->Enable( false ); m_useGerberExtensions->SetValue( false ); + m_useGerberAttributes->Enable( false ); + m_useGerberAttributes->SetValue( false ); m_scaleOpt->Enable( false ); m_scaleOpt->SetSelection( 1 ); m_fineAdjustXscaleOpt->Enable( false ); @@ -407,6 +412,8 @@ void DIALOG_PLOT::SetPlotFormat( wxCommandEvent& event ) m_subtractMaskFromSilk->SetValue( false ); m_useGerberExtensions->Enable( false ); m_useGerberExtensions->SetValue( false ); + m_useGerberAttributes->Enable( false ); + m_useGerberAttributes->SetValue( false ); m_scaleOpt->Enable( true ); m_fineAdjustXscaleOpt->Enable( true ); m_fineAdjustYscaleOpt->Enable( true ); @@ -433,6 +440,7 @@ void DIALOG_PLOT::SetPlotFormat( wxCommandEvent& event ) m_excludeEdgeLayerOpt->Enable( true ); m_subtractMaskFromSilk->Enable( true ); m_useGerberExtensions->Enable( true ); + m_useGerberAttributes->Enable( true ); m_scaleOpt->Enable( false ); m_scaleOpt->SetSelection( 1 ); m_fineAdjustXscaleOpt->Enable( false ); @@ -462,6 +470,8 @@ void DIALOG_PLOT::SetPlotFormat( wxCommandEvent& event ) m_subtractMaskFromSilk->SetValue( false ); m_useGerberExtensions->Enable( false ); m_useGerberExtensions->SetValue( false ); + m_useGerberAttributes->Enable( false ); + m_useGerberAttributes->SetValue( false ); m_scaleOpt->Enable( true ); m_fineAdjustXscaleOpt->Enable( false ); m_fineAdjustYscaleOpt->Enable( false ); @@ -489,6 +499,8 @@ void DIALOG_PLOT::SetPlotFormat( wxCommandEvent& event ) m_subtractMaskFromSilk->SetValue( false ); m_useGerberExtensions->Enable( false ); m_useGerberExtensions->SetValue( false ); + m_useGerberAttributes->Enable( false ); + m_useGerberAttributes->SetValue( false ); m_scaleOpt->Enable( false ); m_scaleOpt->SetSelection( 1 ); m_fineAdjustXscaleOpt->Enable( false ); @@ -667,6 +679,8 @@ void DIALOG_PLOT::applyPlotSettings() tempOptions.SetUseGerberExtensions( m_useGerberExtensions->GetValue() ); + tempOptions.SetUseGerberAttributes( m_useGerberAttributes->GetValue() ); + tempOptions.SetFormat( GetPlotFormat() ); long selectedLayers = 0; @@ -794,7 +808,7 @@ void DIALOG_PLOT::Plot( wxCommandEvent& event ) LOCALE_IO toggle; BOARD *board = m_parent->GetBoard(); PLOTTER *plotter = StartPlotBoard( board, &m_plotOpts, - fn.GetFullPath(), + layer, fn.GetFullPath(), wxEmptyString ); // Print diags in messages box: diff --git a/pcbnew/dialogs/dialog_plot_base.cpp b/pcbnew/dialogs/dialog_plot_base.cpp index b79b361eeb..e252a8a6fa 100644 --- a/pcbnew/dialogs/dialog_plot_base.cpp +++ b/pcbnew/dialogs/dialog_plot_base.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Nov 6 2013) +// C++ code generated with wxFormBuilder (version Feb 26 2014) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -226,6 +226,11 @@ DIALOG_PLOT_BASE::DIALOG_PLOT_BASE( wxWindow* parent, wxWindowID id, const wxStr m_GerberOptionsSizer->Add( m_useGerberExtensions, 0, wxLEFT|wxRIGHT|wxTOP, 2 ); + m_useGerberAttributes = new wxCheckBox( this, wxID_ANY, _("Include extended attributes"), wxDefaultPosition, wxDefaultSize, 0 ); + m_useGerberAttributes->SetToolTip( _("Include extended attributes for non-image data in the Gerber file") ); + + m_GerberOptionsSizer->Add( m_useGerberAttributes, 0, wxTOP|wxRIGHT|wxLEFT, 2 ); + m_subtractMaskFromSilk = new wxCheckBox( this, wxID_ANY, _("Subtract soldermask from silkscreen"), wxDefaultPosition, wxDefaultSize, 0 ); m_subtractMaskFromSilk->SetToolTip( _("Remove silkscreen from areas without soldermask") ); diff --git a/pcbnew/dialogs/dialog_plot_base.fbp b/pcbnew/dialogs/dialog_plot_base.fbp index 1c97178da6..752ae33811 100644 --- a/pcbnew/dialogs/dialog_plot_base.fbp +++ b/pcbnew/dialogs/dialog_plot_base.fbp @@ -2778,6 +2778,90 @@ + + 2 + wxTOP|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Include extended attributes + + 0 + + + 0 + + 1 + m_useGerberAttributes + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + Include extended attributes for non-image data in the Gerber file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 wxTOP|wxRIGHT|wxLEFT diff --git a/pcbnew/dialogs/dialog_plot_base.h b/pcbnew/dialogs/dialog_plot_base.h index aac7fb470f..61ba907191 100644 --- a/pcbnew/dialogs/dialog_plot_base.h +++ b/pcbnew/dialogs/dialog_plot_base.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Nov 6 2013) +// C++ code generated with wxFormBuilder (version Feb 26 2014) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -89,6 +89,7 @@ class DIALOG_PLOT_BASE : public DIALOG_SHIM wxStaticText* m_SolderMaskMinWidthCurrValue; wxStaticBoxSizer* m_GerberOptionsSizer; wxCheckBox* m_useGerberExtensions; + wxCheckBox* m_useGerberAttributes; wxCheckBox* m_subtractMaskFromSilk; wxStaticBoxSizer* m_HPGLOptionsSizer; wxStaticText* m_textPenSize; diff --git a/pcbnew/menubar_pcbframe.cpp b/pcbnew/menubar_pcbframe.cpp index b95b8529fe..649694ac4f 100644 --- a/pcbnew/menubar_pcbframe.cpp +++ b/pcbnew/menubar_pcbframe.cpp @@ -534,8 +534,8 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() #if defined(KICAD_SCRIPTING_WXPYTHON) AddMenuItem( toolsMenu, ID_TOOLBARH_PCB_SCRIPTING_CONSOLE, _( "&Scripting Console" ), - _( "Show/Hide the Scripting console" ), - KiBitmap( book_xpm ) ); + _( "Show/Hide the Python Scripting console" ), + KiBitmap( py_script_xpm ) ); #endif wxMenu* designRulesMenu = new wxMenu; diff --git a/pcbnew/pcb_plot_params.cpp b/pcbnew/pcb_plot_params.cpp index e8a1d8e3e0..bc9ce8bbb6 100644 --- a/pcbnew/pcb_plot_params.cpp +++ b/pcbnew/pcb_plot_params.cpp @@ -79,6 +79,7 @@ PCB_PLOT_PARAMS::PCB_PLOT_PARAMS() m_layerSelection = LAYER_BACK | LAYER_FRONT | SILKSCREEN_LAYER_FRONT | SILKSCREEN_LAYER_BACK; m_useGerberExtensions = true; + m_useGerberAttributes = false; m_excludeEdgeLayer = true; m_lineWidth = g_DrawDefaultLineThickness; m_plotFrameRef = false; @@ -129,6 +130,8 @@ void PCB_PLOT_PARAMS::Format( OUTPUTFORMATTER* aFormatter, long(m_layerSelection) ); aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_usegerberextensions ), m_useGerberExtensions ? trueStr : falseStr ); + aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_usegerberattributes ), + m_useGerberAttributes ? trueStr : falseStr ); aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_excludeedgelayer ), m_excludeEdgeLayer ? trueStr : falseStr ); aFormatter->Print( aNestLevel+1, "(%s %f)\n", getTokenName( T_linewidth ), @@ -194,6 +197,8 @@ bool PCB_PLOT_PARAMS::operator==( const PCB_PLOT_PARAMS &aPcbPlotParams ) const return false; if( m_useGerberExtensions != aPcbPlotParams.m_useGerberExtensions ) return false; + if( m_useGerberAttributes != aPcbPlotParams.m_useGerberAttributes ) + return false; if( m_excludeEdgeLayer != aPcbPlotParams.m_excludeEdgeLayer ) return false; if( m_lineWidth != aPcbPlotParams.m_lineWidth ) @@ -329,6 +334,9 @@ void PCB_PLOT_PARAMS_PARSER::Parse( PCB_PLOT_PARAMS* aPcbPlotParams ) case T_usegerberextensions: aPcbPlotParams->m_useGerberExtensions = parseBool(); break; + case T_usegerberattributes: + aPcbPlotParams->m_useGerberAttributes = parseBool(); + break; case T_psa4output: aPcbPlotParams->m_A4Output = parseBool(); break; diff --git a/pcbnew/pcb_plot_params.h b/pcbnew/pcb_plot_params.h index 60f2b137cc..d6788b5d59 100644 --- a/pcbnew/pcb_plot_params.h +++ b/pcbnew/pcb_plot_params.h @@ -131,6 +131,9 @@ private: * appending a suffix to the board name */ bool m_useGerberExtensions; + /// Include attributes from the Gerber X2 format (chapter 5 in revision J1) + bool m_useGerberAttributes; + /// Plot gerbers using auxiliary (drill) origin instead of page coordinates bool m_useAuxOrigin; @@ -257,6 +260,9 @@ public: void SetOutputDirectory( wxString aDir ) { m_outputDirectory = aDir; }; wxString GetOutputDirectory() const { return m_outputDirectory; }; + void SetUseGerberAttributes( bool aUse ) { m_useGerberAttributes = aUse; }; + bool GetUseGerberAttributes() const { return m_useGerberAttributes; }; + void SetUseGerberExtensions( bool aUse ) { m_useGerberExtensions = aUse; }; bool GetUseGerberExtensions() const { return m_useGerberExtensions; }; diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index d9f4791969..4d9095d040 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -72,6 +72,8 @@ #if defined(KICAD_SCRIPTING) || defined(KICAD_SCRIPTING_WXPYTHON) #include +// The name of the pane info handling the python console: +#define PYTHONCONSOLE_STRID wxT( "PythonPanel" ) #endif #include @@ -203,6 +205,8 @@ BEGIN_EVENT_TABLE( PCB_EDIT_FRAME, PCB_BASE_FRAME ) EVT_TOOL( ID_TOOLBARH_PCB_FREEROUTE_ACCESS, PCB_EDIT_FRAME::Access_to_External_Tool ) #ifdef KICAD_SCRIPTING_WXPYTHON EVT_TOOL( ID_TOOLBARH_PCB_SCRIPTING_CONSOLE, PCB_EDIT_FRAME::ScriptingConsoleEnableDisable ) + EVT_UPDATE_UI( ID_TOOLBARH_PCB_SCRIPTING_CONSOLE, + PCB_EDIT_FRAME::OnUpdateScriptingConsoleState ) #endif // Option toolbar EVT_TOOL( ID_TB_OPTIONS_DRC_OFF, @@ -316,13 +320,13 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : m_RecordingMacros = -1; m_microWaveToolBar = NULL; m_useCmpFileForFpNames = true; +#if defined(KICAD_SCRIPTING_WXPYTHON) + m_pythonPanel = NULL; + m_pythonPanelShow = false; +#endif m_rotationAngle = 900; -#ifdef KICAD_SCRIPTING_WXPYTHON - m_pythonPanel = NULL; -#endif - for ( int i = 0; i < 10; i++ ) m_Macros[i].m_Record.clear(); @@ -415,7 +419,8 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : if( m_microWaveToolBar ) // The auxiliary vertical right toolbar (currently microwave tools) m_auimgr.AddPane( m_microWaveToolBar, - wxAuiPaneInfo( vert ).Name( wxT( "m_microWaveToolBar" ) ).Right().Layer( 1 ).Position(1).Hide() ); + wxAuiPaneInfo( vert ).Name( wxT( "m_microWaveToolBar" ) ). + Right().Layer( 1 ).Position(1).Hide() ); if( m_drawToolBar ) // The main right vertical toolbar m_auimgr.AddPane( m_drawToolBar, @@ -445,23 +450,6 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : m_auimgr.AddPane( m_messagePanel, wxAuiPaneInfo( mesg ).Name( wxT( "MsgPanel" ) ).Bottom().Layer(10) ); - -#if defined(KICAD_SCRIPTING_WXPYTHON) - // Add the scripting panel - EDA_PANEINFO pythonAuiInfo; - pythonAuiInfo.ScriptingToolbarPane(); - pythonAuiInfo.Caption( wxT( "Python Scripting" ) ); - pythonAuiInfo.MinSize( wxSize( 200, 100 ) ); - pythonAuiInfo.BestSize( wxSize( GetClientSize().x/2, 200 ) ); - pythonAuiInfo.Hide(); - - m_pythonPanel = CreatePythonShellWindow( this ); - m_auimgr.AddPane( m_pythonPanel, - pythonAuiInfo.Name( wxT( "PythonPanel" ) ).Bottom().Layer(9) ); - - m_pythonPanelHidden = true; -#endif - ReFillLayerWidget(); // this is near end because contents establish size m_Layers->ReFillRender(); // Update colors in Render after the config is read @@ -1093,19 +1081,39 @@ void PCB_EDIT_FRAME::UpdateTitle() #if defined(KICAD_SCRIPTING_WXPYTHON) void PCB_EDIT_FRAME::ScriptingConsoleEnableDisable( wxCommandEvent& aEvent ) { - if ( m_pythonPanelHidden ) + if( m_pythonPanel == NULL ) { - m_auimgr.GetPane( m_pythonPanel ).Show(); - m_pythonPanelHidden = false; - } - else - { - m_auimgr.GetPane( m_pythonPanel ).Hide(); - m_pythonPanelHidden = true; + // Add the scripting panel + EDA_PANEINFO pythonAuiPane; + pythonAuiPane.ScriptingToolbarPane(); + pythonAuiPane.Caption( wxT( "Python Scripting" ) ); + pythonAuiPane.MinSize( 300, 150 ); + + #if 1 // Set to 0 to make the Python console dockable + // Currently the console is not dockable. Reasons: + // * When docked there is an issue with accelerator keys used in the main menu: + // these keys are not sent to the console, even if it has the focus + // * The console is more easy to move if it is not dockable + pythonAuiPane.Dockable( false ).Float(); + + // Gives a reasonnable position to the console + wxPoint pos = m_canvas->GetScreenPosition(); + pythonAuiPane.FloatingPosition( pos.x + 10, pos.y + 10 ); + pythonAuiPane.FloatingSize( 600, 200 ); + #else + pythonAuiPane.BestSize( 600, 200 ); + pythonAuiPane.LeftDockable( false ).RightDockable( false ); + #endif + + m_pythonPanel = CreatePythonShellWindow( this ); + m_auimgr.AddPane( m_pythonPanel, + pythonAuiPane.Name( PYTHONCONSOLE_STRID ).Bottom().Layer(9) ); } + m_pythonPanelShow = ! m_pythonPanelShow; + m_auimgr.GetPane( PYTHONCONSOLE_STRID ).Show( m_pythonPanelShow ); + m_auimgr.Update(); - } #endif diff --git a/pcbnew/pcbplot.cpp b/pcbnew/pcbplot.cpp index a11987ccb8..4511a8ad37 100644 --- a/pcbnew/pcbplot.cpp +++ b/pcbnew/pcbplot.cpp @@ -109,6 +109,112 @@ wxString GetGerberExtension( LAYER_NUM layer ) } +wxString GetGerberFileFunction( const BOARD *aBoard, LAYER_NUM aLayer ) +{ + wxString attrib = wxEmptyString; + + switch( aLayer ) + { + case LAYER_N_BACK: + attrib = wxString::Format( wxT( "Copper,L%d" ), aBoard->GetCopperLayerCount() ); + break; + + case LAYER_N_2: + case LAYER_N_3: + case LAYER_N_4: + case LAYER_N_5: + case LAYER_N_6: + case LAYER_N_7: + case LAYER_N_8: + case LAYER_N_9: + case LAYER_N_10: + case LAYER_N_11: + case LAYER_N_12: + case LAYER_N_13: + case LAYER_N_14: + case LAYER_N_15: + // LAYER_N_2 is the first inner layer counting from the bottom; this + // must be converted to a 1-based number starting from the top + attrib = wxString::Format( wxT( "Copper,L%d" ), + aBoard->GetCopperLayerCount() - ( aLayer - LAYER_N_2 + 1 ) ); + break; + + case LAYER_N_FRONT: + attrib = wxString( wxT( "Copper,L1" ) ); + break; + + case ADHESIVE_N_FRONT: + attrib = wxString( wxT( "Glue,Top" ) ); + break; + + case ADHESIVE_N_BACK: + attrib = wxString( wxT( "Glue,Bot" ) ); + break; + + case SILKSCREEN_N_FRONT: + attrib = wxString( wxT( "Legend,Top" ) ); + break; + + case SILKSCREEN_N_BACK: + attrib = wxString( wxT( "Legend,Bot" ) ); + break; + + case SOLDERMASK_N_FRONT: + attrib = wxString( wxT( "Soldermask,Top" ) ); + break; + + case SOLDERMASK_N_BACK: + attrib = wxString( wxT( "Soldermask,Bot" ) ); + break; + + case SOLDERPASTE_N_FRONT: + attrib = wxString( wxT( "Paste,Top" ) ); + break; + + case SOLDERPASTE_N_BACK: + attrib = wxString( wxT( "Paste,Bot" ) ); + break; + + case EDGE_N: + attrib = wxString( wxT( "Profile" ) ); + break; + + case DRAW_N: + attrib = wxString( wxT( "Drawing" ) ); + break; + + case COMMENT_N: + attrib = wxString( wxT( "Other,Comment" ) ); + break; + + case ECO1_N: + case ECO2_N: + attrib = wxString::Format( wxT( "Other,ECO%d" ), aLayer - ECO1_N + 1 ); + break; + } + + // Add the signal type of the layer, if relevant + if( FIRST_COPPER_LAYER <= aLayer && aLayer <= LAST_COPPER_LAYER ) { + LAYER_T type = aBoard->GetLayerType( aLayer ); + switch( type ) + { + case LT_SIGNAL: + attrib += wxString( wxT( ",Signal" ) ); + break; + case LT_POWER: + attrib += wxString( wxT( ",Plane" ) ); + break; + case LT_MIXED: + attrib += wxString( wxT( ",Mixed" ) ); + break; + default: + ; // do nothing (but avoid a warning for unhandled LAYER_T values from GCC) + } + } + + return attrib; +} + void BuildPlotFileName( wxFileName* aFilename, const wxString& aOutputDir, const wxString& aSuffix, @@ -241,7 +347,7 @@ bool PLOT_CONTROLLER::OpenPlotfile( const wxString &aSuffix, wxFileName fn( boardFilename ); BuildPlotFileName( &fn, outputDirName, aSuffix, GetDefaultPlotExtension( aFormat ) ); - m_plotter = StartPlotBoard( m_board, &m_plotOpts, fn.GetFullPath(), aSheetDesc ); + m_plotter = StartPlotBoard( m_board, &m_plotOpts, UNDEFINED_LAYER, fn.GetFullPath(), aSheetDesc ); } return( m_plotter != NULL ); diff --git a/pcbnew/pcbplot.h b/pcbnew/pcbplot.h index 50c607e25f..cd6c9788d2 100644 --- a/pcbnew/pcbplot.h +++ b/pcbnew/pcbplot.h @@ -164,6 +164,7 @@ private: PLOTTER* StartPlotBoard( BOARD* aBoard, PCB_PLOT_PARAMS* aPlotOpts, + int aLayer, const wxString& aFullFileName, const wxString& aSheetDesc ); @@ -265,6 +266,16 @@ void BuildPlotFileName( wxFileName* aFilename, */ extern wxString GetGerberExtension( LAYER_NUM aLayer ); +/** + * Function GetGerberFileFunction + * Returns the "file function" attribute for \a aLayer, as defined in the + * Gerber file format specification J1 (chapter 5). The returned string excludes + * the "%TF.FileFunction" attribute prefix and the "*%" suffix. + * @param aBoard = the board, needed to get the total count of copper layers + * @param aLayer = the layer number to create the attribute for + * @return The attribute, as a text string + */ +extern wxString GetGerberFileFunction( const BOARD *aBoard, LAYER_NUM aLayer ); // PLOTGERB.CPP void SelectD_CODE_For_LineDraw( PLOTTER* plotter, int aSize ); diff --git a/pcbnew/plot_board_layers.cpp b/pcbnew/plot_board_layers.cpp index a0d05647b1..85d44422e3 100644 --- a/pcbnew/plot_board_layers.cpp +++ b/pcbnew/plot_board_layers.cpp @@ -877,6 +877,7 @@ static void ConfigureHPGLPenSizes( HPGL_PLOTTER *aPlotter, * (or has a problem) */ PLOTTER* StartPlotBoard( BOARD *aBoard, PCB_PLOT_PARAMS *aPlotOpts, + int aLayer, const wxString& aFullFileName, const wxString& aSheetDesc ) { @@ -938,6 +939,10 @@ PLOTTER* StartPlotBoard( BOARD *aBoard, PCB_PLOT_PARAMS *aPlotOpts, if( plotter->OpenFile( aFullFileName ) ) { + // For the Gerber "file function" attribute, set the layer number + if( plotter->GetPlotterType() == PLOT_FORMAT_GERBER && plotOpts.GetUseGerberAttributes() ) + plotter->SetLayerAttribFunction( GetGerberFileFunction( aBoard, aLayer ) ); + plotter->StartPlot(); // Plot the frame reference if requested @@ -949,7 +954,7 @@ PLOTTER* StartPlotBoard( BOARD *aBoard, PCB_PLOT_PARAMS *aPlotOpts, aSheetDesc, aBoard->GetFileName() ); if( aPlotOpts->GetMirror() ) - initializePlotter( plotter, aBoard, aPlotOpts ); + initializePlotter( plotter, aBoard, aPlotOpts ); } /* When plotting a negative board: draw a black rectangle diff --git a/pcbnew/tool_pcb.cpp b/pcbnew/tool_pcb.cpp index 90c2cf6ee8..ab77b42d1f 100644 --- a/pcbnew/tool_pcb.cpp +++ b/pcbnew/tool_pcb.cpp @@ -307,16 +307,16 @@ void PCB_EDIT_FRAME::ReCreateHToolbar() KiBitmap( web_support_xpm ), _( "Fast access to the Web Based FreeROUTE advanced router" ) ); - m_mainToolBar->AddSeparator(); - // Access to the scripting console #ifdef KICAD_SCRIPTING_WXPYTHON + m_mainToolBar->AddSeparator(); + m_mainToolBar->AddTool( ID_TOOLBARH_PCB_SCRIPTING_CONSOLE, wxEmptyString, KiBitmap( py_script_xpm ), - _( "Show/Hide the Scripting console" ) ); - - m_mainToolBar->AddSeparator(); + _( "Show/Hide the Python Scripting console" ), + wxITEM_CHECK ); #endif + // after adding the buttons to the toolbar, must call Realize() to reflect the changes m_mainToolBar->Realize(); } diff --git a/pcbnew/toolbars_update_user_interface.cpp b/pcbnew/toolbars_update_user_interface.cpp index b94bc75d59..a33915fe4b 100644 --- a/pcbnew/toolbars_update_user_interface.cpp +++ b/pcbnew/toolbars_update_user_interface.cpp @@ -109,6 +109,12 @@ void PCB_EDIT_FRAME::OnUpdateLayerSelectBox( wxUpdateUIEvent& aEvent ) m_SelLayerBox->SetLayerSelection( GetActiveLayer() ); } +#ifdef KICAD_SCRIPTING_WXPYTHON +void PCB_EDIT_FRAME::OnUpdateScriptingConsoleState( wxUpdateUIEvent& aEvent ) +{ + aEvent.Check( m_pythonPanelShow ); +} +#endif void PCB_EDIT_FRAME::OnUpdateZoneDisplayStyle( wxUpdateUIEvent& aEvent ) {