36#include <wx/stc/stc.h>
40 wxWindow* aParent, std::shared_ptr<DRC_RE_CUSTOM_RULE_CONSTRAINT_DATA> aConstraintData ) :
46 wxBoxSizer* sizer =
new wxBoxSizer( wxVERTICAL );
48 m_textCtrl =
new wxStyledTextCtrl(
this, wxID_ANY );
49 sizer->Add(
m_textCtrl, 1, wxEXPAND | wxALL, 5 );
57 [
this]( wxStyledTextEvent& )
68 []( wxKeyEvent& aEvent )
73 [
this]( wxStyledTextEvent& aEvent )
97 text = wxS(
" (constraint clearance (min 0.2mm))" );
119 (void) aValidationMessage;
133 if( body.Trim().IsEmpty() )
134 return wxEmptyString;
136 wxString ruleName = aContext.
ruleName;
137 ruleName.Replace( wxS(
"\"" ), wxS(
"\\\"" ) );
140 rule << wxS(
"(rule \"" ) << ruleName << wxS(
"\"\n" );
142 if( !aContext.
comment.IsEmpty() )
144 wxArrayString lines = wxSplit( aContext.
comment,
'\n',
'\0' );
146 for(
const wxString& line : lines )
151 rule << wxS(
"\t# " ) << line << wxS(
"\n" );
155 rule << body << wxS(
")" );
170 if( aEvent.GetModifiers() == wxMOD_CONTROL && aEvent.GetKey() ==
' ' )
181 enum class EXPR_CONTEXT_T :
int
189 std::stack<wxString> sexprs;
191 EXPR_CONTEXT_T context = EXPR_CONTEXT_T::NONE;
193 for(
int i = startPos; i < currentPos; ++i )
201 else if( context == EXPR_CONTEXT_T::STRING )
204 context = EXPR_CONTEXT_T::NONE;
208 partial = wxEmptyString;
209 context = EXPR_CONTEXT_T::STRING;
213 if( context == EXPR_CONTEXT_T::SEXPR_OPEN && !partial.IsEmpty() )
216 sexprs.push( partial );
219 partial = wxEmptyString;
220 context = EXPR_CONTEXT_T::SEXPR_OPEN;
224 if( !sexprs.empty() )
227 context = EXPR_CONTEXT_T::NONE;
231 if( context == EXPR_CONTEXT_T::SEXPR_OPEN && !partial.IsEmpty() )
234 sexprs.push( partial );
235 context = EXPR_CONTEXT_T::SEXPR_TOKEN;
236 partial = wxEmptyString;
240 context = EXPR_CONTEXT_T::NONE;
250 if( context == EXPR_CONTEXT_T::SEXPR_OPEN )
254 tokens = wxT(
"condition|constraint|layer|severity" );
256 else if( sexprs.top() == wxT(
"rule" ) )
259 tokens = wxT(
"condition|constraint|layer|severity" );
261 else if( sexprs.top() == wxT(
"constraint" ) )
264 tokens = wxT(
"min|max|opt" );
267 else if( context == EXPR_CONTEXT_T::SEXPR_TOKEN )
269 if( !sexprs.empty() && sexprs.top() == wxT(
"constraint" ) )
272 tokens = wxT(
"annular_width|"
276 "courtyard_clearance|"
279 "diff_pair_uncoupled|"
287 "min_resolved_spokes|"
288 "physical_clearance|"
289 "physical_hole_clearance|"
294 "thermal_relief_gap|"
295 "thermal_spoke_width|"
297 "track_segment_length|"
303 else if( !sexprs.empty() && sexprs.top() == wxT(
"layer" ) )
306 tokens = wxT(
"inner|outer" );
308 else if( !sexprs.empty() && sexprs.top() == wxT(
"severity" ) )
311 tokens = wxT(
"error|warning|ignore|exclusion" );
315 if( !tokens.IsEmpty() )
331 ruleName.Replace( wxS(
"\"" ), wxS(
"\\\"" ) );
332 wxString rulesText = wxString::Format( wxS(
"(version 1)\n(rule \"%s\"\n%s)" ), ruleName, body );
334 if( body.Trim().IsEmpty() )
336#if wxCHECK_VERSION( 3, 3, 2 )
337 m_tipWindow = wxTipWindow::New(
this,
_(
"No rule text to check." ) );
339 m_tipWindow =
new wxTipWindow(
this,
_(
"No rule text to check." ) );
349 std::vector<std::shared_ptr<DRC_RULE>> dummyRules;
356 reporter.Report( wxString::Format(
_(
"ERROR at line %d, column %d: %s" ),
371 message =
_(
"Syntax check passed with warnings:\n" ) +
reporter.GetMessages();
375 message =
_(
"Syntax OK" );
378#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