KiCad PCB EDA Suite
panel_setup_severities.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2020-2021 KiCad Developers, see AUTHORS.txt for contributors.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, you may find one here:
18  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19  * or you may search the http://www.gnu.org website for the version 2 license,
20  * or you may write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
24 #include <widgets/paged_dialog.h>
25 #include <widgets/ui_common.h>
26 #include <rc_item.h>
28 #include <wx/radiobut.h>
29 #include <wx/scrolwin.h>
30 #include <wx/stattext.h>
31 #include <wx/treebook.h>
32 
33 
35  std::vector<std::reference_wrapper<RC_ITEM>> aItems,
36  std::map<int, SEVERITY>& aSeverities,
37  RC_ITEM* aPinMapSpecialCase ) :
38  wxPanel( aParent->GetTreebook() ),
39  m_severities( aSeverities ),
40  m_items( aItems ),
41  m_pinMapSpecialCase( aPinMapSpecialCase )
42 {
43  wxString severities[] = { _( "Error" ), _( "Warning" ), _( "Ignore" ) };
44  int severityCount = sizeof( severities ) / sizeof( wxString );
45  int baseID = 1000;
46  wxBoxSizer* panelSizer = new wxBoxSizer( wxVERTICAL );
47  wxScrolledWindow* scrollWin = new wxScrolledWindow( this, wxID_ANY,
48  wxDefaultPosition, wxDefaultSize,
49  wxTAB_TRAVERSAL | wxVSCROLL );
50  bool firstLine = true;
51 
52  scrollWin->SetScrollRate( 0, 5 );
53 
54  wxFlexGridSizer* gridSizer = new wxFlexGridSizer( 0, 2, 0, 5 );
55  gridSizer->SetFlexibleDirection( wxBOTH );
56  gridSizer->SetVGap( 5 );
57 
58  for( const RC_ITEM& item : m_items )
59  {
60  int errorCode = item.GetErrorCode();
61  wxString msg = item.GetErrorText();
62 
64  continue;
65 
66  if( errorCode == 0 )
67  {
68  wxStaticText* heading = new wxStaticText( scrollWin, wxID_ANY, msg );
69  wxFont headingFont = heading->GetFont();
70 
71  heading->SetFont( headingFont.Bold() );
72 
73  if( !firstLine )
74  {
75  gridSizer->AddSpacer( 5 ); // col 1
76  gridSizer->AddSpacer( 5 ); // col 2
77  }
78 
79  gridSizer->Add( heading, 0, wxALIGN_BOTTOM | wxALL | wxEXPAND, 4 );
80  gridSizer->AddSpacer( 0 ); // col 2
81  }
82  else if( !msg.IsEmpty() ) // items with no message are for internal use only
83  {
84  wxStaticText* errorLabel = new wxStaticText( scrollWin, wxID_ANY, msg + wxT( ":" ) );
85  gridSizer->Add( errorLabel, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, 15 );
86 
87  // OSX can't handle more than 100 radio buttons in a single window (yes, seriously),
88  // so we have to create a window for each set
89  wxPanel* radioPanel = new wxPanel( scrollWin );
90  wxBoxSizer* radioSizer = new wxBoxSizer( wxHORIZONTAL );
91 
92  for( int i = 0; i < severityCount; ++i )
93  {
94  m_buttonMap[ errorCode ][i] = new wxRadioButton( radioPanel,
95  baseID + errorCode * 10 + i,
96  severities[i],
97  wxDefaultPosition, wxDefaultSize,
98  i == 0 ? wxRB_GROUP : 0 );
99  radioSizer->Add( m_buttonMap[ errorCode ][i], 0,
100  wxRIGHT | wxALIGN_CENTER_VERTICAL, 30 );
101  }
102 
103  radioPanel->SetSizer( radioSizer );
104  radioPanel->Layout();
105  gridSizer->Add( radioPanel, 0, wxALIGN_CENTER_VERTICAL );
106  }
107 
108  firstLine = false;
109  }
110 
111 
112  if( m_pinMapSpecialCase )
113  {
114  wxString pinMapSeverities[] = { _( "From Pin Conflicts Map" ), wxT( "" ), _( "Ignore" ) };
115  int errorCode = m_pinMapSpecialCase->GetErrorCode();
116  wxString msg = m_pinMapSpecialCase->GetErrorText();
117 
118  wxStaticText* errorLabel = new wxStaticText( scrollWin, wxID_ANY, msg + wxT( ":" ) );
119  gridSizer->Add( errorLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL | wxEXPAND, 15 );
120 
121  wxPanel* radioPanel = new wxPanel( scrollWin );
122  wxBoxSizer* radioSizer = new wxBoxSizer( wxHORIZONTAL );
123 
124  for( size_t i = 0; i < 3; ++i )
125  {
126  if( pinMapSeverities[i] == wxT( "" ) )
127  {
128  wxStaticText* spacer = new wxStaticText( radioPanel, wxID_ANY, wxT( "" ) );
129  radioSizer->Add( spacer, 0, wxRIGHT | wxEXPAND, 17 );
130  }
131  else
132  {
133  m_buttonMap[ errorCode ][i] = new wxRadioButton( radioPanel,
134  baseID + errorCode * 10 + i,
135  pinMapSeverities[i],
136  wxDefaultPosition, wxDefaultSize,
137  i == 0 ? wxRB_GROUP : 0 );
138  radioSizer->Add( m_buttonMap[ errorCode ][i], 0, wxEXPAND );
139  }
140  }
141 
142  radioPanel->SetSizer( radioSizer );
143  radioPanel->Layout();
144  gridSizer->Add( radioPanel, 0, wxALIGN_CENTER_VERTICAL );
145  }
146 
147  scrollWin->SetSizer( gridSizer );
148  scrollWin->Layout();
149  gridSizer->Fit( scrollWin );
150  panelSizer->Add( scrollWin, 1, wxEXPAND | wxALL, 5 );
151 
152  SetSizer( panelSizer );
153  Layout();
154  panelSizer->Fit( this );
155 }
156 
157 
158 void PANEL_SETUP_SEVERITIES::ImportSettingsFrom( std::map<int, SEVERITY>& aSettings )
159 {
160  for( const RC_ITEM& item : m_items )
161  {
162  int errorCode = item.GetErrorCode();
163 
164  if(! m_buttonMap[ errorCode ][0] ) // this entry does not actually exist
165  continue;
166 
167  switch( aSettings[ errorCode ] )
168  {
169  case RPT_SEVERITY_ERROR: m_buttonMap[ errorCode ][0]->SetValue( true ); break;
170  case RPT_SEVERITY_WARNING: m_buttonMap[ errorCode ][1]->SetValue( true ); break;
171  case RPT_SEVERITY_IGNORE: m_buttonMap[ errorCode ][2]->SetValue( true ); break;
172  default: break;
173  }
174  }
175 
176  if( m_pinMapSpecialCase )
177  {
178  int pinMapCode = m_pinMapSpecialCase->GetErrorCode();
179  int newSeverity = aSettings[ pinMapCode ];
180 
181  m_buttonMap[ pinMapCode ][0]->SetValue( newSeverity != RPT_SEVERITY_IGNORE );
182  m_buttonMap[ pinMapCode ][2]->SetValue( newSeverity == RPT_SEVERITY_IGNORE );
183  }
184 }
185 
186 
188 {
189  for( const RC_ITEM& item : m_items )
190  {
191  int errorCode = item.GetErrorCode();
192 
193  if( !m_buttonMap[ errorCode ][0] ) // this entry does not actually exist
194  continue;
195 
196  if( m_pinMapSpecialCase && errorCode == m_pinMapSpecialCase->GetErrorCode() )
197  continue;
198 
199  switch( m_severities[ errorCode ] )
200  {
201  case RPT_SEVERITY_ERROR: m_buttonMap[ errorCode ][0]->SetValue( true ); break;
202  case RPT_SEVERITY_WARNING: m_buttonMap[ errorCode ][1]->SetValue( true ); break;
203  case RPT_SEVERITY_IGNORE: m_buttonMap[ errorCode ][2]->SetValue( true ); break;
204  default: break;
205  }
206  }
207 
208  if( m_pinMapSpecialCase )
209  {
210  int pinMapCode = m_pinMapSpecialCase->GetErrorCode();
211  int severity = m_severities[pinMapCode];
212 
213  m_buttonMap[ pinMapCode ][0]->SetValue( severity != RPT_SEVERITY_IGNORE );
214  m_buttonMap[ pinMapCode ][2]->SetValue( severity == RPT_SEVERITY_IGNORE );
215  }
216 
217  return true;
218 }
219 
220 
222 {
223  for( const RC_ITEM& item : m_items )
224  {
225  int errorCode = item.GetErrorCode();
226 
227  if( m_pinMapSpecialCase && m_pinMapSpecialCase->GetErrorCode() == errorCode )
228  continue;
229 
230  if( !m_buttonMap[ errorCode ][0] ) // this entry does not actually exist
231  continue;
232 
233  SEVERITY severity = RPT_SEVERITY_UNDEFINED;
234 
235  if( m_buttonMap[ errorCode ][0]->GetValue() )
236  severity = RPT_SEVERITY_ERROR;
237  else if( m_buttonMap[ errorCode ][1]->GetValue() )
238  severity = RPT_SEVERITY_WARNING;
239  else if( m_buttonMap[ errorCode ][2]->GetValue() )
240  severity = RPT_SEVERITY_IGNORE;
241 
242  m_severities[ errorCode ] = severity;
243  }
244 
245  if( m_pinMapSpecialCase )
246  {
247  int pinMapCode = m_pinMapSpecialCase->GetErrorCode();
248  SEVERITY severity = RPT_SEVERITY_UNDEFINED;
249 
250  if( m_buttonMap[ pinMapCode ][0]->GetValue() )
251  severity = RPT_SEVERITY_ERROR;
252  else if( m_buttonMap[ pinMapCode ][2]->GetValue() )
253  severity = RPT_SEVERITY_IGNORE;
254 
255  m_severities[ pinMapCode ] = severity;
256  }
257 
258  return true;
259 }
A holder for a rule check item, DRC in Pcbnew or ERC in Eeschema.
Definition: rc_item.h:74
void ImportSettingsFrom(std::map< int, SEVERITY > &aSettings)
wxString GetErrorText() const
Definition: rc_item.h:145
RC_ITEM * m_pinMapSpecialCase
For ERC settings; a pointer to ERC_ITEM::pinTableConflict.
std::map< int, wxRadioButton *[4]> m_buttonMap
int GetErrorCode() const
Definition: rc_item.h:137
Functions to provide common constants and other functions to assist in making a consistent UI.
#define _(s)
SEVERITY
std::vector< std::reference_wrapper< RC_ITEM > > m_items
A list of item templates (to get descriptive text and error codes from)
std::map< int, SEVERITY > & m_severities
PANEL_SETUP_SEVERITIES(PAGED_DIALOG *aParent, std::vector< std::reference_wrapper< RC_ITEM >> aItems, std::map< int, SEVERITY > &aSeverities, RC_ITEM *aPinMapSpecialCase=nullptr)
Creates the severities setup panel.