KiCad PCB EDA Suite
Loading...
Searching...
No Matches
panel_setup_rules.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-2024 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 <bitmaps.h>
25#include <confirm.h>
28#include <pcb_edit_frame.h>
29#include <pcbexpr_evaluator.h>
30#include <board.h>
32#include <project.h>
33#include <string_utils.h>
34#include <tool/tool_manager.h>
35#include <panel_setup_rules.h>
38#include <scintilla_tricks.h>
39#include <drc/drc_rule_parser.h>
40#include <tools/drc_tool.h>
41#include <pgm_base.h>
43
44PANEL_SETUP_RULES::PANEL_SETUP_RULES( wxWindow* aParentWindow, PCB_EDIT_FRAME* aFrame ) :
45 PANEL_SETUP_RULES_BASE( aParentWindow ),
46 m_frame( aFrame ),
47 m_scintillaTricks( nullptr ),
48 m_helpWindow( nullptr )
49{
50 m_scintillaTricks = new SCINTILLA_TRICKS( m_textEditor, wxT( "()" ), false,
51 // onAcceptFn
52 [this]( wxKeyEvent& aEvent )
53 {
54 wxPostEvent( PAGED_DIALOG::GetDialog( this ),
55 wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
56 },
57 // onCharFn
58 [this]( wxStyledTextEvent& aEvent )
59 {
60 onScintillaCharAdded( aEvent );
61 } );
62
63 m_textEditor->AutoCompSetSeparator( '|' );
64
65 m_netClassRegex.Compile( "^NetClass\\s*[!=]=\\s*$", wxRE_ADVANCED );
66 m_netNameRegex.Compile( "^NetName\\s*[!=]=\\s*$", wxRE_ADVANCED );
67 m_typeRegex.Compile( "^Type\\s*[!=]=\\s*$", wxRE_ADVANCED );
68 m_viaTypeRegex.Compile( "^Via_Type\\s*[!=]=\\s*$", wxRE_ADVANCED );
69 m_padTypeRegex.Compile( "^Pad_Type\\s*[!=]=\\s*$", wxRE_ADVANCED );
70 m_pinTypeRegex.Compile( "^Pin_Type\\s*[!=]=\\s*$", wxRE_ADVANCED );
71 m_fabPropRegex.Compile( "^Fabrication_Property\\s*[!=]=\\s*$", wxRE_ADVANCED );
72 m_shapeRegex.Compile( "^Shape\\s*[!=]=\\s*$", wxRE_ADVANCED );
73 m_padShapeRegex.Compile( "^Pad_Shape\\s*[!=]=\\s*$", wxRE_ADVANCED );
74 m_padConnectionsRegex.Compile( "^Pad_Connections\\s*[!=]=\\s*$", wxRE_ADVANCED );
75 m_zoneConnStyleRegex.Compile( "^Zone_Connection_Style\\s*[!=]=\\s*$", wxRE_ADVANCED );
76 m_lineStyleRegex.Compile( "^Line_Style\\s*[!=]=\\s*$", wxRE_ADVANCED );
77 m_hJustRegex.Compile( "^Horizontal_Justification\\s*[!=]=\\s*$", wxRE_ADVANCED );
78 m_vJustRegex.Compile( "^Vertical_Justification\\s*[!=]=\\s*$", wxRE_ADVANCED );
79
80 m_compileButton->SetBitmap( KiBitmapBundle( BITMAPS::drc ) );
81
82 m_textEditor->SetZoom( Pgm().GetCommonSettings()->m_Appearance.text_editor_zoom );
83
84 m_textEditor->UsePopUp( 0 );
85 m_textEditor->Bind( wxEVT_CHAR_HOOK, &PANEL_SETUP_RULES::onCharHook, this );
86}
87
88
90{
91 m_textEditor->Unbind( wxEVT_CHAR_HOOK, &PANEL_SETUP_RULES::onCharHook, this );
92 Pgm().GetCommonSettings()->m_Appearance.text_editor_zoom = m_textEditor->GetZoom();
93
94 delete m_scintillaTricks;
95
96 if( m_helpWindow )
97 m_helpWindow->Destroy();
98};
99
100
101void PANEL_SETUP_RULES::onCharHook( wxKeyEvent& aEvent )
102{
103 if( aEvent.GetKeyCode() == WXK_ESCAPE && !m_textEditor->AutoCompActive() )
104 {
105 if( m_originalText != m_textEditor->GetText() )
106 {
107 if( IsOK( wxGetTopLevelParent( this ), _( "Cancel Changes?" ) ) )
108 {
109 m_textEditor->SetText( m_originalText );
110 m_textEditor->SelectAll();
111 }
112
113 return;
114 }
115 }
116
117 aEvent.Skip();
118}
119
120
121void PANEL_SETUP_RULES::OnContextMenu(wxMouseEvent &event)
122{
123 wxMenu menu;
124
125 menu.Append( wxID_UNDO, _( "Undo" ) );
126 menu.Append( wxID_REDO, _( "Redo" ) );
127
128 menu.AppendSeparator();
129
130 menu.Append( 1, _( "Cut" ) ); // Don't use wxID_CUT, wxID_COPY, etc. On Mac (at least),
131 menu.Append( 2, _( "Copy" ) ); // wxWidgets never delivers them to us.
132 menu.Append( 3, _( "Paste" ) );
133 menu.Append( 4, _( "Delete" ) );
134
135 menu.AppendSeparator();
136
137 menu.Append( 5, _( "Select All" ) );
138
139 menu.AppendSeparator();
140
141 menu.Append( wxID_ZOOM_IN, _( "Zoom In" ) );
142 menu.Append( wxID_ZOOM_OUT, _( "Zoom Out" ) );
143
144
145 switch( GetPopupMenuSelectionFromUser( menu ) )
146 {
147 case wxID_UNDO:
148 m_textEditor->Undo();
149 break;
150 case wxID_REDO:
151 m_textEditor->Redo();
152 break;
153
154 case 1:
155 m_textEditor->Cut();
156 break;
157 case 2:
158 m_textEditor->Copy();
159 break;
160 case 3:
161 m_textEditor->Paste();
162 break;
163 case 4:
164 {
165 long from, to;
166 m_textEditor->GetSelection( &from, &to );
167
168 if( to > from )
169 m_textEditor->DeleteRange( from, to );
170
171 break;
172 }
173
174 case 5:
175 m_textEditor->SelectAll();
176 break;
177
178 case wxID_ZOOM_IN:
179 m_textEditor->ZoomIn();
180 break;
181 case wxID_ZOOM_OUT:
182 m_textEditor->ZoomOut();
183 break;
184 }
185}
186
187
188void PANEL_SETUP_RULES::onScintillaCharAdded( wxStyledTextEvent &aEvent )
189{
190 if( aEvent.GetModifiers() == wxMOD_CONTROL && aEvent.GetKey() == ' ' )
191 {
192 // This is just a short-cut for do-auto-complete
193 }
194 else
195 {
197 }
198
199 m_textEditor->SearchAnchor();
200
201 wxString rules = m_textEditor->GetText();
202 int currentPos = m_textEditor->GetCurrentPos();
203 int startPos = 0;
204
205 for( int line = m_textEditor->LineFromPosition( currentPos ); line > 0; line-- )
206 {
207 int lineStart = m_textEditor->PositionFromLine( line );
208 wxString beginning = m_textEditor->GetTextRange( lineStart, lineStart + 10 );
209
210 if( beginning.StartsWith( wxT( "(rule " ) ) )
211 {
212 startPos = lineStart;
213 break;
214 }
215 }
216
217 enum
218 {
219 NONE,
220 STRING,
221 SEXPR_OPEN,
222 SEXPR_TOKEN,
223 SEXPR_STRING,
224 STRUCT_REF
225 };
226
227 auto isDisallowToken =
228 []( const wxString& token ) -> bool
229 {
230 return token == wxT( "buried_via" )
231 || token == wxT( "graphic" )
232 || token == wxT( "hole" )
233 || token == wxT( "micro_via" )
234 || token == wxT( "pad" )
235 || token == wxT( "text" )
236 || token == wxT( "track" )
237 || token == wxT( "via" )
238 || token == wxT( "zone" );
239 };
240
241 std::stack<wxString> sexprs;
242 wxString partial;
243 wxString last;
244 int context = NONE;
245 int expr_context = NONE;
246
247 for( int i = startPos; i < currentPos; ++i )
248 {
249 wxChar c = m_textEditor->GetCharAt( i );
250
251 if( c == '\\' )
252 {
253 i++; // skip escaped char
254 }
255 else if( context == STRING )
256 {
257 if( c == '"' )
258 {
259 context = NONE;
260 }
261 else
262 {
263 if( expr_context == STRING )
264 {
265 if( c == '\'' )
266 expr_context = NONE;
267 else
268 partial += c;
269 }
270 else if( c == '\'' )
271 {
272 last = partial;
273 partial = wxEmptyString;
274 expr_context = STRING;
275 }
276 else if( c == '.' )
277 {
278 partial = wxEmptyString;
279 expr_context = STRUCT_REF;
280 }
281 else
282 {
283 partial += c;
284 }
285 }
286 }
287 else if( c == '"' )
288 {
289 last = partial;
290 partial = wxEmptyString;
291 context = STRING;
292 }
293 else if( c == '(' )
294 {
295 if( context == SEXPR_OPEN && !partial.IsEmpty() )
296 {
297 m_textEditor->AutoCompCancel();
298 sexprs.push( partial );
299 }
300
301 partial = wxEmptyString;
302 context = SEXPR_OPEN;
303 }
304 else if( c == ')' )
305 {
306 while( !sexprs.empty() && ( sexprs.top() == wxT( "assertion" )
307 || sexprs.top() == wxT( "disallow" )
308 || isDisallowToken( sexprs.top() )
309 || sexprs.top() == wxT( "min_resolved_spokes" )
310 || sexprs.top() == wxT( "zone_connection" ) ) )
311 {
312 sexprs.pop();
313 }
314
315 if( !sexprs.empty() )
316 sexprs.pop();
317
318 context = NONE;
319 }
320 else if( c == ' ' )
321 {
322 if( context == SEXPR_OPEN && !partial.IsEmpty() )
323 {
324 m_textEditor->AutoCompCancel();
325 sexprs.push( partial );
326
327 if( partial == wxT( "constraint" )
328 || partial == wxT( "layer" )
329 || partial == wxT( "severity" ) )
330 {
331 context = SEXPR_TOKEN;
332 }
333 else if( partial == wxT( "rule" )
334 || partial == wxT( "condition" ) )
335 {
336 context = SEXPR_STRING;
337 }
338 else
339 {
340 context = NONE;
341 }
342
343 partial = wxEmptyString;
344 continue;
345 }
346 else if( partial == wxT( "disallow" )
347 || isDisallowToken( partial )
348 || partial == wxT( "min_resolved_spokes" )
349 || partial == wxT( "zone_connection" ) )
350 {
351 m_textEditor->AutoCompCancel();
352 sexprs.push( partial );
353
354 partial = wxEmptyString;
355 context = SEXPR_TOKEN;
356 continue;
357 }
358 else if( partial == wxT( "assertion" ) )
359 {
360 m_textEditor->AutoCompCancel();
361 sexprs.push( partial );
362
363 partial = wxEmptyString;
364 context = SEXPR_STRING;
365 continue;
366 }
367
368 context = NONE;
369 }
370 else
371 {
372 partial += c;
373 }
374 }
375
376 wxString tokens;
377
378 if( context == SEXPR_OPEN )
379 {
380 if( sexprs.empty() )
381 {
382 tokens = wxT( "rule|"
383 "version" );
384 }
385 else if( sexprs.top() == wxT( "rule" ) )
386 {
387 tokens = wxT( "condition|"
388 "constraint|"
389 "layer|"
390 "severity" );
391 }
392 else if( sexprs.top() == wxT( "constraint" ) )
393 {
394 tokens = wxT( "max|min|opt" );
395 }
396 }
397 else if( context == SEXPR_TOKEN )
398 {
399 if( sexprs.empty() )
400 {
401 /* badly formed grammar */
402 }
403 else if( sexprs.top() == wxT( "constraint" ) )
404 {
405 tokens = wxT( "annular_width|"
406 "assertion|"
407 "clearance|"
408 "connection_width|"
409 "courtyard_clearance|"
410 "diff_pair_gap|"
411 "diff_pair_uncoupled|"
412 "disallow|"
413 "edge_clearance|"
414 "length|"
415 "hole_clearance|"
416 "hole_size|"
417 "hole_to_hole|"
418 "min_resolved_spokes|"
419 "physical_clearance|"
420 "physical_hole_clearance|"
421 "silk_clearance|"
422 "skew|"
423 "text_height|"
424 "text_thickness|"
425 "thermal_relief_gap|"
426 "thermal_spoke_width|"
427 "track_width|"
428 "via_count|"
429 "via_diameter|"
430 "zone_connection" );
431 }
432 else if( sexprs.top() == wxT( "disallow" ) || isDisallowToken( sexprs.top() ) )
433 {
434 tokens = wxT( "buried_via|"
435 "footprint|"
436 "graphic|"
437 "hole|"
438 "micro_via|"
439 "pad|"
440 "text|"
441 "track|"
442 "via|"
443 "zone" );
444 }
445 else if( sexprs.top() == wxT( "zone_connection" ) )
446 {
447 tokens = wxT( "none|solid|thermal_reliefs" );
448 }
449 else if( sexprs.top() == wxT( "min_resolved_spokes" ) )
450 {
451 tokens = wxT( "0|1|2|3|4" );
452 }
453 else if( sexprs.top() == wxT( "layer" ) )
454 {
455 tokens = wxT( "inner|outer|\"x\"" );
456 }
457 else if( sexprs.top() == wxT( "severity" ) )
458 {
459 tokens = wxT( "warning|error|ignore|exclusion" );
460 }
461 }
462 else if( context == SEXPR_STRING && !sexprs.empty()
463 && ( sexprs.top() == wxT( "condition" ) || sexprs.top() == wxT( "assertion" ) ) )
464 {
465 m_textEditor->AddText( wxT( "\"" ) );
466 }
467 else if( context == STRING && !sexprs.empty()
468 && ( sexprs.top() == wxT( "condition" ) || sexprs.top() == wxT( "assertion" ) ) )
469 {
470 if( expr_context == STRUCT_REF )
471 {
473 std::set<wxString> propNames;
474
475 for( const PROPERTY_MANAGER::CLASS_INFO& cls : propMgr.GetAllClasses() )
476 {
477 const PROPERTY_LIST& props = propMgr.GetProperties( cls.type );
478
479 for( PROPERTY_BASE* prop : props )
480 {
481 // TODO: It would be nice to replace IsHiddenFromRulesEditor with a nickname
482 // system, so that two different properies don't need to be created. This is
483 // a bigger change than I want to make right now, though.
484 if( prop->IsHiddenFromRulesEditor() )
485 continue;
486
487 wxString ref( prop->Name() );
488 ref.Replace( wxT( " " ), wxT( "_" ) );
489 propNames.insert( ref );
490 }
491 }
492
493 for( const wxString& propName : propNames )
494 tokens += wxT( "|" ) + propName;
495
497
498 for( const wxString& funcSig : functions.GetSignatures() )
499 {
500 if( !funcSig.Contains( "DEPRECATED" ) )
501 tokens += wxT( "|" ) + funcSig;
502 }
503 }
504 else if( expr_context == STRING )
505 {
506 if( m_netClassRegex.Matches( last ) )
507 {
509 std::shared_ptr<NET_SETTINGS>& netSettings = bds.m_NetSettings;
510
511 for( const auto& [ name, netclass ] : netSettings->m_NetClasses )
512 tokens += wxT( "|" ) + name;
513 }
514 else if( m_netNameRegex.Matches( last ) )
515 {
516 BOARD* board = m_frame->GetBoard();
517
518 for( const wxString& netnameCandidate : board->GetNetClassAssignmentCandidates() )
519 tokens += wxT( "|" ) + netnameCandidate;
520 }
521 else if( m_typeRegex.Matches( last ) )
522 {
523 tokens = wxT( "Bitmap|"
524 "Dimension|"
525 "Footprint|"
526 "Graphic|"
527 "Group|"
528 "Leader|"
529 "Pad|"
530 "Target|"
531 "Text|"
532 "Text Box|"
533 "Track|"
534 "Via|"
535 "Zone" );
536 }
537 else if( m_viaTypeRegex.Matches( last ) )
538 {
539 tokens = wxT( "Through|"
540 "Blind/buried|"
541 "Micro" );
542 }
543 else if( m_padTypeRegex.Matches( last ) )
544 {
545 tokens = wxT( "Through-hole|"
546 "SMD|"
547 "Edge connector|"
548 "NPTH, mechanical" );
549 }
550 else if( m_pinTypeRegex.Matches( last ) )
551 {
552 tokens = wxT( "Input|"
553 "Output|"
554 "Bidirectional|"
555 "Tri-state|"
556 "Passive|"
557 "Free|"
558 "Unspecified|"
559 "Power input|"
560 "Power output|"
561 "Open collector|"
562 "Open emitter|"
563 "Unconnected" );
564 }
565 else if( m_fabPropRegex.Matches( last ) )
566 {
567 tokens = wxT( "None|"
568 "BGA pad|"
569 "Fiducial, global to board|"
570 "Fiducial, local to footprint|"
571 "Test point pad|"
572 "Heatsink pad|"
573 "Castellated pad" );
574 }
575 else if( m_shapeRegex.Matches( last ) )
576 {
577 tokens = wxT( "Segment|"
578 "Rectangle|"
579 "Arc|"
580 "Circle|"
581 "Polygon|"
582 "Bezier" );
583 }
584 else if( m_padShapeRegex.Matches( last ) )
585 {
586 tokens = wxT( "Circle|"
587 "Rectangle|"
588 "Oval|"
589 "Trapezoid|"
590 "Rounded rectangle|"
591 "Chamfered rectangle|"
592 "Custom" );
593 }
594 else if( m_padConnectionsRegex.Matches( last ) )
595 {
596 tokens = wxT( "Inherited|"
597 "None|"
598 "Solid|"
599 "Thermal reliefs|"
600 "Thermal reliefs for PTH" );
601 }
602 else if( m_zoneConnStyleRegex.Matches( last ) )
603 {
604 tokens = wxT( "Inherited|"
605 "None|"
606 "Solid|"
607 "Thermal reliefs" );
608 }
609 else if( m_lineStyleRegex.Matches( last ) )
610 {
611 tokens = wxT( "Default|"
612 "Solid|"
613 "Dashed|"
614 "Dotted|"
615 "Dash-Dot|"
616 "Dash-Dot-Dot" );
617 }
618 else if( m_hJustRegex.Matches( last ) )
619 {
620 tokens = wxT( "Left|"
621 "Center|"
622 "Right" );
623 }
624 else if( m_vJustRegex.Matches( last ) )
625 {
626 tokens = wxT( "Top|"
627 "Center|"
628 "Bottom" );
629 }
630 }
631 }
632
633 if( !tokens.IsEmpty() )
634 m_scintillaTricks->DoAutocomplete( partial, wxSplit( tokens, '|' ) );
635}
636
637
638void PANEL_SETUP_RULES::OnCompile( wxCommandEvent& event )
639{
641
642 try
643 {
644 std::vector<std::shared_ptr<DRC_RULE>> dummyRules;
645
646 DRC_RULES_PARSER parser( m_textEditor->GetText(), _( "DRC rules" ) );
647
648 parser.Parse( dummyRules, m_errorsReport );
649 }
650 catch( PARSE_ERROR& pe )
651 {
652 wxString msg = wxString::Format( wxT( "%s <a href='%d:%d'>%s</a>%s" ),
653 _( "ERROR:" ),
654 pe.lineNumber,
655 pe.byteIndex,
656 pe.ParseProblem(),
657 wxEmptyString );
658
660 }
661
663}
664
665
666void PANEL_SETUP_RULES::OnErrorLinkClicked( wxHtmlLinkEvent& event )
667{
668 wxString link = event.GetLinkInfo().GetHref();
669 wxArrayString parts;
670 long line = 0, offset = 0;
671
672 wxStringSplit( link, parts, ':' );
673
674 if( parts.size() > 1 )
675 {
676 parts[0].ToLong( &line );
677 parts[1].ToLong( &offset );
678 }
679
680 int pos = m_textEditor->PositionFromLine( line - 1 ) + ( offset - 1 );
681
682 m_textEditor->GotoPos( pos );
683
684 m_textEditor->SetFocus();
685}
686
687
689{
690 wxFileName rulesFile( m_frame->GetDesignRulesPath() );
691
692 if( rulesFile.FileExists() )
693 {
694 wxTextFile file( rulesFile.GetFullPath() );
695
696 if( file.Open() )
697 {
698 for ( wxString str = file.GetFirstLine(); !file.Eof(); str = file.GetNextLine() )
699 {
701 m_textEditor->AddText( str << '\n' );
702 }
703
704 m_textEditor->EmptyUndoBuffer();
705
706 wxCommandEvent dummy;
707 OnCompile( dummy );
708 }
709 }
710
711 m_originalText = m_textEditor->GetText();
712
713 if( m_frame->Prj().IsNullProject() )
714 {
715 m_textEditor->ClearAll();
716 m_textEditor->AddText( _( "Design rules cannot be added without a project" ) );
717 m_textEditor->Disable();
718 }
719
720 return true;
721}
722
723
725{
726 if( m_originalText == m_textEditor->GetText() )
727 return true;
728
729 if( m_frame->Prj().IsNullProject() )
730 return true;
731
732 wxString rulesFilepath = m_frame->GetDesignRulesPath();
733
734 try
735 {
736 if( m_textEditor->SaveFile( rulesFilepath ) )
737 {
738 m_frame->GetBoard()->GetDesignSettings().m_DRCEngine->InitEngine( rulesFilepath );
739 return true;
740 }
741 }
742 catch( PARSE_ERROR& )
743 {
744 // Don't lock them in to the Setup dialog if they have bad rules. They've already
745 // saved them so we can allow an exit.
746 return true;
747 }
748
749 return false;
750}
751
752
753void PANEL_SETUP_RULES::OnSyntaxHelp( wxHyperlinkEvent& aEvent )
754{
755 if( m_helpWindow )
756 {
758 return;
759 }
760
761 wxString msg =
763 ;
764
765#ifdef __WXMAC__
766 msg.Replace( wxT( "Ctrl+" ), wxT( "Cmd+" ) );
767#endif
768
769 m_helpWindow = new HTML_MESSAGE_BOX( nullptr, _( "Syntax Help" ) );
770 m_helpWindow->SetDialogSizeInDU( 420, 320 );
771
772 wxString html_txt;
773 ConvertMarkdown2Html( wxGetTranslation( msg ), html_txt );
774
775 html_txt.Replace( wxS( "<td" ), wxS( "<td valign=top" ) );
776 m_helpWindow->AddHTML_Text( html_txt );
777
779}
780
781
783{
784 if( !m_frame->Prj().IsNullProject() )
785 {
786 wxFileName relFile = aBoard->GetFileName();
787 relFile.SetExt( FILEEXT::DesignRulesFileExtension );
788
789 wxFileName absFile( aBoard->GetProject()->AbsolutePath( relFile.GetFullName() ) );
790
791 if( absFile.FileExists() )
792 {
793 wxTextFile file( absFile.GetFullPath() );
794
795 if( file.Open() )
796 {
797 for ( wxString str = file.GetFirstLine(); !file.Eof(); str = file.GetNextLine() )
798 {
800 m_textEditor->ClearAll();
801 m_textEditor->AddText( str << '\n' );
802 }
803
804 m_textEditor->EmptyUndoBuffer();
805
806 wxCommandEvent dummy;
807 OnCompile( dummy );
808 }
809 }
810 }
811}
const char * name
Definition: DXF_plotter.cpp:57
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap)
Definition: bitmap.cpp:110
Container for design settings for a BOARD object.
std::shared_ptr< NET_SETTINGS > m_NetSettings
std::shared_ptr< DRC_ENGINE > m_DRCEngine
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:276
std::set< wxString > GetNetClassAssignmentCandidates() const
Return the set of netname candidates for netclass assignment.
Definition: board.cpp:1790
const wxString & GetFileName() const
Definition: board.h:313
PROJECT * GetProject() const
Definition: board.h:457
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:806
void Parse(std::vector< std::shared_ptr< DRC_RULE > > &aRules, REPORTER *aReporter)
void SetDialogSizeInDU(int aWidth, int aHeight)
Set the dialog size, using a "logical" value.
void AddHTML_Text(const wxString &message)
Add HTML text (without any change) to message list.
void ShowModeless()
Show a modeless version of the dialog (without an OK button).
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
void SetModified()
Definition: paged_dialog.h:43
static PAGED_DIALOG * GetDialog(wxWindow *aWindow)
Class PANEL_SETUP_RULES_BASE.
STD_BITMAP_BUTTON * m_compileButton
wxStyledTextCtrl * m_textEditor
WX_HTML_REPORT_BOX * m_errorsReport
bool TransferDataToWindow() override
void OnErrorLinkClicked(wxHtmlLinkEvent &event) override
void onScintillaCharAdded(wxStyledTextEvent &aEvent)
void ImportSettingsFrom(BOARD *aBoard)
PCB_EDIT_FRAME * m_frame
void OnContextMenu(wxMouseEvent &event) override
~PANEL_SETUP_RULES() override
HTML_MESSAGE_BOX * m_helpWindow
void OnCompile(wxCommandEvent &event) override
bool TransferDataFromWindow() override
void OnSyntaxHelp(wxHyperlinkEvent &aEvent) override
PANEL_SETUP_RULES(wxWindow *aParentWindow, PCB_EDIT_FRAME *aFrame)
void onCharHook(wxKeyEvent &aEvent)
SCINTILLA_TRICKS * m_scintillaTricks
const wxArrayString GetSignatures() const
static PCBEXPR_BUILTIN_FUNCTIONS & Instance()
wxString GetDesignRulesPath()
Return the absolute path to the design rules file for the currently-loaded board.
BOARD * GetBoard() const
The main frame for Pcbnew.
virtual const wxString AbsolutePath(const wxString &aFileName) const
Fix up aFileName if it is relative to the project's directory to be an absolute path and filename.
Definition: project.cpp:320
virtual bool IsNullProject() const
Check if this project is a null project (i.e.
Definition: project.cpp:153
Provide class metadata.Helper macro to map type hashes to names.
Definition: property_mgr.h:85
CLASSES_INFO GetAllClasses()
const PROPERTY_LIST & GetProperties(TYPE_ID aType) const
Return all properties for a specific type.
static PROPERTY_MANAGER & Instance()
Definition: property_mgr.h:87
Add cut/copy/paste, dark theme, autocomplete and brace highlighting to a wxStyleTextCtrl instance.
void DoAutocomplete(const wxString &aPartial, const wxArrayString &aTokens)
void SetBitmap(const wxBitmapBundle &aBmp)
void Clear()
Delete the stored messages.
REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
void Flush()
Build the HTML messages page.
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:360
This file is part of the common library.
#define _(s)
static const std::string DesignRulesFileExtension
@ NONE
Definition: kibis.h:54
see class PGM_BASE
std::vector< PROPERTY_BASE * > PROPERTY_LIST
Definition: property_mgr.h:49
@ RPT_SEVERITY_ERROR
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:119
std::vector< FAB_LAYER_COLOR > dummy
bool ConvertSmartQuotesAndDashes(wxString *aString)
Convert curly quotes and em/en dashes to straight quotes and dashes.
void wxStringSplit(const wxString &aText, wxArrayString &aStrings, wxChar aSplitter)
Split aString to a string list separated at aSplitter.
void ConvertMarkdown2Html(const wxString &aMarkdownInput, wxString &aHtmlOutput)
A filename or source description, a problem input line, a line number, a byte offset,...
Definition: ki_exception.h:120
int lineNumber
at which line number, 1 based index.
Definition: ki_exception.h:121
const wxString ParseProblem()
Definition: ki_exception.h:151
int byteIndex
at which byte offset within the line, 1 based index
Definition: ki_exception.h:122
Definition of file extensions used in Kicad.