KiCad PCB EDA Suite
PCB_IO Class Reference

A PLUGIN derivation for saving and loading Pcbnew s-expression formatted files. More...

#include <kicad_plugin.h>

Inheritance diagram for PCB_IO:
PLUGIN CLIPBOARD_IO

Public Member Functions

const wxString PluginName () const override
 Return a brief hard coded name for this PLUGIN. More...
 
const wxString GetFileExtension () const override
 Returns the file extension for the PLUGIN. More...
 
virtual void Save (const wxString &aFileName, BOARD *aBoard, const PROPERTIES *aProperties=nullptr) override
 Write aBoard to a storage file in a format that this PLUGIN implementation knows about or it can be used to write a portion of aBoard to a special kind of export file. More...
 
BOARDLoad (const wxString &aFileName, BOARD *aAppendToMe, const PROPERTIES *aProperties=nullptr, PROJECT *aProject=nullptr) override
 Load information from some input file format that this PLUGIN implementation knows about into either a new BOARD or an existing one. More...
 
BOARDDoLoad (LINE_READER &aReader, BOARD *aAppendToMe, const PROPERTIES *aProperties)
 
void FootprintEnumerate (wxArrayString &aFootprintNames, const wxString &aLibraryPath, bool aBestEfforts, const PROPERTIES *aProperties=nullptr) override
 Return a list of footprint names contained within the library at aLibraryPath. More...
 
const FOOTPRINTGetEnumeratedFootprint (const wxString &aLibraryPath, const wxString &aFootprintName, const PROPERTIES *aProperties=nullptr) override
 A version of FootprintLoad() for use after FootprintEnumerate() for more efficient cache management. More...
 
bool FootprintExists (const wxString &aLibraryPath, const wxString &aFootprintName, const PROPERTIES *aProperties=nullptr) override
 Check for the existence of a footprint. More...
 
FOOTPRINTFootprintLoad (const wxString &aLibraryPath, const wxString &aFootprintName, bool aKeepUUID=false, const PROPERTIES *aProperties=nullptr) override
 Load a footprint having aFootprintName from the aLibraryPath containing a library format that this PLUGIN knows about. More...
 
void FootprintSave (const wxString &aLibraryPath, const FOOTPRINT *aFootprint, const PROPERTIES *aProperties=nullptr) override
 Write aFootprint to an existing library located at aLibraryPath. More...
 
void FootprintDelete (const wxString &aLibraryPath, const wxString &aFootprintName, const PROPERTIES *aProperties=nullptr) override
 Delete aFootprintName from the library at aLibraryPath. More...
 
long long GetLibraryTimestamp (const wxString &aLibraryPath) const override
 Generate a timestamp representing all the files in the library (including the library directory). More...
 
void FootprintLibCreate (const wxString &aLibraryPath, const PROPERTIES *aProperties=nullptr) override
 Create a new empty footprint library at aLibraryPath empty. More...
 
bool FootprintLibDelete (const wxString &aLibraryPath, const PROPERTIES *aProperties=nullptr) override
 Delete an existing footprint library and returns true, or if library does not exist returns false, or throws an exception if library exists but is read only or cannot be deleted for some other reason. More...
 
bool IsFootprintLibWritable (const wxString &aLibraryPath) override
 Return true if the library at aLibraryPath is writable. More...
 
 PCB_IO (int aControlFlags=CTL_FOR_BOARD)
 
virtual ~PCB_IO ()
 
void Format (const BOARD_ITEM *aItem, int aNestLevel=0) const
 Output aItem to aFormatter in s-expression format. More...
 
std::string GetStringOutput (bool doClear)
 
void SetOutputFormatter (OUTPUTFORMATTER *aFormatter)
 
BOARD_ITEMParse (const wxString &aClipboardSourceInput)
 
virtual std::vector< FOOTPRINT * > GetImportedCachedLibraryFootprints ()
 Return a container with the cached library footprints generated in the last call to Load. More...
 
