kicad-developers team mailing list archive
-
kicad-developers team
-
Mailing list archive
-
Message #41620
Re: [PATCH] Board statistics dialog
Hi Jeff,
That's not a problem. Now I'm on 2 weeks vacation ))
We don't use header capitalization in russian language, so it's sometimes confuses me.
All done. You can find changed commit on github if you want.
https://github.com/jasuramme/kicad-source-mirror/commit/6ce77c20ff479f2fa4f1af9ba4e8d7f93d2ee1e5
And patch in the attachment below.
Best regards,
Alex
>Среда, 17 июля 2019, 15:18 +03:00 от Jeff Young <jeff@xxxxxxxxx>:
>
>Hi Alex,
>
>No need for apologies. It’s a steep learning curve.
>
>Some more comments:
>
>1) Dialog items use sentence-capitalization and colons; dialog headers use title-capitalization and no colons. So “Components:” should be “Components”, “Front side:” should be “Front Side”, etc.
>
>2) Right-align the StdButtonSizer (and give it right and left margins).
>
>3) I don’t think this ever made it into the coding guidelines, but we prefer ctor initializers each on their own line (with the colon on the line above):
>
> padsType_t( PAD_ATTR_T aAttribute, wxString aTitle ) :
> attribute( aAttribute ),
>title( aTitle ),
>qty( 0 )
>
>4) And yes, I would space-align the inspectMenu->AddItem calls that the Git checker messed up.
>
>If you don’t have time to make these fixes just holler and I can do it.
>
>Cheers,
>Jeff.
>
>
>>On 17 Jul 2019, at 12:47, Alexander Shuklin < jasuramme@xxxxxxx > wrote:
>>Hi,
>>I'm very sorry. I know, that's stupid, but it takes so much time to get myself familiar with kicad code
>>If it's not too late, can you look for newer patch, not one I sent this morning? Of course, I can make commit on top of it, but I think it doesn't make sense
>>There only few changes, such as
>>- code formatting
>>- I used FinishDialogSettings() instead of just Fit() as written in KiCad documentation
>>- I changed tool name for "pcbnew.InspectionTool.ShowStatisticsDialog" so it would correspond to PCB_INSPECTION_TOOL::ShowStatisticsDialog method
>>- And I changed wxString ( _( "some string " ) ) to just _( "some string" )
>>That's link to github:
>>https://github.com/jasuramme/kicad-source-mirror/commit/7846cc554fa13c27159d6b1ba4693ac96707c559
>>and patch uploaded to this mail
>>Sorry for that, but I've just understood that, during further doxygen documentation reading
>>>Среда, 17 июля 2019, 9:01 +03:00 от Alexander Shuklin < jasuramme@xxxxxxx >:
>>>
>>>Hi!
>>>Sorry for delay, there to much to do for my primary job.
>>>I hope that code will be alright.
>>>That's commit on the github:
>>>https://github.com/jasuramme/kicad-source-mirror/commit/9f9ff463ac679dd79a85a88c9b4156dcec05b337
>>>There's one thing. Git coding standards checkers writes following
>>>
>>>+++ b/pcbnew/menubar_pcb_editor.cpp
>>>@@ -436,7 +436,7 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
>>>
>>> inspectMenu->AddItem( PCB_ACTIONS::listNets, SELECTION_CONDITIONS::ShowAlways );
>>> inspectMenu->AddItem( ACTIONS::measureTool, SELECTION_CONDITIONS::ShowAlways );
>>>- inspectMenu->AddItem( PCB_ACTIONS::boardStatistics, SELECTION_CONDITIONS::ShowAlways );
>>>+ inspectMenu->AddItem( PCB_ACTIONS::boardStatistics, SELECTION_CONDITIONS::ShowAlways );
>>>
>>>
>>>
>>>But I would leave whitespaces, for better code looking as all functions around use it
>>>
>>>
>>>
>>>>Понедельник, 8 июля 2019, 17:03 +03:00 от Jeff Young < jeff@xxxxxxxxx >:
>>>>
>>>>Hi Alex,
>>>>
>>>>Have a look at the second half of DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::TransferDataToWindow(). That code builds a read-only grid. You could then have columns for Top, Bottom, and Total.
>>>>
>>>>(BTW, I think we use Front/Back nomenclature rather than Top/Bottom.)
>>>>
>>>>Cheers,
>>>>Jeff.
>>>>
>>>>
>>>>>On 8 Jul 2019, at 13:48, Alexander Shuklin < jasuramme@xxxxxxx > wrote:
>>>>>Hi Jeff,
>>>>>that bug reports are some job to do)
>>>>>
>>>>>Well, reason why I went up with that top-side/bottom-side checkboxes is if you will want to count let's say SMD components on the bottom side, you can manage it with setting top one off. I'm not sure, how important it is. On the another hand, we could write down something like:
>>>>>THT components: top: 15, bottom: 32, total: 47
>>>>>SMD components: top: 14, bottom: 31, total: 45
>>>>>But that would be ugly as well.
>>>>>
>>>>>If there would be more options and more components properties, maybe better to write all data to wxTextCtrl then? Just in big text field, which you could copy. And that will be easy to change and expand.
>>>>>
>>>>>>Понедельник, 8 июля 2019, 14:24 +03:00 от Jeff Young < jeff@xxxxxxxxx >:
>>>>>>
>>>>>>Hi Alex,
>>>>>>
>>>>>>I don’t like the top-side/bottom-side checkboxes (because I want to see both numbers at once), but I do like the other three.
>>>>>>
>>>>>>I think we need to move to a list or grid presentation, though. One of the other features we’ve talked about is user-defined attributes, so there might be more things than just THT, SMD and Virtual.
>>>>>>
>>>>>>Cheers,
>>>>>>Jeff.
>>>>>>
>>>>>>[1] https://bugs.launchpad.net/kicad/+bug/1789363
>>>>>>[2] https://bugs.launchpad.net/kicad/+bug/980919
>>>>>>
>>>>>>
>>>>>>
>>>>>>>On 8 Jul 2019, at 11:20, Alexander Shuklin < jasuramme@xxxxxxx > wrote:
>>>>>>>Hi!, I added stuff for footprints THT,SMD,virtual properties and now it's calculate area.
>>>>>>>But for me dialog is not very straight forward now. Can you please advice, what better to do?
>>>>>>>I attached 2 pics. I think, maybe right way is to add few checkboxes which will change dialog data as soon as you pressed them?
>>>>>>>Just look at pics and say what would be better, as I'm in doubt.
>>>>>>>Second one is in WxFormBuilder so it looks a bit different.
>>>>>>>
>>>>>>>
>>>>>>>>Пятница, 5 июля 2019, 0:05 +03:00 от Jeff Young < jeff@xxxxxxxxx >:
>>>>>>>>
>>>>>>>>I agree that it shouldn’t be its own tool, but PCB_EDITOR_CONTROL is getting too big.
>>>>>>>>
>>>>>>>>Let’s just name this tool the PCB_INSPECTION_TOOL, and then I’ll move the highlight and list nets stuff, and the DRC dialog to it later. That’ll nicely parallel the EE_INSPECTION_TOOL.
>>>>>>>>
>>>>>>>>Cheers,
>>>>>>>>Jeff.
>>>>>>>>
>>>>>>>>>On 4 Jul 2019, at 21:56, Ian McInerney < Ian.S.McInerney@xxxxxxxx > wrote:
>>>>>>>>>This looks nice, but a few comments from my initial usage of it:
>>>>>>>>>
>>>>>>>>>Usability:
>>>>>>>>>1) When I use english units, your statistics dialog gives the dimensions in mils. It should probably give those in inches instead, since that is what the grid panel at the bottom gives.
>>>>>>>>>2) Including the board area would also be useful, definitely the area of the bounding box, and possibly the area of the actual PCB (but that is more complicated). I know of several board houses that charge based on area, so this could provide a quick way to estimate price for the user.
>>>>>>>>>3) I am not sure I am a fan of the icon used for the menu item, since this dialog focuses on board statistics rather than footprint statistics and that icon is used mainly for footprint actions. Could a variant of the pcbnew icon be used?
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>While the code as you gave works, I think the following changes could be beneficial:
>>>>>>>>>1) It seems that this action could just be added to PCB_EDITOR_CONTROL as the action "pcbnew.Control.BoardStatistics" rather than creating a new tool just for this.
>>>>>>>>>2) I think the launching of the window could be simplified if you used a modal window instead (see https://docs.wxwidgets.org/3.0/classwx_dialog.html , the Modal and Modeless section). Then you don't have to keep track of the window pointer, and could actually just make launching this a single function instead of an entire class (this would go nicely with point #1).
>>>>>>>>>3) The function to start the window should be TransferDataToWindow, not TransferDataFromWindow. FromWindow is called when the window is destroyed and ToWindow is called when it is created. Also, it is called automatically when the window is started, so there is no need to manually call it.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>Other code parts:
>>>>>>>>>1) There are some lines that are too long in dialog_board_statistics.cpp (max 100 characters per line)
>>>>>>>>>2) There are a few whitespace errors when applying it:
>>>>>>>>>Applying: added board statistics dialog, which shows info for production and assembly
>>>>>>>>>/home/imcinerney/Downloads/0001-added-board-statistics-dialog-which-shows-info-for-p.patch:158: trailing whitespace.
>>>>>>>>> /* if pin has drill with width==0 and height==0, we
>>>>>>>>>/home/imcinerney/Downloads/0001-added-board-statistics-dialog-which-shows-info-for-p.patch:1612: new blank line at EOF.
>>>>>>>>>+
>>>>>>>>>warning: 2 lines add whitespace errors.
>>>>>>>>>
>>>>>>>>>Overall though it looks pretty nice.
>>>>>>>>>
>>>>>>>>>-Ian
>>>>>>>>>On Thu, Jul 4, 2019 at 3:07 PM Шуклин Александр < jasuramme@xxxxxxx > wrote:
>>>>>>>>>>Hi, that's first time I try to contribute to KiCad and write to Launchpad mailing lists, so please, don't beat me to hard )))
>>>>>>>>>>I really miss some board statistic dialog, where you can see quantity of SMD pads, THT pads, board dimensions, all the stuff, you need for PCB production and assembly. There was also issue in the bug tracker
>>>>>>>>>>https://bugs.launchpad.net/kicad/+bug/1817232
>>>>>>>>>>And like guy from bug issue, I moved from Altium Designer and miss that dialog as well.
>>>>>>>>>>Can you please look at that and commit if you think it's useful or tell me what to change.
>>>>>>>>>>That's my commit in the github:
>>>>>>>>>>https://github.com/jasuramme/kicad-source-mirror/commit/6290375c1d41ddb89d4b08067593f170c7d344c5
>>>>>>>>>>and branch:
>>>>>>>>>>https://github.com/jasuramme/kicad-source-mirror/tree/statistic_dialog
>>>>>>>>>>and there's also patch and dialogs pics in the attachment.
>>>>>>>>>>
>>>>>>>>>>_______________________________________________
>>>>>>>>>>Mailing list: https://launchpad.net/~kicad-developers
>>>>>>>>>>Post to : kicad-developers@xxxxxxxxxxxxxxxxxxx
>>>>>>>>>>Unsubscribe : https://launchpad.net/~kicad-developers
>>>>>>>>>>More help : https://help.launchpad.net/ListHelp
>>>>>>>>>_______________________________________________
>>>>>>>>>Mailing list: https://launchpad.net/~kicad-developers
>>>>>>>>>Post to : kicad-developers@xxxxxxxxxxxxxxxxxxx
>>>>>>>>>Unsubscribe : https://launchpad.net/~kicad-developers
>>>>>>>>>More help : https://help.launchpad.net/ListHelp
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>--
>>>>>>>Alexander Shuklin
>>>>>>><1.png> <2.png>
>>>>>
>>>>>
>>>>>--
>>>>>Alexander Shuklin
>>>
>>>
>>>--
>>>Alexander Shuklin
>>
>>
>>--
>>Alexander Shuklin
>><0001-added-board-statistics-dialog-which-shows-info-for-p.patch>
--
Alexander Shuklin
From 6ce77c20ff479f2fa4f1af9ba4e8d7f93d2ee1e5 Mon Sep 17 00:00:00 2001
From: Alexander <alexandr.shuklin@biovitrum.ru>
Date: Tue, 16 Jul 2019 22:34:07 +0300
Subject: [PATCH] added board statistics dialog, which shows info for
production and assembly
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="------------2.22.0"
This is a multi-part message in MIME format.
--------------2.22.0
Content-Type: text/plain; charset=UTF-8; format=fixed
Content-Transfer-Encoding: 8bit
---
pcbnew/CMakeLists.txt | 3 +
pcbnew/dialogs/dialog_board_statistics.cpp | 252 ++++++++
pcbnew/dialogs/dialog_board_statistics.h | 121 ++++
.../dialogs/dialog_board_statistics_base.cpp | 183 ++++++
.../dialogs/dialog_board_statistics_base.fbp | 558 ++++++++++++++++++
pcbnew/dialogs/dialog_board_statistics_base.h | 55 ++
pcbnew/menubar_pcb_editor.cpp | 1 +
pcbnew/pcb_edit_frame.cpp | 2 +
pcbnew/tools/pcb_actions.cpp | 5 +
pcbnew/tools/pcb_actions.h | 1 +
pcbnew/tools/pcb_inspection_tool.cpp | 45 ++
pcbnew/tools/pcb_inspection_tool.h | 55 ++
12 files changed, 1281 insertions(+)
create mode 100644 pcbnew/dialogs/dialog_board_statistics.cpp
create mode 100644 pcbnew/dialogs/dialog_board_statistics.h
create mode 100644 pcbnew/dialogs/dialog_board_statistics_base.cpp
create mode 100644 pcbnew/dialogs/dialog_board_statistics_base.fbp
create mode 100644 pcbnew/dialogs/dialog_board_statistics_base.h
create mode 100644 pcbnew/tools/pcb_inspection_tool.cpp
create mode 100644 pcbnew/tools/pcb_inspection_tool.h
--------------2.22.0
Content-Type: text/x-patch; name="0001-added-board-statistics-dialog-which-shows-info-for-p.patch"
Content-Transfer-Encoding: 8bit
Content-Disposition: attachment; filename="0001-added-board-statistics-dialog-which-shows-info-for-p.patch"
diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt
index 78da64280..dc4f8d765 100644
--- a/pcbnew/CMakeLists.txt
+++ b/pcbnew/CMakeLists.txt
@@ -54,6 +54,8 @@ set( PCBNEW_DIALOGS
dialogs/dialog_block_options.cpp
dialogs/dialog_block_options_base.cpp
dialogs/dialog_board_setup.cpp
+ dialogs/dialog_board_statistics.cpp
+ dialogs/dialog_board_statistics_base.cpp
dialogs/dialog_choose_footprint.cpp
dialogs/dialog_cleanup_tracks_and_vias.cpp
dialogs/dialog_cleanup_tracks_and_vias_base.cpp
@@ -304,6 +306,7 @@ set( PCBNEW_CLASS_SRCS
tools/pcb_actions.cpp
tools/pcb_bright_box.cpp
tools/pcb_editor_control.cpp
+ tools/pcb_inspection_tool.cpp
tools/pcb_selection_conditions.cpp
tools/pcb_tool_base.cpp
tools/pcbnew_control.cpp
diff --git a/pcbnew/dialogs/dialog_board_statistics.cpp b/pcbnew/dialogs/dialog_board_statistics.cpp
new file mode 100644
index 000000000..dbd6e2856
--- /dev/null
+++ b/pcbnew/dialogs/dialog_board_statistics.cpp
@@ -0,0 +1,252 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2019 Alexander Shuklin, jasuramme@gmail.com
+ * 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
+ */
+
+
+#include "dialog_board_statistics.h"
+
+
+DIALOG_BOARD_STATISTICS::DIALOG_BOARD_STATISTICS( PCB_EDIT_FRAME* aParentFrame )
+ : DIALOG_BOARD_STATISTICS_BASE( aParentFrame )
+{
+ m_parentFrame = aParentFrame;
+
+ // Remove wxgrid's selection boxes
+ m_gridComponents->SetCellHighlightPenWidth( 0 );
+ m_gridPads->SetCellHighlightPenWidth( 0 );
+ m_gridBoard->SetCellHighlightPenWidth( 0 );
+ m_gridComponents->SetColMinimalAcceptableWidth( 80 );
+ m_gridPads->SetColMinimalAcceptableWidth( 80 );
+ m_gridBoard->SetColMinimalAcceptableWidth( 80 );
+
+ // Make labels for grids
+ m_gridBoard->SetCellValue( 0, 0, _( "Width" ) );
+ m_gridBoard->SetCellValue( 1, 0, _( "Height" ) );
+ m_gridBoard->SetCellValue( 2, 0, _( "Area" ) );
+ m_gridComponents->SetCellValue( 0, 1, _( "Front Side" ) );
+ m_gridComponents->SetCellValue( 0, 2, _( "Bottom Side" ) );
+ m_gridComponents->SetCellValue( 0, 3, _( "Total" ) );
+}
+
+void DIALOG_BOARD_STATISTICS::refreshItemsTypes()
+{
+ m_componentsTypes.clear();
+
+ // If you need some more types to be shown, simply add them to the
+ // corresponding list
+ m_componentsTypes.push_back( componentsType_t( MOD_CMS, _( "THT" ) ) );
+ m_componentsTypes.push_back( componentsType_t( MOD_DEFAULT, _( "SMD" ) ) );
+ m_componentsTypes.push_back( componentsType_t( MOD_VIRTUAL, _( "Virtual" ) ) );
+
+ m_padsTypes.clear();
+ m_padsTypes.push_back( padsType_t( PAD_ATTRIB_STANDARD, _( "THT" ) ) );
+ m_padsTypes.push_back( padsType_t( PAD_ATTRIB_SMD, _( "SMD" ) ) );
+ m_padsTypes.push_back( padsType_t( PAD_ATTRIB_CONN, _( "Connector" ) ) );
+ m_padsTypes.push_back( padsType_t( PAD_ATTRIB_HOLE_NOT_PLATED, _( "NPH" ) ) );
+
+ // If there not enough rows in grids, append some
+ size_t appendRows = m_componentsTypes.size() + 2 - m_gridComponents->GetNumberRows();
+ if( appendRows > 0 )
+ m_gridComponents->AppendRows( appendRows );
+
+ appendRows = m_padsTypes.size() + 1 - m_gridPads->GetNumberRows();
+ if( appendRows > 0 )
+ m_gridPads->AppendRows( appendRows );
+}
+
+bool DIALOG_BOARD_STATISTICS::TransferDataToWindow()
+{
+ refreshItemsTypes();
+ getDataFromPCB();
+ updateWidets();
+ Layout();
+ FinishDialogSettings();
+ return true;
+}
+
+void DIALOG_BOARD_STATISTICS::getDataFromPCB()
+{
+ auto board = m_parentFrame->GetBoard();
+
+ for( MODULE* module : board->Modules() )
+ {
+ auto& pads = module->Pads();
+
+ // Do not proceed modules with no pads if checkbox checked
+ if( m_checkBoxExcludeComponentsNoPins->GetValue() && !pads.size() )
+ continue;
+
+ // Go through components types list
+ for( auto& type : m_componentsTypes )
+ {
+ if( module->GetAttributes() == type.attribute )
+ {
+ if( module->IsFlipped() )
+ type.frontSideQty++;
+ else
+ type.backSideQty++;
+ break;
+ }
+ }
+
+ for( auto& pad : pads )
+ {
+ // Go through pads types list
+ for( auto& type : m_padsTypes )
+ {
+ if( pad->GetAttribute() == type.attribute )
+ {
+ type.qty++;
+ break;
+ }
+ }
+ }
+ }
+
+ bool boundingBoxCreated = false; //flag if bounding box initialized
+ BOX2I bbox;
+ SHAPE_POLY_SET polySet;
+ m_hasOutline = board->GetBoardPolygonOutlines( polySet );
+
+ // If board has no Edge Cuts lines, board->GetBoardPolygonOutlines will
+ // return small rectangle, so we double check that
+ bool edgeCutsExists = false;
+ for( auto& drawing : board->Drawings() )
+ {
+ if( drawing->GetLayer() == Edge_Cuts )
+ {
+ edgeCutsExists = true;
+ break;
+ }
+ }
+
+ if( !edgeCutsExists )
+ m_hasOutline = false;
+
+ if( m_hasOutline )
+ {
+ m_boardArea = 0;
+ int outlinesCount = polySet.OutlineCount();
+ for( int i = 0; i < outlinesCount; i++ )
+ {
+ auto& outline = polySet.Outline( i );
+ m_boardArea += abs( outline.Area() );
+
+ // If checkbox "subtract holes" is checked
+ if( m_checkBoxSubtractHoles->GetValue() )
+ {
+ int holesCount = polySet.HoleCount( i );
+ for( int j = 0; j < holesCount; j++ )
+ {
+ m_boardArea -= abs( polySet.Hole( i, j ).Area() );
+ }
+ }
+
+ if( boundingBoxCreated )
+ {
+ bbox.Merge( outline.BBox() );
+ }
+ else
+ {
+ bbox = outline.BBox();
+ boundingBoxCreated = true;
+ }
+ }
+ m_boardWidth = bbox.GetWidth();
+ m_boardHeight = bbox.GetHeight();
+ }
+}
+
+void DIALOG_BOARD_STATISTICS::updateWidets()
+{
+ int totalPads = 0;
+ int currentRow = 0;
+ for( auto& type : m_padsTypes )
+ {
+ m_gridPads->SetCellValue( currentRow, 0, type.title );
+ m_gridPads->SetCellValue( currentRow, 1, wxString::Format( wxT( "%i " ), type.qty ) );
+ totalPads += type.qty;
+ currentRow++;
+ }
+ m_gridPads->SetCellValue( currentRow, 0, _( "Total" ) );
+ m_gridPads->SetCellValue( currentRow, 1, wxString::Format( wxT( "%i " ), totalPads ) );
+
+ int totalFront = 0;
+ int totalBack = 0;
+
+ // We don't use row 0, as there labels are
+ currentRow = 1;
+ for( auto& type : m_componentsTypes )
+ {
+ m_gridComponents->SetCellValue( currentRow, 0, type.title );
+ m_gridComponents->SetCellValue(
+ currentRow, 1, wxString::Format( wxT( "%i " ), type.frontSideQty ) );
+ m_gridComponents->SetCellValue(
+ currentRow, 2, wxString::Format( wxT( "%i " ), type.backSideQty ) );
+ m_gridComponents->SetCellValue( currentRow, 3,
+ wxString::Format( wxT( "%i " ), type.frontSideQty + type.backSideQty ) );
+ totalFront += type.frontSideQty;
+ totalBack += type.backSideQty;
+ currentRow++;
+ }
+ m_gridComponents->SetCellValue( currentRow, 0, _( "Total" ) );
+ m_gridComponents->SetCellValue( currentRow, 1, wxString::Format( wxT( "%i " ), totalFront ) );
+ m_gridComponents->SetCellValue( currentRow, 2, wxString::Format( wxT( "%i " ), totalBack ) );
+ m_gridComponents->SetCellValue(
+ currentRow, 3, wxString::Format( wxT( "%i " ), totalFront + totalBack ) );
+
+ if( m_hasOutline )
+ {
+ m_gridBoard->SetCellValue( 0, 1,
+ MessageTextFromValue( m_parentFrame->GetUserUnits(), m_boardWidth, false ) + " " );
+ m_gridBoard->SetCellValue( 1, 1,
+ MessageTextFromValue( m_parentFrame->GetUserUnits(), m_boardHeight, false ) + " " );
+ if( GetUserUnits() == INCHES )
+ m_boardArea /= ( IU_PER_MILS * IU_PER_MILS * 1000000 );
+ else
+ m_boardArea /= ( IU_PER_MM * IU_PER_MM );
+ m_gridBoard->SetCellValue( 2, 1,
+ wxString::Format( wxT( "%.3f %s²" ), m_boardArea,
+ GetAbbreviatedUnitsLabel( GetUserUnits(), false ) ) );
+ }
+ else
+ {
+ m_gridBoard->SetCellValue( 0, 1, _( "unknown" ) );
+ m_gridBoard->SetCellValue( 1, 1, _( "unknown" ) );
+ m_gridBoard->SetCellValue( 2, 1, _( "unknown" ) );
+ }
+
+ m_gridComponents->AutoSize();
+ m_gridPads->AutoSize();
+ m_gridBoard->AutoSize();
+}
+
+// If any checkbox clicked, we have to refresh dialog data
+void DIALOG_BOARD_STATISTICS::checkboxClicked( wxCommandEvent& event )
+{
+ TransferDataToWindow();
+}
+
+DIALOG_BOARD_STATISTICS::~DIALOG_BOARD_STATISTICS()
+{
+}
diff --git a/pcbnew/dialogs/dialog_board_statistics.h b/pcbnew/dialogs/dialog_board_statistics.h
new file mode 100644
index 000000000..5f26cd280
--- /dev/null
+++ b/pcbnew/dialogs/dialog_board_statistics.h
@@ -0,0 +1,121 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2019 Alexander Shuklin, jasuramme@gmail.com
+ * 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
+ */
+
+
+#ifndef _DIALOG_BOARD_STATISTICS_H
+#define _DIALOG_BOARD_STATISTICS_H
+
+
+#include <base_units.h>
+#include <class_board.h>
+#include <class_drawsegment.h>
+#include <dialog_board_statistics_base.h>
+#include <pad_shapes.h>
+#include <pcb_base_frame.h>
+#include <pcb_edit_frame.h>
+
+
+/**
+ * Class DIALOG_BOARD_STATISTIC
+ *
+ * Dialog to show common board info.
+ */
+class DIALOG_BOARD_STATISTICS : public DIALOG_BOARD_STATISTICS_BASE
+{
+public:
+ /**
+ * Struct holds information about pad type (such as SMD, THT, NPH
+ * and so on), which will be shown in the dialog. Also holds quantity
+ * of pads
+ */
+ struct padsType_t
+ {
+ padsType_t( PAD_ATTR_T aAttribute, wxString aTitle )
+ : attribute( aAttribute ),
+ title( aTitle ),
+ qty( 0 )
+ {
+ }
+ PAD_ATTR_T attribute;
+ wxString title;
+ int qty;
+ };
+
+ /**
+ * Struct holds information about component type (such as SMD, THT,
+ * Virtual and so on), which will be shown in the dialog. Holds both
+ * front and bottom components quantities
+ */
+ struct componentsType_t
+ {
+ componentsType_t( MODULE_ATTR_T aAttribute, wxString aTitle )
+ : attribute( aAttribute ),
+ title( aTitle ),
+ frontSideQty( 0 ),
+ backSideQty( 0 )
+ {
+ }
+ MODULE_ATTR_T attribute;
+ wxString title;
+ int frontSideQty;
+ int backSideQty;
+ };
+
+ using componentsTypeList_t = std::deque<componentsType_t>;
+ using padsTypeList_t = std::deque<padsType_t>;
+
+ DIALOG_BOARD_STATISTICS( PCB_EDIT_FRAME* aParentFrame );
+ ~DIALOG_BOARD_STATISTICS();
+
+ ///> Get data from the PCB board and print it to dialog
+ bool TransferDataToWindow() override;
+
+ ///> Function to fill up all items types to be shown in the dialog.
+ void inline refreshItemsTypes();
+
+ ///> Gets data from board
+ void inline getDataFromPCB();
+
+ ///> Applies data to dialog widgets
+ void inline updateWidets();
+
+ void checkboxClicked( wxCommandEvent& event ) override;
+
+private:
+ PCB_EDIT_FRAME* m_parentFrame;
+ int m_boardWidth;
+ int m_boardHeight;
+ double m_boardArea;
+
+ ///> Shows if board outline properly defined
+ bool m_hasOutline;
+
+ ///> Holds all components types to be shown in the dialog
+ componentsTypeList_t m_componentsTypes;
+
+ ///> Holds all pads types to be shown in the dialog
+ padsTypeList_t m_padsTypes;
+};
+
+#endif // __DIALOG_BOARD_STATISTICS_H
diff --git a/pcbnew/dialogs/dialog_board_statistics_base.cpp b/pcbnew/dialogs/dialog_board_statistics_base.cpp
new file mode 100644
index 000000000..2cdf488d0
--- /dev/null
+++ b/pcbnew/dialogs/dialog_board_statistics_base.cpp
@@ -0,0 +1,183 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 25 2019)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO *NOT* EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_board_statistics_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_BOARD_STATISTICS_BASE::DIALOG_BOARD_STATISTICS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+ this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWFRAME ) );
+
+ wxBoxSizer* bMainBoxSizer;
+ bMainBoxSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxGridBagSizer* gbConentsSizer;
+ gbConentsSizer = new wxGridBagSizer( 5, 10 );
+ gbConentsSizer->SetFlexibleDirection( wxBOTH );
+ gbConentsSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ wxStaticBoxSizer* sbComponentsSizer;
+ sbComponentsSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Components") ), wxVERTICAL );
+
+ m_gridComponents = new wxGrid( sbComponentsSizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL );
+
+ // Grid
+ m_gridComponents->CreateGrid( 5, 4 );
+ m_gridComponents->EnableEditing( false );
+ m_gridComponents->EnableGridLines( false );
+ m_gridComponents->SetGridLineColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWFRAME ) );
+ m_gridComponents->EnableDragGridSize( false );
+ m_gridComponents->SetMargins( 0, 0 );
+
+ // Columns
+ m_gridComponents->EnableDragColMove( false );
+ m_gridComponents->EnableDragColSize( true );
+ m_gridComponents->SetColLabelSize( 0 );
+ m_gridComponents->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
+
+ // Rows
+ m_gridComponents->EnableDragRowSize( true );
+ m_gridComponents->SetRowLabelSize( 0 );
+ m_gridComponents->SetRowLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
+
+ // Label Appearance
+ m_gridComponents->SetLabelBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BACKGROUND ) );
+ m_gridComponents->SetLabelFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) );
+
+ // Cell Defaults
+ m_gridComponents->SetDefaultCellBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWFRAME ) );
+ m_gridComponents->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
+ m_gridComponents->SetMaxSize( wxSize( -1,400 ) );
+
+ sbComponentsSizer->Add( m_gridComponents, 0, wxALIGN_CENTER|wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+
+ gbConentsSizer->Add( sbComponentsSizer, wxGBPosition( 0, 0 ), wxGBSpan( 2, 1 ), wxEXPAND, 5 );
+
+ wxStaticBoxSizer* sbPadsSizer;
+ sbPadsSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Pads") ), wxVERTICAL );
+
+ m_gridPads = new wxGrid( sbPadsSizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL );
+
+ // Grid
+ m_gridPads->CreateGrid( 5, 2 );
+ m_gridPads->EnableEditing( false );
+ m_gridPads->EnableGridLines( false );
+ m_gridPads->SetGridLineColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWFRAME ) );
+ m_gridPads->EnableDragGridSize( false );
+ m_gridPads->SetMargins( 10, 0 );
+
+ // Columns
+ m_gridPads->EnableDragColMove( false );
+ m_gridPads->EnableDragColSize( true );
+ m_gridPads->SetColLabelSize( 0 );
+ m_gridPads->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
+
+ // Rows
+ m_gridPads->EnableDragRowSize( true );
+ m_gridPads->SetRowLabelSize( 0 );
+ m_gridPads->SetRowLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
+
+ // Label Appearance
+ m_gridPads->SetLabelBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BACKGROUND ) );
+ m_gridPads->SetLabelFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) );
+
+ // Cell Defaults
+ m_gridPads->SetDefaultCellBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWFRAME ) );
+ m_gridPads->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
+ m_gridPads->SetMaxSize( wxSize( -1,300 ) );
+
+ sbPadsSizer->Add( m_gridPads, 0, wxALL, 5 );
+
+
+ gbConentsSizer->Add( sbPadsSizer, wxGBPosition( 0, 1 ), wxGBSpan( 1, 1 ), wxEXPAND, 5 );
+
+ wxStaticBoxSizer* sbBoardSizer;
+ sbBoardSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Board") ), wxVERTICAL );
+
+ m_gridBoard = new wxGrid( sbBoardSizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL );
+
+ // Grid
+ m_gridBoard->CreateGrid( 3, 2 );
+ m_gridBoard->EnableEditing( false );
+ m_gridBoard->EnableGridLines( false );
+ m_gridBoard->SetGridLineColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWFRAME ) );
+ m_gridBoard->EnableDragGridSize( false );
+ m_gridBoard->SetMargins( 10, 0 );
+
+ // Columns
+ m_gridBoard->EnableDragColMove( false );
+ m_gridBoard->EnableDragColSize( true );
+ m_gridBoard->SetColLabelSize( 0 );
+ m_gridBoard->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
+
+ // Rows
+ m_gridBoard->EnableDragRowSize( true );
+ m_gridBoard->SetRowLabelSize( 0 );
+ m_gridBoard->SetRowLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
+
+ // Label Appearance
+ m_gridBoard->SetLabelBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BACKGROUND ) );
+ m_gridBoard->SetLabelFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) );
+
+ // Cell Defaults
+ m_gridBoard->SetDefaultCellBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWFRAME ) );
+ m_gridBoard->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
+ m_gridBoard->SetMaxSize( wxSize( -1,300 ) );
+
+ sbBoardSizer->Add( m_gridBoard, 0, wxALL, 5 );
+
+
+ gbConentsSizer->Add( sbBoardSizer, wxGBPosition( 1, 1 ), wxGBSpan( 1, 1 ), wxEXPAND, 5 );
+
+
+ gbConentsSizer->AddGrowableCol( 0 );
+ gbConentsSizer->AddGrowableCol( 1 );
+ gbConentsSizer->AddGrowableRow( 0 );
+
+ bMainBoxSizer->Add( gbConentsSizer, 1, wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 10 );
+
+ wxGridSizer* gOptionsSizer;
+ gOptionsSizer = new wxGridSizer( 0, 2, 0, 0 );
+
+ m_checkBoxSubtractHoles = new wxCheckBox( this, wxID_ANY, _("Subtract holes from board area"), wxDefaultPosition, wxDefaultSize, 0 );
+ gOptionsSizer->Add( m_checkBoxSubtractHoles, 0, wxALL|wxEXPAND, 5 );
+
+ m_checkBoxExcludeComponentsNoPins = new wxCheckBox( this, wxID_ANY, _("Exclude components with no pins"), wxDefaultPosition, wxDefaultSize, 0 );
+ gOptionsSizer->Add( m_checkBoxExcludeComponentsNoPins, 0, wxALL|wxEXPAND, 5 );
+
+
+ bMainBoxSizer->Add( gOptionsSizer, 0, wxEXPAND|wxLEFT|wxRIGHT, 10 );
+
+ m_sdbControlSizer = new wxStdDialogButtonSizer();
+ m_sdbControlSizerOK = new wxButton( this, wxID_OK );
+ m_sdbControlSizer->AddButton( m_sdbControlSizerOK );
+ m_sdbControlSizer->Realize();
+
+ bMainBoxSizer->Add( m_sdbControlSizer, 0, wxALIGN_RIGHT|wxBOTTOM|wxLEFT|wxRIGHT|wxTOP, 10 );
+
+
+ this->SetSizer( bMainBoxSizer );
+ this->Layout();
+ bMainBoxSizer->Fit( this );
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ m_checkBoxSubtractHoles->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_BOARD_STATISTICS_BASE::checkboxClicked ), NULL, this );
+ m_checkBoxExcludeComponentsNoPins->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_BOARD_STATISTICS_BASE::checkboxClicked ), NULL, this );
+}
+
+DIALOG_BOARD_STATISTICS_BASE::~DIALOG_BOARD_STATISTICS_BASE()
+{
+ // Disconnect Events
+ m_checkBoxSubtractHoles->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_BOARD_STATISTICS_BASE::checkboxClicked ), NULL, this );
+ m_checkBoxExcludeComponentsNoPins->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_BOARD_STATISTICS_BASE::checkboxClicked ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_board_statistics_base.fbp b/pcbnew/dialogs/dialog_board_statistics_base.fbp
new file mode 100644
index 000000000..fe9a222b5
--- /dev/null
+++ b/pcbnew/dialogs/dialog_board_statistics_base.fbp
@@ -0,0 +1,558 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="15" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration">; </property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_board_statistics_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="indent_with_spaces"></property>
+ <property name="internationalize">0</property>
+ <property name="name">DIALOG_BOARD_STATISTCS_BASE</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg">wxSYS_COLOUR_WINDOWFRAME</property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_BOARD_STATISTICS_BASE</property>
+ <property name="pos"></property>
+ <property name="size"></property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h; forward_declare</property>
+ <property name="title">Board Statistics</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainBoxSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">10</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">1</property>
+ <object class="wxGridBagSizer" expanded="1">
+ <property name="empty_cell_size"></property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">0</property>
+ <property name="growablerows">0</property>
+ <property name="hgap">10</property>
+ <property name="minimum_size"></property>
+ <property name="name">gbConentsSizer</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="vgap">5</property>
+ <object class="gbsizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">0</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="row">0</property>
+ <property name="rowspan">2</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Components</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbComponentsSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="parent">1</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER|wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxGrid" 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="autosize_cols">0</property>
+ <property name="autosize_rows">0</property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="cell_bg">wxSYS_COLOUR_WINDOWFRAME</property>
+ <property name="cell_font"></property>
+ <property name="cell_horiz_alignment">wxALIGN_LEFT</property>
+ <property name="cell_text"></property>
+ <property name="cell_vert_alignment">wxALIGN_TOP</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="col_label_horiz_alignment">wxALIGN_CENTER</property>
+ <property name="col_label_size">0</property>
+ <property name="col_label_values"></property>
+ <property name="col_label_vert_alignment">wxALIGN_CENTER</property>
+ <property name="cols">4</property>
+ <property name="column_sizes"></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="drag_col_move">0</property>
+ <property name="drag_col_size">1</property>
+ <property name="drag_grid_size">0</property>
+ <property name="drag_row_size">1</property>
+ <property name="editing">0</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="grid_line_color">wxSYS_COLOUR_WINDOWFRAME</property>
+ <property name="grid_lines">0</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label_bg">wxSYS_COLOUR_BACKGROUND</property>
+ <property name="label_font">,90,90,-1,70,0</property>
+ <property name="label_text"></property>
+ <property name="margin_height">0</property>
+ <property name="margin_width">0</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size">-1,400</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_gridComponents</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="row_label_horiz_alignment">wxALIGN_CENTER</property>
+ <property name="row_label_size">0</property>
+ <property name="row_label_values"></property>
+ <property name="row_label_vert_alignment">wxALIGN_CENTER</property>
+ <property name="row_sizes"></property>
+ <property name="rows">5</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass">; ; forward_declare</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">wxVSCROLL</property>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="gbsizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">1</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="row">0</property>
+ <property name="rowspan">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Pads</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbPadsSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="parent">1</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxGrid" 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="autosize_cols">0</property>
+ <property name="autosize_rows">0</property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="cell_bg">wxSYS_COLOUR_WINDOWFRAME</property>
+ <property name="cell_font"></property>
+ <property name="cell_horiz_alignment">wxALIGN_LEFT</property>
+ <property name="cell_text"></property>
+ <property name="cell_vert_alignment">wxALIGN_TOP</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="col_label_horiz_alignment">wxALIGN_CENTER</property>
+ <property name="col_label_size">0</property>
+ <property name="col_label_values"></property>
+ <property name="col_label_vert_alignment">wxALIGN_CENTER</property>
+ <property name="cols">2</property>
+ <property name="column_sizes"></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="drag_col_move">0</property>
+ <property name="drag_col_size">1</property>
+ <property name="drag_grid_size">0</property>
+ <property name="drag_row_size">1</property>
+ <property name="editing">0</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="grid_line_color">wxSYS_COLOUR_WINDOWFRAME</property>
+ <property name="grid_lines">0</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label_bg">wxSYS_COLOUR_BACKGROUND</property>
+ <property name="label_font">,90,90,-1,70,0</property>
+ <property name="label_text"></property>
+ <property name="margin_height">0</property>
+ <property name="margin_width">10</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size">-1,300</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_gridPads</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="row_label_horiz_alignment">wxALIGN_CENTER</property>
+ <property name="row_label_size">0</property>
+ <property name="row_label_values"></property>
+ <property name="row_label_vert_alignment">wxALIGN_CENTER</property>
+ <property name="row_sizes"></property>
+ <property name="rows">5</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass">; ; forward_declare</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">wxVSCROLL</property>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="gbsizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">1</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="row">1</property>
+ <property name="rowspan">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Board</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbBoardSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="parent">1</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxGrid" 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="autosize_cols">0</property>
+ <property name="autosize_rows">0</property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="cell_bg">wxSYS_COLOUR_WINDOWFRAME</property>
+ <property name="cell_font"></property>
+ <property name="cell_horiz_alignment">wxALIGN_LEFT</property>
+ <property name="cell_text"></property>
+ <property name="cell_vert_alignment">wxALIGN_TOP</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="col_label_horiz_alignment">wxALIGN_CENTER</property>
+ <property name="col_label_size">0</property>
+ <property name="col_label_values"></property>
+ <property name="col_label_vert_alignment">wxALIGN_CENTER</property>
+ <property name="cols">2</property>
+ <property name="column_sizes"></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="drag_col_move">0</property>
+ <property name="drag_col_size">1</property>
+ <property name="drag_grid_size">0</property>
+ <property name="drag_row_size">1</property>
+ <property name="editing">0</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="grid_line_color">wxSYS_COLOUR_WINDOWFRAME</property>
+ <property name="grid_lines">0</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label_bg">wxSYS_COLOUR_BACKGROUND</property>
+ <property name="label_font">,90,90,-1,70,0</property>
+ <property name="label_text"></property>
+ <property name="margin_height">0</property>
+ <property name="margin_width">10</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size">-1,300</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_gridBoard</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="row_label_horiz_alignment">wxALIGN_CENTER</property>
+ <property name="row_label_size">0</property>
+ <property name="row_label_values"></property>
+ <property name="row_label_vert_alignment">wxALIGN_CENTER</property>
+ <property name="row_sizes"></property>
+ <property name="rows">3</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass">; ; forward_declare</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">wxVSCROLL</property>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">10</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxGridSizer" expanded="1">
+ <property name="cols">2</property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">gOptionsSizer</property>
+ <property name="permission">none</property>
+ <property name="rows">0</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" 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="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">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">Subtract holes from board area</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_checkBoxSubtractHoles</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">; ; 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="OnCheckBox">checkboxClicked</event>
+ </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="wxCheckBox" 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="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">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">Exclude components with no pins</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_checkBoxExcludeComponentsNoPins</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">; ; 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="OnCheckBox">checkboxClicked</event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">10</property>
+ <property name="flag">wxALIGN_RIGHT|wxBOTTOM|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">0</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbControlSizer</property>
+ <property name="permission">protected</property>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_board_statistics_base.h b/pcbnew/dialogs/dialog_board_statistics_base.h
new file mode 100644
index 000000000..0494adcfe
--- /dev/null
+++ b/pcbnew/dialogs/dialog_board_statistics_base.h
@@ -0,0 +1,55 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 25 2019)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO *NOT* EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#pragma once
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include "dialog_shim.h"
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/string.h>
+#include <wx/font.h>
+#include <wx/grid.h>
+#include <wx/gdicmn.h>
+#include <wx/sizer.h>
+#include <wx/statbox.h>
+#include <wx/gbsizer.h>
+#include <wx/checkbox.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_BOARD_STATISTICS_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_BOARD_STATISTICS_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxGrid* m_gridComponents;
+ wxGrid* m_gridPads;
+ wxGrid* m_gridBoard;
+ wxCheckBox* m_checkBoxSubtractHoles;
+ wxCheckBox* m_checkBoxExcludeComponentsNoPins;
+ wxStdDialogButtonSizer* m_sdbControlSizer;
+ wxButton* m_sdbControlSizerOK;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void checkboxClicked( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_BOARD_STATISTICS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Board Statistics"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE );
+ ~DIALOG_BOARD_STATISTICS_BASE();
+
+};
+
diff --git a/pcbnew/menubar_pcb_editor.cpp b/pcbnew/menubar_pcb_editor.cpp
index af83c60ab..98b879ea0 100644
--- a/pcbnew/menubar_pcb_editor.cpp
+++ b/pcbnew/menubar_pcb_editor.cpp
@@ -436,6 +436,7 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
inspectMenu->AddItem( PCB_ACTIONS::listNets, SELECTION_CONDITIONS::ShowAlways );
inspectMenu->AddItem( ACTIONS::measureTool, SELECTION_CONDITIONS::ShowAlways );
+ inspectMenu->AddItem( PCB_ACTIONS::boardStatistics, SELECTION_CONDITIONS::ShowAlways );
inspectMenu->AddSeparator();
inspectMenu->AddItem( PCB_ACTIONS::runDRC, SELECTION_CONDITIONS::ShowAlways );
diff --git a/pcbnew/pcb_edit_frame.cpp b/pcbnew/pcb_edit_frame.cpp
index 43ca7e5d2..78b50b81e 100644
--- a/pcbnew/pcb_edit_frame.cpp
+++ b/pcbnew/pcb_edit_frame.cpp
@@ -74,6 +74,7 @@
#include <tools/point_editor.h>
#include <tools/pcbnew_control.h>
#include <tools/pcb_editor_control.h>
+#include <tools/pcb_inspection_tool.h>
#include <tools/placement_tool.h>
#include <tools/pad_tool.h>
#include <tools/microwave_tool.h>
@@ -420,6 +421,7 @@ void PCB_EDIT_FRAME::setupTools()
m_toolManager->RegisterTool( new POINT_EDITOR );
m_toolManager->RegisterTool( new PCBNEW_CONTROL );
m_toolManager->RegisterTool( new PCB_EDITOR_CONTROL );
+ m_toolManager->RegisterTool( new PCB_INSPECTION_TOOL );
m_toolManager->RegisterTool( new ALIGN_DISTRIBUTE_TOOL );
m_toolManager->RegisterTool( new MICROWAVE_TOOL );
m_toolManager->RegisterTool( new POSITION_RELATIVE_TOOL );
diff --git a/pcbnew/tools/pcb_actions.cpp b/pcbnew/tools/pcb_actions.cpp
index c8d72ceeb..5c888f121 100644
--- a/pcbnew/tools/pcb_actions.cpp
+++ b/pcbnew/tools/pcb_actions.cpp
@@ -906,6 +906,11 @@ TOOL_ACTION PCB_ACTIONS::deleteTool( "pcbnew.Control.deleteTool",
_( "Delete Items Tool" ), _( "Click on items to delete them" ),
delete_xpm );
+//Show board statistics tool
+TOOL_ACTION PCB_ACTIONS::boardStatistics( "pcbnew.InspectionTool.ShowStatisticsDialog", AS_GLOBAL,
+ 0, LEGACY_HK_NAME( "Board statistics" ), _( "Show board statistics" ),
+ _( "Shows board statistics" ), pcbnew_xpm );
+
// PLACEMENT_TOOL
//
diff --git a/pcbnew/tools/pcb_actions.h b/pcbnew/tools/pcb_actions.h
index 35523fa91..f1a9cb7fa 100644
--- a/pcbnew/tools/pcb_actions.h
+++ b/pcbnew/tools/pcb_actions.h
@@ -414,6 +414,7 @@ public:
static TOOL_ACTION drillOrigin;
static TOOL_ACTION appendBoard;
static TOOL_ACTION showEeschema;
+ static TOOL_ACTION boardStatistics;
// Ratsnest
static TOOL_ACTION localRatsnestTool;
diff --git a/pcbnew/tools/pcb_inspection_tool.cpp b/pcbnew/tools/pcb_inspection_tool.cpp
new file mode 100644
index 000000000..8298f27ab
--- /dev/null
+++ b/pcbnew/tools/pcb_inspection_tool.cpp
@@ -0,0 +1,45 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * 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
+ */
+
+
+#include "pcb_inspection_tool.h"
+
+
+PCB_INSPECTION_TOOL::PCB_INSPECTION_TOOL()
+ : PCB_TOOL_BASE( "pcbnew.InspectionTool.ShowStatisticsDialog" )
+{
+}
+
+int PCB_INSPECTION_TOOL::ShowStatisticsDialog( const TOOL_EVENT& aEvent )
+{
+ auto frame = getEditFrame<PCB_EDIT_FRAME>();
+
+ DIALOG_BOARD_STATISTICS dialog( frame );
+ dialog.ShowModal();
+ return 0;
+}
+
+void PCB_INSPECTION_TOOL::setTransitions()
+{
+ Go( &PCB_INSPECTION_TOOL::ShowStatisticsDialog, PCB_ACTIONS::boardStatistics.MakeEvent() );
+}
diff --git a/pcbnew/tools/pcb_inspection_tool.h b/pcbnew/tools/pcb_inspection_tool.h
new file mode 100644
index 000000000..ef49ac039
--- /dev/null
+++ b/pcbnew/tools/pcb_inspection_tool.h
@@ -0,0 +1,55 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * 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
+ */
+
+#ifndef __BOARD_STATISTICS_TOOL_H
+#define __BOARD_STATISTICS_TOOL_H
+
+
+#include <dialogs/dialog_board_statistics.h>
+#include <pcb_edit_frame.h>
+#include <tools/pcb_actions.h>
+#include <tools/pcb_tool_base.h>
+
+
+/**
+ * Class PCB_INSPECTION_TOOL
+ *
+ * Tool for pcb inspection.
+ */
+class PCB_INSPECTION_TOOL : public PCB_TOOL_BASE
+{
+public:
+ PCB_INSPECTION_TOOL();
+
+ /**
+ * Function ShowStatisticDialog()
+ *
+ * Shows dialog with board statistics
+ */
+ int ShowStatisticsDialog( const TOOL_EVENT& aEvent );
+
+ ///> Bind handlers to corresponding TOOL_ACTIONs
+ void setTransitions() override;
+};
+
+#endif //__BOARD_STATISTICS_TOOL_H
--------------2.22.0--
Follow ups
References