KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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-2023 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
25#include <widgets/ui_common.h>
26#include <rc_item.h>
28#include <wx/radiobut.h>
29#include <wx/scrolwin.h>
30#include <wx/sizer.h>
31#include <wx/stattext.h>
32#include "confirm.h"
33
34
36 std::vector<std::reference_wrapper<RC_ITEM>> aItems,
37 std::map<int, SEVERITY>& aSeverities,
38 RC_ITEM* aPinMapSpecialCase ) :
39 wxPanel( aParentWindow ),
40 m_severities( aSeverities ),
41 m_items( std::move( aItems ) ),
42 m_pinMapSpecialCase( aPinMapSpecialCase )
43{
44 wxString severities[] = { _( "Error" ), _( "Warning" ), _( "Ignore" ) };
45 int severityCount = sizeof( severities ) / sizeof( wxString );
46 int baseID = 1000;
47 wxBoxSizer* panelSizer = new wxBoxSizer( wxVERTICAL );
48 wxScrolledWindow* scrollWin = new wxScrolledWindow( this, wxID_ANY,
49 wxDefaultPosition, wxDefaultSize,
50 wxTAB_TRAVERSAL | wxVSCROLL );
51 bool firstLine = true;
52
53 scrollWin->SetScrollRate( 0, 5 );
54
55 wxBoxSizer* scrollWinSizer = new wxBoxSizer( wxVERTICAL );
56 scrollWin->SetSizer( scrollWinSizer );
57
58 wxFlexGridSizer* gridSizer = new wxFlexGridSizer( 0, 2, 0, 5 );
59 gridSizer->SetFlexibleDirection( wxBOTH );
60 gridSizer->SetVGap( 5 );
61
62 for( const RC_ITEM& item : m_items )
63 {
64 int errorCode = item.GetErrorCode();
65 wxString msg = item.GetErrorText();
66
68 continue;
69
70 if( errorCode == 0 )
71 {
72 wxStaticText* heading = new wxStaticText( scrollWin, wxID_ANY, msg );
73 wxFont headingFont = heading->GetFont();
74
75 heading->SetFont( headingFont.Bold() );
76
77 if( !firstLine )
78 {
79 gridSizer->AddSpacer( 5 ); // col 1
80 gridSizer->AddSpacer( 5 ); // col 2
81 }
82
83 gridSizer->Add( heading, 0, wxALIGN_BOTTOM | wxALL | wxEXPAND, 4 );
84 gridSizer->AddSpacer( 0 ); // col 2
85 }
86 else if( !msg.IsEmpty() ) // items with no message are for internal use only
87 {
88 wxStaticText* errorLabel = new wxStaticText( scrollWin, wxID_ANY, msg + wxT( ":" ) );
89 gridSizer->Add( errorLabel, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, 15 );
90
91 // OSX can't handle more than 100 radio buttons in a single window (yes, seriously),
92 // so we have to create a window for each set
93 wxPanel* radioPanel = new wxPanel( scrollWin );
94 wxBoxSizer* radioSizer = new wxBoxSizer( wxHORIZONTAL );
95
96 for( int i = 0; i < severityCount; ++i )
97 {
98 m_buttonMap[ errorCode ][i] = new wxRadioButton( radioPanel,
99 baseID + errorCode * 10 + i,
100 severities[i],
101 wxDefaultPosition, wxDefaultSize,
102 i == 0 ? wxRB_GROUP : 0 );
103 radioSizer->Add( m_buttonMap[ errorCode ][i], 0,
104 wxRIGHT | wxALIGN_CENTER_VERTICAL, 30 );
105 }
106
107 radioPanel->SetSizer( radioSizer );
108 radioPanel->Layout();
109 gridSizer->Add( radioPanel, 0, wxALIGN_CENTER_VERTICAL );
110 }
111
112 firstLine = false;
113 }
114
115
117 {
118 wxString pinMapSeverities[] = { _( "From Pin Conflicts Map" ), wxT( "" ), _( "Ignore" ) };
119 int errorCode = m_pinMapSpecialCase->GetErrorCode();
120 wxString msg = m_pinMapSpecialCase->GetErrorText();
121
122 wxStaticText* errorLabel = new wxStaticText( scrollWin, wxID_ANY, msg + wxT( ":" ) );
123 gridSizer->Add( errorLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL | wxEXPAND, 15 );
124
125 wxPanel* radioPanel = new wxPanel( scrollWin );
126 wxBoxSizer* radioSizer = new wxBoxSizer( wxHORIZONTAL );
127
128 for( size_t i = 0; i < 3; ++i )
129 {
130 if( pinMapSeverities[i] == wxT( "" ) )
131 {
132 wxStaticText* spacer = new wxStaticText( radioPanel, wxID_ANY, wxT( "" ) );
133 radioSizer->Add( spacer, 0, wxRIGHT | wxEXPAND, 17 );
134 }
135 else
136 {
137 m_buttonMap[ errorCode ][i] = new wxRadioButton( radioPanel,
138 baseID + errorCode * 10 + i,
139 pinMapSeverities[i],
140 wxDefaultPosition, wxDefaultSize,
141 i == 0 ? wxRB_GROUP : 0 );
142 radioSizer->Add( m_buttonMap[ errorCode ][i], 0, wxEXPAND );
143 }
144 }
145
146 radioPanel->SetSizer( radioSizer );
147 radioPanel->Layout();
148 gridSizer->Add( radioPanel, 0, wxALIGN_CENTER_VERTICAL );
149 }
150
151 scrollWinSizer->Add( gridSizer, 1, wxEXPAND | wxALL, 5 );
152 panelSizer->Add( scrollWin, 1, wxEXPAND, 0 );
153
154 Bind( wxEVT_IDLE,
155 [this]( wxIdleEvent& aEvent )
156 {
158 {
159 wxWindow* dialog = wxGetTopLevelParent( this );
160 wxWindow* topLevelFocus = wxGetTopLevelParent( wxWindow::FindFocus() );
161
162 if( topLevelFocus == dialog )
163 checkReload();
164 }
165 } );
166
167 SetSizer( panelSizer );
168 Layout();
169 panelSizer->Fit( this );
170}
171
172
174{
175 // MUST update lastLoaded before calling IsOK (or we'll end up re-entering through the idle
176 // event until we crash the stack).
178
179 if( IsOK( m_parent, _( "The violation severities have been changed outside the Setup dialog.\n"
180 "Do you wish to reload them?" ) ) )
181 {
183 }
184}
185
186
187void PANEL_SETUP_SEVERITIES::ImportSettingsFrom( std::map<int, SEVERITY>& aSettings )
188{
189 for( const RC_ITEM& item : m_items )
190 {
191 int errorCode = item.GetErrorCode();
192
193 wxRadioButton* button = nullptr;
194
195 switch( aSettings[ errorCode ] )
196 {
197 case RPT_SEVERITY_ERROR: button = m_buttonMap[ errorCode ][0]; break;
198 case RPT_SEVERITY_WARNING: button = m_buttonMap[ errorCode ][1]; break;
199 case RPT_SEVERITY_IGNORE: button = m_buttonMap[ errorCode ][2]; break;
200 default: break;
201 }
202
203 if( button ) // this entry must actually exist
204 button->SetValue( true );
205 }
206
208 {
209 int pinMapCode = m_pinMapSpecialCase->GetErrorCode();
210 int newSeverity = aSettings[ pinMapCode ];
211
212 m_buttonMap[ pinMapCode ][0]->SetValue( newSeverity != RPT_SEVERITY_IGNORE );
213 m_buttonMap[ pinMapCode ][2]->SetValue( newSeverity == RPT_SEVERITY_IGNORE );
214 }
215}
216
217
219{
221
222 for( const RC_ITEM& item : m_items )
223 {
224 int errorCode = item.GetErrorCode();
225
226 if( !m_buttonMap[ errorCode ][0] ) // this entry does not actually exist
227 continue;
228
230 continue;
231
232 switch( m_severities[ errorCode ] )
233 {
234 case RPT_SEVERITY_ERROR: m_buttonMap[ errorCode ][0]->SetValue( true ); break;
235 case RPT_SEVERITY_WARNING: m_buttonMap[ errorCode ][1]->SetValue( true ); break;
236 case RPT_SEVERITY_IGNORE: m_buttonMap[ errorCode ][2]->SetValue( true ); break;
237 default: break;
238 }
239 }
240
242 {
243 int pinMapCode = m_pinMapSpecialCase->GetErrorCode();
244 int severity = m_severities[pinMapCode];
245
246 m_buttonMap[ pinMapCode ][0]->SetValue( severity != RPT_SEVERITY_IGNORE );
247 m_buttonMap[ pinMapCode ][2]->SetValue( severity == RPT_SEVERITY_IGNORE );
248 }
249
250 return true;
251}
252
253
255{
256 for( const RC_ITEM& item : m_items )
257 {
258 int errorCode = item.GetErrorCode();
259
261 continue;
262
263 if( !m_buttonMap[ errorCode ][0] ) // this entry does not actually exist
264 continue;
265
267
268 if( m_buttonMap[ errorCode ][0]->GetValue() )
269 severity = RPT_SEVERITY_ERROR;
270 else if( m_buttonMap[ errorCode ][1]->GetValue() )
271 severity = RPT_SEVERITY_WARNING;
272 else if( m_buttonMap[ errorCode ][2]->GetValue() )
273 severity = RPT_SEVERITY_IGNORE;
274
275 m_severities[ errorCode ] = severity;
276 }
277
279 {
280 int pinMapCode = m_pinMapSpecialCase->GetErrorCode();
282
283 if( m_buttonMap[ pinMapCode ][0]->GetValue() )
284 severity = RPT_SEVERITY_ERROR;
285 else if( m_buttonMap[ pinMapCode ][2]->GetValue() )
286 severity = RPT_SEVERITY_IGNORE;
287
288 m_severities[ pinMapCode ] = severity;
289 }
290
291 return true;
292}
void ImportSettingsFrom(std::map< int, SEVERITY > &aSettings)
std::map< int, SEVERITY > & m_severities
RC_ITEM * m_pinMapSpecialCase
For ERC settings; a pointer to ERC_ITEM::pinTableConflict.
PANEL_SETUP_SEVERITIES(wxWindow *aParentWindow, std::vector< std::reference_wrapper< RC_ITEM > > aItems, std::map< int, SEVERITY > &aSeverities, RC_ITEM *aPinMapSpecialCase=nullptr)
Creates the severities setup panel.
std::map< int, wxRadioButton *[4]> m_buttonMap
std::map< int, SEVERITY > m_lastLoaded
std::vector< std::reference_wrapper< RC_ITEM > > m_items
A list of item templates (to get descriptive text and error codes from)
A holder for a rule check item, DRC in Pcbnew or ERC in Eeschema.
Definition: rc_item.h:79
int GetErrorCode() const
Definition: rc_item.h:153
wxString GetErrorText() const
Definition: rc_item.h:166
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:250
This file is part of the common library.
#define _(s)
STL namespace.
SEVERITY
@ RPT_SEVERITY_WARNING
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_UNDEFINED
@ RPT_SEVERITY_IGNORE
Functions to provide common constants and other functions to assist in making a consistent UI.