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 m_textCtrl->SetToolTip(
_(
"Complete rule text in the DRC rule language" ) );
46 sizer->Add(
m_textCtrl, 1, wxEXPAND | wxALL, 5 );
54 [
this]( wxStyledTextEvent& )
65 []( wxKeyEvent& aEvent )
70 [
this]( wxStyledTextEvent& aEvent )
94 text = wxS(
" (constraint clearance (min 0.2mm))" );
116 (void) aValidationMessage;
130 if( body.Trim().IsEmpty() )
131 return wxEmptyString;
133 wxString ruleName = aContext.
ruleName;
134 ruleName.Replace( wxS(
"\"" ), wxS(
"\\\"" ) );
137 rule << wxS(
"(rule \"" ) << ruleName << wxS(
"\"\n" );
139 if( !aContext.
comment.IsEmpty() )
141 wxArrayString lines = wxSplit( aContext.
comment,
'\n',
'\0' );
143 for(
const wxString& line : lines )
148 rule << wxS(
"\t# " ) << line << wxS(
"\n" );
152 rule << body << wxS(
")" );
167 if( aEvent.GetModifiers() == wxMOD_CONTROL && aEvent.GetKey() ==
' ' )
178 enum class EXPR_CONTEXT_T :
int
186 std::stack<wxString> sexprs;
188 EXPR_CONTEXT_T context = EXPR_CONTEXT_T::NONE;
190 for(
int i = startPos; i < currentPos; ++i )
198 else if( context == EXPR_CONTEXT_T::STRING )
201 context = EXPR_CONTEXT_T::NONE;
205 partial = wxEmptyString;
206 context = EXPR_CONTEXT_T::STRING;
210 if( context == EXPR_CONTEXT_T::SEXPR_OPEN && !partial.IsEmpty() )
213 sexprs.push( partial );
216 partial = wxEmptyString;
217 context = EXPR_CONTEXT_T::SEXPR_OPEN;
221 if( !sexprs.empty() )
224 context = EXPR_CONTEXT_T::NONE;
228 if( context == EXPR_CONTEXT_T::SEXPR_OPEN && !partial.IsEmpty() )
231 sexprs.push( partial );
232 context = EXPR_CONTEXT_T::SEXPR_TOKEN;
233 partial = wxEmptyString;
237 context = EXPR_CONTEXT_T::NONE;
247 if( context == EXPR_CONTEXT_T::SEXPR_OPEN )
251 tokens = wxT(
"condition|constraint|layer|severity" );
253 else if( sexprs.top() == wxT(
"rule" ) )
256 tokens = wxT(
"condition|constraint|layer|severity" );
258 else if( sexprs.top() == wxT(
"constraint" ) )
261 tokens = wxT(
"min|max|opt" );
264 else if( context == EXPR_CONTEXT_T::SEXPR_TOKEN )
266 if( !sexprs.empty() && sexprs.top() == wxT(
"constraint" ) )
269 tokens = wxT(
"annular_width|"
273 "courtyard_clearance|"
276 "diff_pair_uncoupled|"
284 "min_resolved_spokes|"
285 "physical_clearance|"
286 "physical_hole_clearance|"
291 "thermal_relief_gap|"
292 "thermal_spoke_width|"
294 "track_segment_length|"
300 else if( !sexprs.empty() && sexprs.top() == wxT(
"layer" ) )
303 tokens = wxT(
"inner|outer" );
305 else if( !sexprs.empty() && sexprs.top() == wxT(
"severity" ) )
308 tokens = wxT(
"error|warning|ignore|exclusion" );
312 if( !tokens.IsEmpty() )
328 ruleName.Replace( wxS(
"\"" ), wxS(
"\\\"" ) );
329 wxString rulesText = wxString::Format( wxS(
"(version 2)\n(rule \"%s\"\n%s)" ), ruleName, body );
331 if( body.Trim().IsEmpty() )
333#if wxCHECK_VERSION( 3, 3, 2 )
334 m_tipWindow = wxTipWindow::New(
this,
_(
"No rule text to check." ) );
336 m_tipWindow =
new wxTipWindow(
this,
_(
"No rule text to check." ) );
346 std::vector<std::shared_ptr<DRC_RULE>> dummyRules;
353 reporter.Report( wxString::Format(
_(
"ERROR at line %d, column %d: %s" ),
368 message =
_(
"Syntax check passed with warnings:\n" ) +
reporter.GetMessages();
372 message =
_(
"Syntax OK" );
375#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