Board stack manager: add a basic reporter to copy the current stackup to the clipboard.

This commit is contained in:
jean-pierre charras 2019-09-06 11:26:27 +02:00
parent 90b5cd3032
commit e0c82fb003
10 changed files with 322 additions and 33 deletions

View File

@ -186,6 +186,7 @@ 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
board_stackup_manager/board_stackup_reporter.cpp
)
set( PCBNEW_IMPORT_GFX

View File

@ -0,0 +1,135 @@
/*
* 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) 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
*/
/**
* @file board_stackup_reporter.cpp
*/
#include "wx/string.h"
#include <base_units.h>
#include "class_board_stackup.h"
#include "stackup_predefined_prms.h"
#include "board_stackup_reporter.h"
wxString BuildStackupReport( BOARD_STACKUP& aStackup, EDA_UNITS_T aUnits )
{
// Build a ascii representation of stackup and copy it in the clipboard
wxString report;
wxString txt;
int row = 0;
LOCALE_IO toggle; // toggles on the C locale to write floating values, then off.
for( const auto item : aStackup.GetList() )
{
// Skip stackup items useless for the current board
if( !item->m_Enabled )
{
row++;
continue;
}
txt.Printf( "layer \"%s\" type \"%s\"", item->m_LayerName, item->m_TypeName );
report << txt;
if( item->HasEpsilonRValue() )
{
txt.Printf( " EpsilonR %f", item->m_EpsilonR );
report << txt;
}
if( item->HasLossTangentValue() )
{
txt.Printf( " LossTg %f", item->m_LossTangent );
report << txt;
}
if( item->IsMaterialEditable() )
{
txt.Printf( " Material \"%s\"", item->m_Material );
report << txt;
}
if( item->m_Type == BS_ITEM_TYPE_DIELECTRIC )
{
txt.Printf( " \"%s\"", item->m_TypeName );
report << txt;
}
if( item->IsThicknessEditable() )
{
txt.Printf( " Thickness %s",
StringFromValue( aUnits, item->m_Thickness, true, true ) );
report << txt;
if( item->m_Type == BS_ITEM_TYPE_DIELECTRIC && item->m_ThicknessLocked )
{
txt.Printf( " Locked" );
report << txt;
}
}
if( item->IsColorEditable() )
{
txt.Printf( " Color \"%s\"", item->m_Color );
report << txt;
}
row++;
report << '\n';
}
// Finish and other options:
txt.Printf( "Finish \"%s\"", aStackup.m_FinishType );
report << txt;
if( aStackup.m_HasDielectricConstrains )
report << " Option \"Impedance Controlled\"";
if( aStackup.m_EdgePlating )
report << " Option \"Plated edges\"";
if( aStackup.m_CastellatedPads )
report << " Option \"Castellated Pads\"";
if( aStackup.m_EdgeConnectorConstraints != BS_EDGE_CONNECTOR_NONE )
{
wxString conn_txt = "yes";
if( aStackup.m_EdgeConnectorConstraints == BS_EDGE_CONNECTOR_BEVELLED )
conn_txt << ",bevelled";
txt.Printf( " EdgeConnector \"%s\"", conn_txt );
report << txt;
}
report << '\n';
return report;
}

View File

@ -0,0 +1,37 @@
/*
* 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) 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
*/
/**
* @file board_stackup_reporter.h
*/
#ifndef BOARD_STACKUP_REPORTER_H
#define BOARD_STACKUP_REPORTER_H
#include <common.h> // for EDA_UNITS_T
class BOARD_STACKUP;
wxString BuildStackupReport( BOARD_STACKUP& aStackup, EDA_UNITS_T aUnits );
#endif // #ifndef BOARD_STACKUP_REPORTER_H

View File

@ -88,6 +88,7 @@ BOARD_STACKUP_ITEM::BOARD_STACKUP_ITEM( BOARD_STACKUP_ITEM& aOther )
m_Enabled = aOther.m_Enabled;
m_DielectricLayerId = aOther.m_DielectricLayerId;
m_TypeName = aOther.m_TypeName;
m_LayerName = aOther.m_LayerName;
m_Material = aOther.m_Material;
m_Color = aOther.m_Color;
m_Thickness = aOther.m_Thickness;

View File

@ -68,6 +68,7 @@ public:
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_LayerName; /// name of layer as shown in layer manager. Usefull to create reports
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,

View File

@ -34,7 +34,10 @@
#include "panel_board_stackup.h"
#include "stackup_predefined_prms.h"
#include <panel_setup_layers.h>
#include "board_stackup_reporter.h"
#include <bitmaps.h>
#include <wx/clipbrd.h>
#include <wx/dataobj.h>
// Some wx widget ID to know what widget has fired a event:
#define ID_INCREMENT 128 // space between 2 ID type. Bigger than the layer count max
@ -132,6 +135,25 @@ void PANEL_SETUP_BOARD_STACKUP::disconnectEvents()
}
void PANEL_SETUP_BOARD_STACKUP::onExportToClipboard( wxCommandEvent& event )
{
if( !transferDataFromUIToStackup() )
return;
// Build a ascii representation of stackup and copy it in the clipboard
wxString report = BuildStackupReport( m_stackup, m_units );
if( wxTheClipboard->Open() )
{
// This data objects are held by the clipboard,
// so do not delete them in the app.
wxTheClipboard->SetData( new wxTextDataObject( report ) );
wxTheClipboard->Close();
}
}
wxColor PANEL_SETUP_BOARD_STACKUP::GetSelectedColor( int aRow ) const
{
wxBitmapComboBox* choice = static_cast<wxBitmapComboBox*>( m_rowUiItemsList[aRow].m_ColorCtrl );
@ -423,9 +445,9 @@ void PANEL_SETUP_BOARD_STACKUP::buildLayerStackPanel()
}
else
{
// wxString lname = BOARD::GetStandardLayerName( item->m_LayerId );
wxString lname = m_board->GetLayerName( item->m_LayerId );
wxStaticText* st_text = new wxStaticText( m_scGridWin, wxID_ANY, lname );
// item->m_LayerName = BOARD::GetStandardLayerName( item->m_LayerId );
item->m_LayerName = m_board->GetLayerName( item->m_LayerId );
wxStaticText* st_text = new wxStaticText( m_scGridWin, wxID_ANY, item->m_LayerName );
m_fgGridSizer->Add( st_text, 0, wxALL|wxALIGN_CENTER_VERTICAL, 1 );
st_text->Show( show_item );
ui_row_item.m_LayerName = st_text;
@ -598,8 +620,11 @@ void PANEL_SETUP_BOARD_STACKUP::buildLayerStackPanel()
}
bool PANEL_SETUP_BOARD_STACKUP::TransferDataFromWindow()
// Transfer current UI settings to m_stackup but not to the board
bool PANEL_SETUP_BOARD_STACKUP::transferDataFromUIToStackup()
{
// First, verify the list of layers currently in stackup:
// if it does not mach the list of layers set in PANEL_SETUP_LAYERS
// prompt the user to update the stackup
@ -660,6 +685,8 @@ bool PANEL_SETUP_BOARD_STACKUP::TransferDataFromWindow()
continue;
}
item->m_LayerName = m_rowUiItemsList[row].m_LayerName->GetLabel();
if( item->HasEpsilonRValue() )
{
wxTextCtrl* textCtrl = static_cast<wxTextCtrl*>( m_rowUiItemsList[row].m_EpsilonCtrl );
@ -752,15 +779,30 @@ bool PANEL_SETUP_BOARD_STACKUP::TransferDataFromWindow()
return false;
}
BOARD_STACKUP& brd_stackup = m_brdSettings->GetStackupDescriptor();
wxArrayString finish_list = GetCopperFinishStandardList( false );
int finish = m_choiceFinish->GetSelection() >= 0 ? m_choiceFinish->GetSelection() : 0;
brd_stackup.m_FinishType = finish_list[finish];
brd_stackup.m_HasDielectricConstrains = m_rbDielectricConstraint->GetSelection() == 1;
brd_stackup.m_EdgeConnectorConstraints = (BS_EDGE_CONNECTOR_CONSTRAINTS)m_choiceEdgeConn->GetSelection();
brd_stackup.m_CastellatedPads = m_cbCastellatedPads->GetValue();
brd_stackup.m_EdgePlating = m_cbEgdesPlated->GetValue();
m_stackup.m_FinishType = finish_list[finish];
m_stackup.m_HasDielectricConstrains = m_rbDielectricConstraint->GetSelection() == 1;
m_stackup.m_EdgeConnectorConstraints = (BS_EDGE_CONNECTOR_CONSTRAINTS)m_choiceEdgeConn->GetSelection();
m_stackup.m_CastellatedPads = m_cbCastellatedPads->GetValue();
m_stackup.m_EdgePlating = m_cbEgdesPlated->GetValue();
return true;
}
bool PANEL_SETUP_BOARD_STACKUP::TransferDataFromWindow()
{
if( !transferDataFromUIToStackup() )
return false;
BOARD_STACKUP& brd_stackup = m_brdSettings->GetStackupDescriptor();
brd_stackup.m_FinishType = m_stackup.m_FinishType;
brd_stackup.m_HasDielectricConstrains = m_stackup.m_HasDielectricConstrains;
brd_stackup.m_EdgeConnectorConstraints = m_stackup.m_EdgeConnectorConstraints;
brd_stackup.m_CastellatedPads = m_stackup.m_CastellatedPads;
brd_stackup.m_EdgePlating = m_stackup.m_EdgePlating;
// copy enabled items to the new board stackup
brd_stackup.RemoveAll();

View File

@ -37,22 +37,6 @@
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
@ -91,11 +75,12 @@ public:
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
/** 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 );
@ -105,6 +90,8 @@ public:
BOARD_STACKUP& GetStackup() { return m_stackup; }
int GetPcbTickness();
// Called by wxWidgets: transfer current settings stored in m_stackup to the board
bool TransferDataFromWindow() override;
std::vector<wxColor> m_UserColors; // the list of user colors for each grid row
@ -130,12 +117,17 @@ private:
*/
void RebuildLayerStackPanel();
/** Transfer current UI settings to m_stackup but not to the board
*/
bool transferDataFromUIToStackup();
void onUpdateThicknessValue( wxUpdateUIEvent& event ) override;
void onCalculateDielectricThickness( wxCommandEvent& event ) override;
void onColorSelected( wxCommandEvent& event );
void onMaterialChange( wxCommandEvent& event );
void onThicknessChange( wxCommandEvent& event );
void onExportToClipboard( wxCommandEvent& event ) override;
/** Update the icons color (swatches in first grid column)
* @param aRow is the row (index in m_rowUiItemsList) that manages the icon to update.

View File

@ -64,7 +64,7 @@ PANEL_SETUP_BOARD_STACKUP_BASE::PANEL_SETUP_BOARD_STACKUP_BASE( wxWindow* parent
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|wxALIGN_CENTER_VERTICAL, 5 );
m_fgGridSizer->Add( m_staticText7, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_staticText8 = new wxStaticText( m_scGridWin, wxID_ANY, _("Name"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText8->Wrap( -1 );
@ -164,6 +164,9 @@ PANEL_SETUP_BOARD_STACKUP_BASE::PANEL_SETUP_BOARD_STACKUP_BASE( wxWindow* parent
bSizerRight->Add( sbSizerBrdOptions, 0, wxEXPAND, 5 );
m_buttonExport = new wxButton( this, wxID_ANY, _("Export in Clipboard"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerRight->Add( m_buttonExport, 0, wxALL|wxEXPAND, 5 );
bSizerStackup->Add( bSizerRight, 0, wxEXPAND, 5 );
@ -177,6 +180,7 @@ PANEL_SETUP_BOARD_STACKUP_BASE::PANEL_SETUP_BOARD_STACKUP_BASE( wxWindow* parent
// 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 );
m_buttonExport->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_BOARD_STACKUP_BASE::onExportToClipboard ), NULL, this );
}
PANEL_SETUP_BOARD_STACKUP_BASE::~PANEL_SETUP_BOARD_STACKUP_BASE()
@ -184,5 +188,6 @@ 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 );
m_buttonExport->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_BOARD_STACKUP_BASE::onExportToClipboard ), NULL, this );
}

View File

@ -1574,6 +1574,79 @@
</object>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxButton" expanded="1">
<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="bitmap"></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="current"></property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="disabled"></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="focus"></property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Export in Clipboard</property>
<property name="margins"></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_buttonExport</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="position"></property>
<property name="pressed"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</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="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">onExportToClipboard</event>
</object>
</object>
</object>
</object>
</object>

View File

@ -66,10 +66,12 @@ class PANEL_SETUP_BOARD_STACKUP_BASE : public wxPanel
wxChoice* m_choiceFinish;
wxStaticText* m_staticTextEdgeConn;
wxChoice* m_choiceEdgeConn;
wxButton* m_buttonExport;
// Virtual event handlers, overide them in your derived class
virtual void onUpdateThicknessValue( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void onCalculateDielectricThickness( wxCommandEvent& event ) { event.Skip(); }
virtual void onExportToClipboard( wxCommandEvent& event ) { event.Skip(); }
public: