KiCad PCB EDA Suite
template_fieldnames.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) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
5  * Copyright (C) 2015-2020 KiCad Developers, see CHANGELOG.TXT for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
25 #include <macros.h>
26 #include <template_fieldnames.h>
27 #include <pgm_base.h>
28 
29 using namespace TFIELD_T;
30 
31 #define REFCANONICAL "Reference"
32 #define VALCANONICAL "Value"
33 #define FTPCANONICAL "Footprint"
34 #define DSHCANONICAL "Datasheet"
35 
36 const wxString TEMPLATE_FIELDNAME::GetDefaultFieldName( int aFieldNdx, bool aTranslate )
37 {
38  static void* locale = nullptr;
39  static wxString referenceDefault;
40  static wxString valueDefault;
41  static wxString footprintDefault;
42  static wxString datasheetDefault;
43  static wxString fieldDefault;
44 
45  if( !aTranslate )
46  {
47  switch( aFieldNdx )
48  {
49  case REFERENCE_FIELD: return REFCANONICAL; // The component reference, R1, C1, etc.
50  case VALUE_FIELD: return VALCANONICAL; // The component value + name
51  case FOOTPRINT_FIELD: return FTPCANONICAL; // The footprint for use with Pcbnew
52  case DATASHEET_FIELD: return DSHCANONICAL; // Link to a datasheet for component
53  }
54  }
55 
56  // Fetching translations can take a surprising amount of time when loading libraries,
57  // so only do it when necessary.
58  if( Pgm().GetLocale() != locale )
59  {
60  referenceDefault = _( REFCANONICAL );
61  valueDefault = _( VALCANONICAL );
62  footprintDefault = _( FTPCANONICAL );
63  datasheetDefault = _( DSHCANONICAL );
64  fieldDefault = _( "Field%d" );
65  locale = Pgm().GetLocale();
66  }
67 
68  // Fixed values for the mandatory fields
69  switch( aFieldNdx )
70  {
71  case REFERENCE_FIELD: return referenceDefault; // The component reference, R1, C1, etc.
72  case VALUE_FIELD: return valueDefault; // The component value + name
73  case FOOTPRINT_FIELD: return footprintDefault; // The footprint for use with Pcbnew
74  case DATASHEET_FIELD: return datasheetDefault; // Link to a datasheet for component
75  default: return wxString::Format( fieldDefault, aFieldNdx );
76  }
77 
78 }
79 
80 #undef REFCANONICAL
81 #undef VALCANONICAL
82 #undef FTPCANONICAL
83 #undef DSHCANONICAL
84 
85 
86 void TEMPLATE_FIELDNAME::Format( OUTPUTFORMATTER* out, int nestLevel ) const
87 {
88  out->Print( nestLevel, "(field (name %s)", out->Quotew( m_Name ).c_str() );
89 
90  if( m_Visible )
91  out->Print( 0, " visible" );
92 
93  if( m_URL )
94  out->Print( 0, " url" );
95 
96  out->Print( 0, ")\n" );
97 }
98 
99 
100 void TEMPLATE_FIELDNAME::Parse( TEMPLATE_FIELDNAMES_LEXER* in )
101 {
102  T tok;
103 
104  in->NeedLEFT(); // begin (name ...)
105 
106  if( ( tok = in->NextTok() ) != T_name )
107  in->Expecting( T_name );
108 
109  in->NeedSYMBOLorNUMBER();
110 
111  m_Name = FROM_UTF8( in->CurText() );
112 
113  in->NeedRIGHT(); // end (name ...)
114 
115  while( (tok = in->NextTok() ) != T_RIGHT && tok != T_EOF )
116  {
117  // "visible" has no '(' prefix, "value" does, so T_LEFT is optional.
118  if( tok == T_LEFT )
119  tok = in->NextTok();
120 
121  switch( tok )
122  {
123  case T_value:
124  // older format; silently skip
125  in->NeedSYMBOLorNUMBER();
126  in->NeedRIGHT();
127  break;
128 
129  case T_visible:
130  m_Visible = true;
131  break;
132 
133  case T_url:
134  m_URL = true;
135  break;
136 
137  default:
138  in->Expecting( "value|url|visible" );
139  break;
140  }
141  }
142 }
143 
144 
145 void TEMPLATES::Format( OUTPUTFORMATTER* out, int nestLevel, bool aGlobal ) const
146 {
147  // We'll keep this general, and include the \n, even though the only known
148  // use at this time will not want the newlines or the indentation.
149  out->Print( nestLevel, "(templatefields" );
150 
151  const TEMPLATE_FIELDNAMES& source = aGlobal ? m_globals : m_project;
152 
153  for( const TEMPLATE_FIELDNAME& temp : source )
154  temp.Format( out, nestLevel+1 );
155 
156  out->Print( 0, ")\n" );
157 }
158 
159 
160 void TEMPLATES::Parse( TEMPLATE_FIELDNAMES_LEXER* in, bool aGlobal )
161 {
162  T tok;
163 
164  while( ( tok = in->NextTok() ) != T_RIGHT && tok != T_EOF )
165  {
166  if( tok == T_LEFT )
167  tok = in->NextTok();
168 
169  switch( tok )
170  {
171  case T_templatefields: // a token indicating class TEMPLATES.
172 
173  // Be flexible regarding the starting point of the TEMPLATE_FIELDNAMES_LEXER
174  // stream. Caller may not have read the first two tokens out of the
175  // stream: T_LEFT and T_templatefields, so ignore them if seen here.
176  break;
177 
178  case T_field:
179  {
180  // instantiate on stack, so if exception is thrown,
181  // destructor runs
182  TEMPLATE_FIELDNAME field;
183 
184  field.Parse( in );
185 
186  // add the field
187  AddTemplateFieldName( field, aGlobal );
188  }
189  break;
190 
191  default:
192  in->Unexpected( in->CurText() );
193  break;
194  }
195  }
196 }
197 
198 
199 /*
200  * Flatten project and global templates into a single list. (Project templates take
201  * precedence.)
202  */
204 {
205  m_resolved = m_project;
206 
207  // Note: order N^2 algorithm. Would need changing if fieldname template sets ever
208  // get large.
209 
210  for( const TEMPLATE_FIELDNAME& global : m_globals )
211  {
212  for( const TEMPLATE_FIELDNAME& project : m_project )
213  {
214  if( global.m_Name == project.m_Name )
215  continue;
216  }
217 
218  m_resolved.push_back( global );
219  }
220 
221  m_resolvedDirty = false;
222 }
223 
224 
225 void TEMPLATES::AddTemplateFieldName( const TEMPLATE_FIELDNAME& aFieldName, bool aGlobal )
226 {
227  // Ensure that the template fieldname does not match a fixed fieldname.
228  for( int i = 0; i < MANDATORY_FIELDS; ++i )
229  {
230  if( TEMPLATE_FIELDNAME::GetDefaultFieldName( i ) == aFieldName.m_Name )
231  return;
232  }
233 
234  TEMPLATE_FIELDNAMES& target = aGlobal ? m_globals : m_project;
235 
236  // ensure uniqueness, overwrite any template fieldname by the same name.
237  for( TEMPLATE_FIELDNAME& temp : target )
238  {
239  if( temp.m_Name == aFieldName.m_Name )
240  {
241  temp = aFieldName;
242  m_resolvedDirty = true;
243  return;
244  }
245  }
246 
247  // the name is legal and not previously added to the config container, append
248  // it and return its index within the container.
249  target.push_back( aFieldName );
250  m_resolvedDirty = true;
251 }
252 
253 
255 {
256  if( aGlobal )
257  {
258  m_globals.clear();
259  m_resolved = m_project;
260  }
261  else
262  {
263  m_project.clear();
264  m_resolved = m_globals;
265  }
266 
267  m_resolvedDirty = false;
268 }
269 
270 
272 {
273  if( m_resolvedDirty )
274  resolveTemplates();
275 
276  return m_resolved;
277 }
278 
279 
281 {
282  if( aGlobal )
283  return m_globals;
284  else
285  return m_project;
286 }
287 
288 
289 const TEMPLATE_FIELDNAME* TEMPLATES::GetFieldName( const wxString& aName )
290 {
291  if( m_resolvedDirty )
292  resolveTemplates();
293 
294  for( const TEMPLATE_FIELDNAME& field : m_resolved )
295  {
296  if( field.m_Name == aName )
297  return &field;
298  }
299 
300  return nullptr;
301 }
302 
void Format(OUTPUTFORMATTER *out, int nestLevel, bool aGlobal) const
Serialize this object out as text into the given OUTPUTFORMATTER.
static wxString FROM_UTF8(const char *cstring)
Convert a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:110
void AddTemplateFieldName(const TEMPLATE_FIELDNAME &aFieldName, bool aGlobal)
Insert or append a wanted symbol field name into the field names template.
The first 4 are mandatory, and must be instantiated in SCH_COMPONENT and LIB_PART constructors.
void Parse(TEMPLATE_FIELDNAMES_LEXER *in, bool aGlobal)
Fill this object from information in the input stream handled by #TEMPLATE_FIELDNAMES_LEXER.
#define DSHCANONICAL
void Parse(TEMPLATE_FIELDNAMES_LEXER *aSpec)
Fill this object from information in the input stream aSpec, which is a #TEMPLATE_FIELDNAMES_LEXER.
An interface used to output 8 bit text in a convenient way.
Definition: richio.h:306
void DeleteAllFieldNameTemplates(bool aGlobal)
Delete the entire contents.
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:106
void Format(OUTPUTFORMATTER *out, int nestLevel) const
Serialize this object out as text into the given OUTPUTFORMATTER.
name of datasheet
This file contains miscellaneous commonly used macros and functions.
Field Value of part, i.e. "3.3K".
#define VALCANONICAL
std::vector< TEMPLATE_FIELDNAME > TEMPLATE_FIELDNAMES
static const wxString GetDefaultFieldName(int aFieldNdx, bool aTranslate=true)
Return a default symbol field name for field aFieldNdx for all components.
const TEMPLATE_FIELDNAME * GetFieldName(const wxString &aName)
Search for aName in the the template field name list.
Field Name Module PCB, i.e. "16DIP300".
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
see class PGM_BASE
#define _(s)
Definition: 3d_actions.cpp:33
Hold a name of a symbol's field, field value, and default visibility.
#define REFCANONICAL
#define FTPCANONICAL
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:408
Field Reference of part, i.e. "IC21".
const TEMPLATE_FIELDNAMES & GetTemplateFieldNames()
Return a template field name list for read only access.
std::string Quotew(const wxString &aWrapee) const
Definition: richio.cpp:476