32#include <wx/stc/stc.h>
36 wxWindow* aParent, std::shared_ptr<DRC_RE_CUSTOM_RULE_CONSTRAINT_DATA> aConstraintData ) :
42 wxBoxSizer* sizer =
new wxBoxSizer( wxVERTICAL );
44 m_textCtrl =
new wxStyledTextCtrl(
this, wxID_ANY );
45 sizer->Add(
m_textCtrl, 1, wxEXPAND | wxALL, 5 );
53 [
this]( wxStyledTextEvent& )
64 []( wxKeyEvent& aEvent )
69 [
this]( wxStyledTextEvent& aEvent )
93 text = wxS(
" (constraint clearance (min 0.2mm))" );
115 (void) aValidationMessage;
129 if( body.Trim().IsEmpty() )
130 return wxEmptyString;
132 wxString ruleName = aContext.
ruleName;
133 ruleName.Replace( wxS(
"\"" ), wxS(
"\\\"" ) );
136 rule << wxS(
"(rule \"" ) << ruleName << wxS(
"\"\n" );
138 if( !aContext.
comment.IsEmpty() )
140 wxArrayString lines = wxSplit( aContext.
comment,
'\n',
'\0' );
142 for(
const wxString& line : lines )
147 rule << wxS(
"\t# " ) << line << wxS(
"\n" );
151 rule << body << wxS(
")" );
166 if( aEvent.GetModifiers() == wxMOD_CONTROL && aEvent.GetKey() ==
' ' )
177 enum class EXPR_CONTEXT_T :
int
185 std::stack<wxString> sexprs;
187 EXPR_CONTEXT_T context = EXPR_CONTEXT_T::NONE;
189 for(
int i = startPos; i < currentPos; ++i )
197 else if( context == EXPR_CONTEXT_T::STRING )
200 context = EXPR_CONTEXT_T::NONE;
204 partial = wxEmptyString;
205 context = EXPR_CONTEXT_T::STRING;
209 if( context == EXPR_CONTEXT_T::SEXPR_OPEN && !partial.IsEmpty() )
212 sexprs.push( partial );
215 partial = wxEmptyString;
216 context = EXPR_CONTEXT_T::SEXPR_OPEN;
220 if( !sexprs.empty() )
223 context = EXPR_CONTEXT_T::NONE;
227 if( context == EXPR_CONTEXT_T::SEXPR_OPEN && !partial.IsEmpty() )
230 sexprs.push( partial );
231 context = EXPR_CONTEXT_T::SEXPR_TOKEN;
232 partial = wxEmptyString;
236 context = EXPR_CONTEXT_T::NONE;
246 if( context == EXPR_CONTEXT_T::SEXPR_OPEN )
250 tokens = wxT(
"condition|constraint|layer|severity" );
252 else if( sexprs.top() == wxT(
"rule" ) )
255 tokens = wxT(
"condition|constraint|layer|severity" );
257 else if( sexprs.top() == wxT(
"constraint" ) )
260 tokens = wxT(
"min|max|opt" );
263 else if( context == EXPR_CONTEXT_T::SEXPR_TOKEN )
265 if( !sexprs.empty() && sexprs.top() == wxT(
"constraint" ) )
268 tokens = wxT(
"annular_width|"
272 "courtyard_clearance|"
275 "diff_pair_uncoupled|"
283 "min_resolved_spokes|"
284 "physical_clearance|"
285 "physical_hole_clearance|"
290 "thermal_relief_gap|"
291 "thermal_spoke_width|"
293 "track_segment_length|"
299 else if( !sexprs.empty() && sexprs.top() == wxT(
"layer" ) )
302 tokens = wxT(
"inner|outer" );
304 else if( !sexprs.empty() && sexprs.top() == wxT(
"severity" ) )
307 tokens = wxT(
"error|warning|ignore|exclusion" );
311 if( !tokens.IsEmpty() )
327 ruleName.Replace( wxS(
"\"" ), wxS(
"\\\"" ) );
328 wxString rulesText = wxString::Format( wxS(
"(version 2)\n(rule \"%s\"\n%s)" ), ruleName, body );
330 if( body.Trim().IsEmpty() )
332#if wxCHECK_VERSION( 3, 3, 2 )
333 m_tipWindow = wxTipWindow::New(
this,
_(
"No rule text to check." ) );
335 m_tipWindow =
new wxTipWindow(
this,
_(
"No rule text to check." ) );
345 std::vector<std::shared_ptr<DRC_RULE>> dummyRules;
352 reporter.Report( wxString::Format(
_(
"ERROR at line %d, column %d: %s" ),
367 message =
_(
"Syntax check passed with warnings:\n" ) +
reporter.GetMessages();
371 message =
_(
"Syntax OK" );
374#if wxCHECK_VERSION( 3, 3, 2 )
bool TransferDataFromWindow() override
wxStyledTextCtrl * m_textCtrl
bool TransferDataToWindow() override
wxTipWindow * m_tipWindow
~DRC_RE_CUSTOM_RULE_PANEL() override
void UpdateRuleName(const wxString &aName)
void onScintillaCharAdded(wxStyledTextEvent &aEvent)
bool ValidateInputs(int *aErrorCount, wxString *aValidationMessage) override
wxString GenerateRule(const RULE_GENERATION_CONTEXT &aContext) override
std::shared_ptr< DRC_RE_CUSTOM_RULE_CONSTRAINT_DATA > m_constraintData
std::unique_ptr< SCINTILLA_TRICKS > m_scintillaTricks
wxButton * m_checkSyntaxBtn
DRC_RE_CUSTOM_RULE_PANEL(wxWindow *aParent, std::shared_ptr< DRC_RE_CUSTOM_RULE_CONSTRAINT_DATA > aConstraintData)
void onCheckSyntax(wxCommandEvent &aEvent)
void Parse(std::vector< std::shared_ptr< DRC_RULE > > &aRules, REPORTER *aReporter)
void SetModified()
Marks the dialog as modified, indicating unsaved changes.
static RULE_EDITOR_DIALOG_BASE * GetDialog(wxWindow *aWindow)
Static method to retrieve the rule editor dialog instance associated with a given window.
A wrapper for reporting to a wxString object.
A filename or source description, a problem input line, a line number, a byte offset,...
int lineNumber
at which line number, 1 based index.
const wxString ParseProblem()
int byteIndex
at which byte offset within the line, 1 based index
IbisParser parser & reporter