33#include <wx/filedlg.h>
41#define COL_FRONT_SIDE 1
42#define COL_BOTTOM_SIDE 2
46#define ROW_BOARD_DIMS 0
47#define ROW_BOARD_AREA 1
48#define ROW_FRONT_COPPER_AREA 2
49#define ROW_BACK_COPPER_AREA 3
83 m_frame( aParentFrame ),
87 m_frontCopperArea( 0.0 ),
88 m_backCopperArea( 0.0 ),
89 m_hasOutline( false ),
90 m_startLayerColInitialSize( 1 ),
91 m_stopLayerColInitialSize( 1 )
125 grid->SetCellHighlightPenWidth( 0 );
126 grid->SetColMinimalAcceptableWidth( 80 );
128 for(
int row = 0; row <
grid->GetNumberRows(); row++ )
130 grid->SetCellAlignment( row,
COL_LABEL, wxALIGN_LEFT, wxALIGN_CENTRE );
133 grid->SetCellAlignment( row, col, wxALIGN_RIGHT, wxALIGN_CENTER );
142 fn.SetName( fn.GetName() + wxT(
"_report" ) );
143 fn.SetExt( wxT(
"txt" ) );
209 + wxSystemSettings::GetMetric( wxSYS_VSCROLL_X ),
240 if( ( footprint->GetAttributes() & line.attribute_mask ) == line.attribute_value )
242 switch( footprint->GetSide() )
244 case F_Cu: line.frontSideQty++;
break;
245 case B_Cu: line.backSideQty++;
break;
253 for(
PAD*
pad : footprint->Pads() )
258 if(
pad->GetAttribute() == line.attribute )
265 if(
pad->GetDrillSize().x > 0 &&
pad->GetDrillSize().y > 0 )
269 if(
pad->GetLayerSet().CuStack().empty() )
277 top =
pad->GetLayerSet().CuStack().front();
278 bottom =
pad->GetLayerSet().CuStack().back();
282 pad->GetDrillShape(),
283 pad->GetAttribute() != PAD_ATTRIB::NPTH,
316 if(
via->GetViaType() == line.attribute )
324 PAD_DRILL_SHAPE::CIRCLE,
true,
false,
via->TopLayer(),
325 via->BottomLayer() );
365 for(
int j = 0; j < polySet.
HoleCount( i ); j++ )
370 for(
PAD*
pad : fp->Pads() )
372 if( !
pad->HasHole() )
375 auto hole =
pad->GetEffectiveHoleShape();
376 const SEG& seg = hole->GetSeg();
377 double width = hole->GetWidth();
378 double area = seg.
Length() * width;
383 area += M_PI * 0.25 * width * width;
393 double drill =
via->GetDrillValue();
441 int R =
via->GetDrillValue() / 2;
450 RECURSE_MODE::RECURSE );
465 return wxString::Format( wxT(
"%i" ), aCount );
478 totalPads += line.qty;
492 totalVias += line.qty;
512 totalFront += line.frontSideQty;
513 totalBack += line.backSideQty;
525 wxString::Format( wxT(
"%s x %s" ),
561 wxString startLayerStr;
562 wxString stopLayerStr;
566 case PAD_DRILL_SHAPE::CIRCLE: shapeStr =
_(
"Round" );
break;
567 case PAD_DRILL_SHAPE::OBLONG: shapeStr =
_(
"Slot" );
break;
568 default: shapeStr =
_(
"???" );
break;
572 startLayerStr =
_(
"N/A" );
577 stopLayerStr =
_(
"N/A" );
597 bool aUseFirstColAsLabel )
599 std::vector<int> widths( aGrid->GetNumberCols(), 0 );
600 int rowLabelsWidth = 0;
606 for(
int col = 0; col < aGrid->GetNumberCols(); col++ )
607 widths[col] = (
int) aGrid->GetColLabelValue( col ).length();
610 for(
int row = 0; row < aGrid->GetNumberRows(); row++ )
612 rowLabelsWidth = std::max( rowLabelsWidth, (
int) aGrid->GetRowLabelValue( row ).length() );
614 for(
int col = 0; col < aGrid->GetNumberCols(); col++ )
615 widths[col] = std::max( widths[col], (
int) aGrid->GetCellValue( row, col ).length() );
626 for(
int col = 0; col < aGrid->GetNumberCols(); col++ )
629 tmp.Printf( wxT(
" %*s |" ), widths[col], aGrid->GetColLabelValue( col ) );
631 tmp.Printf( wxT(
" %*s |" ), widths[col], aGrid->GetCellValue( 0, col ) );
642 for(
int col = 0; col < aGrid->GetNumberCols(); col++ )
645 aStr.Append(
'-', widths[col] );
653 int firstRow = 0, firstCol = 0;
658 if( aUseFirstColAsLabel )
661 for(
int row = firstRow; row < aGrid->GetNumberRows(); row++ )
663 if( aUseFirstColAsLabel )
664 tmp.Printf( wxT(
"|%-*s |" ), widths[0], aGrid->GetCellValue( row, 0 ) );
666 tmp.Printf( wxT(
"|" ) );
670 for(
int col = firstCol; col < aGrid->GetNumberCols(); col++ )
672 tmp.Printf( wxT(
" %*s |" ), widths[col], aGrid->GetCellValue( row, col ) );
683 wxGridUpdateLocker deferRepaintsTillLeavingScope(
m_gridDrills );
690 for(
int i = 0; i <
m_gridDrills->GetNumberCols(); i++ )
696 double scalingFactor = std::max( 1.0,
726 boardName = fn.GetName();
729 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
731 if( dlg.ShowModal() == wxID_CANCEL )
737 outFile = wxFopen( dlg.GetPath(), wxT(
"wt" ) );
739 if( outFile ==
nullptr )
741 msg.Printf(
_(
"Failed to create file '%s'." ), dlg.GetPath() );
746 msg <<
_(
"PCB statistics report\n=====================" ) << wxT(
"\n" );
747 msg << wxS(
"- " ) <<
_(
"Date" ) << wxS(
": " ) << wxDateTime::Now().Format() << wxT(
"\n" );
748 msg << wxS(
"- " ) <<
_(
"Project" ) << wxS(
": " )<<
Prj().
GetProjectName() << wxT(
"\n" );
749 msg << wxS(
"- " ) <<
_(
"Board name" ) << wxS(
": " )<< boardName << wxT(
"\n" );
752 msg <<
_(
"Board" ) << wxT(
"\n-----\n" );
756 msg << wxS(
"- " ) <<
_(
"Width" ) << wxS(
": " )
758 msg << wxS(
"- " ) <<
_(
"Height" ) << wxS(
": " )
760 msg << wxS(
"- " ) <<
_(
"Area" ) + wxS(
": " )
765 msg << wxS(
"- " ) <<
_(
"Dimensions" ) << wxS(
": " ) <<
_(
"unknown" ) << wxT(
"\n" );
766 msg << wxS(
"- " ) <<
_(
"Area" ) << wxS(
": " ) <<
_(
"unknown" ) << wxT(
"\n" );
769 msg << wxS(
"- " ) <<
_(
"Front copper area" ) + wxS(
": " )
771 msg << wxS(
"- " ) <<
_(
"Back copper area" ) + wxS(
": " )
775 msg <<
_(
"Pads" ) << wxT(
"\n----\n" );
778 msg << wxT(
"- " ) << type.title << wxS(
" " ) << type.qty << wxT(
"\n" );
781 msg <<
_(
"Vias" ) << wxT(
"\n----\n" );
784 msg << wxT(
"- " ) << type.title << wxS(
" " ) << type.qty << wxT(
"\n" );
788 std::vector<int> widths;
789 std::vector<wxString> labels{ wxT(
"" ),
_(
"Front Side" ),
_(
"Back Side" ),
_(
"Total" ) };
792 widths.reserve( labels.size() );
794 for(
const wxString& label : labels )
795 widths.push_back( (
int) label.size() );
803 widths[0] = std::max( (
int) line.title.size(), widths[0] );
804 frontTotal += line.frontSideQty;
805 backTotal += line.backSideQty;
809 tmp.Printf( wxT(
"%i" ), frontTotal );
810 widths[1] = std::max( (
int) tmp.size(), widths[1] );
811 tmp.Printf( wxT(
"%i" ), backTotal );
812 widths[2] = std::max( (
int) tmp.size(), widths[2] );
813 tmp.Printf( wxT(
"%i" ), frontTotal + backTotal );
814 widths[3] = std::max( (
int) tmp.size(), widths[3] );
818 msg <<
_(
"Components" ) << wxT(
"\n----------\n" );
824 msg <<
_(
"Drill holes" ) << wxT(
"\n-----------\n" );
829 if( fprintf( outFile,
"%s",
TO_UTF8( msg ) ) < 0 )
831 msg.Printf(
_(
"Error writing file '%s'." ), dlg.GetPath() );
constexpr int ARC_LOW_DEF
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
virtual void TransformShapeToPolySet(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc) const
Convert the item shape to a polyset.
virtual bool IsOnLayer(PCB_LAYER_ID aLayer) const
Test to see if this object is on the given layer.
Information pertinent to a Pcbnew printed circuit board.
bool GetBoardPolygonOutlines(SHAPE_POLY_SET &aOutlines, OUTLINE_ERROR_HANDLER *aErrorHandler=nullptr, bool aAllowUseArcsInPolygons=false, bool aIncludeNPTHAsOutlines=false)
Extract the board outlines and build a closed polygon from lines, arcs and circle items on edge cut l...
const FOOTPRINTS & Footprints() const
const TRACKS & Tracks() const
const wxString & GetFileName() const
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
void RunOnChildren(const std::function< void(BOARD_ITEM *)> &aFunction, RECURSE_MODE aMode) const override
Invoke a function on all children.
constexpr size_type GetWidth() const
constexpr size_type GetHeight() const
Class DIALOG_BOARD_STATISTICS_BASE.
wxCheckBox * m_checkBoxSubtractHoles
wxStaticText * m_boardLabel
wxButton * m_sdbControlSizerCancel
wxStaticText * m_padsLabel
wxGrid * m_gridComponents
wxCheckBox * m_checkBoxExcludeComponentsNoPins
wxStaticText * m_componentsLabel
wxStaticText * m_viasLabel
wxCheckBox * m_checkBoxSubtractHolesFromCopper
void checkboxClicked(wxCommandEvent &aEvent) override
Save board statistics to a file.
void printGridToStringAsTable(wxGrid *aGrid, wxString &aStr, bool aUseColLabels, bool aUseFirstColAsLabel)
std::deque< FP_LINE_ITEM > m_fpTypes
int m_startLayerColInitialSize
Width of the start layer column as calculated by the wxWidgets autosizing algorithm.
void updateWidets()
Update drills grid.
void saveReportClicked(wxCommandEvent &aEvent) override
std::deque< LINE_ITEM< PAD_ATTRIB > > m_padTypes
void updateDrillGrid()
Print grid to string in tabular format.
~DIALOG_BOARD_STATISTICS()
Get data from the PCB board and print it to dialog.
int m_stopLayerColInitialSize
Width of the stop layer column.
DIALOG_BOARD_STATISTICS(PCB_EDIT_FRAME *aParentFrame)
void drillGridSort(wxGridEvent &aEvent)
void refreshItemsTypes()
< Function to fill up all items types to be shown in the dialog.
void drillGridSize(wxSizeEvent &aEvent) override
bool m_hasOutline
Show if board outline properly defined.
void adjustDrillGridColumns()
bool TransferDataToWindow() override
std::deque< DRILL_LINE_ITEM > m_drillTypes
std::deque< LINE_ITEM< VIATYPE > > m_viaTypes
void getDataFromPCB()
Apply data to dialog widgets.
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
KICAD_T Type() const
Returns the type of object.
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
The main frame for Pcbnew.
virtual const wxString GetProjectFullName() const
Return the full path and name of the project.
virtual const wxString GetProjectName() const
Return the short name of the project.
int Length() const
Return the length (this).
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
double Area(bool aAbsolute=true) const
Return the area of this chain.
Represent a set of closed polygons.
double Area()
Return the area of this poly set.
int HoleCount(int aOutline) const
Returns the number of holes in a given outline.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
SHAPE_LINE_CHAIN & Hole(int aOutline, int aHole)
Return the reference to aHole-th hole in the aIndex-th outline.
int OutlineCount() const
Return the number of outlines in the set.
void BooleanSubtract(const SHAPE_POLY_SET &b)
Perform boolean polyset difference.
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
wxString MessageTextFromValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
A lower-precision version of StringFromValue().
void EnsureColLabelsVisible()
Ensure the height of the row displaying the column labels is enough, even if labels are multiline tex...
void ClearRows()
wxWidgets recently added an ASSERT which fires if the position is greater than or equal to the number...
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
This file is part of the common library.
void TransformCircleToPolygon(SHAPE_LINE_CHAIN &aBuffer, const VECTOR2I &aCenter, int aRadius, int aError, ERROR_LOC aErrorLoc, int aMinSegCount=0)
Convert a circle to a polygon, using multiple straight lines.
static DIALOG_BOARD_STATISTICS_SAVED_STATE s_savedDialogState
#define ROW_BACK_COPPER_AREA
#define ROW_FRONT_COPPER_AREA
static wxString formatCount(int aCount)
static wxString TextFileWildcard()
PCB_LAYER_ID
A quick note on layer IDs:
This file contains miscellaneous commonly used macros and functions.
KICOMMON_API wxFont GetStatusFont(wxWindow *aWindow)
KICOMMON_API wxFont GetSmallInfoFont(wxWindow *aWindow)
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Footprint attributes (such as SMD, THT, Virtual and so on), which will be shown in the dialog.
Type information, which will be shown in dialog.
The dialog last saved state.
bool saveReportInitialized
bool subtractHolesFromCopper
DIALOG_BOARD_STATISTICS_SAVED_STATE()
wxString saveReportFolder
@ PCB_GENERATOR_T
class PCB_GENERATOR, generator on a layer
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
@ PCB_GROUP_T
class PCB_GROUP, a set of BOARD_ITEMs
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
@ PCB_PAD_T
class PAD, a pad in a footprint
Definition of file extensions used in Kicad.