KiCad PCB EDA Suite
Loading...
Searching...
No Matches
drc_re_content_panel_base.h
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) 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#ifndef DRC_RE_CLASSES_H_
25#define DRC_RE_CLASSES_H_
26
27#include <wx/arrstr.h>
28#include <wx/bitmap.h>
29#include <wx/chartype.h>
30#include <wx/tokenzr.h>
31
32#include <confirm.h>
33#include <eda_text.h>
36#include <grid_tricks.h>
37#include <kidialog.h>
38#include <pgm_base.h>
40#include <template_fieldnames.h>
41#include <string_utils.h>
42
43#include <algorithm>
44#include <vector>
45
47
49{
50public:
52
54
55 virtual bool TransferDataToWindow() = 0;
56 virtual bool TransferDataFromWindow() = 0;
57
58 virtual bool ValidateInputs( int* aErrorCount, wxString* aValidationMessage ) = 0;
59
60 virtual wxString GenerateRule( const RULE_GENERATION_CONTEXT& aContext ) = 0;
61
62protected:
63 static wxString sanitizeRuleName( const wxString& aRuleName )
64 {
65 if( aRuleName.IsEmpty() )
66 return wxString( wxS( "rule" ) );
67
68 wxString result;
69 result.reserve( aRuleName.length() );
70
71 for( wxUniChar c : aRuleName )
72 {
73 if( wxIsspace( c ) )
74 {
75 result.append( '_' );
76 }
77 else if( wxIsalnum( c ) || c == '_' || c == '-' || c == '.' )
78 {
79 result.append( c );
80 }
81 else
82 {
83 result.append( '_' );
84 }
85 }
86
87 // Avoid names starting with a digit which S-expression parsers treat specially.
88 if( !result.empty() && wxIsdigit( *result.begin() ) )
89 result.Prepend( wxS( "r_" ) );
90
91 return result;
92 }
93
94 static wxString escapeCondition( const wxString& aCondition )
95 {
96 return EscapeString( aCondition, CTX_QUOTED_STR );
97 }
98
99 static wxString trimTrailingZeros( const wxString& aValue )
100 {
101 wxString result( aValue );
102
103 if( !result.Contains( '.' ) )
104 return result;
105
106 while( result.Length() > 1 && result.Last() == '0' )
107 result.Truncate( result.Length() - 1 );
108
109 if( result.Last() == '.' )
110 result.Truncate( result.Length() - 1 );
111
112 return result;
113 }
114
115 static wxString formatDouble( double aValue, int aPrecision = 6 )
116 {
117 wxString formatted = wxString::Format( wxS( "%.*f" ), aPrecision, aValue );
118 return trimTrailingZeros( formatted );
119 }
120
121 wxString buildRule( const RULE_GENERATION_CONTEXT& aContext,
122 const std::vector<wxString>& aConstraintClauses ) const
123 {
124 wxString rule;
125 rule << wxS( "(rule " ) << sanitizeRuleName( aContext.ruleName ) << wxS( "\n" );
126
127 if( !aContext.comment.IsEmpty() )
128 {
129 wxArrayString lines = wxSplit( aContext.comment, '\n', '\0' );
130
131 for( const wxString& line : lines )
132 {
133 if( line.IsEmpty() )
134 continue;
135
136 rule << wxS( "\t# " ) << line << wxS( "\n" );
137 }
138 }
139
140 if( !aContext.layerClause.IsEmpty() )
141 rule << wxS( "\t" ) << aContext.layerClause << wxS( "\n" );
142
143 for( const wxString& clause : aConstraintClauses )
144 {
145 if( clause.IsEmpty() )
146 continue;
147
148 rule << wxS( "\t" ) << clause << wxS( "\n" );
149 }
150
151 if( !aContext.conditionExpression.IsEmpty() )
152 {
153 rule << wxS( "\t(condition \"" ) << escapeCondition( aContext.conditionExpression )
154 << wxS( "\")\n" );
155 }
156
157 rule << wxS( ")\n" );
158
159 return rule;
160 }
161};
162
163#endif // DRC_RE_CLASSES_H_
static wxString escapeCondition(const wxString &aCondition)
virtual bool TransferDataFromWindow()=0
wxString buildRule(const RULE_GENERATION_CONTEXT &aContext, const std::vector< wxString > &aConstraintClauses) const
virtual wxString GenerateRule(const RULE_GENERATION_CONTEXT &aContext)=0
static wxString trimTrailingZeros(const wxString &aValue)
virtual ~DRC_RULE_EDITOR_CONTENT_PANEL_BASE()=default
virtual bool ValidateInputs(int *aErrorCount, wxString *aValidationMessage)=0
static wxString formatDouble(double aValue, int aPrecision=6)
static wxString sanitizeRuleName(const wxString &aRuleName)
This file is part of the common library.
see class PGM_BASE
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
@ CTX_QUOTED_STR
wxString result
Test unit parsing edge cases and error handling.