virtual void PrefetchLib (const wxString &aLibraryPath, const PROPERTIES *aProperties=nullptr)
 If possible, prefetches the specified library (e.g. More...
 
virtual void FootprintLibOptions (PROPERTIES *aListToAppendTo) const
 Append supported PLUGIN options to aListToAppenTo along with internationalized descriptions. More...
 

Protected Member Functions

void validateCache (const wxString &aLibraryPath, bool checkModified=true)
 
const FOOTPRINTgetFootprint (const wxString &aLibraryPath, const wxString &aFootprintName, const PROPERTIES *aProperties, bool checkModified)
 
void init (const PROPERTIES *aProperties)
 
void formatSetup (const BOARD *aBoard, int aNestLevel=0) const
 formats the board setup information More...
 
void formatGeneral (const BOARD *aBoard, int aNestLevel=0) const
 formats the General section of the file More...
 
void formatBoardLayers (const BOARD *aBoard, int aNestLevel=0) const
 formats the board layer information More...
 
void formatNetInformation (const BOARD *aBoard, int aNestLevel=0) const
 formats the Nets and Netclasses More...
 
void formatProperties (const BOARD *aBoard, int aNestLevel=0) const
 formats the Nets and Netclasses More...
 
void formatHeader (const BOARD *aBoard, int aNestLevel=0) const
 writes everything that comes before the board_items, like settings and layers etc More...
 

Protected Attributes

wxString m_error
 for throwing exceptions More...
 
BOARDm_board
 which BOARD, no ownership here More...
 
const PROPERTIESm_props
 passed via Save() or Load(), no ownership, may be NULL. More...
 
FP_CACHEm_cache
 Footprint library cache. More...
 
LINE_READERm_reader
 no ownership here. More...
 
wxString m_filename
 for saves only, name is in m_reader for loads More...
 
STRING_FORMATTER m_sf
 
OUTPUTFORMATTERm_out
 output any Format()s to this, no ownership More...
 
int m_ctl
 
PCB_PARSERm_parser
 
NETINFO_MAPPINGm_mapping
 mapping for net codes, so only not empty net codes are stored with consecutive integers as net codes More...
 

Private Member Functions

void format (const BOARD *aBoard, int aNestLevel=0) const
 
void format (const DIMENSION_BASE *aDimension, int aNestLevel=0) const
 
void format (const FP_SHAPE *aFPShape, int aNestLevel=0) const
 
void format (const PCB_GROUP *aGroup, int aNestLevel=0) const
 
void format (const PCB_SHAPE *aSegment, int aNestLevel=0) const
 
void format (const PCB_TARGET *aTarget, int aNestLevel=0) const
 
void format (const FOOTPRINT *aFootprint, int aNestLevel=0) const
 
void format (const PAD *aPad, int aNestLevel=0) const
 
void format (const PCB_TEXT *aText, int aNestLevel=0) const
 
void format (const FP_TEXT *aText, int aNestLevel=0) const
 
void format (const TRACK *aTrack, int aNestLevel=0) const
 
void format (const ZONE *aZone, int aNestLevel=0) const
 
void formatLayer (const BOARD_ITEM *aItem) const
 
void formatLayers (LSET aLayerMask, int aNestLevel=0) const
 

Friends

class FP_CACHE
 

Detailed Description

A PLUGIN derivation for saving and loading Pcbnew s-expression formatted files.

Note
This class is not thread safe, but it is re-entrant multiple times in sequence.

Definition at line 133 of file pcbnew/plugins/kicad/kicad_plugin.h.

Constructor & Destructor Documentation

◆ PCB_IO()

PCB_IO::PCB_IO ( int  aControlFlags = CTL_FOR_BOARD)

Definition at line 2132 of file kicad_plugin.cpp.

2132  :
2133  m_cache( 0 ),
2134  m_ctl( aControlFlags ),
2135  m_parser( new PCB_PARSER() ),
2136  m_mapping( new NETINFO_MAPPING() )
2137 {
2138  init( 0 );
2139  m_out = &m_sf;
2140 }
OUTPUTFORMATTER * m_out
output any Format()s to this, no ownership
FP_CACHE * m_cache
Footprint library cache.
Read a Pcbnew s-expression formatted LINE_READER object and returns the appropriate BOARD_ITEM object...
Definition: pcb_parser.h:68
void init(const PROPERTIES *aProperties)
NETINFO_MAPPING * m_mapping
mapping for net codes, so only not empty net codes are stored with consecutive integers as net codes

References init(), m_out, and m_sf.

◆ ~PCB_IO()

PCB_IO::~PCB_IO ( )
virtual

Definition at line 2143 of file kicad_plugin.cpp.

2144 {
2145  delete m_cache;
2146  delete m_parser;
2147  delete m_mapping;
2148 }
FP_CACHE * m_cache
Footprint library cache.
NETINFO_MAPPING * m_mapping
mapping for net codes, so only not empty net codes are stored with consecutive integers as net codes

References m_cache, m_mapping, and m_parser.

Member Function Documentation

◆ DoLoad()

BOARD * PCB_IO::DoLoad ( LINE_READER aReader,
BOARD aAppendToMe,
const PROPERTIES aProperties 
)

Definition at line 2166 of file kicad_plugin.cpp.

2167 {
2168  init( aProperties );
2169 
2170  m_parser->SetLineReader( &aReader );
2171  m_parser->SetBoard( aAppendToMe );
2172 
2173  BOARD* board;
2174 
2175  try
2176  {
2177  board = dynamic_cast<BOARD*>( m_parser->Parse() );
2178  }
2179  catch( const FUTURE_FORMAT_ERROR& )
2180  {
2181  // Don't wrap a FUTURE_FORMAT_ERROR in another
2182  throw;
2183  }
2184  catch( const PARSE_ERROR& parse_error )
2185  {
2186  if( m_parser->IsTooRecent() )
2187  throw FUTURE_FORMAT_ERROR( parse_error, m_parser->GetRequiredVersion() );
2188  else
2189  throw;
2190  }
2191 
2192  if( !board )
2193  {
2194  // The parser loaded something that was valid, but wasn't a board.
2195  THROW_PARSE_ERROR( _( "this file does not contain a PCB" ),
2196  m_parser->CurSource(), m_parser->CurLine(),
2197  m_parser->CurLineNumber(), m_parser->CurOffset() );
2198  }
2199 
2200  return board;
2201 }
void init(const PROPERTIES *aProperties)
wxString GetRequiredVersion()
Return a string representing the version of KiCad required to open this file.
Definition: pcb_parser.cpp:184
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
Definition: ki_exception.h:164
void SetBoard(BOARD *aBoard)
Definition: pcb_parser.h:94
BOARD_ITEM * Parse()
Definition: pcb_parser.cpp:473
LINE_READER * SetLineReader(LINE_READER *aReader)
Set aLineReader into the parser, and returns the previous one, if any.
Definition: pcb_parser.h:87
bool IsTooRecent()
Return whether a version number, if any was parsed, was too recent.
Definition: pcb_parser.h:116
A filename or source description, a problem input line, a line number, a byte offset,...
Definition: ki_exception.h:118
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:190
#define _(s)
Definition: 3d_actions.cpp:33
Variant of PARSE_ERROR indicating that a syntax or related error was likely caused by a file generate...
Definition: ki_exception.h:174

References _, PCB_PARSER::GetRequiredVersion(), init(), PCB_PARSER::IsTooRecent(), m_parser, PCB_PARSER::Parse(), PCB_PARSER::SetBoard(), PCB_PARSER::SetLineReader(), and THROW_PARSE_ERROR.

Referenced by PANEL_PCBNEW_COLOR_SETTINGS::createPreviewItems(), and Load().

◆ FootprintDelete()

void PCB_IO::FootprintDelete ( const wxString &  aLibraryPath,
const wxString &  aFootprintName,
const PROPERTIES aProperties = nullptr 
)
overridevirtual

Delete aFootprintName from the library at aLibraryPath.

Parameters
aLibraryPathis a locator for the "library", usually a directory, file, or URL containing several footprints.
aFootprintNameis the name of a footprint to delete from the specified library.
aPropertiesis an associative array that can be used to tell the library delete function anything special, because it can take any number of additional named tuning arguments that the plugin is known to support. The caller continues to own this object (plugin may not delete it), and plugins should expect it to be optionally NULL.
Exceptions
IO_ERRORif there is a problem finding the footprint or the library, or deleting it.

Reimplemented from PLUGIN.

Definition at line 2435 of file kicad_plugin.cpp.

2437 {
2438  LOCALE_IO toggle; // toggles on, then off, the C locale.
2439 
2440  init( aProperties );
2441 
2442  validateCache( aLibraryPath );
2443 
2444  if( !m_cache->IsWritable() )
2445  {
2446  THROW_IO_ERROR( wxString::Format( _( "Library \"%s\" is read only." ),
2447  aLibraryPath.GetData() ) );
2448  }
2449 
2450  m_cache->Remove( aFootprintName );
2451 }
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:40
FP_CACHE * m_cache
Footprint library cache.
void init(const PROPERTIES *aProperties)
void Remove(const wxString &aFootprintName)
void validateCache(const wxString &aLibraryPath, bool checkModified=true)
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
bool IsWritable() const
#define _(s)
Definition: 3d_actions.cpp:33
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38

References _, Format(), init(), FP_CACHE::IsWritable(), m_cache, FP_CACHE::Remove(), THROW_IO_ERROR, and validateCache().

◆ FootprintEnumerate()

void PCB_IO::FootprintEnumerate ( wxArrayString &  aFootprintNames,
const wxString &  aLibraryPath,
bool  aBestEfforts,
const PROPERTIES aProperties = nullptr 
)
overridevirtual

Return a list of footprint names contained within the library at aLibraryPath.

Parameters
aLibraryPathis a locator for the "library", usually a directory, file, or URL containing several footprints.
aPropertiesis an associative array that can be used to tell the plugin anything needed about how to perform with respect to aLibraryPath. The caller continues to own this object (plugin may not delete it), and plugins should expect it to be optionally NULL.
aFootprintNamesis the array of available footprint names inside a library.
aBestEffortsif true, don't throw on errors, just return an empty list.
Exceptions
IO_ERRORif the library cannot be found, or footprint cannot be loaded.

Reimplemented from PLUGIN.

Definition at line 2224 of file kicad_plugin.cpp.

2226 {
2227  LOCALE_IO toggle; // toggles on, then off, the C locale.
2228  wxDir dir( aLibPath );
2229  wxString errorMsg;
2230 
2231  init( aProperties );
2232 
2233  try
2234  {
2235  validateCache( aLibPath );
2236  }
2237  catch( const IO_ERROR& ioe )
2238  {
2239  errorMsg = ioe.What();
2240  }
2241 
2242  // Some of the files may have been parsed correctly so we want to add the valid files to
2243  // the library.
2244 
2245  for( const auto& footprint : m_cache->GetFootprints() )
2246  aFootprintNames.Add( footprint.first );
2247 
2248  if( !errorMsg.IsEmpty() && !aBestEfforts )
2249  THROW_IO_ERROR( errorMsg );
2250 }
FOOTPRINT_MAP & GetFootprints()
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:40
FP_CACHE * m_cache
Footprint library cache.
void init(const PROPERTIES *aProperties)
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:29
void validateCache(const wxString &aLibraryPath, bool checkModified=true)
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:75
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38

References FP_CACHE::GetFootprints(), init(), m_cache, THROW_IO_ERROR, validateCache(), and IO_ERROR::What().

◆ FootprintExists()

bool PCB_IO::FootprintExists ( const wxString &  aLibraryPath,
const wxString &  aFootprintName,
const PROPERTIES aProperties = nullptr 
)
overridevirtual

Check for the existence of a footprint.

Reimplemented from PLUGIN.

Definition at line 2289 of file kicad_plugin.cpp.

2291 {
2292  // Note: checking the cache sounds like a good idea, but won't catch files which differ
2293  // only in case.
2294  //
2295  // Since this goes out to the native filesystem, we get platform differences (ie: MSW's
2296  // case-insensitive filesystem) handled "for free".
2297  // Warning: footprint names frequently contain a point. So be careful when initializing
2298  // wxFileName, and use a CTOR with extension specified
2299  wxFileName footprintFile( aLibraryPath, aFootprintName, KiCadFootprintFileExtension );
2300 
2301  return footprintFile.Exists();
2302 }
const std::string KiCadFootprintFileExtension

References KiCadFootprintFileExtension.

◆ FootprintLibCreate()

void PCB_IO::FootprintLibCreate ( const wxString &  aLibraryPath,
const PROPERTIES aProperties = nullptr 
)
overridevirtual

Create a new empty footprint library at aLibraryPath empty.

It is an error to attempt to create an existing library or to attempt to create on a "read only" location.

Parameters
aLibraryPathis a locator for the "library", usually a directory, file, or URL containing several footprints.
aPropertiesis an associative array that can be used to tell the library create function anything special, because it can take any number of additional named tuning arguments that the plugin is known to support. The caller continues to own this object (plugin may not delete it), and plugins should expect it to be optionally NULL.
Exceptions
IO_ERRORif there is a problem finding the library, or creating it.

Reimplemented from PLUGIN.

Definition at line 2461 of file kicad_plugin.cpp.

2462 {
2463  if( wxDir::Exists( aLibraryPath ) )
2464  {
2465  THROW_IO_ERROR( wxString::Format( _( "Cannot overwrite library path \"%s\"." ),
2466  aLibraryPath.GetData() ) );
2467  }
2468 
2469  LOCALE_IO toggle;
2470 
2471  init( aProperties );
2472 
2473  delete m_cache;
2474  m_cache = new FP_CACHE( this, aLibraryPath );
2475  m_cache->Save();
2476 }
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:40
void Save(FOOTPRINT *aFootprint=nullptr)
Save the footprint cache or a single footprint from it to disk.
FP_CACHE * m_cache
Footprint library cache.
void init(const PROPERTIES *aProperties)
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
#define _(s)
Definition: 3d_actions.cpp:33
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38

References _, Format(), FP_CACHE, init(), m_cache, FP_CACHE::Save(), and THROW_IO_ERROR.

◆ FootprintLibDelete()

bool PCB_IO::FootprintLibDelete ( const wxString &  aLibraryPath,
const PROPERTIES aProperties = nullptr 
)
overridevirtual

Delete an existing footprint library and returns true, or if library does not exist returns false, or throws an exception if library exists but is read only or cannot be deleted for some other reason.

Parameters
aLibraryPathis a locator for the "library", usually a directory or file which will contain footprints.
aPropertiesis an associative array that can be used to tell the library delete implementation function anything special, because it can take any number of additional named tuning arguments that the plugin is known to support. The caller continues to own this object (plugin may not delete it), and plugins should expect it to be optionally NULL.
Returns
true if library deleted, false if library did not exist.
Exceptions
IO_ERRORif there is a problem deleting an existing library.

Reimplemented from PLUGIN.

Definition at line 2479 of file kicad_plugin.cpp.

2480 {
2481  wxFileName fn;
2482  fn.SetPath( aLibraryPath );
2483 
2484  // Return if there is no library path to delete.
2485  if( !fn.DirExists() )
2486  return false;
2487 
2488  if( !fn.IsDirWritable() )
2489  {
2490  THROW_IO_ERROR( wxString::Format( _( "User does not have permission to delete directory \"%s\"." ),
2491  aLibraryPath.GetData() ) );
2492  }
2493 
2494  wxDir dir( aLibraryPath );
2495 
2496  if( dir.HasSubDirs() )
2497  {
2498  THROW_IO_ERROR( wxString::Format( _( "Library directory \"%s\" has unexpected sub-directories." ),
2499  aLibraryPath.GetData() ) );
2500  }
2501 
2502  // All the footprint files must be deleted before the directory can be deleted.
2503  if( dir.HasFiles() )
2504  {
2505  unsigned i;
2506  wxFileName tmp;
2507  wxArrayString files;
2508 
2509  wxDir::GetAllFiles( aLibraryPath, &files );
2510 
2511  for( i = 0; i < files.GetCount(); i++ )
2512  {
2513  tmp = files[i];
2514 
2515  if( tmp.GetExt() != KiCadFootprintFileExtension )
2516  {
2517  THROW_IO_ERROR( wxString::Format( _( "Unexpected file \"%s\" was found in library path \"%s\"." ),
2518  files[i].GetData(), aLibraryPath.GetData() ) );
2519  }
2520  }
2521 
2522  for( i = 0; i < files.GetCount(); i++ )
2523  wxRemoveFile( files[i] );
2524  }
2525 
2526  wxLogTrace( traceKicadPcbPlugin, wxT( "Removing footprint library \"%s\"." ),
2527  aLibraryPath.GetData() );
2528 
2529  // Some of the more elaborate wxRemoveFile() crap puts up its own wxLog dialog
2530  // we don't want that. we want bare metal portability with no UI here.
2531  if( !wxRmdir( aLibraryPath ) )
2532  {
2533  THROW_IO_ERROR( wxString::Format( _( "Footprint library \"%s\" cannot be deleted." ),
2534  aLibraryPath.GetData() ) );
2535  }
2536 
2537  // For some reason removing a directory in Windows is not immediately updated. This delay
2538  // prevents an error when attempting to immediately recreate the same directory when over
2539  // writing an existing library.
2540 #ifdef __WINDOWS__
2541  wxMilliSleep( 250L );
2542 #endif
2543 
2544  if( m_cache && !m_cache->IsPath( aLibraryPath ) )
2545  {
2546  delete m_cache;
2547  m_cache = nullptr;
2548  }
2549 
2550  return true;
2551 }
const std::string KiCadFootprintFileExtension
FP_CACHE * m_cache
Footprint library cache.
bool IsPath(const wxString &aPath) const
Check if aPath is the same as the current cache path.
const wxChar *const traceKicadPcbPlugin
Flag to enable GEDA PCB plugin debug output.
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
#define _(s)
Definition: 3d_actions.cpp:33
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38

References _, Format(), FP_CACHE::IsPath(), KiCadFootprintFileExtension, m_cache, THROW_IO_ERROR, and traceKicadPcbPlugin.

◆ FootprintLibOptions()

void PLUGIN::FootprintLibOptions ( PROPERTIES aListToAppendTo) const
virtualinherited

Append supported PLUGIN options to aListToAppenTo along with internationalized descriptions.

Options are typically appended so that a derived PLUGIN can call its base class function by the same name first, thus inheriting options declared there. Some base class options could pertain to all Footprint*() functions in all derived PLUGINs.

Note
Since aListToAppendTo is a PROPERTIES object, all options will be unique and last guy wins.
Parameters
aListToAppendToholds a tuple of
option
This eventually is what shows up into the fp-lib-table "options" field, possibly combined with others.
internationalized description
The internationalized description is displayed in DIALOG_FP_PLUGIN_OPTIONS. It may be multi-line and be quite explanatory of the option.

In the future perhaps aListToAppendTo evolves to something capable of also holding a wxValidator for the cells in said dialog: http://forums.wxwidgets.org/viewtopic.php?t=23277&p=104180. This would require a 3 column list, and introducing wx GUI knowledge to PLUGIN, which has been avoided to date.

Reimplemented in EAGLE_PLUGIN.

Definition at line 149 of file plugin.cpp.

150 {
151  // disable all these in another couple of months, after everyone has seen them:
152 #if 1
153  (*aListToAppendTo)["debug_level"] = UTF8( _(
154  "Enable <b>debug</b> logging for Footprint*() functions in this PLUGIN."
155  ));
156 
157  (*aListToAppendTo)["read_filter_regex"] = UTF8( _(
158  "Regular expression <b>footprint name</b> filter."
159  ));
160 
161  (*aListToAppendTo)["enable_transaction_logging"] = UTF8( _(
162  "Enable transaction logging. The mere presence of this option turns on the "
163  "logging, no need to set a Value."
164  ));
165 
166  (*aListToAppendTo)["username"] = UTF8( _(
167  "User name for <b>login</b> to some special library server."
168  ));
169 
170  (*aListToAppendTo)["password"] = UTF8( _(
171  "Password for <b>login</b> to some special library server."
172  ));
173 #endif
174 
175 #if 1
176  // Suitable for a C++ to python PLUGIN::Footprint*() adapter, move it to the adapter
177  // if and when implemented.
178  (*aListToAppendTo)["python_footprint_plugin"] = UTF8( _(
179  "Enter the python module which implements the PLUGIN::Footprint*() functions."
180  ));
181 #endif
182 }
An 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to and fro...
Definition: utf8.h:70
#define _(s)
Definition: 3d_actions.cpp:33

References _.

Referenced by EAGLE_PLUGIN::FootprintLibOptions().

◆ FootprintLoad()

FOOTPRINT * PCB_IO::FootprintLoad ( const wxString &  aLibraryPath,
const wxString &  aFootprintName,
bool  aKeepUUID = false,
const PROPERTIES aProperties = nullptr 
)
overridevirtual

Load a footprint having aFootprintName from the aLibraryPath containing a library format that this PLUGIN knows about.

Parameters
aLibraryPathis a locator for the "library", usually a directory, file, or URL containing several footprints.
aFootprintNameis the name of the footprint to load.
aPropertiesis an associative array that can be used to tell the loader implementation to do something special, because it can take any number of additional named tuning arguments that the plugin is known to support. The caller continues to own this object (plugin may not delete it), and plugins should expect it to be optionally NULL.
aKeepUUID= true to keep initial items UUID, false to set new UUID normally true if loaded in the footprint editor, false if loaded in the board editor. Make sense only in kicad_plugin
Returns
the FOOTPRINT object if found caller owns it, else NULL if not found.
Exceptions
IO_ERRORif the library cannot be found or read. No exception is thrown in the case where aFootprintName cannot be found.

Reimplemented from PLUGIN.

Definition at line 2305 of file kicad_plugin.cpp.

2309 {
2310  const FOOTPRINT* footprint = getFootprint( aLibraryPath, aFootprintName, aProperties, true );
2311 
2312  if( footprint )
2313  {
2314  FOOTPRINT* copy;
2315 
2316  if( aKeepUUID )
2317  copy = static_cast<FOOTPRINT*>( footprint->Clone() );
2318  else
2319  copy = static_cast<FOOTPRINT*>( footprint->Duplicate() );
2320 
2321  copy->SetParent( nullptr );
2322  return copy;
2323  }
2324 
2325  return nullptr;
2326 }
const FOOTPRINT * getFootprint(const wxString &aLibraryPath, const wxString &aFootprintName, const PROPERTIES *aProperties, bool checkModified)
BOARD_ITEM * Duplicate() const override
Create a copy of this BOARD_ITEM.
Definition: footprint.cpp:1601
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: footprint.cpp:1169

References FOOTPRINT::Clone(), copy, FOOTPRINT::Duplicate(), and getFootprint().

◆ FootprintSave()

void PCB_IO::FootprintSave ( const wxString &  aLibraryPath,
const FOOTPRINT aFootprint,
const PROPERTIES aProperties = nullptr 
)
overridevirtual

Write aFootprint to an existing library located at aLibraryPath.

If a footprint by the same name already exists, it is replaced.

Parameters
aLibraryPathis a locator for the "library", usually a directory, file, or URL containing several footprints.
aFootprintis what to store in the library. The caller continues to own the footprint after this call.
aPropertiesis an associative array that can be used to tell the saver how to save the footprint, because it can take any number of additional named tuning arguments that the plugin is known to support. The caller continues to own this object (plugin may not delete it), and plugins should expect it to be optionally NULL.
Exceptions
IO_ERRORif there is a problem saving.

Reimplemented from PLUGIN.

Definition at line 2329 of file kicad_plugin.cpp.

2331 {
2332  LOCALE_IO toggle; // toggles on, then off, the C locale.
2333 
2334  init( aProperties );
2335 
2336  // In this public PLUGIN API function, we can safely assume it was
2337  // called for saving into a library path.
2339 
2340  validateCache( aLibraryPath );
2341 
2342  if( !m_cache->IsWritable() )
2343  {
2344  if( !m_cache->Exists() )
2345  {
2346  const wxString msg = wxString::Format( _( "Library \"%s\" does not exist.\n"
2347  "Would you like to create it?"),
2348  aLibraryPath );
2349 
2350  if( wxMessageBox( msg, _( "Library Not Found"), wxYES_NO | wxICON_QUESTION ) != wxYES )
2351  return;
2352 
2353  // Save throws its own IO_ERROR on failure, so no need to recreate here
2354  m_cache->Save( nullptr );
2355  }
2356  else
2357  {
2358  wxString msg = wxString::Format( _( "Library \"%s\" is read only" ), aLibraryPath );
2359  THROW_IO_ERROR( msg );
2360  }
2361  }
2362 
2363  wxString footprintName = aFootprint->GetFPID().GetLibItemName();
2364 
2365  FOOTPRINT_MAP& footprints = m_cache->GetFootprints();
2366 
2367  // Quietly overwrite footprint and delete footprint file from path for any by same name.
2368  wxFileName fn( aLibraryPath, aFootprint->GetFPID().GetLibItemName(),
2370 
2371 #ifndef __WINDOWS__
2372  // Write through symlinks, don't replace them
2373  if( fn.Exists( wxFILE_EXISTS_SYMLINK ) )
2374  {
2375  char buffer[ PATH_MAX + 1 ];
2376  ssize_t pathLen = readlink( TO_UTF8( fn.GetFullPath() ), buffer, PATH_MAX );
2377 
2378  if( pathLen > 0 )
2379  {
2380  buffer[ pathLen ] = '\0';
2381  fn.Assign( fn.GetPath() + wxT( "/" ) + wxString::FromUTF8( buffer ) );
2382  fn.Normalize();
2383  }
2384  }
2385 #endif
2386 
2387  if( !fn.IsOk() )
2388  {
2389  THROW_IO_ERROR( wxString::Format( _( "Footprint file name \"%s\" is not valid." ),
2390  fn.GetFullPath() ) );
2391  }
2392 
2393  if( fn.FileExists() && !fn.IsFileWritable() )
2394  {
2395  THROW_IO_ERROR( wxString::Format( _( "No write permissions to delete file \"%s\"" ),
2396  fn.GetFullPath() ) );
2397  }
2398 
2399  wxString fullPath = fn.GetFullPath();
2400  wxString fullName = fn.GetFullName();
2401  FOOTPRINT_MAP::const_iterator it = footprints.find( footprintName );
2402 
2403  if( it != footprints.end() )
2404  {
2405  wxLogTrace( traceKicadPcbPlugin, wxT( "Removing footprint file '%s'." ), fullPath );
2406  footprints.erase( footprintName );
2407  wxRemoveFile( fullPath );
2408  }
2409 
2410  // I need my own copy for the cache
2411  FOOTPRINT* footprint = static_cast<FOOTPRINT*>( aFootprint->Clone() );
2412 
2413  // It's orientation should be zero and it should be on the front layer.
2414  footprint->SetOrientation( 0 );
2415 
2416  if( footprint->GetLayer() != F_Cu )
2417  {
2418  PCBNEW_SETTINGS* cfg = dynamic_cast<PCBNEW_SETTINGS*>( Kiface().KifaceSettings() );
2419 
2420  if( cfg )
2421  footprint->Flip( footprint->GetPosition(), cfg->m_FlipLeftRight );
2422  else
2423  footprint->Flip( footprint->GetPosition(), false );
2424  }
2425 
2426  // Detach it from the board
2427  footprint->SetParent( nullptr );
2428 
2429  wxLogTrace( traceKicadPcbPlugin, wxT( "Creating s-expr footprint file '%s'." ), fullPath );
2430  footprints.insert( footprintName, new FP_CACHE_ITEM( footprint, WX_FILENAME( fn.GetPath(), fullName ) ) );
2431  m_cache->Save( footprint );
2432 }
FOOTPRINT_MAP & GetFootprints()
const UTF8 & GetLibItemName() const
Definition: lib_id.h:106
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:40
void Save(FOOTPRINT *aFootprint=nullptr)
Save the footprint cache or a single footprint from it to disk.
const std::string KiCadFootprintFileExtension
FP_CACHE * m_cache
Footprint library cache.
void init(const PROPERTIES *aProperties)
#define CTL_FOR_LIBRARY
Format output for a footprint library instead of clipboard or BOARD.
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:166
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
void validateCache(const wxString &aLibraryPath, bool checkModified=true)
void SetOrientation(double aNewAngle)
Definition: footprint.cpp:1557
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
void Flip(const wxPoint &aCentre, bool aFlipLeftRight) override
Flip this object, i.e.
Definition: footprint.cpp:1367
const wxChar *const traceKicadPcbPlugin
Flag to enable GEDA PCB plugin debug output.
const LIB_ID & GetFPID() const
Definition: footprint.h:190
Helper class for creating a footprint library cache.
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
bool IsWritable() const
A wrapper around a wxFileName which is much more performant with a subset of the API.
Definition: wx_filename.h:36
#define _(s)
Definition: 3d_actions.cpp:33
std::map< wxString, FOOTPRINT * > FOOTPRINT_MAP
Definition: eagle_parser.h:50
wxPoint GetPosition() const override
Definition: footprint.h:182
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: footprint.cpp:1169
bool Exists() const
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:173
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38

References _, FOOTPRINT::Clone(), CTL_FOR_LIBRARY, FP_CACHE::Exists(), F_Cu, FOOTPRINT::Flip(), Format(), FP_CACHE::GetFootprints(), FOOTPRINT::GetFPID(), BOARD_ITEM::GetLayer(), LIB_ID::GetLibItemName(), FOOTPRINT::GetPosition(), init(), FP_CACHE::IsWritable(), KiCadFootprintFileExtension, Kiface(), m_cache, m_ctl, PCBNEW_SETTINGS::m_FlipLeftRight, FP_CACHE::Save(), FOOTPRINT::SetOrientation(), EDA_ITEM::SetParent(), THROW_IO_ERROR, TO_UTF8, traceKicadPcbPlugin, and validateCache().

◆ Format()

void PCB_IO::Format ( const BOARD_ITEM aItem,
int  aNestLevel = 0 
) const

Output aItem to aFormatter in s-expression format.

Parameters
aItemA pointer the an BOARD_ITEM object to format.
aNestLevelThe indentation nest level.
Exceptions
IO_ERRORon write error.

Definition at line 389 of file kicad_plugin.cpp.

390 {
391  LOCALE_IO toggle; // public API function, perform anything convenient for caller
392 
393  switch( aItem->Type() )
394  {
395  case PCB_T:
396  format( static_cast<const BOARD*>( aItem ), aNestLevel );
397  break;
398 
399  case PCB_DIM_ALIGNED_T:
400  case PCB_DIM_CENTER_T:
402  case PCB_DIM_LEADER_T:
403  format( static_cast<const DIMENSION_BASE*>( aItem ), aNestLevel );
404  break;
405 
406  case PCB_SHAPE_T:
407  format( static_cast<const PCB_SHAPE*>( aItem ), aNestLevel );
408  break;
409 
410  case PCB_FP_SHAPE_T:
411  format( static_cast<const FP_SHAPE*>( aItem ), aNestLevel );
412  break;
413 
414  case PCB_TARGET_T:
415  format( static_cast<const PCB_TARGET*>( aItem ), aNestLevel );
416  break;
417 
418  case PCB_FOOTPRINT_T:
419  format( static_cast<const FOOTPRINT*>( aItem ), aNestLevel );
420  break;
421 
422  case PCB_PAD_T:
423  format( static_cast<const PAD*>( aItem ), aNestLevel );
424  break;
425 
426  case PCB_TEXT_T:
427  format( static_cast<const PCB_TEXT*>( aItem ), aNestLevel );
428  break;
429 
430  case PCB_FP_TEXT_T:
431  format( static_cast<const FP_TEXT*>( aItem ), aNestLevel );
432  break;
433 
434  case PCB_GROUP_T:
435  format( static_cast<const PCB_GROUP*>( aItem ), aNestLevel );
436  break;
437 
438  case PCB_TRACE_T:
439  case PCB_ARC_T:
440  case PCB_VIA_T:
441  format( static_cast<const TRACK*>( aItem ), aNestLevel );
442  break;
443 
444  case PCB_FP_ZONE_T:
445  case PCB_ZONE_T:
446  format( static_cast<const ZONE*>( aItem ), aNestLevel );
447  break;
448 
449  default:
450  wxFAIL_MSG( wxT( "Cannot format item " ) + aItem->GetClass() );
451  }
452 }
void format(const BOARD *aBoard, int aNestLevel=0) const
class ALIGNED_DIMENSION, a linear dimension (graphic item)
Definition: typeinfo.h:100
class LEADER, a leader dimension (graphic item)
Definition: typeinfo.h:101
Definition: typeinfo.h:84
class FP_TEXT, text in a footprint
Definition: typeinfo.h:92
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:40
class PCB_GROUP, a set of BOARD_ITEMs
Definition: typeinfo.h:108
class CENTER_DIMENSION, a center point marking (graphic item)
Definition: typeinfo.h:102
class PCB_TEXT, text on a layer
Definition: typeinfo.h:91
class ARC, an arc track segment on a copper layer
Definition: typeinfo.h:97
class FP_SHAPE, a footprint edge
Definition: typeinfo.h:93
class PAD, a pad in a footprint
Definition: typeinfo.h:89
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
class ZONE, a copper pour area
Definition: typeinfo.h:105
class PCB_TARGET, a target (graphic item)
Definition: typeinfo.h:104
class FOOTPRINT, a footprint
Definition: typeinfo.h:88
virtual wxString GetClass() const =0
Return the class name.
class ZONE, managed by a footprint
Definition: typeinfo.h:94
class ORTHOGONAL_DIMENSION, a linear dimension constrained to x/y
Definition: typeinfo.h:103
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:90
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:163

References format(), EDA_ITEM::GetClass(), PCB_ARC_T, PCB_DIM_ALIGNED_T, PCB_DIM_CENTER_T, PCB_DIM_LEADER_T, PCB_DIM_ORTHOGONAL_T, PCB_FOOTPRINT_T, PCB_FP_SHAPE_T, PCB_FP_TEXT_T, PCB_FP_ZONE_T, PCB_GROUP_T, PCB_PAD_T, PCB_SHAPE_T, PCB_T, PCB_TARGET_T, PCB_TEXT_T, PCB_TRACE_T, PCB_VIA_T, PCB_ZONE_T, and EDA_ITEM::Type().

Referenced by FOOTPRINT_EDIT_FRAME::ExportFootprint(), format(), CLIPBOARD_IO::Save(), FP_CACHE::Save(), Save(), and CLIPBOARD_IO::SaveSelection().

◆ format() [1/12]

void PCB_IO::format ( const BOARD aBoard,
int  aNestLevel = 0 
) const
private

Definition at line 639 of file kicad_plugin.cpp.

640 {
641  std::set<BOARD_ITEM*, BOARD_ITEM::ptr_cmp> sorted_footprints( aBoard->Footprints().begin(),
642  aBoard->Footprints().end() );
643  std::set<BOARD_ITEM*, BOARD_ITEM::ptr_cmp> sorted_drawings( aBoard->Drawings().begin(),
644  aBoard->Drawings().end() );
645  std::set<TRACK*, TRACK::cmp_tracks> sorted_tracks( aBoard->Tracks().begin(),
646  aBoard->Tracks().end() );
647  std::set<BOARD_ITEM*, BOARD_ITEM::ptr_cmp> sorted_zones( aBoard->Zones().begin(),
648  aBoard->Zones().end() );
649  std::set<BOARD_ITEM*, BOARD_ITEM::ptr_cmp> sorted_groups( aBoard->Groups().begin(),
650  aBoard->Groups().end() );
651 
652  formatHeader( aBoard, aNestLevel );
653 
654  // Save the footprints.
655  for( BOARD_ITEM* footprint : sorted_footprints )
656  {
657  Format( footprint, aNestLevel );
658  m_out->Print( 0, "\n" );
659  }
660 
661  // Save the graphical items on the board (not owned by a footprint)
662  for( BOARD_ITEM* item : sorted_drawings )
663  Format( item, aNestLevel );
664 
665  if( sorted_drawings.size() )
666  m_out->Print( 0, "\n" );
667 
668  // Do not save PCB_MARKERs, they can be regenerated easily.
669 
670  // Save the tracks and vias.
671  for( TRACK* track : sorted_tracks )
672  Format( track, aNestLevel );
673 
674  if( sorted_tracks.size() )
675  m_out->Print( 0, "\n" );
676 
677  // Save the polygon (which are the newer technology) zones.
678  for( auto zone : sorted_zones )
679  Format( zone, aNestLevel );
680 
681  // Save the groups
682  for( BOARD_ITEM* group : sorted_groups )
683  Format( group, aNestLevel );
684 }
OUTPUTFORMATTER * m_out
output any Format()s to this, no ownership
ZONES & Zones()
Definition: board.h:311
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:82
GROUPS & Groups()
The groups must maintain the following invariants.
Definition: board.h:325
void formatHeader(const BOARD *aBoard, int aNestLevel=0) const
writes everything that comes before the board_items, like settings and layers etc
FOOTPRINTS & Footprints()
Definition: board.h:305
void Format(const BOARD_ITEM *aItem, int aNestLevel=0) const
Output aItem to aFormatter in s-expression format.
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:408
DRAWINGS & Drawings()
Definition: board.h:308
TRACKS & Tracks()
Definition: board.h:302
Definition: track.h:83

References BOARD::Drawings(), BOARD::Footprints(), Format(), formatHeader(), group, BOARD::Groups(), m_out, OUTPUTFORMATTER::Print(), BOARD::Tracks(), and BOARD::Zones().

Referenced by Format().

◆ format() [2/12]

void PCB_IO::format ( const DIMENSION_BASE aDimension,
int  aNestLevel = 0 
) const
private

Definition at line 687 of file kicad_plugin.cpp.

688 {
689  const ALIGNED_DIMENSION* aligned = dynamic_cast<const ALIGNED_DIMENSION*>( aDimension );
690  const ORTHOGONAL_DIMENSION* ortho = dynamic_cast<const ORTHOGONAL_DIMENSION*>( aDimension );
691  const CENTER_DIMENSION* center = dynamic_cast<const CENTER_DIMENSION*>( aDimension );
692  const LEADER* leader = dynamic_cast<const LEADER*>( aDimension );
693 
694  m_out->Print( aNestLevel, "(dimension" );
695 
696  if( aDimension->Type() == PCB_DIM_ALIGNED_T )
697  m_out->Print( 0, " (type aligned)" );
698  else if( aDimension->Type() == PCB_DIM_LEADER_T )
699  m_out->Print( 0, " (type leader)" );
700  else if( aDimension->Type() == PCB_DIM_CENTER_T )
701  m_out->Print( 0, " (type center)" );
702  else if( aDimension->Type() == PCB_DIM_ORTHOGONAL_T )
703  m_out->Print( 0, " (type orthogonal)" );
704  else
705  wxFAIL_MSG( wxT( "Cannot format unknown dimension type!" ) );
706 
707  formatLayer( aDimension );
708 
709  m_out->Print( 0, " (tstamp %s)", TO_UTF8( aDimension->m_Uuid.AsString() ) );
710 
711  m_out->Print( 0, "\n" );
712 
713  m_out->Print( aNestLevel+1, "(pts (xy %s %s) (xy %s %s))\n",
714  FormatInternalUnits( aDimension->GetStart().x ).c_str(),
715  FormatInternalUnits( aDimension->GetStart().y ).c_str(),
716  FormatInternalUnits( aDimension->GetEnd().x ).c_str(),
717  FormatInternalUnits( aDimension->GetEnd().y ).c_str() );
718 
719  if( aligned )
720  m_out->Print( aNestLevel+1, "(height %s)\n",
721  FormatInternalUnits( aligned->GetHeight() ).c_str() );
722 
723  if( ortho )
724  m_out->Print( aNestLevel+1, "(orientation %d)\n",
725  static_cast<int>( ortho->GetOrientation() ) );
726 
727  if( !center )
728  {
729  Format( &aDimension->Text(), aNestLevel + 1 );
730 
731  m_out->Print( aNestLevel + 1, "(format" );
732 
733  if( !aDimension->GetPrefix().IsEmpty() )
734  m_out->Print( 0, " (prefix %s)", m_out->Quotew( aDimension->GetPrefix() ).c_str() );
735 
736  if( !aDimension->GetSuffix().IsEmpty() )
737  m_out->Print( 0, " (suffix %s)", m_out->Quotew( aDimension->GetSuffix() ).c_str() );
738 
739  m_out->Print( 0, " (units %d) (units_format %d) (precision %d)",
740  static_cast<int>( aDimension->GetUnitsMode() ),
741  static_cast<int>( aDimension->GetUnitsFormat() ), aDimension->GetPrecision() );
742 
743  if( aDimension->GetOverrideTextEnabled() )
744  m_out->Print( 0, " (override_value %s)",
745  m_out->Quotew( aDimension->GetOverrideText() ).c_str() );
746 
747  if( aDimension->GetSuppressZeroes() )
748  m_out->Print( 0, " suppress_zeroes" );
749 
750  m_out->Print( 0, ")\n" );
751  }
752 
753  m_out->Print( aNestLevel+1, "(style (thickness %s) (arrow_length %s) (text_position_mode %d)",
754  FormatInternalUnits( aDimension->GetLineThickness() ).c_str(),
755  FormatInternalUnits( aDimension->GetArrowLength() ).c_str(),
756  static_cast<int>( aDimension->GetTextPositionMode() ) );
757 
758  if( aligned )
759  {
760  m_out->Print( 0, " (extension_height %s)",
761  FormatInternalUnits( aligned->GetExtensionHeight() ).c_str() );
762  }
763 
764  if( leader )
765  m_out->Print( 0, " (text_frame %d)", static_cast<int>( leader->GetTextFrame() ) );
766 
767  m_out->Print( 0, " (extension_offset %s)",
768  FormatInternalUnits( aDimension->GetExtensionOffset() ).c_str() );
769 
770  if( aDimension->GetKeepTextAligned() )
771  m_out->Print( 0, " keep_text_aligned" );
772 
773  m_out->Print( 0, ")\n" );
774 
775  m_out->Print( aNestLevel, ")\n" );
776 }
bool GetSuppressZeroes() const
Definition: dimension.h:172
OUTPUTFORMATTER * m_out
output any Format()s to this, no ownership
bool GetOverrideTextEnabled() const
Definition: dimension.h:130
class ALIGNED_DIMENSION, a linear dimension (graphic item)
Definition: typeinfo.h:100
class LEADER, a leader dimension (graphic item)
Definition: typeinfo.h:101
void formatLayer(const BOARD_ITEM *aItem) const
DIM_UNITS_FORMAT GetUnitsFormat() const
Definition: dimension.h:166
DIM_UNITS_MODE GetUnitsMode() const
Definition: dimension.cpp:150
DIM_TEXT_FRAME GetTextFrame() const
Definition: dimension.h:502
class CENTER_DIMENSION, a center point marking (graphic item)
Definition: typeinfo.h:102
virtual const wxPoint & GetStart() const
The dimension's origin is the first feature point for the dimension.
Definition: dimension.h:121
DIM_TEXT_POSITION GetTextPositionMode() const
Definition: dimension.h:179
wxString AsString() const
Definition: kiid.cpp:218
wxString GetOverrideText() const
Definition: dimension.h:133
int GetPrecision() const
Definition: dimension.h:169
int GetLineThickness() const
Definition: dimension.h:187
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
wxString GetSuffix() const
Definition: dimension.h:155
wxString GetPrefix() const
Definition: dimension.h:152
A leader is a dimension-like object pointing to a specific point.
Definition: dimension.h:478
int GetExtensionHeight() const
Definition: dimension.h:381
PCB_TEXT & Text()
Definition: dimension.h:209
An orthogonal dimension is like an aligned dimension, but the extension lines are locked to the X or ...
Definition: dimension.h:414
const KIID m_Uuid
Definition: eda_item.h:525
int GetHeight() const
Definition: dimension.h:372
void Format(const BOARD_ITEM *aItem, int aNestLevel=0) const
Output aItem to aFormatter in s-expression format.
class ORTHOGONAL_DIMENSION, a linear dimension constrained to x/y
Definition: typeinfo.h:103
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:408
For better understanding of the points that make a dimension:
Definition: dimension.h:334
bool GetKeepTextAligned() const
Definition: dimension.h:175
virtual const wxPoint & GetEnd() const
Definition: dimension.h:124
int GetArrowLength() const
Definition: dimension.h:181
int GetExtensionOffset() const
Definition: dimension.h:185
std::string FormatInternalUnits(int aValue)
Function FormatInternalUnits converts aValue from internal units to a string appropriate for writing ...
Definition: base_units.cpp:471
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:163
std::string Quotew(const wxString &aWrapee) const
Definition: richio.cpp:476
Marks the center of a circle or arc with a cross shape The size and orientation of the cross is adjus...
Definition: dimension.h:517

References KIID::AsString(), Format(), FormatInternalUnits(), formatLayer(), DIMENSION_BASE::GetArrowLength(), DIMENSION_BASE::GetEnd(), ALIGNED_DIMENSION::GetExtensionHeight(), DIMENSION_BASE::GetExtensionOffset(), ALIGNED_DIMENSION::GetHeight(), DIMENSION_BASE::GetKeepTextAligned(), DIMENSION_BASE::GetLineThickness(), DIMENSION_BASE::GetOverrideText(), DIMENSION_BASE::GetOverrideTextEnabled(), DIMENSION_BASE::GetPrecision(), DIMENSION_BASE::GetPrefix(), DIMENSION_BASE::GetStart(), DIMENSION_BASE::GetSuffix(), DIMENSION_BASE::GetSuppressZeroes(), LEADER::GetTextFrame(), DIMENSION_BASE::GetTextPositionMode(), DIMENSION_BASE::GetUnitsFormat(), DIMENSION_BASE::GetUnitsMode(), m_out, EDA_ITEM::m_Uuid, ortho, PCB_DIM_ALIGNED_T, PCB_DIM_CENTER_T, PCB_DIM_LEADER_T, PCB_DIM_ORTHOGONAL_T, OUTPUTFORMATTER::Print(), OUTPUTFORMATTER::Quotew(), DIMENSION_BASE::Text(), TO_UTF8, and EDA_ITEM::Type().

◆ format() [3/12]

void PCB_IO::format ( const FP_SHAPE aFPShape,
int  aNestLevel = 0 
) const
private

Definition at line 882 of file kicad_plugin.cpp.

883 {
884  switch( aFPShape->GetShape() )
885  {
886  case S_SEGMENT: // Line
887  m_out->Print( aNestLevel, "(fp_line (start %s) (end %s)",
888  FormatInternalUnits( aFPShape->GetStart0() ).c_str(),
889  FormatInternalUnits( aFPShape->GetEnd0() ).c_str() );
890  break;
891 
892  case S_RECT: // Rectangle
893  m_out->Print( aNestLevel, "(fp_rect (start %s) (end %s)",
894  FormatInternalUnits( aFPShape->GetStart0() ).c_str(),
895  FormatInternalUnits( aFPShape->GetEnd0() ).c_str() );
896  break;
897 
898  case S_CIRCLE: // Circle
899  m_out->Print( aNestLevel, "(fp_circle (center %s) (end %s)",
900  FormatInternalUnits( aFPShape->GetStart0() ).c_str(),
901  FormatInternalUnits( aFPShape->GetEnd0() ).c_str() );
902  break;
903 
904  case S_ARC: // Arc
905  m_out->Print( aNestLevel, "(fp_arc (start %s) (end %s) (angle %s)",
906  FormatInternalUnits( aFPShape->GetStart0() ).c_str(),
907  FormatInternalUnits( aFPShape->GetEnd0() ).c_str(),
908  FormatAngle( aFPShape->GetAngle() ).c_str() );
909  break;
910 
911  case S_POLYGON: // Polygonal segment
912  if( aFPShape->IsPolyShapeValid() )
913  {
914  const SHAPE_POLY_SET& poly = aFPShape->GetPolyShape();
915  const SHAPE_LINE_CHAIN& outline = poly.Outline( 0 );
916  int pointsCount = outline.PointCount();
917 
918  m_out->Print( aNestLevel, "(fp_poly (pts" );
919 
920  for( int ii = 0; ii < pointsCount; ++ii )
921  {
922  int nestLevel = 0;
923 
924  if( ii && ( !( ii%4 ) || !ADVANCED_CFG::GetCfg().m_CompactSave ) ) // newline every 4 pts
925  {
926  nestLevel = aNestLevel + 1;
927  m_out->Print( 0, "\n" );
928  }
929 
930  m_out->Print( nestLevel, "%s(xy %s)",
931  nestLevel ? "" : " ", FormatInternalUnits( outline.CPoint( ii ) ).c_str() );
932  }
933 
934  m_out->Print( 0, ")" );
935  }
936  else
937  {
938  wxFAIL_MSG( wxT( "Cannot format invalid polygon." ) );
939  return;
940  }
941  break;
942 
943  case S_CURVE: // Bezier curve
944  m_out->Print( aNestLevel, "(fp_curve (pts (xy %s) (xy %s) (xy %s) (xy %s))",
945  FormatInternalUnits( aFPShape->GetStart0() ).c_str(),
946  FormatInternalUnits( aFPShape->GetBezier0_C1() ).c_str(),
947  FormatInternalUnits( aFPShape->GetBezier0_C2() ).c_str(),
948  FormatInternalUnits( aFPShape->GetEnd0() ).c_str() );
949  break;
950 
951  default:
952  wxFAIL_MSG( "PCB_IO::format cannot format unknown FP_SHAPE shape:"
953  + PCB_SHAPE_TYPE_T_asString( aFPShape->GetShape() ) );
954  return;
955  };
956 
957  formatLayer( aFPShape );
958 
959  m_out->Print( 0, " (width %s)", FormatInternalUnits( aFPShape->GetWidth() ).c_str() );
960 
961  // The filled flag represents if a solid fill is present on circles, rectangles and polygons
962  if( ( aFPShape->GetShape() == S_POLYGON ) || ( aFPShape->GetShape() == S_RECT )
963  || ( aFPShape->GetShape() == S_CIRCLE ) )
964  {
965  if( aFPShape->IsFilled() )
966  m_out->Print( 0, " (fill solid)" );
967  else
968  m_out->Print( 0, " (fill none)" );
969  }
970 
971  if( aFPShape->IsLocked() )
972  m_out->Print( 0, " (locked)" );
973 
974  m_out->Print( 0, " (tstamp %s)", TO_UTF8( aFPShape->m_Uuid.AsString() ) );
975 
976  m_out->Print( 0, ")\n" );
977 }
bool IsPolyShapeValid() const
Definition: pcb_shape.cpp:1215
OUTPUTFORMATTER * m_out
output any Format()s to this, no ownership
bool IsFilled() const
Definition: pcb_shape.h:96
void formatLayer(const BOARD_ITEM *aItem) const
SHAPE_POLY_SET & GetPolyShape()
Definition: pcb_shape.h:268
int GetWidth() const
Definition: pcb_shape.h:118
polygon (not yet used for tracks, but could be in microwave apps)
Definition: board_item.h:54
const wxPoint & GetStart0() const
Definition: fp_shape.h:112
usual segment : line with rounded ends
Definition: board_item.h:50
wxString AsString() const
Definition: kiid.cpp:218
Arcs (with rounded ends)
Definition: board_item.h:52
segment with non rounded ends
Definition: board_item.h:51
int PointCount() const
Function PointCount()
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
const VECTOR2I & CPoint(int aIndex) const
Function Point()
std::string FormatAngle(double aAngle)
Function FormatAngle converts aAngle from board units to a string appropriate for writing to file.
Definition: base_units.cpp:506
Represent a set of closed polygons.
SHAPE_LINE_CHAIN & Outline(int aIndex)
static wxString PCB_SHAPE_TYPE_T_asString(PCB_SHAPE_TYPE_T a)
Definition: board_item.h:59
const KIID m_Uuid
Definition: eda_item.h:525
const wxPoint & GetBezier0_C2() const
Definition: fp_shape.h:124
virtual bool IsLocked() const
Definition: board_item.h:249
const wxPoint & GetBezier0_C1() const
Definition: fp_shape.h:121
SHAPE_LINE_CHAIN.
double GetAngle() const
Definition: pcb_shape.h:127
const wxPoint & GetEnd0() const
Definition: fp_shape.h:115
ring
Definition: board_item.h:53
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
PCB_SHAPE_TYPE_T GetShape() const
Definition: pcb_shape.h:130
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:408
Bezier Curve.
Definition: board_item.h:55
std::string FormatInternalUnits(int aValue)
Function FormatInternalUnits converts aValue from internal units to a string appropriate for writing ...
Definition: base_units.cpp:471

References KIID::AsString(), SHAPE_LINE_CHAIN::CPoint(), FormatAngle(), FormatInternalUnits(), formatLayer(), PCB_SHAPE::GetAngle(), FP_SHAPE::GetBezier0_C1(), FP_SHAPE::GetBezier0_C2(), ADVANCED_CFG::GetCfg(), FP_SHAPE::GetEnd0(), PCB_SHAPE::GetPolyShape(), PCB_SHAPE::GetShape(), FP_SHAPE::GetStart0(), PCB_SHAPE::GetWidth(), PCB_SHAPE::IsFilled(), BOARD_ITEM::IsLocked(), PCB_SHAPE::IsPolyShapeValid(), m_out, EDA_ITEM::m_Uuid, SHAPE_POLY_SET::Outline(), PCB_SHAPE_TYPE_T_asString(), SHAPE_LINE_CHAIN::PointCount(), OUTPUTFORMATTER::Print(), S_ARC, S_CIRCLE, S_CURVE, S_POLYGON, S_RECT, S_SEGMENT, and TO_UTF8.

◆ format() [4/12]

void PCB_IO::format ( const PCB_GROUP aGroup,
int  aNestLevel = 0 
) const
private

Definition at line 1644 of file kicad_plugin.cpp.

1645 {
1646  // Don't write empty groups
1647  if( aGroup->GetItems().empty() )
1648  return;
1649 
1650  m_out->Print( aNestLevel, "(group %s (id %s)\n",
1651  m_out->Quotew( aGroup->GetName() ).c_str(),
1652  TO_UTF8( aGroup->m_Uuid.AsString() ) );
1653 
1654  m_out->Print( aNestLevel + 1, "(members\n" );
1655 
1656  wxArrayString memberIds;
1657 
1658  for( BOARD_ITEM* member : aGroup->GetItems() )
1659  memberIds.Add( member->m_Uuid.AsString() );
1660 
1661  memberIds.Sort();
1662 
1663  for( const wxString& memberId : memberIds )
1664  m_out->Print( aNestLevel + 2, "%s\n", TO_UTF8( memberId ) );
1665 
1666  m_out->Print( 0, " )\n" );
1667  m_out->Print( aNestLevel, ")\n" );
1668 }
OUTPUTFORMATTER * m_out
output any Format()s to this, no ownership
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:82
wxString AsString() const
Definition: kiid.cpp:218
std::unordered_set< BOARD_ITEM * > & GetItems()
Definition: pcb_group.h:68
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
wxString GetName() const
Definition: pcb_group.h:65
const KIID m_Uuid
Definition: eda_item.h:525
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:408
std::string Quotew(const wxString &aWrapee) const
Definition: richio.cpp:476

References KIID::AsString(), PCB_GROUP::GetItems(), PCB_GROUP::GetName(), m_out, EDA_ITEM::m_Uuid, OUTPUTFORMATTER::Print(), OUTPUTFORMATTER::Quotew(), and TO_UTF8.

◆ format() [5/12]

void PCB_IO::format ( const PCB_SHAPE aSegment,
int  aNestLevel = 0 
) const
private

Definition at line 779 of file kicad_plugin.cpp.

780 {
781  switch( aShape->GetShape() )
782  {
783  case S_SEGMENT: // Line
784  m_out->Print( aNestLevel, "(gr_line (start %s) (end %s)",
785  FormatInternalUnits( aShape->GetStart() ).c_str(),
786  FormatInternalUnits( aShape->GetEnd() ).c_str() );
787 
788  if( aShape->GetAngle() != 0.0 )
789  m_out->Print( 0, " (angle %s)", FormatAngle( aShape->GetAngle() ).c_str() );
790 
791  break;
792 
793  case S_RECT: // Rectangle
794  m_out->Print( aNestLevel, "(gr_rect (start %s) (end %s)",
795  FormatInternalUnits( aShape->GetStart() ).c_str(),
796  FormatInternalUnits( aShape->GetEnd() ).c_str() );
797  break;
798 
799  case S_CIRCLE: // Circle
800  m_out->Print( aNestLevel, "(gr_circle (center %s) (end %s)",
801  FormatInternalUnits( aShape->GetStart() ).c_str(),
802  FormatInternalUnits( aShape->GetEnd() ).c_str() );
803  break;
804 
805  case S_ARC: // Arc
806  m_out->Print( aNestLevel, "(gr_arc (start %s) (end %s) (angle %s)",
807  FormatInternalUnits( aShape->GetStart() ).c_str(),
808  FormatInternalUnits( aShape->GetEnd() ).c_str(),
809  FormatAngle( aShape->GetAngle() ).c_str() );
810  break;
811 
812  case S_POLYGON: // Polygon
813  if( aShape->IsPolyShapeValid() )
814  {
815  const SHAPE_POLY_SET& poly = aShape->GetPolyShape();
816  const SHAPE_LINE_CHAIN& outline = poly.Outline( 0 );
817  const int pointsCount = outline.PointCount();
818 
819  m_out->Print( aNestLevel, "(gr_poly (pts\n" );
820 
821  for( int ii = 0; ii < pointsCount; ++ii )
822  {
823  int nestLevel = 0;
824 
825  if( ii && ( !( ii%4 ) || !ADVANCED_CFG::GetCfg().m_CompactSave ) ) // newline every 4 pts
826  {
827  nestLevel = aNestLevel + 1;
828  m_out->Print( 0, "\n" );
829  }
830 
831  m_out->Print( nestLevel, "%s(xy %s)",
832  nestLevel ? "" : " ", FormatInternalUnits( outline.CPoint( ii ) ).c_str() );
833  }
834 
835  m_out->Print( 0, ")" );
836  }
837  else
838  {
839  wxFAIL_MSG( wxT( "Cannot format invalid polygon." ) );
840  return;
841  }
842 
843  break;
844 
845  case S_CURVE: // Bezier curve
846  m_out->Print( aNestLevel, "(gr_curve (pts (xy %s) (xy %s) (xy %s) (xy %s))",
847  FormatInternalUnits( aShape->GetStart() ).c_str(),
848  FormatInternalUnits( aShape->GetBezControl1() ).c_str(),
849  FormatInternalUnits( aShape->GetBezControl2() ).c_str(),
850  FormatInternalUnits( aShape->GetEnd() ).c_str() );
851  break;
852 
853  default:
854  wxFAIL_MSG( "PCB_IO::format cannot format unknown PCB_SHAPE shape:"
855  + PCB_SHAPE_TYPE_T_asString( aShape->GetShape()) );
856  return;
857  };
858 
859  formatLayer( aShape );
860 
861  m_out->Print( 0, " (width %s)", FormatInternalUnits( aShape->GetWidth() ).c_str() );
862 
863  // The filled flag represents if a solid fill is present on circles, rectangles and polygons
864  if( ( aShape->GetShape() == S_POLYGON ) || ( aShape->GetShape() == S_RECT )
865  || ( aShape->GetShape() == S_CIRCLE ) )
866  {
867  if( aShape->IsFilled() )
868  m_out->Print( 0, " (fill solid)" );
869  else
870  m_out->Print( 0, " (fill none)" );
871  }
872 
873  if( aShape->IsLocked() )
874  m_out->Print( 0, " (locked)" );
875 
876  m_out->Print( 0, " (tstamp %s)", TO_UTF8( aShape->m_Uuid.AsString() ) );
877 
878  m_out->Print( 0, ")\n" );
879 }
OUTPUTFORMATTER * m_out
output any Format()s to this, no ownership
void formatLayer(const BOARD_ITEM *aItem) const
polygon (not yet used for tracks, but could be in microwave apps)
Definition: board_item.h:54
usual segment : line with rounded ends
Definition: board_item.h:50
Arcs (with rounded ends)
Definition: board_item.h:52
segment with non rounded ends
Definition: board_item.h:51
int PointCount() const
Function PointCount()
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
const VECTOR2I & CPoint(int aIndex) const
Function Point()
std::string FormatAngle(double aAngle)
Function FormatAngle converts aAngle from board units to a string appropriate for writing to file.
Definition: base_units.cpp:506
Represent a set of closed polygons.
SHAPE_LINE_CHAIN & Outline(int aIndex)
static wxString PCB_SHAPE_TYPE_T_asString(PCB_SHAPE_TYPE_T a)
Definition: board_item.h:59
SHAPE_LINE_CHAIN.
ring
Definition: board_item.h:53
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:408
Bezier Curve.
Definition: board_item.h:55
std::string FormatInternalUnits(int aValue)
Function FormatInternalUnits converts aValue from internal units to a string appropriate for writing ...
Definition: base_units.cpp:471

References KIID::AsString(), SHAPE_LINE_CHAIN::CPoint(), FormatAngle(), FormatInternalUnits(), formatLayer(), PCB_SHAPE::GetAngle(), PCB_SHAPE::GetBezControl1(), PCB_SHAPE::GetBezControl2(), ADVANCED_CFG::GetCfg(), PCB_SHAPE::GetEnd(), PCB_SHAPE::GetPolyShape(), PCB_SHAPE::GetShape(), PCB_SHAPE::GetStart(), PCB_SHAPE::GetWidth(), PCB_SHAPE::IsFilled(), BOARD_ITEM::IsLocked(), PCB_SHAPE::IsPolyShapeValid(), m_out, EDA_ITEM::m_Uuid, SHAPE_POLY_SET::Outline(), PCB_SHAPE_TYPE_T_asString(), SHAPE_LINE_CHAIN::PointCount(), OUTPUTFORMATTER::Print(), S_ARC, S_CIRCLE, S_CURVE, S_POLYGON, S_RECT, S_SEGMENT, and TO_UTF8.

◆ format() [6/12]

void PCB_IO::format ( const PCB_TARGET aTarget,
int  aNestLevel = 0 
) const
private

Definition at line 980 of file kicad_plugin.cpp.

981 {
982  m_out->Print( aNestLevel, "(target %s (at %s) (size %s)",
983  ( aTarget->GetShape() ) ? "x" : "plus",
984  FormatInternalUnits( aTarget->GetPosition() ).c_str(),
985  FormatInternalUnits( aTarget->GetSize() ).c_str() );
986 
987  if( aTarget->GetWidth() != 0 )
988  m_out->Print( 0, " (width %s)", FormatInternalUnits( aTarget->GetWidth() ).c_str() );
989 
990  formatLayer( aTarget );
991 
992  m_out->Print( 0, " (tstamp %s)", TO_UTF8( aTarget->m_Uuid.AsString() ) );
993 
994  m_out->Print( 0, ")\n" );
995 }
OUTPUTFORMATTER * m_out
output any Format()s to this, no ownership
void formatLayer(const BOARD_ITEM *aItem) const
int GetSize() const
Definition: pcb_target.h:67
wxString AsString() const
Definition: kiid.cpp:218
wxPoint GetPosition() const override
Definition: pcb_target.h:61
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
int GetWidth() const
Definition: pcb_target.h:70
const KIID m_Uuid
Definition: eda_item.h:525
int GetShape() const
Definition: pcb_target.h:64
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:408
std::string FormatInternalUnits(int aValue)
Function FormatInternalUnits converts aValue from internal units to a string appropriate for writing ...
Definition: base_units.cpp:471

References KIID::AsString(), FormatInternalUnits(), formatLayer(), PCB_TARGET::GetPosition(), PCB_TARGET::GetShape(), PCB_TARGET::GetSize(), PCB_TARGET::GetWidth(), m_out, EDA_ITEM::m_Uuid, OUTPUTFORMATTER::Print(), and TO_UTF8.

◆ format() [7/12]

void PCB_IO::format ( const FOOTPRINT aFootprint,
int  aNestLevel = 0 
) const
private

Definition at line 998 of file kicad_plugin.cpp.

999 {
1000  if( !( m_ctl & CTL_OMIT_INITIAL_COMMENTS ) )
1001  {
1002  const wxArrayString* initial_comments = aFootprint->GetInitialComments();
1003 
1004  if( initial_comments )
1005  {
1006  for( unsigned i = 0; i < initial_comments->GetCount(); ++i )
1007  m_out->Print( aNestLevel, "%s\n", TO_UTF8( (*initial_comments)[i] ) );
1008 
1009  m_out->Print( 0, "\n" ); // improve readability?
1010  }
1011  }
1012 
1013  if( m_ctl & CTL_OMIT_LIBNAME )
1014  m_out->Print( aNestLevel, "(footprint %s",
1015  m_out->Quotes( aFootprint->GetFPID().GetLibItemNameAndRev() ).c_str() );
1016  else
1017  m_out->Print( aNestLevel, "(footprint %s",
1018  m_out->Quotes( aFootprint->GetFPID().Format() ).c_str() );
1019 
1020  if( !( m_ctl & CTL_OMIT_FOOTPRINT_VERSION ) )
1021  m_out->Print( 0, " (version %d) (generator pcbnew)", SEXPR_BOARD_FILE_VERSION );
1022 
1023  if( aFootprint->IsLocked() )
1024  m_out->Print( 0, " locked" );
1025 
1026  if( aFootprint->IsPlaced() )
1027  m_out->Print( 0, " placed" );
1028 
1029  formatLayer( aFootprint );
1030 
1031  m_out->Print( 0, "\n" );
1032  m_out->Print( aNestLevel+1, "(tedit %lX)", (unsigned long)aFootprint->GetLastEditTime() );
1033 
1034  if( !( m_ctl & CTL_OMIT_TSTAMPS ) )
1035  m_out->Print( 0, " (tstamp %s)", TO_UTF8( aFootprint->m_Uuid.AsString() ) );
1036 
1037  m_out->Print( 0, "\n" );
1038 
1039  if( !( m_ctl & CTL_OMIT_AT ) )
1040  {
1041  m_out->Print( aNestLevel+1, "(at %s", FormatInternalUnits( aFootprint->GetPosition() ).c_str() );
1042 
1043  if( aFootprint->GetOrientation() != 0.0 )
1044  m_out->Print( 0, " %s", FormatAngle( aFootprint->GetOrientation() ).c_str() );
1045 
1046  m_out->Print( 0, ")\n" );
1047  }
1048 
1049  if( !aFootprint->GetDescription().IsEmpty() )
1050  m_out->Print( aNestLevel+1, "(descr %s)\n",
1051  m_out->Quotew( aFootprint->GetDescription() ).c_str() );
1052 
1053  if( !aFootprint->GetKeywords().IsEmpty() )
1054  m_out->Print( aNestLevel+1, "(tags %s)\n",
1055  m_out->Quotew( aFootprint->GetKeywords() ).c_str() );
1056 
1057  const std::map<wxString, wxString>& props = aFootprint->GetProperties();
1058 
1059  for( const std::pair<const wxString, wxString>& prop : props )
1060  {
1061  m_out->Print( aNestLevel+1, "(property %s %s)\n",
1062  m_out->Quotew( prop.first ).c_str(),
1063  m_out->Quotew( prop.second ).c_str() );
1064  }
1065 
1066  if( !( m_ctl & CTL_OMIT_PATH ) && !aFootprint->GetPath().empty() )
1067  m_out->Print( aNestLevel+1, "(path %s)\n",
1068  m_out->Quotew( aFootprint->GetPath().AsString() ).c_str() );
1069 
1070  if( aFootprint->GetPlacementCost90() != 0 )
1071  m_out->Print( aNestLevel+1, "(autoplace_cost90 %d)\n", aFootprint->GetPlacementCost90() );
1072 
1073  if( aFootprint->GetPlacementCost180() != 0 )
1074  m_out->Print( aNestLevel+1, "(autoplace_cost180 %d)\n", aFootprint->GetPlacementCost180() );
1075 
1076  if( aFootprint->GetLocalSolderMaskMargin() != 0 )
1077  m_out->Print( aNestLevel+1, "(solder_mask_margin %s)\n",
1078  FormatInternalUnits( aFootprint->GetLocalSolderMaskMargin() ).c_str() );
1079 
1080  if( aFootprint->GetLocalSolderPasteMargin() != 0 )
1081  m_out->Print( aNestLevel+1, "(solder_paste_margin %s)\n",
1082  FormatInternalUnits( aFootprint->GetLocalSolderPasteMargin() ).c_str() );
1083 
1084  if( aFootprint->GetLocalSolderPasteMarginRatio() != 0 )
1085  m_out->Print( aNestLevel+1, "(solder_paste_ratio %s)\n",
1086  Double2Str( aFootprint->GetLocalSolderPasteMarginRatio() ).c_str() );
1087 
1088  if( aFootprint->GetLocalClearance() != 0 )
1089  m_out->Print( aNestLevel+1, "(clearance %s)\n",
1090  FormatInternalUnits( aFootprint->GetLocalClearance() ).c_str() );
1091 
1092  if( aFootprint->GetZoneConnection() != ZONE_CONNECTION::INHERITED )
1093  m_out->Print( aNestLevel+1, "(zone_connect %d)\n",
1094  static_cast<int>( aFootprint->GetZoneConnection() ) );
1095 
1096  if( aFootprint->GetThermalWidth() != 0 )
1097  m_out->Print( aNestLevel+1, "(thermal_width %s)\n",
1098  FormatInternalUnits( aFootprint->GetThermalWidth() ).c_str() );
1099 
1100  if( aFootprint->GetThermalGap() != 0 )
1101  m_out->Print( aNestLevel+1, "(thermal_gap %s)\n",
1102  FormatInternalUnits( aFootprint->GetThermalGap() ).c_str() );
1103 
1104  // Attributes
1105  if( aFootprint->GetAttributes() )
1106  {
1107  m_out->Print( aNestLevel+1, "(attr" );
1108 
1109  if( aFootprint->GetAttributes() & FP_SMD )
1110  m_out->Print( 0, " smd" );
1111 
1112  if( aFootprint->GetAttributes() & FP_THROUGH_HOLE )
1113  m_out->Print( 0, " through_hole" );
1114 
1115  if( aFootprint->GetAttributes() & FP_BOARD_ONLY )
1116  m_out->Print( 0, " board_only" );
1117 
1118  if( aFootprint->GetAttributes() & FP_EXCLUDE_FROM_POS_FILES )
1119  m_out->Print( 0, " exclude_from_pos_files" );
1120 
1121  if( aFootprint->GetAttributes() & FP_EXCLUDE_FROM_BOM )
1122  m_out->Print( 0, " exclude_from_bom" );
1123 
1124  m_out->Print( 0, ")\n" );
1125  }
1126 
1127  Format((BOARD_ITEM*) &aFootprint->Reference(), aNestLevel + 1 );
1128  Format((BOARD_ITEM*) &aFootprint->Value(), aNestLevel + 1 );
1129 
1130  std::set<PAD*, FOOTPRINT::cmp_pads> sorted_pads( aFootprint->Pads().begin(),
1131  aFootprint->Pads().end() );
1132  std::set<BOARD_ITEM*, FOOTPRINT::cmp_drawings> sorted_drawings( aFootprint->GraphicalItems().begin(),
1133  aFootprint->GraphicalItems().end() );
1134  std::set<BOARD_ITEM*, BOARD_ITEM::ptr_cmp> sorted_zones( aFootprint->Zones().begin(),
1135  aFootprint->Zones().end() );
1136  std::set<BOARD_ITEM*, PCB_GROUP::ptr_cmp> sorted_groups( aFootprint->Groups().begin(),
1137  aFootprint->Groups().end() );
1138 
1139  // Save drawing elements.
1140 
1141  for( BOARD_ITEM* gr : sorted_drawings )
1142  Format( gr, aNestLevel+1 );
1143 
1144  // Save pads.
1145  for( PAD* pad : sorted_pads )
1146  Format( pad, aNestLevel+1 );
1147 
1148  // Save zones.
1149  for( BOARD_ITEM* zone : sorted_zones )
1150  Format( zone, aNestLevel + 1 );
1151 
1152  // Save groups.
1153  for( BOARD_ITEM* group : sorted_groups )
1154  Format( group, aNestLevel + 1 );
1155 
1156  // Save 3D info.
1157  auto bs3D = aFootprint->Models().begin();
1158  auto es3D = aFootprint->Models().end();
1159 
1160  while( bs3D != es3D )
1161  {
1162  if( !bs3D->m_Filename.IsEmpty() )
1163  {
1164  m_out->Print( aNestLevel+1, "(model %s%s\n",
1165  m_out->Quotew( bs3D->m_Filename ).c_str(),
1166  bs3D->m_Show ? "" : " hide" );
1167 
1168  if( bs3D->m_Opacity != 1.0 )
1169  m_out->Print( aNestLevel+2, "(opacity %0.4f)", bs3D->m_Opacity );
1170 
1171  m_out->Print( aNestLevel+2, "(offset (xyz %s %s %s))\n",
1172  Double2Str( bs3D->m_Offset.x ).c_str(),
1173  Double2Str( bs3D->m_Offset.y ).c_str(),
1174  Double2Str( bs3D->m_Offset.z ).c_str() );
1175 
1176  m_out->Print( aNestLevel+2, "(scale (xyz %s %s %s))\n",
1177  Double2Str( bs3D->m_Scale.x ).c_str(),
1178  Double2Str( bs3D->m_Scale.y ).c_str(),
1179  Double2Str( bs3D->m_Scale.z ).c_str() );
1180 
1181  m_out->Print( aNestLevel+2, "(rotate (xyz %s %s %s))\n",
1182  Double2Str( bs3D->m_Rotation.x ).c_str(),
1183  Double2Str( bs3D->m_Rotation.y ).c_str(),
1184  Double2Str( bs3D->m_Rotation.z ).c_str() );
1185 
1186  m_out->Print( aNestLevel+1, ")\n" );
1187  }
1188  ++bs3D;
1189  }
1190 
1191  m_out->Print( aNestLevel, ")\n" );
1192 }
bool IsLocked() const override
Definition: footprint.h:282
OUTPUTFORMATTER * m_out
output any Format()s to this, no ownership
const wxString & GetDescription() const
Definition: footprint.h:193
std::list< FP_3DMODEL > & Models()
Definition: footprint.h:178
void formatLayer(const BOARD_ITEM *aItem) const
#define CTL_OMIT_AT
Omit position and rotation.
const KIID_PATH & GetPath() const
Definition: footprint.h:199
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:82
int GetPlacementCost180() const
Definition: footprint.h:534
#define CTL_OMIT_TSTAMPS
Omit component time stamp (useless in library)
double GetOrientation() const
Definition: footprint.h:186
#define CTL_OMIT_INITIAL_COMMENTS
omit FOOTPRINT initial comments
wxString AsString() const
Definition: kiid.cpp:218
virtual std::string Quotes(const std::string &aWrapee) const
Check aWrapee input string for a need to be quoted (e.g.
Definition: richio.cpp:437
timestamp_t GetLastEditTime() const
Definition: footprint.h:332
PADS & Pads()
Definition: footprint.h:164
#define CTL_OMIT_FOOTPRINT_VERSION
Omit the version string from the (footprint)
FP_TEXT & Value()
read/write accessors:
Definition: footprint.h:462
UTF8 GetLibItemNameAndRev() const
Definition: lib_id.cpp:255
FP_TEXT & Reference()
Definition: footprint.h:463
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
FP_ZONES & Zones()
Definition: footprint.h:170
std::string FormatAngle(double aAngle)
Function FormatAngle converts aAngle from board units to a string appropriate for writing to file.
Definition: base_units.cpp:506
#define CTL_OMIT_LIBNAME
Omit lib alias when saving (used for.
int GetLocalClearance() const
Definition: footprint.h:205
DRAWINGS & GraphicalItems()
Definition: footprint.h:167
bool IsPlaced() const
Definition: footprint.h:300
const LIB_ID & GetFPID() const
Definition: footprint.h:190
const wxString & GetKeywords() const
Definition: footprint.h:196
int GetThermalWidth() const
Definition: footprint.h:226
UTF8 Format() const
Definition: lib_id.cpp:233
const KIID m_Uuid
Definition: eda_item.h:525
const wxArrayString * GetInitialComments() const
Definition: footprint.h:644
FP_GROUPS & Groups()
Definition: footprint.h:173
void Format(const BOARD_ITEM *aItem, int aNestLevel=0) const
Output aItem to aFormatter in s-expression format.
int GetLocalSolderMaskMargin() const
Definition: footprint.h:202
int GetAttributes() const
Definition: footprint.h:231
#define SEXPR_BOARD_FILE_VERSION
Current s-expression file format version. 2 was the last legacy format version.
#define CTL_OMIT_PATH
Omit component sheet time stamp (useless in library)
wxString AsString() const
Definition: kiid.cpp:256
wxPoint GetPosition() const override
Definition: footprint.h:182
double GetLocalSolderPasteMarginRatio() const
Definition: footprint.h:219
const std::map< wxString, wxString > & GetProperties() const
Definition: footprint.h:469
ZONE_CONNECTION GetZoneConnection() const
Definition: footprint.h:223
int GetPlacementCost90() const
Definition: footprint.h:537
int GetLocalSolderPasteMargin() const
Definition: footprint.h:216
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:408
Definition: pad.h:60
int GetThermalGap() const
Definition: footprint.h:229
std::string FormatInternalUnits(int aValue)
Function FormatInternalUnits converts aValue from internal units to a string appropriate for writing ...
Definition: base_units.cpp:471
std::string Quotew(const wxString &aWrapee) const
Definition: richio.cpp:476
std::string Double2Str(double aValue)
Prints a float number without using scientific notation and no trailing 0 We want to avoid scientific...
Definition: string.cpp:872

References KIID::AsString(), KIID_PATH::AsString(), CTL_OMIT_AT, CTL_OMIT_FOOTPRINT_VERSION, CTL_OMIT_INITIAL_COMMENTS, CTL_OMIT_LIBNAME, CTL_OMIT_PATH, CTL_OMIT_TSTAMPS, Double2Str(), LIB_ID::Format(), Format(), FormatAngle(), FormatInternalUnits(), formatLayer(), FP_BOARD_ONLY, FP_EXCLUDE_FROM_BOM, FP_EXCLUDE_FROM_POS_FILES, FP_SMD, FP_THROUGH_HOLE, FOOTPRINT::GetAttributes(), FOOTPRINT::GetDescription(), FOOTPRINT::GetFPID(), FOOTPRINT::GetInitialComments(), FOOTPRINT::GetKeywords(), FOOTPRINT::GetLastEditTime(), LIB_ID::GetLibItemNameAndRev(), FOOTPRINT::GetLocalClearance(), FOOTPRINT::GetLocalSolderMaskMargin(), FOOTPRINT::GetLocalSolderPasteMargin(), FOOTPRINT::GetLocalSolderPasteMarginRatio(), FOOTPRINT::GetOrientation(), FOOTPRINT::GetPath(), FOOTPRINT::GetPlacementCost180(), FOOTPRINT::GetPlacementCost90(), FOOTPRINT::GetPosition(), FOOTPRINT::GetProperties(), FOOTPRINT::GetThermalGap(), FOOTPRINT::GetThermalWidth(), FOOTPRINT::GetZoneConnection(), FOOTPRINT::GraphicalItems(), group, FOOTPRINT::Groups(), INHERITED, FOOTPRINT::IsLocked(), FOOTPRINT::IsPlaced(), m_ctl, m_out, EDA_ITEM::m_Uuid, FOOTPRINT::Models(), pad, FOOTPRINT::Pads(), OUTPUTFORMATTER::Print(), OUTPUTFORMATTER::Quotes(), OUTPUTFORMATTER::Quotew(), FOOTPRINT::Reference(), SEXPR_BOARD_FILE_VERSION, TO_UTF8, FOOTPRINT::Value(), and FOOTPRINT::Zones().

◆ format() [8/12]

void PCB_IO::format ( const PAD aPad,
int  aNestLevel = 0 
) const
private

Definition at line 1282 of file kicad_plugin.cpp.

1283 {
1284  const char* shape;
1285 
1286  switch( aPad->GetShape() )
1287  {
1288  case PAD_SHAPE_CIRCLE: shape = "circle"; break;
1289  case PAD_SHAPE_RECT: shape = "rect"; break;
1290  case PAD_SHAPE_OVAL: shape = "oval"; break;
1291  case PAD_SHAPE_TRAPEZOID: shape = "trapezoid"; break;
1293  case PAD_SHAPE_ROUNDRECT: shape = "roundrect"; break;
1294  case PAD_SHAPE_CUSTOM: shape = "custom"; break;
1295 
1296  default:
1297  THROW_IO_ERROR( wxString::Format( _( "unknown pad type: %d"), aPad->GetShape() ) );
1298  }
1299 
1300  const char* type;
1301 
1302  switch( aPad->GetAttribute() )
1303  {
1304  case PAD_ATTRIB_PTH: type = "thru_hole"; break;
1305  case PAD_ATTRIB_SMD: type = "smd"; break;
1306  case PAD_ATTRIB_CONN: type = "connect"; break;
1307  case PAD_ATTRIB_NPTH: type = "np_thru_hole"; break;
1308 
1309  default:
1310  THROW_IO_ERROR( wxString::Format( "unknown pad attribute: %d", aPad->GetAttribute() ) );
1311  }
1312 
1313  const char* property = nullptr;
1314 
1315  switch( aPad->GetProperty() )
1316  {
1317  case PAD_PROP_NONE: break; // could be also "none"
1318  case PAD_PROP_BGA: property = "pad_prop_bga"; break;
1319  case PAD_PROP_FIDUCIAL_GLBL: property = "pad_prop_fiducial_glob"; break;
1320  case PAD_PROP_FIDUCIAL_LOCAL: property = "pad_prop_fiducial_loc"; break;
1321  case PAD_PROP_TESTPOINT: property = "pad_prop_testpoint"; break;
1322  case PAD_PROP_HEATSINK: property = "pad_prop_heatsink"; break;
1323  case PAD_PROP_CASTELLATED: property = "pad_prop_castellated"; break;
1324 
1325  default:
1326  THROW_IO_ERROR( wxString::Format( "unknown pad property: %d", aPad->GetProperty() ) );
1327  }
1328 
1329  m_out->Print( aNestLevel, "(pad %s %s %s",
1330  m_out->Quotew( aPad->GetName() ).c_str(),
1331  type,
1332  shape );
1333  m_out->Print( 0, " (at %s", FormatInternalUnits( aPad->GetPos0() ).c_str() );
1334 
1335  if( aPad->GetOrientation() != 0.0 )
1336  m_out->Print( 0, " %s", FormatAngle( aPad->GetOrientation() ).c_str() );
1337 
1338  m_out->Print( 0, ")" );
1339 
1340  if( aPad->IsLocked() )
1341  m_out->Print( 0, " (locked)" );
1342 
1343  m_out->Print( 0, " (size %s)", FormatInternalUnits( aPad->GetSize() ).c_str() );
1344 
1345  if( (aPad->GetDelta().GetWidth()) != 0 || (aPad->GetDelta().GetHeight() != 0 ) )
1346  m_out->Print( 0, " (rect_delta %s )", FormatInternalUnits( aPad->GetDelta() ).c_str() );
1347 
1348  wxSize sz = aPad->GetDrillSize();
1349  wxPoint shapeoffset = aPad->GetOffset();
1350 
1351  if( (sz.GetWidth() > 0) || (sz.GetHeight() > 0) ||
1352  (shapeoffset.x != 0) || (shapeoffset.y != 0) )
1353  {
1354  m_out->Print( 0, " (drill" );
1355 
1356  if( aPad->GetDrillShape() == PAD_DRILL_SHAPE_OBLONG )
1357  m_out->Print( 0, " oval" );
1358 
1359  if( sz.GetWidth() > 0 )
1360  m_out->Print( 0, " %s", FormatInternalUnits( sz.GetWidth() ).c_str() );
1361 
1362  if( sz.GetHeight() > 0 && sz.GetWidth() != sz.GetHeight() )
1363  m_out->Print( 0, " %s", FormatInternalUnits( sz.GetHeight() ).c_str() );
1364 
1365  if( (shapeoffset.x != 0) || (shapeoffset.y != 0) )
1366  m_out->Print( 0, " (offset %s)", FormatInternalUnits( aPad->GetOffset() ).c_str() );
1367 
1368  m_out->Print( 0, ")" );
1369  }
1370 
1371  // Add pad property, if exists.
1372  if( property )
1373  m_out->Print( 0, " (property %s)", property );
1374 
1375  formatLayers( aPad->GetLayerSet() );
1376 
1377  if( aPad->GetAttribute() == PAD_ATTRIB_PTH )
1378  {
1379  if( aPad->GetRemoveUnconnected() )
1380  {
1381  m_out->Print( 0, " (remove_unused_layers)" );
1382 
1383  if( aPad->GetKeepTopBottom() )
1384  m_out->Print( 0, " (keep_end_layers)" );
1385  }
1386  }
1387 
1388  // Output the radius ratio for rounded and chamfered rect pads
1389  if( aPad->GetShape() == PAD_SHAPE_ROUNDRECT || aPad->GetShape() == PAD_SHAPE_CHAMFERED_RECT)
1390  {
1391  m_out->Print( 0, " (roundrect_rratio %s)",
1392  Double2Str( aPad->GetRoundRectRadiusRatio() ).c_str() );
1393  }
1394 
1395  // Output the chamfer corners for chamfered rect pads
1396  if( aPad->GetShape() == PAD_SHAPE_CHAMFERED_RECT)
1397  {
1398  m_out->Print( 0, "\n" );
1399 
1400  m_out->Print( aNestLevel+1, "(chamfer_ratio %s)",
1401  Double2Str( aPad->GetChamferRectRatio() ).c_str() );
1402 
1403  m_out->Print( 0, " (chamfer" );
1404 
1405  if( ( aPad->GetChamferPositions() & RECT_CHAMFER_TOP_LEFT ) )
1406  m_out->Print( 0, " top_left" );
1407 
1408  if( ( aPad->GetChamferPositions() & RECT_CHAMFER_TOP_RIGHT ) )
1409  m_out->Print( 0, " top_right" );
1410 
1411  if( ( aPad->GetChamferPositions() & RECT_CHAMFER_BOTTOM_LEFT ) )
1412  m_out->Print( 0, " bottom_left" );
1413 
1415  m_out->Print( 0, " bottom_right" );
1416 
1417  m_out->Print( 0, ")" );
1418  }
1419 
1420  std::string output;
1421 
1422  // Unconnected pad is default net so don't save it.
1423  if( !( m_ctl & CTL_OMIT_PAD_NETS ) && aPad->GetNetCode() != NETINFO_LIST::UNCONNECTED )
1424  {
1425  StrPrintf( &output, " (net %d %s)", m_mapping->Translate( aPad->GetNetCode() ),
1426  m_out->Quotew( aPad->GetNetname() ).c_str() );
1427  }
1428 
1429  // Pin functions and types are closely related to nets, so if CTL_OMIT_NETS is set, omit
1430  // them as well (for instance when saved from library editor).
1431  if( !( m_ctl & CTL_OMIT_PAD_NETS ) )
1432  {
1433  if( !aPad->GetPinFunction().IsEmpty() )
1434  {
1435  StrPrintf( &output, " (pinfunction %s)",
1436  m_out->Quotew( aPad->GetPinFunction() ).c_str() );
1437  }
1438 
1439  if( !aPad->GetPinType().IsEmpty() )
1440  {
1441  StrPrintf( &output, " (pintype %s)",
1442  m_out->Quotew( aPad->GetPinType() ).c_str() );
1443  }
1444  }
1445 
1446  if( aPad->GetPadToDieLength() != 0 )
1447  {
1448  StrPrintf( &output, " (die_length %s)",
1449  FormatInternalUnits( aPad->GetPadToDieLength() ).c_str() );
1450  }
1451 
1452  if( aPad->GetLocalSolderMaskMargin() != 0 )
1453  {
1454  StrPrintf( &output, " (solder_mask_margin %s)",
1455  FormatInternalUnits( aPad->GetLocalSolderMaskMargin() ).c_str() );
1456  }
1457 
1458  if( aPad->GetLocalSolderPasteMargin() != 0 )
1459  {
1460  StrPrintf( &output, " (solder_paste_margin %s)",
1461  FormatInternalUnits( aPad->GetLocalSolderPasteMargin() ).c_str() );
1462  }
1463 
1464  if( aPad->GetLocalSolderPasteMarginRatio() != 0 )
1465  {
1466  StrPrintf( &output, " (solder_paste_margin_ratio %s)",
1467  Double2Str( aPad->GetLocalSolderPasteMarginRatio() ).c_str() );
1468  }
1469 
1470  if( aPad->GetLocalClearance() != 0 )
1471  {
1472  StrPrintf( &output, " (clearance %s)",
1473  FormatInternalUnits( aPad->GetLocalClearance() ).c_str() );
1474  }
1475 
1477  {
1478  StrPrintf( &output, " (zone_connect %d)",
1479  static_cast<int>( aPad->GetEffectiveZoneConnection() ) );
1480  }
1481 
1482  if( aPad->GetThermalSpokeWidth() != 0 )
1483  {
1484  StrPrintf( &output, " (thermal_width %s)",
1485  FormatInternalUnits( aPad->GetThermalSpokeWidth() ).c_str() );
1486  }
1487 
1488  if( aPad->GetThermalGap() != 0 )
1489  {
1490  StrPrintf( &output, " (thermal_gap %s)",
1491  FormatInternalUnits( aPad->GetThermalGap() ).c_str() );
1492  }
1493 
1494  if( output.size() )
1495  {
1496  m_out->Print( 0, "\n" );
1497  m_out->Print( aNestLevel+1, "%s", output.c_str()+1 ); // +1 skips 1st space on 1st element
1498  }
1499 
1500  if( aPad->GetShape() == PAD_SHAPE_CUSTOM )
1501  {
1502  m_out->Print( 0, "\n");
1503  m_out->Print( aNestLevel+1, "(options" );
1504 
1506  m_out->Print( 0, " (clearance convexhull)" );
1507  #if 1 // Set to 1 to output the default option
1508  else
1509  m_out->Print( 0, " (clearance outline)" );
1510  #endif
1511 
1512  // Output the anchor pad shape (circle/rect)
1513  if( aPad->GetAnchorPadShape() == PAD_SHAPE_RECT )
1514  shape = "rect";
1515  else
1516  shape = "circle";
1517 
1518  m_out->Print( 0, " (anchor %s)", shape );
1519 
1520  m_out->Print( 0, ")"); // end of (options ...
1521 
1522  // Output graphic primitive of the pad shape
1523  m_out->Print( 0, "\n");
1524  m_out->Print( aNestLevel+1, "(primitives" );
1525 
1526  int nested_level = aNestLevel+2;
1527 
1528  // Output all basic shapes
1529  for( const std::shared_ptr<PCB_SHAPE>& primitive : aPad->GetPrimitives() )
1530  {
1531  m_out->Print( 0, "\n");
1532 
1533  switch( primitive->GetShape() )
1534  {
1535  case S_SEGMENT: // usual segment : line with rounded ends
1536  m_out->Print( nested_level, "(gr_line (start %s) (end %s)",
1537  FormatInternalUnits( primitive->GetStart() ).c_str(),
1538  FormatInternalUnits( primitive->GetEnd() ).c_str() );
1539  break;
1540 
1541  case S_RECT:
1542  m_out->Print( nested_level, "(gr_rect (start %s) (end %s)",
1543  FormatInternalUnits( primitive->GetStart() ).c_str(),
1544  FormatInternalUnits( primitive->GetEnd() ).c_str() );
1545  break;
1546 
1547  case S_ARC: // Arc with rounded ends
1548  m_out->Print( nested_level, "(gr_arc (start %s) (end %s) (angle %s)",
1549  FormatInternalUnits( primitive->GetStart() ).c_str(),
1550  FormatInternalUnits( primitive->GetEnd() ).c_str(),
1551  FormatAngle( primitive->GetAngle() ).c_str() );
1552  break;
1553 
1554  case S_CIRCLE: // ring or circle (circle if width == 0
1555  m_out->Print( nested_level, "(gr_circle (center %s) (end %s)",
1556  FormatInternalUnits( primitive->GetStart() ).c_str(),
1557  FormatInternalUnits( primitive->GetEnd() ).c_str() );
1558  break;
1559 
1560  case S_CURVE: // Bezier Curve
1561  m_out->Print( nested_level, "(gr_curve (pts (xy %s) (xy %s) (xy %s) (xy %s))",
1562  FormatInternalUnits( primitive->GetStart() ).c_str(),
1563  FormatInternalUnits( primitive->GetBezControl1() ).c_str(),
1564  FormatInternalUnits( primitive->GetBezControl2() ).c_str(),
1565  FormatInternalUnits( primitive->GetEnd() ).c_str() );
1566  break;
1567 
1568  case S_POLYGON: // polygon
1569  if( primitive->GetPolyShape().COutline( 0 ).CPoints().size() < 2 )
1570  break; // Malformed polygon.
1571 
1572  {
1573  m_out->Print( nested_level, "(gr_poly (pts\n");
1574 
1575  // Write the polygon corners coordinates:
1576  int newLine = 0;
1577 
1578  for( const VECTOR2I &pt : primitive->GetPolyShape().COutline( 0 ).CPoints() )
1579  {
1580  if( newLine == 0 )
1581  m_out->Print( nested_level+1, "(xy %s)",
1582  FormatInternalUnits( (wxPoint) pt ).c_str() );
1583  else
1584  m_out->Print( 0, " (xy %s)",
1585  FormatInternalUnits( (wxPoint) pt ).c_str() );
1586 
1587  if( ++newLine > 4 || !ADVANCED_CFG::GetCfg().m_CompactSave )
1588  {
1589  newLine = 0;
1590  m_out->Print( 0, "\n" );
1591  }
1592  }
1593 
1594  m_out->Print( newLine ? 0 : nested_level, ")" );
1595  }
1596  break;
1597 
1598  default:
1599  break;
1600  }
1601 
1602  m_out->Print( 0, " (width %s)",
1603  FormatInternalUnits( primitive->GetWidth() ).c_str() );
1604 
1605  if( primitive->IsFilled() )
1606  m_out->Print( 0, " (fill yes)" );
1607 
1608  m_out->Print( 0, ")" );
1609  }
1610 
1611  m_out->Print( 0, "\n");
1612  m_out->Print( aNestLevel+1, ")" ); // end of (basic_shapes
1613  }
1614 
1615  m_out->Print( 0, " (tstamp %s)", TO_UTF8( aPad->m_Uuid.AsString() ) );
1616 
1617  m_out->Print( 0, ")\n" );
1618 }
int GetLocalSolderMaskMargin() const
Definition: pad.h:386
OUTPUTFORMATTER * m_out
output any Format()s to this, no ownership
int GetLocalSolderPasteMargin() const
Definition: pad.h:393
no special fabrication property
Definition: pad_shapes.h:96
double GetRoundRectRadiusRatio() const
Definition: pad.h:523
a fiducial (usually a smd) for the full board
Definition: pad_shapes.h:98
Smd pad, appears on the solder paste layer (default)
Definition: pad_shapes.h:81
polygon (not yet used for tracks, but could be in microwave apps)
Definition: board_item.h:54
bool IsLocked() const override
Definition: pad.cpp:138
usual segment : line with rounded ends
Definition: board_item.h:50
Smd pad, used in BGA footprints.
Definition: pad_shapes.h:97
wxString GetNetname() const
wxString AsString() const
Definition: kiid.cpp:218
Arcs (with rounded ends)
Definition: board_item.h:52
PAD_SHAPE_T GetShape() const
Definition: pad.h:169
like PAD_PTH, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:85
a pad used as heat sink, usually in SMD footprints
Definition: pad_shapes.h:101
segment with non rounded ends
Definition: board_item.h:51
int GetThermalGap() const
Definition: pad.h:499
bool GetKeepTopBottom() const
Definition: pad.h:563
a pad with a castellated through hole
Definition: pad_shapes.h:102
PAD_ATTR_T GetAttribute() const
Definition: pad.h:371
int StrPrintf(std::string *result, const char *format,...)
This is like sprintf() but the output is appended to a std::string instead of to a character array.
Definition: richio.cpp:78
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
const wxPoint & GetOffset() const
Definition: pad.h:249
const wxSize & GetDrillSize() const
Definition: pad.h:242
std::string FormatAngle(double aAngle)
Function FormatAngle converts aAngle from board units to a string appropriate for writing to file.
Definition: base_units.cpp:506
int GetThermalSpokeWidth() const
Definition: pad.h:491
double GetOrientation() const
Return the rotation angle of the pad in a variety of units (the basic call returns tenths of degrees)...
Definition: pad.h:349
const wxSize & GetSize() const
Definition: pad.h:232
ZONE_CONNECTION GetEffectiveZoneConnection(wxString *aSource=nullptr) const
Return the zone connection in effect (either locally overridden or overridden in the parent footprint...
Definition: pad.cpp:792
const wxString & GetName() const
Definition: pad.h:133
const wxString & GetPinType() const
Definition: pad.h:145
LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
Definition: pad.h:368
PAD_SHAPE_T GetAnchorPadShape() const
Definition: pad.h:182
Like smd, does not appear on the solder paste layer (default) note also has a special attribute in Ge...
Definition: pad_shapes.h:82
NETINFO_MAPPING * m_mapping
mapping for net codes, so only not empty net codes are stored with consecutive integers as net codes
int GetLocalClearance(wxString *aSource) const override
Return any local clearances set in the "classic" (ie: pre-rule) system.
Definition: pad.cpp:686
PAD_PROP_T GetProperty() const
Definition: pad.h:374
double GetLocalSolderPasteMarginRatio() const
Definition: pad.h:396
const KIID m_Uuid
Definition: eda_item.h:525
const wxSize & GetDelta() const
Definition: pad.h:239
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
const wxPoint & GetPos0() const
Definition: pad.h:226
CUST_PAD_SHAPE_IN_ZONE GetCustomShapeInZoneOpt() const
Definition: pad.h:187
a fiducial (usually a smd) local to the parent footprint
Definition: pad_shapes.h:99
double GetChamferRectRatio() const
Definition: pad.h:532
PAD_DRILL_SHAPE_T GetDrillShape() const
Definition: pad.h:354
#define _(s)
Definition: 3d_actions.cpp:33
#define CTL_OMIT_PAD_NETS
Omit pads net names (useless in library)
Plated through hole pad.
Definition: pad_shapes.h:80
ring
Definition: board_item.h:53
int GetChamferPositions() const
Definition: pad.h:542
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
void formatLayers(LSET aLayerMask, int aNestLevel=0) const
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:408
a test point pad
Definition: pad_shapes.h:100
Bezier Curve.
Definition: board_item.h:55
int GetPadToDieLength() const
Definition: pad.h:384
const wxString & GetPinFunction() const
Definition: pad.h:139
static const int UNCONNECTED
Constant that forces initialization of a netinfo item to the NETINFO_ITEM ORPHANED (typically -1) whe...
Definition: netinfo.h:365
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
bool GetRemoveUnconnected() const
Definition: pad.h:557
const std::vector< std::shared_ptr< PCB_SHAPE > > & GetPrimitives() const
Accessor to the basic shape list for custom-shaped pads.
Definition: pad.h:301
std::string FormatInternalUnits(int aValue)
Function FormatInternalUnits converts aValue from internal units to a string appropriate for writing ...
Definition: base_units.cpp:471
int Translate(int aNetCode) const
Translate net number according to the map prepared by Update() function.
std::string Quotew(const wxString &aWrapee) const
Definition: richio.cpp:476
std::string Double2Str(double aValue)
Prints a float number without using scientific notation and no trailing 0 We want to avoid scientific...
Definition: string.cpp:872

References _, KIID::AsString(), CTL_OMIT_PAD_NETS, CUST_PAD_SHAPE_IN_ZONE_CONVEXHULL, Double2Str(), Format(), FormatAngle(), FormatInternalUnits(), formatLayers(), PAD::GetAnchorPadShape(), PAD::GetAttribute(), ADVANCED_CFG::GetCfg(), PAD::GetChamferPositions(), PAD::GetChamferRectRatio(), PAD::GetCustomShapeInZoneOpt(), PAD::GetDelta(), PAD::GetDrillShape(), PAD::GetDrillSize(), PAD::GetEffectiveZoneConnection(), PAD::GetKeepTopBottom(), PAD::GetLayerSet(), PAD::GetLocalClearance(), PAD::GetLocalSolderMaskMargin(), PAD::GetLocalSolderPasteMargin(), PAD::GetLocalSolderPasteMarginRatio(), PAD::GetName(), BOARD_CONNECTED_ITEM::GetNetCode(), BOARD_CONNECTED_ITEM::GetNetname(), PAD::GetOffset(), PAD::GetOrientation(), PAD::GetPadToDieLength(), PAD::GetPinFunction(), PAD::GetPinType(), PAD::GetPos0(), PAD::GetPrimitives(), PAD::GetProperty(), PAD::GetRemoveUnconnected(), PAD::GetRoundRectRadiusRatio(), PAD::GetShape(), PAD::GetSize(), PAD::GetThermalGap(), PAD::GetThermalSpokeWidth(), INHERITED, PAD::IsLocked(), m_ctl, m_mapping, m_out, EDA_ITEM::m_Uuid, PAD_ATTRIB_CONN, PAD_ATTRIB_NPTH, PAD_ATTRIB_PTH, PAD_ATTRIB_SMD, PAD_DRILL_SHAPE_OBLONG, PAD_PROP_BGA, PAD_PROP_CASTELLATED, PAD_PROP_FIDUCIAL_GLBL, PAD_PROP_FIDUCIAL_LOCAL, PAD_PROP_HEATSINK, PAD_PROP_NONE, PAD_PROP_TESTPOINT, PAD_SHAPE_CHAMFERED_RECT, PAD_SHAPE_CIRCLE, PAD_SHAPE_CUSTOM, PAD_SHAPE_OVAL, PAD_SHAPE_RECT, PAD_SHAPE_ROUNDRECT, PAD_SHAPE_TRAPEZOID, OUTPUTFORMATTER::Print(), OUTPUTFORMATTER::Quotew(), RECT_CHAMFER_BOTTOM_LEFT, RECT_CHAMFER_BOTTOM_RIGHT, RECT_CHAMFER_TOP_LEFT, RECT_CHAMFER_TOP_RIGHT, S_ARC, S_CIRCLE, S_CURVE, S_POLYGON, S_RECT, S_SEGMENT, StrPrintf(), THROW_IO_ERROR, TO_UTF8, NETINFO_MAPPING::Translate(), and NETINFO_LIST::UNCONNECTED.

◆ format() [9/12]

void PCB_IO::format ( const PCB_TEXT aText,
int  aNestLevel = 0 
) const
private

Definition at line 1621 of file kicad_plugin.cpp.

1622 {
1623  m_out->Print( aNestLevel, "(gr_text %s (at %s",
1624  m_out->Quotew( aText->GetText() ).c_str(),
1625  FormatInternalUnits( aText->GetTextPos() ).c_str() );
1626 
1627  if( aText->GetTextAngle() != 0.0 )
1628  m_out->Print( 0, " %s", FormatAngle( aText->GetTextAngle() ).c_str() );
1629 
1630  m_out->Print( 0, ")" );
1631 
1632  formatLayer( aText );
1633 
1634  m_out->Print( 0, " (tstamp %s)", TO_UTF8( aText->m_Uuid.AsString() ) );
1635 
1636  m_out->Print( 0, "\n" );
1637 
1638  aText->EDA_TEXT::Format( m_out, aNestLevel, m_ctl );
1639 
1640  m_out->Print( aNestLevel, ")\n" );
1641 }
OUTPUTFORMATTER * m_out
output any Format()s to this, no ownership
void formatLayer(const BOARD_ITEM *aItem) const
double GetTextAngle() const
Definition: eda_text.h:181
wxString AsString() const
Definition: kiid.cpp:218
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
std::string FormatAngle(double aAngle)
Function FormatAngle converts aAngle from board units to a string appropriate for writing to file.
Definition: base_units.cpp:506
const KIID m_Uuid
Definition: eda_item.h:525
const wxPoint & GetTextPos() const
Definition: eda_text.h:254
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:408
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:133
std::string FormatInternalUnits(int aValue)
Function FormatInternalUnits converts aValue from internal units to a string appropriate for writing ...
Definition: base_units.cpp:471
std::string Quotew(const wxString &aWrapee) const
Definition: richio.cpp:476

References KIID::AsString(), FormatAngle(), FormatInternalUnits(), formatLayer(), EDA_TEXT::GetText(), EDA_TEXT::GetTextAngle(), EDA_TEXT::GetTextPos(), m_ctl, m_out, EDA_ITEM::m_Uuid, OUTPUTFORMATTER::Print(), OUTPUTFORMATTER::Quotew(), and TO_UTF8.

◆ format() [10/12]

void PCB_IO::format ( const FP_TEXT aText,
int  aNestLevel = 0 
) const
private

Definition at line 1671 of file kicad_plugin.cpp.

1672 {
1673  std::string type;
1674 
1675  switch( aText->GetType() )
1676  {
1677  case FP_TEXT::TEXT_is_REFERENCE: type = "reference"; break;
1678  case FP_TEXT::TEXT_is_VALUE: type = "value"; break;
1679  case FP_TEXT::TEXT_is_DIVERS: type = "user";
1680  }
1681 
1682  m_out->Print( aNestLevel, "(fp_text %s %s (at %s",
1683  type.c_str(),
1684  m_out->Quotew( aText->GetText() ).c_str(),
1685  FormatInternalUnits( aText->GetPos0() ).c_str() );
1686 
1687  // Due to Pcbnew history, fp_text angle is saved as an absolute on screen angle,
1688  // but internally the angle is held relative to its parent footprint. parent
1689  // may be NULL when saving a footprint outside a BOARD.
1690  double orient = aText->GetTextAngle();
1691  FOOTPRINT* parent = (FOOTPRINT*) aText->GetParent();
1692 
1693  if( parent )
1694  {
1695  // GetTextAngle() is always in -360..+360 range because of
1696  // FP_TEXT::SetTextAngle(), but summing that angle with an
1697  // additional board angle could kick sum up >= 360 or <= -360, so to have
1698  // consistent results, normalize again for the BOARD save. A footprint
1699  // save does not use this code path since parent is NULL.
1700 #if 0
1701  // This one could be considered reasonable if you like positive angles
1702  // in your board text.
1703  orient = NormalizeAnglePos( orient + parent->GetOrientation() );
1704 #else
1705  // Choose compatibility for now, even though this is only a 720 degree clamp
1706  // with two possible values for every angle.
1707  orient = NormalizeAngle360Min( orient + parent->GetOrientation() );
1708 #endif
1709  }
1710 
1711  if( orient != 0.0 )
1712  m_out->Print( 0, " %s", FormatAngle( orient ).c_str() );
1713 
1714  if( !aText->IsKeepUpright() )
1715  m_out->Print( 0, " unlocked" );
1716 
1717  m_out->Print( 0, ")" );
1718  formatLayer( aText );
1719 
1720  if( !aText->IsVisible() )
1721  m_out->Print( 0, " hide" );
1722 
1723  m_out->Print( 0, "\n" );
1724 
1725  aText->EDA_TEXT::Format( m_out, aNestLevel, m_ctl | CTL_OMIT_HIDE );
1726 
1727  m_out->Print( aNestLevel + 1, "(tstamp %s)\n", TO_UTF8( aText->m_Uuid.AsString() ) );
1728 
1729  m_out->Print( aNestLevel, ")\n" );
1730 }
OUTPUTFORMATTER * m_out
output any Format()s to this, no ownership
void formatLayer(const BOARD_ITEM *aItem) const
bool IsKeepUpright() const
Definition: fp_text.h:110
bool IsVisible() const
Definition: eda_text.h:193
double GetOrientation() const
Definition: footprint.h:186
double GetTextAngle() const
Definition: eda_text.h:181
wxString AsString() const
Definition: kiid.cpp:218
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
std::string FormatAngle(double aAngle)
Function FormatAngle converts aAngle from board units to a string appropriate for writing to file.
Definition: base_units.cpp:506
TEXT_TYPE GetType() const
Definition: fp_text.h:141
const KIID m_Uuid
Definition: eda_item.h:525
const wxPoint & GetPos0() const
Definition: fp_text.h:166
T NormalizeAnglePos(T Angle)
Normalize angle to be in the 0.0 .
Definition: trigo.h:279
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:408
T NormalizeAngle360Min(T Angle)
Normalize angle to be > -360.0 and < 360.0 Angle equal to -360 or +360 are set to 0.
Definition: trigo.h:254
BOARD_ITEM_CONTAINER * GetParent() const
Definition: board_item.h:168
#define CTL_OMIT_HIDE
Definition: eda_text.h:56
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:133
std::string FormatInternalUnits(int aValue)
Function FormatInternalUnits converts aValue from internal units to a string appropriate for writing ...
Definition: base_units.cpp:471
std::string Quotew(const wxString &aWrapee) const
Definition: richio.cpp:476

References KIID::AsString(), CTL_OMIT_HIDE, FormatAngle(), FormatInternalUnits(), formatLayer(), FOOTPRINT::GetOrientation(), BOARD_ITEM::GetParent(), FP_TEXT::GetPos0(), EDA_TEXT::GetText(), EDA_TEXT::GetTextAngle(), FP_TEXT::GetType(), FP_TEXT::IsKeepUpright(), EDA_TEXT::IsVisible(), m_ctl, m_out, EDA_ITEM::m_Uuid, NormalizeAngle360Min(), NormalizeAnglePos(), OUTPUTFORMATTER::Print(), OUTPUTFORMATTER::Quotew(), FP_TEXT::TEXT_is_DIVERS, FP_TEXT::TEXT_is_REFERENCE, FP_TEXT::TEXT_is_VALUE, and TO_UTF8.

◆ format() [11/12]

void PCB_IO::format ( const TRACK aTrack,
int  aNestLevel = 0 
) const
private

Definition at line 1733 of file kicad_plugin.cpp.

1734 {
1735  if( aTrack->Type() == PCB_VIA_T )
1736  {
1737  PCB_LAYER_ID layer1, layer2;
1738 
1739  const VIA* via = static_cast<const VIA*>( aTrack );
1740  BOARD* board = (BOARD*) via->GetParent();
1741 
1742  wxCHECK_RET( board != 0, wxT( "Via " ) + via->GetSelectMenuText( EDA_UNITS::MILLIMETRES )
1743  + wxT( " has no parent." ) );
1744 
1745  m_out->Print( aNestLevel, "(via" );
1746 
1747  via->LayerPair( &layer1, &layer2 );
1748 
1749  switch( via->GetViaType() )
1750  {
1751  case VIATYPE::THROUGH: // Default shape not saved.
1752  break;
1753 
1754  case VIATYPE::BLIND_BURIED:
1755  m_out->Print( 0, " blind" );
1756  break;
1757 
1758  case VIATYPE::MICROVIA:
1759  m_out->Print( 0, " micro" );
1760  break;
1761 
1762  default:
1763  THROW_IO_ERROR( wxString::Format( _( "unknown via type %d" ), via->GetViaType() ) );
1764  }
1765 
1766  m_out->Print( 0, " (at %s) (size %s)",
1767  FormatInternalUnits( aTrack->GetStart() ).c_str(),
1768  FormatInternalUnits( aTrack->GetWidth() ).c_str() );
1769 
1770  // Old boards were using UNDEFINED_DRILL_DIAMETER value in file for via drill when
1771  // via drill was the netclass value.
1772  // recent boards always set the via drill to the actual value, but now we need to
1773  // always store the drill value, because netclass value is not stored in the board file.
1774  // Otherwise the drill value of some (old) vias can be unknown
1775  if( via->GetDrill() != UNDEFINED_DRILL_DIAMETER )
1776  m_out->Print( 0, " (drill %s)", FormatInternalUnits( via->GetDrill() ).c_str() );
1777  else // Probably old board!
1778  m_out->Print( 0, " (drill %s)", FormatInternalUnits( via->GetDrillValue() ).c_str() );
1779 
1780  m_out->Print( 0, " (layers %s %s)",
1781  m_out->Quotew( LSET::Name( layer1 ) ).c_str(),
1782  m_out->Quotew( LSET::Name( layer2 ) ).c_str() );
1783 
1784  if( via->GetRemoveUnconnected() )
1785  {
1786  m_out->Print( 0, " (remove_unused_layers)" );
1787 
1788  if( via->GetKeepTopBottom() )
1789  m_out->Print( 0, " (keep_end_layers)" );
1790  }
1791 
1792  if( via->GetIsFree() )
1793  m_out->Print( 0, " (free)" );
1794  }
1795  else if( aTrack->Type() == PCB_ARC_T )
1796  {
1797  const ARC* arc = static_cast<const ARC*>( aTrack );
1798 
1799  m_out->Print( aNestLevel, "(arc (start %s) (mid %s) (end %s) (width %s)",
1800  FormatInternalUnits( arc->GetStart() ).c_str(),
1801  FormatInternalUnits( arc->GetMid() ).c_str(),
1802  FormatInternalUnits( arc->GetEnd() ).c_str(),
1803  FormatInternalUnits( arc->GetWidth() ).c_str() );
1804 
1805  m_out->Print( 0, " (layer %s)", m_out->Quotew( LSET::Name( arc->GetLayer() ) ).c_str() );
1806  }
1807  else
1808  {
1809  m_out->Print( aNestLevel, "(segment (start %s) (end %s) (width %s)",
1810  FormatInternalUnits( aTrack->GetStart() ).c_str(),
1811  FormatInternalUnits( aTrack->GetEnd() ).c_str(),
1812  FormatInternalUnits( aTrack->GetWidth() ).c_str() );
1813 
1814  m_out->Print( 0, " (layer %s)", m_out->Quotew( LSET::Name( aTrack->GetLayer() ) ).c_str() );
1815  }
1816 
1817  if( aTrack->IsLocked() )
1818  m_out->Print( 0, " (locked)" );
1819 
1820  m_out->Print( 0, " (net %d)", m_mapping->Translate( aTrack->GetNetCode() ) );
1821 
1822  m_out->Print( 0, " (tstamp %s)", TO_UTF8( aTrack->m_Uuid.AsString() ) );
1823 
1824  m_out->Print( 0, ")\n" );
1825 }
Definition: track.h:343
OUTPUTFORMATTER * m_out
output any Format()s to this, no ownership
const wxPoint & GetStart() const
Definition: track.h:116
class ARC, an arc track segment on a copper layer
Definition: typeinfo.h:97
wxString AsString() const
Definition: kiid.cpp:218
#define UNDEFINED_DRILL_DIAMETER
Definition: track.h:77
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
PCB_LAYER_ID
A quick note on layer IDs:
const wxPoint & GetMid() const
Definition: track.h:292
static const wxChar * Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
Definition: lset.cpp:82
NETINFO_MAPPING * m_mapping
mapping for net codes, so only not empty net codes are stored with consecutive integers as net codes
const KIID m_Uuid
Definition: eda_item.h:525
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
virtual bool IsLocked() const
Definition: board_item.h:249
int GetWidth() const
Definition: track.h:110
Definition: track.h:262
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:190
#define _(s)
Definition: 3d_actions.cpp:33
const wxPoint & GetEnd() const
Definition: track.h:113
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:408
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:173
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
std::string FormatInternalUnits(int aValue)
Function FormatInternalUnits converts aValue from internal units to a string appropriate for writing ...
Definition: base_units.cpp:471
int Translate(int aNetCode) const
Translate net number according to the map prepared by Update() function.
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:163
std::string Quotew(const wxString &aWrapee) const
Definition: richio.cpp:476

References _, KIID::AsString(), BLIND_BURIED, Format(), FormatInternalUnits(), TRACK::GetEnd(), BOARD_ITEM::GetLayer(), ARC::GetMid(), BOARD_CONNECTED_ITEM::GetNetCode(), TRACK::GetStart(), TRACK::GetWidth(), BOARD_ITEM::IsLocked(), m_mapping, m_out, EDA_ITEM::m_Uuid, MICROVIA, MILLIMETRES, LSET::Name(), PCB_ARC_T, PCB_VIA_T, OUTPUTFORMATTER::Print(), OUTPUTFORMATTER::Quotew(), THROUGH, THROW_IO_ERROR, TO_UTF8, NETINFO_MAPPING::Translate(), EDA_ITEM::Type(), UNDEFINED_DRILL_DIAMETER, and via.

◆ format() [12/12]

void PCB_IO::format ( const ZONE aZone,
int  aNestLevel = 0 
) const
private

Definition at line 1828 of file kicad_plugin.cpp.

1829 {
1830  // Save the NET info; For keepout zones, net code and net name are irrelevant
1831  // so be sure a dummy value is stored, just for ZONE compatibility
1832  // (perhaps netcode and netname should be not stored)
1833  m_out->Print( aNestLevel, "(zone (net %d) (net_name %s)",
1834  aZone->GetIsRuleArea() ? 0 : m_mapping->Translate( aZone->GetNetCode() ),
1835  m_out->Quotew( aZone->GetIsRuleArea() ? wxT("") : aZone->GetNetname() ).c_str() );
1836 
1837  // If a zone exists on multiple layers, format accordingly
1838  if( aZone->GetLayerSet().count() > 1 )
1839  {
1840  formatLayers( aZone->GetLayerSet() );
1841  }
1842  else
1843  {
1844  formatLayer( aZone );
1845  }
1846 
1847  m_out->Print( 0, " (tstamp %s)", TO_UTF8( aZone->m_Uuid.AsString() ) );
1848 
1849  if( !aZone->GetZoneName().empty() )
1850  m_out->Print( 0, " (name %s)", m_out->Quotew( aZone->GetZoneName() ).c_str() );
1851 
1852  // Save the outline aux info
1853  std::string hatch;
1854 
1855  switch( aZone->GetHatchStyle() )
1856  {
1857  default:
1858  case ZONE_BORDER_DISPLAY_STYLE::NO_HATCH: hatch = "none"; break;
1859  case ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_EDGE: hatch = "edge"; break;
1860  case ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_FULL: hatch = "full"; break;
1861  }
1862 
1863  m_out->Print( 0, " (hatch %s %s)\n", hatch.c_str(),
1864  FormatInternalUnits( aZone->GetBorderHatchPitch() ).c_str() );
1865 
1866  if( aZone->GetPriority() > 0 )
1867  m_out->Print( aNestLevel+1, "(priority %d)\n", aZone->GetPriority() );
1868 
1869  m_out->Print( aNestLevel+1, "(connect_pads" );
1870 
1871  switch( aZone->GetPadConnection() )
1872  {
1873  default:
1874  case ZONE_CONNECTION::THERMAL: // Default option not saved or loaded.
1875  break;
1876 
1878  m_out->Print( 0, " thru_hole_only" );
1879  break;
1880 
1881  case ZONE_CONNECTION::FULL:
1882  m_out->Print( 0, " yes" );
1883  break;
1884 
1885  case ZONE_CONNECTION::NONE:
1886  m_out->Print( 0, " no" );
1887  break;
1888  }
1889 
1890  m_out->Print( 0, " (clearance %s))\n",
1891  FormatInternalUnits( aZone->GetLocalClearance() ).c_str() );
1892 
1893  m_out->Print( aNestLevel+1, "(min_thickness %s)",
1894  FormatInternalUnits( aZone->GetMinThickness() ).c_str() );
1895 
1896  // write it only if V 6.O version option is used (i.e. do not write if the "legacy"
1897  // algorithm is used)
1898  if( !aZone->GetFilledPolysUseThickness() )
1899  m_out->Print( 0, " (filled_areas_thickness no)" );
1900 
1901  m_out->Print( 0, "\n" );
1902 
1903  if( aZone->GetIsRuleArea() )
1904  {
1905  m_out->Print( aNestLevel+1, "(keepout (tracks %s) (vias %s) (pads %s ) (copperpour %s) (footprints %s))\n",
1906  aZone->GetDoNotAllowTracks() ? "not_allowed" : "allowed",
1907  aZone->GetDoNotAllowVias() ? "not_allowed" : "allowed",
1908  aZone->GetDoNotAllowPads() ? "not_allowed" : "allowed",
1909  aZone->GetDoNotAllowCopperPour() ? "not_allowed" : "allowed",
1910  aZone->GetDoNotAllowFootprints() ? "not_allowed" : "allowed" );
1911  }
1912 
1913  m_out->Print( aNestLevel+1, "(fill" );
1914 
1915  // Default is not filled.
1916  if( aZone->IsFilled() )
1917  m_out->Print( 0, " yes" );
1918 
1919  // Default is polygon filled.
1920  if( aZone->GetFillMode() == ZONE_FILL_MODE::HATCH_PATTERN )
1921  m_out->Print( 0, " (mode hatch)" );
1922 
1923  m_out->Print( 0, " (thermal_gap %s) (thermal_bridge_width %s)",
1924  FormatInternalUnits( aZone->GetThermalReliefGap() ).c_str(),
1925  FormatInternalUnits( aZone->GetThermalReliefSpokeWidth() ).c_str() );
1926 
1928  {
1929  m_out->Print( 0, " (smoothing" );
1930 
1931  switch( aZone->GetCornerSmoothingType() )
1932  {
1934  m_out->Print( 0, " chamfer" );
1935  break;
1936 
1938  m_out->Print( 0, " fillet" );
1939  break;
1940 
1941  default:
1942  THROW_IO_ERROR( wxString::Format( _( "unknown zone corner smoothing type %d" ),
1943  aZone->GetCornerSmoothingType() ) );
1944  }
1945  m_out->Print( 0, ")" );
1946 
1947  if( aZone->GetCornerRadius() != 0 )
1948  m_out->Print( 0, " (radius %s)",
1949  FormatInternalUnits( aZone->GetCornerRadius() ).c_str() );
1950  }
1951 
1953  {
1954  m_out->Print( 0, " (island_removal_mode %d) (island_area_min %s)",
1955  static_cast<int>( aZone->GetIslandRemovalMode() ),
1956  FormatInternalUnits( aZone->GetMinIslandArea() / IU_PER_MM ).c_str() );
1957  }
1958 
1959  if( aZone->GetFillMode() == ZONE_FILL_MODE::HATCH_PATTERN )
1960  {
1961  m_out->Print( 0, "\n" );
1962  m_out->Print( aNestLevel+2, "(hatch_thickness %s) (hatch_gap %s) (hatch_orientation %s)",
1963  FormatInternalUnits( aZone->GetHatchThickness() ).c_str(),
1964  FormatInternalUnits( aZone->GetHatchGap() ).c_str(),
1965  Double2Str( aZone->GetHatchOrientation() ).c_str() );
1966 
1967  if( aZone->GetHatchSmoothingLevel() > 0 )
1968  {
1969  m_out->Print( 0, "\n" );
1970  m_out->Print( aNestLevel+2, "(hatch_smoothing_level %d) (hatch_smoothing_value %s)",
1971  aZone->GetHatchSmoothingLevel(),
1972  Double2Str( aZone->GetHatchSmoothingValue() ).c_str() );
1973  }
1974 
1975  m_out->Print( 0, "\n" );
1976  m_out->Print( aNestLevel+2, "(hatch_border_algorithm %s) (hatch_min_hole_area %s)",
1977  aZone->GetHatchBorderAlgorithm() ? "hatch_thickness" : "min_thickness",
1978  Double2Str( aZone->GetHatchHoleMinArea() ).c_str() );
1979  }
1980 
1981  m_out->Print( 0, ")\n" );
1982 
1983  int newLine = 0;
1984 
1985  if( aZone->GetNumCorners() )
1986  {
1987  bool new_polygon = true;
1988  bool is_closed = false;
1989 
1990  for( auto iterator = aZone->CIterateWithHoles(); iterator; ++iterator )
1991  {
1992  if( new_polygon )
1993  {
1994  newLine = 0;
1995  m_out->Print( aNestLevel + 1, "(polygon\n" );
1996  m_out->Print( aNestLevel + 2, "(pts\n" );
1997  new_polygon = false;
1998  is_closed = false;
1999  }
2000 
2001  if( newLine == 0 )
2002  m_out->Print( aNestLevel + 3, "(xy %s %s)",
2003  FormatInternalUnits( iterator->x ).c_str(),
2004  FormatInternalUnits( iterator->y ).c_str() );
2005  else
2006  m_out->Print( 0, " (xy %s %s)",
2007  FormatInternalUnits( iterator->x ).c_str(),
2008  FormatInternalUnits( iterator->y ).c_str() );
2009 
2010  if( newLine < 4 && ADVANCED_CFG::GetCfg().m_CompactSave )
2011  {
2012  newLine += 1;
2013  }
2014  else
2015  {
2016  newLine = 0;
2017  m_out->Print( 0, "\n" );
2018  }
2019 
2020  if( iterator.IsEndContour() )
2021  {
2022  is_closed = true;
2023 
2024  if( newLine != 0 )
2025  m_out->Print( 0, "\n" );
2026 
2027  m_out->Print( aNestLevel + 2, ")\n" );
2028  m_out->Print( aNestLevel + 1, ")\n" );
2029  new_polygon = true;
2030  }
2031  }
2032 
2033  if( !is_closed ) // Should not happen, but...
2034  {
2035  if( newLine != 0 )
2036  m_out->Print( 0, "\n" );
2037 
2038  m_out->Print( aNestLevel + 2, ")\n" );
2039  m_out->Print( aNestLevel + 1, ")\n" );
2040  }
2041  }
2042 
2043  // Save the PolysList (filled areas)
2044  for( PCB_LAYER_ID layer : aZone->GetLayerSet().Seq() )
2045  {
2046  const SHAPE_POLY_SET& fv = aZone->GetFilledPolysList( layer );
2047  newLine = 0;
2048 
2049  if( !fv.IsEmpty() )
2050  {
2051  int poly_index = 0;
2052  bool new_polygon = true;
2053  bool is_closed = false;
2054 
2055  for( auto it = fv.CIterate(); it; ++it )
2056  {
2057  if( new_polygon )
2058  {
2059  newLine = 0;
2060  m_out->Print( aNestLevel + 1, "(filled_polygon\n" );
2061  m_out->Print( aNestLevel + 2, "(layer %s)\n",
2062  m_out->Quotew( LSET::Name( layer ) ).c_str() );
2063 
2064  if( aZone->IsIsland( layer, poly_index ) )
2065  m_out->Print( aNestLevel + 2, "(island)\n" );
2066 
2067  m_out->Print( aNestLevel + 2, "(pts\n" );
2068  new_polygon = false;
2069  is_closed = false;
2070  poly_index++;
2071  }
2072 
2073  if( newLine == 0 )
2074  m_out->Print( aNestLevel + 3, "(xy %s %s)",
2075  FormatInternalUnits( it->x ).c_str(),
2076  FormatInternalUnits( it->y ).c_str() );
2077  else
2078  m_out->Print( 0, " (xy %s %s)", FormatInternalUnits( it->x ).c_str(),
2079  FormatInternalUnits( it->y ).c_str() );
2080 
2081  if( newLine < 4 && ADVANCED_CFG::GetCfg().m_CompactSave )
2082  {
2083  newLine += 1;
2084  }
2085  else
2086  {
2087  newLine = 0;
2088  m_out->Print( 0, "\n" );
2089  }
2090 
2091  if( it.IsEndContour() )
2092  {
2093  is_closed = true;
2094 
2095  if( newLine != 0 )
2096  m_out->Print( 0, "\n" );
2097 
2098  m_out->Print( aNestLevel + 2, ")\n" );
2099  m_out->Print( aNestLevel + 1, ")\n" );
2100  new_polygon = true;
2101  }
2102  }
2103 
2104  if( !is_closed ) // Should not happen, but...
2105  m_out->Print( aNestLevel + 1, ")\n" );
2106  }
2107 
2108  // Save the filling segments list
2109  const auto& segs = aZone->FillSegments( layer );
2110 
2111  if( segs.size() )
2112  {
2113  m_out->Print( aNestLevel + 1, "(fill_segments\n" );
2114  m_out->Print( aNestLevel + 2, "(layer %s)\n",
2115  TO_UTF8( BOARD::GetStandardLayerName( layer ) ) );
2116 
2117  for( ZONE_SEGMENT_FILL::const_iterator it = segs.begin(); it != segs.end(); ++it )
2118  {
2119  m_out->Print( aNestLevel + 2, "(pts (xy %s) (xy %s))\n",
2120  FormatInternalUnits( wxPoint( it->A ) ).c_str(),
2121  FormatInternalUnits( wxPoint( it->B ) ).c_str() );
2122  }
2123 
2124  m_out->Print( aNestLevel + 1, ")\n" );
2125  }
2126  }
2127 
2128  m_out->Print( aNestLevel, ")\n" );
2129 }
int GetNumCorners(void) const
Access to m_Poly parameters.
Definition: zone.h:520
int GetHatchGap() const
Definition: zone.h:253
OUTPUTFORMATTER * m_out
output any Format()s to this, no ownership
bool m_CompactSave
Save files in compact display mode When is is not specified, points are written one per line.
bool GetDoNotAllowFootprints() const
Definition: zone.h:735
void formatLayer(const BOARD_ITEM *aItem) const
int GetHatchThickness() const
Definition: zone.h:250
unsigned GetPriority() const
Definition: zone.h:122
bool GetIsRuleArea() const
Accessors to parameters used in Rule Area zones:
Definition: zone.h:730
SHAPE_POLY_SET::CONST_ITERATOR CIterateWithHoles() const
Return an iterator to visit all points of the zone's main outline with holes.
Definition: zone.h:550
static constexpr double IU_PER_MM
Mock up a conversion function.
int GetBorderHatchPitch() const
HatchBorder related methods.
Definition: zone.cpp:887
bool GetDoNotAllowVias() const
Definition: zone.h:732
bool IsEmpty() const
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
Definition: zone.cpp:289
double GetHatchSmoothingValue() const
Definition: zone.h:262
wxString AsString() const
Definition: kiid.cpp:218
const SHAPE_POLY_SET & GetFilledPolysList(PCB_LAYER_ID aLayer) const
Definition: zone.h:632
bool IsFilled() const
Definition: zone.h:231
LSEQ Seq(const PCB_LAYER_ID *aWishListSequence, unsigned aCount) const
Return an LSEQ from the union of this LSET and a desired sequence.
Definition: lset.cpp:411
ZONE_FILL_MODE GetFillMode() const
Definition: zone.h:181
int GetThermalReliefGap() const
Definition: zone.h:190
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
double GetHatchHoleMinArea() const
Definition: zone.h:265
bool GetDoNotAllowPads() const
Definition: zone.h:734
PCB_LAYER_ID
A quick note on layer IDs:
bool GetDoNotAllowCopperPour() const
Definition: zone.h:731
pads are covered by copper
int GetMinThickness() const
Definition: zone.h:241
int GetHatchSmoothingLevel() const
Definition: zone.h:259
static const wxChar * Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
Definition: lset.cpp:82
Represent a set of closed polygons.
int GetLocalClearance(wxString *aSource) const override
Return any local clearances set in the "classic" (ie: pre-rule) system.
Definition: zone.cpp:492
bool GetDoNotAllowTracks() const
Definition: zone.h:733
ZONE_BORDER_DISPLAY_STYLE GetHatchStyle() const
Definition: zone.h:610
NETINFO_MAPPING * m_mapping
mapping for net codes, so only not empty net codes are stored with consecutive integers as net codes
CONST_ITERATOR CIterate(int aFirst, int aLast, bool aIterateHoles=false) const
Thermal relief only for THT pads.
const KIID m_Uuid
Definition: eda_item.h:525
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
double GetHatchOrientation() const
Definition: zone.h:256
Use thermal relief for pads.
unsigned int GetCornerRadius() const
Definition: zone.h:684
int GetHatchBorderAlgorithm() const
Definition: zone.h:268
const ISLAND_REMOVAL_MODE GetIslandRemovalMode() const
Definition: zone.h:746
bool IsIsland(PCB_LAYER_ID aLayer, int aPolyIdx) const
Check if a given filled polygon is an insulated island.
Definition: zone.cpp:1122
#define _(s)
Definition: 3d_actions.cpp:33
Pads are not covered.
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
long long int GetMinIslandArea() const
Definition: zone.h:750
ZONE_SEGMENT_FILL & FillSegments(PCB_LAYER_ID aLayer)
Definition: zone.h:305
int GetThermalReliefSpokeWidth() const
Definition: zone.h:200
void formatLayers(LSET aLayerMask, int aNestLevel=0) const
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:408
ZONE_CONNECTION GetPadConnection(PAD *aPad, wxString *aSource=nullptr) const
Definition: zone.cpp:771
wxString GetZoneName() const
Definition: zone.h:129
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
int GetCornerSmoothingType() const
Definition: zone.h:680
std::string FormatInternalUnits(int aValue)
Function FormatInternalUnits converts aValue from internal units to a string appropriate for writing ...
Definition: base_units.cpp:471
int Translate(int aNetCode) const
Translate net number according to the map prepared by Update() function.
std::string Quotew(const wxString &aWrapee) const
Definition: richio.cpp:476
static wxString GetStandardLayerName(PCB_LAYER_ID aLayerId)
Return an "English Standard" name of a PCB layer when given aLayerNumber.
Definition: board.h:676
bool GetFilledPolysUseThickness() const
Definition: zone.h:686
std::string Double2Str(double aValue)
Prints a float number without using scientific notation and no trailing 0 We want to avoid scientific...
Definition: string.cpp:872

References _, ALWAYS, KIID::AsString(), SHAPE_POLY_SET::CIterate(), ZONE::CIterateWithHoles(), DIAGONAL_EDGE, DIAGONAL_FULL, Double2Str(), ZONE::FillSegments(), Format(), FormatInternalUnits(), formatLayer(), formatLayers(), FULL, ZONE::GetBorderHatchPitch(), ADVANCED_CFG::GetCfg(), ZONE::GetCornerRadius(), ZONE::GetCornerSmoothingType(), ZONE::GetDoNotAllowCopperPour(), ZONE::GetDoNotAllowFootprints(), ZONE::GetDoNotAllowPads(), ZONE::GetDoNotAllowTracks(), ZONE::GetDoNotAllowVias(), ZONE::GetFilledPolysList(), ZONE::GetFilledPolysUseThickness(), ZONE::GetFillMode(), ZONE::GetHatchBorderAlgorithm(), ZONE::GetHatchGap(), ZONE::GetHatchHoleMinArea(), ZONE::GetHatchOrientation(), ZONE::GetHatchSmoothingLevel(), ZONE::GetHatchSmoothingValue(), ZONE::GetHatchStyle(), ZONE::GetHatchThickness(), ZONE::GetIslandRemovalMode(), ZONE::GetIsRuleArea(), ZONE::GetLayerSet(), ZONE::GetLocalClearance(), ZONE::GetMinIslandArea(), ZONE::GetMinThickness(), BOARD_CONNECTED_ITEM::GetNetCode(), BOARD_CONNECTED_ITEM::GetNetname(), ZONE::GetNumCorners(), ZONE::GetPadConnection(), ZONE::GetPriority(), BOARD::GetStandardLayerName(), ZONE::GetThermalReliefGap(), ZONE::GetThermalReliefSpokeWidth(), ZONE::GetZoneName(), HATCH_PATTERN, SHAPE_POLY_SET::IsEmpty(), ZONE::IsFilled(), ZONE::IsIsland(), IU_PER_MM, ADVANCED_CFG::m_CompactSave, m_mapping, m_out, EDA_ITEM::m_Uuid, LSET::Name(), NO_HATCH, NONE, OUTPUTFORMATTER::Print(), OUTPUTFORMATTER::Quotew(), LSET::Seq(), ZONE_SETTINGS::SMOOTHING_CHAMFER, ZONE_SETTINGS::SMOOTHING_FILLET, ZONE_SETTINGS::SMOOTHING_NONE, THERMAL, THROW_IO_ERROR, THT_THERMAL, TO_UTF8, and NETINFO_MAPPING::Translate().

◆ formatBoardLayers()

void PCB_IO::formatBoardLayers ( const BOARD aBoard,
int  aNestLevel = 0 
) const
protected

formats the board layer information

Definition at line 523 of file kicad_plugin.cpp.

524 {
525  m_out->Print( aNestLevel, "(layers\n" );
526 
527  // Save only the used copper layers from front to back.
528 
529  for( LSEQ cu = aBoard->GetEnabledLayers().CuStack(); cu; ++cu )
530  {
531  PCB_LAYER_ID layer = *cu;
532 
533  m_out->Print( aNestLevel+1, "(%d %s %s", layer,
534  m_out->Quotew( LSET::Name( layer ) ).c_str(),
535  LAYER::ShowType( aBoard->GetLayerType( layer ) ) );
536 
537  if( LSET::Name( layer ) != m_board->GetLayerName( layer ) )
538  m_out->Print( 0, " %s", m_out->Quotew( m_board->GetLayerName( layer ) ).c_str() );
539 
540  m_out->Print( 0, ")\n" );
541  }
542 
543  // Save used non-copper layers in the order they are defined.
544  // desired sequence for non Cu BOARD layers.
545  static const PCB_LAYER_ID non_cu[] =
546  {
547  B_Adhes, // 32
548  F_Adhes,
549  B_Paste,
550  F_Paste,
551  B_SilkS,
552  F_SilkS,
553  B_Mask,
554  F_Mask,
555  Dwgs_User,
556  Cmts_User,
557  Eco1_User,
558  Eco2_User,
559  Edge_Cuts,
560  Margin,
561  B_CrtYd,
562  F_CrtYd,
563  B_Fab,
564  F_Fab,
565  User_1,
566  User_2,
567  User_3,
568  User_4,
569  User_5,
570  User_6,
571  User_7,
572  User_8,
573  User_9
574  };
575 
576  for( LSEQ seq = aBoard->GetEnabledLayers().Seq( non_cu, arrayDim( non_cu ) ); seq; ++seq )
577  {
578  PCB_LAYER_ID layer = *seq;
579 
580  m_out->Print( aNestLevel+1, "(%d %s user", layer,
581  m_out->Quotew( LSET::Name( layer ) ).c_str() );
582 
583  if( m_board->GetLayerName( layer ) != LSET::Name( layer ) )
584  m_out->Print( 0, " %s", m_out->Quotew( m_board->GetLayerName( layer ) ).c_str() );
585 
586  m_out->Print( 0, ")\n" );
587  }
588 
589  m_out->Print( aNestLevel, ")\n\n" );
590 }
OUTPUTFORMATTER * m_out
output any Format()s to this, no ownership
LSEQ CuStack() const
Return a sequence of copper layers in starting from the front/top and extending to the back/bottom.
Definition: lset.cpp:170
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition: board.cpp:342
LSET GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings Returns a bit-mask of all t...
Definition: board.cpp:447
LSEQ Seq(const PCB_LAYER_ID *aWishListSequence, unsigned aCount) const
Return an LSEQ from the union of this LSET and a desired sequence.
Definition: lset.cpp:411
static const char * ShowType(LAYER_T aType)
Convert a LAYER_T enum to a string representation of the layer type.
Definition: board.cpp:407
PCB_LAYER_ID
A quick note on layer IDs:
static const wxChar * Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
Definition: lset.cpp:82
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Returns # of elements in an array.
Definition: arraydim.h:31
LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
LAYER_T GetLayerType(PCB_LAYER_ID aLayer) const
Return the type of the copper layer given by aLayer.
Definition: board.cpp:376
BOARD * m_board
which BOARD, no ownership here
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:408
std::string Quotew(const wxString &aWrapee) const
Definition: richio.cpp:476

References arrayDim(), B_Adhes, B_CrtYd, B_Fab, B_Mask, B_Paste, B_SilkS, Cmts_User, LSET::CuStack(), Dwgs_User, Eco1_User, Eco2_User, Edge_Cuts, F_Adhes, F_CrtYd, F_Fab, F_Mask, F_Paste, F_SilkS, BOARD::GetEnabledLayers(), BOARD::GetLayerName(), BOARD::GetLayerType(), m_board, m_out, Margin, LSET::Name(), OUTPUTFORMATTER::Print(), OUTPUTFORMATTER::Quotew(), LSET::Seq(), LAYER::ShowType(), User_1, User_2, User_3, User_4, User_5, User_6, User_7, User_8, and User_9.

Referenced by formatHeader(), and CLIPBOARD_IO::SaveSelection().

◆ formatGeneral()

void PCB_IO::formatGeneral ( const BOARD aBoard,
int  aNestLevel = 0 
) const
protected

formats the General section of the file

Definition at line 507 of file kicad_plugin.cpp.

508 {
509  const BOARD_DESIGN_SETTINGS& dsnSettings = aBoard->GetDesignSettings();
510 
511  m_out->Print( 0, "\n" );
512  m_out->Print( aNestLevel, "(general\n" );
513  m_out->Print( aNestLevel+1, "(thickness %s)\n",
514  FormatInternalUnits( dsnSettings.GetBoardThickness() ).c_str() );
515 
516  m_out->Print( aNestLevel, ")\n\n" );
517 
518  aBoard->GetPageSettings().Format( m_out, aNestLevel, m_ctl );
519  aBoard->GetTitleBlock().Format( m_out, aNestLevel, m_ctl );
520 }
OUTPUTFORMATTER * m_out
output any Format()s to this, no ownership
const PAGE_INFO & GetPageSettings() const
Definition: board.h:608
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.h:593
void Format(OUTPUTFORMATTER *aFormatter, int aNestLevel, int aControlBits) const
Output the page class to aFormatter in s-expression form.
Definition: page_info.cpp:271
virtual void Format(OUTPUTFORMATTER *aFormatter, int aNestLevel, int aControlBits) const
Output the object to aFormatter in s-expression form.
Definition: title_block.cpp:29
TITLE_BLOCK & GetTitleBlock()
Definition: board.h:614
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:408
std::string FormatInternalUnits(int aValue)
Function FormatInternalUnits converts aValue from internal units to a string appropriate for writing ...
Definition: base_units.cpp:471
Container for design settings for a BOARD object.

References TITLE_BLOCK::Format(), PAGE_INFO::Format(), FormatInternalUnits(), BOARD_DESIGN_SETTINGS::GetBoardThickness(), BOARD::GetDesignSettings(), BOARD::GetPageSettings(), BOARD::GetTitleBlock(), m_ctl, m_out, and OUTPUTFORMATTER::Print().

Referenced by formatHeader().

◆ formatHeader()

void PCB_IO::formatHeader ( const BOARD aBoard,
int  aNestLevel = 0 
) const
protected

writes everything that comes before the board_items, like settings and layers etc

Definition at line 622 of file kicad_plugin.cpp.

623 {
624  formatGeneral( aBoard, aNestLevel );
625  // Layers list.
626  formatBoardLayers( aBoard, aNestLevel );
627 
628  // Setup
629  formatSetup( aBoard, aNestLevel );
630 
631  // Properties
632  formatProperties( aBoard, aNestLevel );
633 
634  // Save net codes and names
635  formatNetInformation( aBoard, aNestLevel );
636 }
void formatBoardLayers(const BOARD *aBoard, int aNestLevel=0) const
formats the board layer information
void formatProperties(const BOARD *aBoard, int aNestLevel=0) const
formats the Nets and Netclasses
void formatGeneral(const BOARD *aBoard, int aNestLevel=0) const
formats the General section of the file
void formatNetInformation(const BOARD *aBoard, int aNestLevel=0) const
formats the Nets and Netclasses
void formatSetup(const BOARD *aBoard, int aNestLevel=0) const
formats the board setup information

References formatBoardLayers(), formatGeneral(), formatNetInformation(), formatProperties(), and formatSetup().

Referenced by format().

◆ formatLayer()

void PCB_IO::formatLayer ( const BOARD_ITEM aItem) const
private

Definition at line 455 of file kicad_plugin.cpp.

456 {
457  PCB_LAYER_ID layer = aItem->GetLayer();
458 
459  m_out->Print( 0, " (layer %s)", m_out->Quotew( LSET::Name( layer ) ).c_str() );
460 }
OUTPUTFORMATTER * m_out
output any Format()s to this, no ownership
PCB_LAYER_ID
A quick note on layer IDs:
static const wxChar * Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
Definition: lset.cpp:82
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:408
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:173
std::string Quotew(const wxString &aWrapee) const
Definition: richio.cpp:476

References BOARD_ITEM::GetLayer(), m_out, LSET::Name(), OUTPUTFORMATTER::Print(), and OUTPUTFORMATTER::Quotew().

Referenced by format().

◆ formatLayers()

void PCB_IO::formatLayers ( LSET  aLayerMask,
int  aNestLevel = 0 
) const
private

Definition at line 1195 of file kicad_plugin.cpp.

1196 {
1197  std::string output;
1198 
1199  if( aNestLevel == 0 )
1200  output += ' ';
1201 
1202  output += "(layers";
1203 
1204  static const LSET cu_all( LSET::AllCuMask() );
1205  static const LSET fr_bk( 2, B_Cu, F_Cu );
1206  static const LSET adhes( 2, B_Adhes, F_Adhes );
1207  static const LSET paste( 2, B_Paste, F_Paste );
1208  static const LSET silks( 2, B_SilkS, F_SilkS );
1209  static const LSET mask( 2, B_Mask, F_Mask );
1210  static const LSET crt_yd(2, B_CrtYd, F_CrtYd );
1211  static const LSET fab( 2, B_Fab, F_Fab );
1212 
1213  LSET cu_mask = cu_all;
1214 
1215  // output copper layers first, then non copper
1216 
1217  if( ( aLayerMask & cu_mask ) == cu_mask )
1218  {
1219  output += " *.Cu";
1220  aLayerMask &= ~cu_all; // clear bits, so they are not output again below
1221  }
1222  else if( ( aLayerMask & cu_mask ) == fr_bk )
1223  {
1224  output += " F&B.Cu";
1225  aLayerMask &= ~fr_bk;
1226  }
1227 
1228  if( ( aLayerMask & adhes ) == adhes )
1229  {
1230  output += " *.Adhes";
1231  aLayerMask &= ~adhes;
1232  }
1233 
1234  if( ( aLayerMask & paste ) == paste )
1235  {
1236  output += " *.Paste";
1237  aLayerMask &= ~paste;
1238  }
1239 
1240  if( ( aLayerMask & silks ) == silks )
1241  {
1242  output += " *.SilkS";
1243  aLayerMask &= ~silks;
1244  }
1245 
1246  if( ( aLayerMask & mask ) == mask )
1247  {
1248  output += " *.Mask";
1249  aLayerMask &= ~mask;
1250  }
1251 
1252  if( ( aLayerMask & crt_yd ) == crt_yd )
1253  {
1254  output += " *.CrtYd";
1255  aLayerMask &= ~crt_yd;
1256  }
1257 
1258  if( ( aLayerMask & fab ) == fab )
1259  {
1260  output += " *.Fab";
1261  aLayerMask &= ~fab;
1262  }
1263 
1264  // output any individual layers not handled in wildcard combos above
1265 
1266  wxString layerName;
1267 
1268  for( LAYER_NUM layer = 0; layer < PCB_LAYER_ID_COUNT; ++layer )
1269  {
1270  if( aLayerMask[layer] )
1271  {
1272  layerName = LSET::Name( PCB_LAYER_ID( layer ) );
1273  output += ' ';
1274  output += m_out->Quotew( layerName );
1275  }
1276  }
1277 
1278  m_out->Print( aNestLevel, "%s)", output.c_str() );
1279 }
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:750
OUTPUTFORMATTER * m_out
output any Format()s to this, no ownership
PCB_LAYER_ID
A quick note on layer IDs:
LSET is a set of PCB_LAYER_IDs.
static const wxChar * Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
Definition: lset.cpp:82
int LAYER_NUM
This can be replaced with int and removed.
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:408
std::string Quotew(const wxString &aWrapee) const
Definition: richio.cpp:476

References LSET::AllCuMask(), B_Adhes, B_CrtYd, B_Cu, B_Fab, B_Mask, B_Paste, B_SilkS, F_Adhes, F_CrtYd, F_Cu, F_Fab, F_Mask, F_Paste, F_SilkS, m_out, LSET::Name(), paste, PCB_LAYER_ID_COUNT, OUTPUTFORMATTER::Print(), and OUTPUTFORMATTER::Quotew().

Referenced by format().

◆ formatNetInformation()

void PCB_IO::formatNetInformation ( const BOARD aBoard,
int  aNestLevel = 0 
) const
protected

formats the Nets and Netclasses

Definition at line 593 of file kicad_plugin.cpp.

594 {
595  for( NETINFO_ITEM* net : *m_mapping )
596  {
597  if( net == nullptr ) // Skip not actually existing nets (orphan nets)
598  continue;
599 
600  m_out->Print( aNestLevel, "(net %d %s)\n",
601  m_mapping->Translate( net->GetNetCode() ),
602  m_out->Quotew( net->GetNetname() ).c_str() );
603  }
604 
605  m_out->Print( 0, "\n" );
606 }
OUTPUTFORMATTER * m_out
output any Format()s to this, no ownership
NETINFO_MAPPING * m_mapping
mapping for net codes, so only not empty net codes are stored with consecutive integers as net codes
Handle the data for a net.
Definition: netinfo.h:64
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:408
int Translate(int aNetCode) const
Translate net number according to the map prepared by Update() function.
std::string Quotew(const wxString &aWrapee) const
Definition: richio.cpp:476

References m_mapping, m_out, OUTPUTFORMATTER::Print(), OUTPUTFORMATTER::Quotew(), and NETINFO_MAPPING::Translate().

Referenced by formatHeader(), and CLIPBOARD_IO::SaveSelection().

◆ formatProperties()

void PCB_IO::formatProperties ( const BOARD aBoard,
int  aNestLevel = 0 
) const
protected

formats the Nets and Netclasses

Definition at line 609 of file kicad_plugin.cpp.

610 {
611  for( const std::pair<const wxString, wxString>& prop : aBoard->GetProperties() )
612  {
613  m_out->Print( aNestLevel, "(property %s %s)\n",
614  m_out->Quotew( prop.first ).c_str(),
615  m_out->Quotew( prop.second ).c_str() );
616  }
617 
618  m_out->Print( 0, "\n" );
619 }
OUTPUTFORMATTER * m_out
output any Format()s to this, no ownership
const std::map< wxString, wxString > & GetProperties() const
Definition: board.h:330
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:408
std::string Quotew(const wxString &aWrapee) const
Definition: richio.cpp:476

References BOARD::GetProperties(), m_out, OUTPUTFORMATTER::Print(), and OUTPUTFORMATTER::Quotew().

Referenced by formatHeader().

◆ formatSetup()

void PCB_IO::formatSetup ( const BOARD aBoard,
int  aNestLevel = 0 
) const
protected

formats the board setup information

Definition at line 463 of file kicad_plugin.cpp.

464 {
465  // Setup
466  m_out->Print( aNestLevel, "(setup\n" );
467 
468  // Save the board physical stackup structure
469  const BOARD_STACKUP& stackup = aBoard->GetDesignSettings().GetStackupDescriptor();
470 
471  if( aBoard->GetDesignSettings().m_HasStackup )
472  stackup.FormatBoardStackup( m_out, aBoard, aNestLevel+1 );
473 
474  BOARD_DESIGN_SETTINGS& dsnSettings = aBoard->GetDesignSettings();
475 
476  m_out->Print( aNestLevel+1, "(pad_to_mask_clearance %s)\n",
477  FormatInternalUnits( dsnSettings.m_SolderMaskMargin ).c_str() );
478 
479  if( dsnSettings.m_SolderMaskMinWidth )
480  m_out->Print( aNestLevel+1, "(solder_mask_min_width %s)\n",
481  FormatInternalUnits( dsnSettings.m_SolderMaskMinWidth ).c_str() );
482 
483  if( dsnSettings.m_SolderPasteMargin != 0 )
484  m_out->Print( aNestLevel+1, "(pad_to_paste_clearance %s)\n",
485  FormatInternalUnits( dsnSettings.m_SolderPasteMargin ).c_str() );
486 
487  if( dsnSettings.m_SolderPasteMarginRatio != 0 )
488  m_out->Print( aNestLevel+1, "(pad_to_paste_clearance_ratio %s)\n",
489  Double2Str( dsnSettings.m_SolderPasteMarginRatio ).c_str() );
490 
491  if( dsnSettings.m_AuxOrigin != wxPoint( 0, 0 ) )
492  m_out->Print( aNestLevel+1, "(aux_axis_origin %s %s)\n",
493  FormatInternalUnits( dsnSettings.m_AuxOrigin.x ).c_str(),
494  FormatInternalUnits( dsnSettings.m_AuxOrigin.y ).c_str() );
495 
496  if( dsnSettings.m_GridOrigin != wxPoint( 0, 0 ) )
497  m_out->Print( aNestLevel+1, "(grid_origin %s %s)\n",
498  FormatInternalUnits( dsnSettings.m_GridOrigin.x ).c_str(),
499  FormatInternalUnits( dsnSettings.m_GridOrigin.y ).c_str() );
500 
501  aBoard->GetPlotOptions().Format( m_out, aNestLevel+1 );
502 
503  m_out->Print( aNestLevel, ")\n\n" );
504 }
OUTPUTFORMATTER * m_out
output any Format()s to this, no ownership
const PCB_PLOT_PARAMS & GetPlotOptions() const
Definition: board.h:611
wxPoint m_GridOrigin
origin for grid offsets
Manage layers needed to make a physical board.
void Format(OUTPUTFORMATTER *aFormatter, int aNestLevel, int aControl=0) const
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.h:593
BOARD_STACKUP & GetStackupDescriptor()
void FormatBoardStackup(OUTPUTFORMATTER *aFormatter, const BOARD *aBoard, int aNestLevel) const
Write the stackup info on board file.
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:408
wxPoint m_AuxOrigin
origin for plot exports
std::string FormatInternalUnits(int aValue)
Function FormatInternalUnits converts aValue from internal units to a string appropriate for writing ...
Definition: base_units.cpp:471
Container for design settings for a BOARD object.
std::string Double2Str(double aValue)
Prints a float number without using scientific notation and no trailing 0 We want to avoid scientific...
Definition: string.cpp:872

References Double2Str(), PCB_PLOT_PARAMS::Format(), BOARD_STACKUP::FormatBoardStackup(), FormatInternalUnits(), BOARD::GetDesignSettings(), BOARD::GetPlotOptions(), BOARD_DESIGN_SETTINGS::GetStackupDescriptor(), BOARD_DESIGN_SETTINGS::m_AuxOrigin, BOARD_DESIGN_SETTINGS::m_GridOrigin, BOARD_DESIGN_SETTINGS::m_HasStackup, m_out, BOARD_DESIGN_SETTINGS::m_SolderMaskMargin, BOARD_DESIGN_SETTINGS::m_SolderMaskMinWidth, BOARD_DESIGN_SETTINGS::m_SolderPasteMargin, BOARD_DESIGN_SETTINGS::m_SolderPasteMarginRatio, and OUTPUTFORMATTER::Print().

Referenced by formatHeader().

◆ GetEnumeratedFootprint()

const FOOTPRINT * PCB_IO::GetEnumeratedFootprint ( const wxString &  aLibraryPath,
const wxString &  aFootprintName,
const PROPERTIES aProperties = nullptr 
)
overridevirtual

A version of FootprintLoad() for use after FootprintEnumerate() for more efficient cache management.

Reimplemented from PLUGIN.

Definition at line 2281 of file kicad_plugin.cpp.

2284 {
2285  return getFootprint( aLibraryPath, aFootprintName, aProperties, false );
2286 }
const FOOTPRINT * getFootprint(const wxString &aLibraryPath, const wxString &aFootprintName, const PROPERTIES *aProperties, bool checkModified)

References getFootprint().

◆ GetFileExtension()

const wxString PCB_IO::GetFileExtension ( ) const
inlineoverridevirtual

Returns the file extension for the PLUGIN.

Implements PLUGIN.

Definition at line 141 of file pcbnew/plugins/kicad/kicad_plugin.h.

142  {
143  // Would have used wildcards_and_files_ext.cpp's KiCadPcbFileExtension,
144  // but to be pure, a plugin should not assume that it will always be linked
145  // with the core of the Pcbnew code. (Might someday be a DLL/DSO.) Besides,
146  // file extension policy should be controlled by the plugin.
147  return wxT( "kicad_pcb" );
148  }

◆ getFootprint()

const FOOTPRINT * PCB_IO::getFootprint ( const wxString &  aLibraryPath,
const wxString &  aFootprintName,
const PROPERTIES aProperties,
bool  checkModified 
)
protected

Definition at line 2253 of file kicad_plugin.cpp.

2257 {
2258  LOCALE_IO toggle; // toggles on, then off, the C locale.
2259 
2260  init( aProperties );
2261 
2262  try
2263  {
2264  validateCache( aLibraryPath, checkModified );
2265  }
2266  catch( const IO_ERROR& )
2267  {
2268  // do nothing with the error
2269  }
2270 
2271  FOOTPRINT_MAP& footprints = m_cache->GetFootprints();
2272  FOOTPRINT_MAP::const_iterator it = footprints.find( aFootprintName );
2273 
2274  if( it == footprints.end() )
2275  return nullptr;
2276 
2277  return it->second->GetFootprint();
2278 }
FOOTPRINT_MAP & GetFootprints()
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:40
FP_CACHE * m_cache
Footprint library cache.
void init(const PROPERTIES *aProperties)
void validateCache(const wxString &aLibraryPath, bool checkModified=true)
std::map< wxString, FOOTPRINT * > FOOTPRINT_MAP
Definition: eagle_parser.h:50
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:75

References FP_CACHE::GetFootprints(), init(), m_cache, and validateCache().

Referenced by FootprintLoad(), and GetEnumeratedFootprint().

◆ GetImportedCachedLibraryFootprints()

std::vector< FOOTPRINT * > PLUGIN::GetImportedCachedLibraryFootprints ( )
virtualinherited

Return a container with the cached library footprints generated in the last call to Load.

This function is intended to be used ONLY by the non-KiCad board importers for the purpose of obtaining the footprint library of the design and creating a project-specific library.

Returns
Footprints (caller owns the objects)

Reimplemented in EAGLE_PLUGIN, and CADSTAR_PCB_ARCHIVE_PLUGIN.

Definition at line 54 of file plugin.cpp.

55 {
56  not_implemented( this, __FUNCTION__ );
57  return std::vector<FOOTPRINT*>();
58 }
static void not_implemented(PLUGIN *aPlugin, const char *aCaller)
Throw an IO_ERROR and complains of an API function not being implemented.
Definition: plugin.cpp:38

References not_implemented().

Referenced by PCB_EDIT_FRAME::OpenProjectFiles().

◆ GetLibraryTimestamp()

long long PCB_IO::GetLibraryTimestamp ( const wxString &  aLibraryPath) const
overridevirtual

Generate a timestamp representing all the files in the library (including the library directory).

Timestamps should not be considered ordered, they either match or they don't.

Implements PLUGIN.

Definition at line 2455 of file kicad_plugin.cpp.

2456 {
2457  return FP_CACHE::GetTimestamp( aLibraryPath );
2458 }
static long long GetTimestamp(const wxString &aLibPath)
Generate a timestamp representing all source files in the cache (including the parent directory).

References FP_CACHE::GetTimestamp().

◆ GetStringOutput()

std::string PCB_IO::GetStringOutput ( bool  doClear)
inline

Definition at line 201 of file pcbnew/plugins/kicad/kicad_plugin.h.

202  {
203  std::string ret = m_sf.GetString();
204 
205  if( doClear )
206  m_sf.Clear();
207 
208  return ret;
209  }
const std::string & GetString()
Definition: richio.h:435
void Clear()
Clear the buffer and empties the internal string.
Definition: richio.h:425

References STRING_FORMATTER::Clear(), STRING_FORMATTER::GetString(), and m_sf.

Referenced by FOOTPRINT_EDIT_FRAME::ExportFootprint().

◆ init()

void PCB_IO::init ( const PROPERTIES aProperties)
protected

Definition at line 2204 of file kicad_plugin.cpp.

2205 {
2206  m_board = nullptr;
2207  m_reader = nullptr;
2208  m_props = aProperties;
2209 }
LINE_READER * m_reader
no ownership here.
const PROPERTIES * m_props
passed via Save() or Load(), no ownership, may be NULL.
BOARD * m_board
which BOARD, no ownership here

References m_board, m_props, and m_reader.

Referenced by DoLoad(), FootprintDelete(), FootprintEnumerate(), FootprintLibCreate(), FootprintSave(), getFootprint(), IsFootprintLibWritable(), CLIPBOARD_IO::Load(), PCB_IO(), CLIPBOARD_IO::Save(), and Save().

◆ IsFootprintLibWritable()

bool PCB_IO::IsFootprintLibWritable ( const wxString &  aLibraryPath)
overridevirtual

Return true if the library at aLibraryPath is writable.

The system libraries are typically read only because of where they are installed..

Parameters
aLibraryPathis a locator for the "library", usually a directory, file, or URL containing several footprints.
Exceptions
IO_ERRORif no library at aLibraryPath exists.

Reimplemented from PLUGIN.

Definition at line 2554 of file kicad_plugin.cpp.

2555 {
2556  LOCALE_IO toggle;
2557 
2558  init( nullptr );
2559 
2560  validateCache( aLibraryPath );
2561 
2562  return m_cache->IsWritable();
2563 }
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:40
FP_CACHE * m_cache
Footprint library cache.
void init(const PROPERTIES *aProperties)
void validateCache(const wxString &aLibraryPath, bool checkModified=true)
bool IsWritable() const

References init(), FP_CACHE::IsWritable(), m_cache, and validateCache().

◆ Load()

BOARD * PCB_IO::Load ( const wxString &  aFileName,
BOARD aAppendToMe,
const PROPERTIES aProperties = nullptr,
PROJECT aProject = nullptr 
)
overridevirtual

Load information from some input file format that this PLUGIN implementation knows about into either a new BOARD or an existing one.

This may be used to load an entire new BOARD, or to augment an existing one if aAppendToMe is not NULL.

Parameters
aFileNameis the name of the file to use as input and may be foreign in nature or native in nature.
aAppendToMeis an existing BOARD to append to, but if NULL then this means "do not append, rather load anew".
aPropertiesis an associative array that can be used to tell the loader how to load the file, because it can take any number of additional named arguments that the plugin is known to support. These are tuning parameters for the import or load. The caller continues to own this object (plugin may not delete it), and plugins should expect it to be optionally NULL.
aProjectis the optional PROJECT object primarily used by third party importers.
Returns
the successfully loaded board, or the same one as aAppendToMe if aAppendToMe was not NULL, and caller owns it.
Exceptions
IO_ERRORif there is a problem loading, and its contents should say what went wrong, using line number and character offsets of the input file if possible.

Reimplemented from PLUGIN.

Definition at line 2151 of file kicad_plugin.cpp.

2153 {
2154  FILE_LINE_READER reader( aFileName );
2155 
2156  BOARD* board = DoLoad( reader, aAppendToMe, aProperties );
2157 
2158  // Give the filename to the board if it's new
2159  if( !aAppendToMe )
2160  board->SetFileName( aFileName );
2161 
2162  return board;
2163 }
A LINE_READER that reads from an open file.
Definition: richio.h:172
void SetFileName(const wxString &aFileName)
Definition: board.h:298
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:190
BOARD * DoLoad(LINE_READER &aReader, BOARD *aAppendToMe, const PROPERTIES *aProperties)

References DoLoad(), and BOARD::SetFileName().

Referenced by PNS_LOG_FILE::Load().

◆ Parse()

BOARD_ITEM * PCB_IO::Parse ( const wxString &  aClipboardSourceInput)

Definition at line 367 of file kicad_plugin.cpp.

368 {
369  std::string input = TO_UTF8( aClipboardSourceInput );
370 
371  STRING_LINE_READER reader( input, wxT( "clipboard" ) );
372 
373  m_parser->SetLineReader( &reader );
374 
375  try
376  {
377  return m_parser->Parse();
378  }
379  catch( const PARSE_ERROR& parse_error )
380  {
381  if( m_parser->IsTooRecent() )
382  throw FUTURE_FORMAT_ERROR( parse_error, m_parser->GetRequiredVersion() );
383  else
384  throw;
385  }
386 }
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
wxString GetRequiredVersion()
Return a string representing the version of KiCad required to open this file.
Definition: pcb_parser.cpp:184
BOARD_ITEM * Parse()
Definition: pcb_parser.cpp:473
LINE_READER * SetLineReader(LINE_READER *aReader)
Set aLineReader into the parser, and returns the previous one, if any.
Definition: pcb_parser.h:87
bool IsTooRecent()
Return whether a version number, if any was parsed, was too recent.
Definition: pcb_parser.h:116
A filename or source description, a problem input line, a line number, a byte offset,...
Definition: ki_exception.h:118
Variant of PARSE_ERROR indicating that a syntax or related error was likely caused by a file generate...
Definition: ki_exception.h:174
Is a LINE_READER that reads from a multiline 8 bit wide std::string.
Definition: richio.h:237

References PCB_PARSER::GetRequiredVersion(), PCB_PARSER::IsTooRecent(), m_parser, PCB_PARSER::Parse(), PCB_PARSER::SetLineReader(), and TO_UTF8.

Referenced by CLIPBOARD_IO::Parse(), and parse_footprint_kicad().

◆ PluginName()

const wxString PCB_IO::PluginName ( ) const
inlineoverridevirtual

Return a brief hard coded name for this PLUGIN.

Implements PLUGIN.

Definition at line 136 of file pcbnew/plugins/kicad/kicad_plugin.h.

137  {
138  return wxT( "KiCad" );
139  }

◆ PrefetchLib()

void PLUGIN::PrefetchLib ( const wxString &  aLibraryPath,
const PROPERTIES aProperties = nullptr 
)
virtualinherited

If possible, prefetches the specified library (e.g.

performing downloads). Does not parse. Threadsafe.

This is a no-op for libraries that cannot be prefetched. Plugins that cannot prefetch need not override this; a default no-op is provided.

Parameters
aLibraryPathis a locator for the "library", usually a directory, file, or URL containing several footprints.
aPropertiesis an associative array that can be used to tell the plugin anything needed about how to perform with respect to aLibraryPath. The caller continues to own this object (plugin may not delete it), and plugins should expect it to be optionally NULL.
Exceptions
IO_ERRORif there is an error prefetching the library.

Definition at line 75 of file plugin.cpp.

76 {
77  (void) aLibraryPath;
78  (void) aProperties;
79 }

◆ Save()

void PCB_IO::Save ( const wxString &  aFileName,
BOARD aBoard,
const PROPERTIES aProperties = nullptr 
)
overridevirtual

Write aBoard to a storage file in a format that this PLUGIN implementation knows about or it can be used to write a portion of aBoard to a special kind of export file.

Parameters
aFileNameis the name of a file to save to on disk.
aBoardis the class BOARD in memory document tree from which to extract information when writing to aFileName. The caller continues to own the BOARD, and the plugin should refrain from modifying the BOARD if possible.
aPropertiesis an associative array that can be used to tell the saver how to save the file, because it can take any number of additional named tuning arguments that the plugin is known to support. The caller continues to own this object (plugin may not delete it) and plugins should expect it to be optionally NULL.
Exceptions
IO_ERRORif there is a problem saving or exporting.

Reimplemented from PLUGIN.

Reimplemented in CLIPBOARD_IO.

Definition at line 329 of file kicad_plugin.cpp.

330 {
331  LOCALE_IO toggle; // toggles on, then off, the C locale.
332 
333  wxString sanityResult = aBoard->GroupsSanityCheck();
334 
335  if( sanityResult != wxEmptyString )
336  {
337  KIDIALOG dlg( nullptr, wxString::Format(
338  _( "Please report this bug. Error validating group structure: %s"
339  "\n\nSave anyway?" ), sanityResult ),
340  _( "Internal group data structure corrupt" ),
341  wxOK | wxCANCEL | wxICON_ERROR );
342  dlg.SetOKLabel( _( "Save Anyway" ) );
343 
344  if( dlg.ShowModal() == wxID_CANCEL )
345  return;
346  }
347 
348  init( aProperties );
349 
350  m_board = aBoard; // after init()
351 
352  // Prepare net mapping that assures that net codes saved in a file are consecutive integers
353  m_mapping->SetBoard( aBoard );
354 
355  FILE_OUTPUTFORMATTER formatter( aFileName );
356 
357  m_out = &formatter; // no ownership
358 
359  m_out->Print( 0, "(kicad_pcb (version %d) (generator pcbnew)\n", SEXPR_BOARD_FILE_VERSION );
360 
361  Format( aBoard, 1 );
362 
363  m_out->Print( 0, ")\n" );
364 }
OUTPUTFORMATTER * m_out
output any Format()s to this, no ownership
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:40
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
Definition: confirm.h:45
void init(const PROPERTIES *aProperties)
void SetBoard(const BOARD *aBoard)
Set a BOARD object that is used to prepare the net code map.
Definition: netinfo.h:193
NETINFO_MAPPING * m_mapping
mapping for net codes, so only not empty net codes are stored with consecutive integers as net codes
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
void Format(const BOARD_ITEM *aItem, int aNestLevel=0) const
Output aItem to aFormatter in s-expression format.
#define SEXPR_BOARD_FILE_VERSION
Current s-expression file format version. 2 was the last legacy format version.
#define _(s)
Definition: 3d_actions.cpp:33
BOARD * m_board
which BOARD, no ownership here
Used for text file output.
Definition: richio.h:453
wxString GroupsSanityCheck(bool repair=false)
Definition: board.cpp:2076
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:408

References _, Format(), Format(), BOARD::GroupsSanityCheck(), init(), m_board, m_mapping, m_out, OUTPUTFORMATTER::Print(), NETINFO_MAPPING::SetBoard(), SEXPR_BOARD_FILE_VERSION, and KIDIALOG::ShowModal().

Referenced by KI_TEST::DumpBoardToFile(), and ROUTER_TOOL::saveRouterDebugLog().

◆ SetOutputFormatter()

void PCB_IO::SetOutputFormatter ( OUTPUTFORMATTER aFormatter)
inline

Definition at line 211 of file pcbnew/plugins/kicad/kicad_plugin.h.

211 { m_out = aFormatter; }
OUTPUTFORMATTER * m_out
output any Format()s to this, no ownership

References m_out.

Referenced by FP_CACHE::Save().

◆ validateCache()

void PCB_IO::validateCache ( const wxString &  aLibraryPath,
bool  checkModified = true 
)
protected

Definition at line 2212 of file kicad_plugin.cpp.

2213 {
2214  if( !m_cache || !m_cache->IsPath( aLibraryPath ) || ( checkModified && m_cache->IsModified() ) )
2215  {
2216  // a spectacular episode in memory management:
2217  delete m_cache;
2218  m_cache = new FP_CACHE( this, aLibraryPath );
2219  m_cache->Load();
2220  }
2221 }
bool IsModified()
Return true if the cache is not up-to-date.
FP_CACHE * m_cache
Footprint library cache.
bool IsPath(const wxString &aPath) const
Check if aPath is the same as the current cache path.
void Load()

References FP_CACHE, FP_CACHE::IsModified(), FP_CACHE::IsPath(), FP_CACHE::Load(), and m_cache.

Referenced by FootprintDelete(), FootprintEnumerate(), FootprintSave(), getFootprint(), and IsFootprintLibWritable().

Friends And Related Function Documentation

◆ FP_CACHE

friend class FP_CACHE
friend

Definition at line 270 of file pcbnew/plugins/kicad/kicad_plugin.h.

Referenced by FootprintLibCreate(), and validateCache().

Member Data Documentation

◆ m_board

BOARD* PCB_IO::m_board
protected

◆ m_cache

◆ m_ctl

int PCB_IO::m_ctl
protected

Definition at line 285 of file pcbnew/plugins/kicad/kicad_plugin.h.

Referenced by FootprintSave(), format(), and formatGeneral().

◆ m_error

wxString PCB_IO::m_error
protected

for throwing exceptions

Definition at line 273 of file pcbnew/plugins/kicad/kicad_plugin.h.

◆ m_filename

wxString PCB_IO::m_filename
protected

for saves only, name is in m_reader for loads

Definition at line 281 of file pcbnew/plugins/kicad/kicad_plugin.h.

◆ m_mapping

NETINFO_MAPPING* PCB_IO::m_mapping
protected

mapping for net codes, so only not empty net codes are stored with consecutive integers as net codes

Definition at line 287 of file pcbnew/plugins/kicad/kicad_plugin.h.

Referenced by format(), formatNetInformation(), CLIPBOARD_IO::Save(), Save(), CLIPBOARD_IO::SaveSelection(), and ~PCB_IO().

◆ m_out

◆ m_parser

PCB_PARSER* PCB_IO::m_parser
protected

◆ m_props

const PROPERTIES* PCB_IO::m_props
protected

passed via Save() or Load(), no ownership, may be NULL.

Definition at line 277 of file pcbnew/plugins/kicad/kicad_plugin.h.

Referenced by init().

◆ m_reader

LINE_READER* PCB_IO::m_reader
protected

no ownership here.

Definition at line 280 of file pcbnew/plugins/kicad/kicad_plugin.h.

Referenced by init().

◆ m_sf

STRING_FORMATTER PCB_IO::m_sf
protected

Definition at line 283 of file pcbnew/plugins/kicad/kicad_plugin.h.

Referenced by GetStringOutput(), and PCB_IO().


The documentation for this class was generated from the following files: