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, PROGRESS_REPORTER *aProgressReporter=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, PROGRESS_REPORTER *aProgressReporter, unsigned aLineCount)
 
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 PCB_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 PCB_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 141 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 2259 of file kicad_plugin.cpp.

2259  :
2260  m_cache( nullptr ),
2261  m_ctl( aControlFlags ),
2262  m_parser( new PCB_PARSER() ),
2263  m_mapping( new NETINFO_MAPPING() )
2264 {
2265  init( nullptr );
2266  m_out = &m_sf;
2267 }
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:71
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 2270 of file kicad_plugin.cpp.

2271 {
2272  delete m_cache;
2273  delete m_parser;
2274  delete m_mapping;
2275 }
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,
PROGRESS_REPORTER aProgressReporter,
unsigned  aLineCount 
)

Definition at line 2308 of file kicad_plugin.cpp.

2310 {
2311  init( aProperties );
2312 
2313  m_parser->SetLineReader( &aReader );
2314  m_parser->SetBoard( aAppendToMe );
2315  m_parser->SetProgressReporter( aProgressReporter, &aReader, aLineCount );
2316 
2317  BOARD* board;
2318 
2319  try
2320  {
2321  board = dynamic_cast<BOARD*>( m_parser->Parse() );
2322  }
2323  catch( const FUTURE_FORMAT_ERROR& )
2324  {
2325  // Don't wrap a FUTURE_FORMAT_ERROR in another
2326  throw;
2327  }
2328  catch( const PARSE_ERROR& parse_error )
2329  {
2330  if( m_parser->IsTooRecent() )
2331  throw FUTURE_FORMAT_ERROR( parse_error, m_parser->GetRequiredVersion() );
2332  else
2333  throw;
2334  }
2335 
2336  if( !board )
2337  {
2338  // The parser loaded something that was valid, but wasn't a board.
2339  THROW_PARSE_ERROR( _( "This file does not contain a PCB." ), m_parser->CurSource(),
2340  m_parser->CurLine(), m_parser->CurLineNumber(), m_parser->CurOffset() );
2341  }
2342 
2343  return board;
2344 }
void SetProgressReporter(PROGRESS_REPORTER *aProgressReporter, const LINE_READER *aLineReader, unsigned aLineCount)
Definition: pcb_parser.h:110
void init(const PROPERTIES *aProperties)
wxString GetRequiredVersion()
Return a string representing the version of KiCad required to open this file.
Definition: pcb_parser.cpp:246
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
Definition: ki_exception.h:164
void SetBoard(BOARD *aBoard)
Definition: pcb_parser.h:101
#define _(s)
BOARD_ITEM * Parse()
Definition: pcb_parser.cpp:626
LINE_READER * SetLineReader(LINE_READER *aReader)
Set aLineReader into the parser, and returns the previous one, if any.
Definition: pcb_parser.h:94
bool IsTooRecent()
Return whether a version number, if any was parsed, was too recent.
Definition: pcb_parser.h:132
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
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(), PCB_PARSER::SetProgressReporter(), 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 2566 of file kicad_plugin.cpp.

2568 {
2569  LOCALE_IO toggle; // toggles on, then off, the C locale.
2570 
2571  init( aProperties );
2572 
2573  validateCache( aLibraryPath );
2574 
2575  if( !m_cache->IsWritable() )
2576  {
2577  THROW_IO_ERROR( wxString::Format( _( "Library '%s' is read only." ),
2578  aLibraryPath.GetData() ) );
2579  }
2580 
2581  m_cache->Remove( aFootprintName );
2582 }
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)
#define _(s)
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 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 2367 of file kicad_plugin.cpp.

2369 {
2370  LOCALE_IO toggle; // toggles on, then off, the C locale.
2371  wxDir dir( aLibPath );
2372  wxString errorMsg;
2373 
2374  init( aProperties );
2375 
2376  try
2377  {
2378  validateCache( aLibPath );
2379  }
2380  catch( const IO_ERROR& ioe )
2381  {
2382  errorMsg = ioe.What();
2383  }
2384 
2385  // Some of the files may have been parsed correctly so we want to add the valid files to
2386  // the library.
2387 
2388  for( const auto& footprint : m_cache->GetFootprints() )
2389  aFootprintNames.Add( footprint.first );
2390 
2391  if( !errorMsg.IsEmpty() && !aBestEfforts )
2392  THROW_IO_ERROR( errorMsg );
2393 }
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:30
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 2432 of file kicad_plugin.cpp.

2434 {
2435  // Note: checking the cache sounds like a good idea, but won't catch files which differ
2436  // only in case.
2437  //
2438  // Since this goes out to the native filesystem, we get platform differences (ie: MSW's
2439  // case-insensitive filesystem) handled "for free".
2440  // Warning: footprint names frequently contain a point. So be careful when initializing
2441  // wxFileName, and use a CTOR with extension specified
2442  wxFileName footprintFile( aLibraryPath, aFootprintName, KiCadFootprintFileExtension );
2443 
2444  return footprintFile.Exists();
2445 }
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 2592 of file kicad_plugin.cpp.

2593 {
2594  if( wxDir::Exists( aLibraryPath ) )
2595  {
2596  THROW_IO_ERROR( wxString::Format( _( "Cannot overwrite library path '%s'." ),
2597  aLibraryPath.GetData() ) );
2598  }
2599 
2600  LOCALE_IO toggle;
2601 
2602  init( aProperties );
2603 
2604  delete m_cache;
2605  m_cache = new FP_CACHE( this, aLibraryPath );
2606  m_cache->Save();
2607 }
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)
#define _(s)
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 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 2610 of file kicad_plugin.cpp.

2611 {
2612  wxFileName fn;
2613  fn.SetPath( aLibraryPath );
2614 
2615  // Return if there is no library path to delete.
2616  if( !fn.DirExists() )
2617  return false;
2618 
2619  if( !fn.IsDirWritable() )
2620  {
2621  THROW_IO_ERROR( wxString::Format( _( "Insufficient permissions to delete folder '%s'." ),
2622  aLibraryPath.GetData() ) );
2623  }
2624 
2625  wxDir dir( aLibraryPath );
2626 
2627  if( dir.HasSubDirs() )
2628  {
2629  THROW_IO_ERROR( wxString::Format( _( "Library folder '%s' has unexpected sub-folders." ),
2630  aLibraryPath.GetData() ) );
2631  }
2632 
2633  // All the footprint files must be deleted before the directory can be deleted.
2634  if( dir.HasFiles() )
2635  {
2636  unsigned i;
2637  wxFileName tmp;
2638  wxArrayString files;
2639 
2640  wxDir::GetAllFiles( aLibraryPath, &files );
2641 
2642  for( i = 0; i < files.GetCount(); i++ )
2643  {
2644  tmp = files[i];
2645 
2646  if( tmp.GetExt() != KiCadFootprintFileExtension )
2647  {
2648  THROW_IO_ERROR( wxString::Format( _( "Unexpected file '%s' found in library "
2649  "path '%s'." ),
2650  files[i].GetData(),
2651  aLibraryPath.GetData() ) );
2652  }
2653  }
2654 
2655  for( i = 0; i < files.GetCount(); i++ )
2656  wxRemoveFile( files[i] );
2657  }
2658 
2659  wxLogTrace( traceKicadPcbPlugin, wxT( "Removing footprint library '%s'." ),
2660  aLibraryPath.GetData() );
2661 
2662  // Some of the more elaborate wxRemoveFile() crap puts up its own wxLog dialog
2663  // we don't want that. we want bare metal portability with no UI here.
2664  if( !wxRmdir( aLibraryPath ) )
2665  {
2666  THROW_IO_ERROR( wxString::Format( _( "Footprint library '%s' cannot be deleted." ),
2667  aLibraryPath.GetData() ) );
2668  }
2669 
2670  // For some reason removing a directory in Windows is not immediately updated. This delay
2671  // prevents an error when attempting to immediately recreate the same directory when over
2672  // writing an existing library.
2673 #ifdef __WINDOWS__
2674  wxMilliSleep( 250L );
2675 #endif
2676 
2677  if( m_cache && !m_cache->IsPath( aLibraryPath ) )
2678  {
2679  delete m_cache;
2680  m_cache = nullptr;
2681  }
2682 
2683  return true;
2684 }
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.
#define _(s)
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 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 147 of file plugin.cpp.

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

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 2448 of file kicad_plugin.cpp.

2452 {
2453  const FOOTPRINT* footprint = getFootprint( aLibraryPath, aFootprintName, aProperties, true );
2454 
2455  if( footprint )
2456  {
2457  FOOTPRINT* copy;
2458 
2459  if( aKeepUUID )
2460  copy = static_cast<FOOTPRINT*>( footprint->Clone() );
2461  else
2462  copy = static_cast<FOOTPRINT*>( footprint->Duplicate() );
2463 
2464  copy->SetParent( nullptr );
2465  return copy;
2466  }
2467 
2468  return nullptr;
2469 }
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:1706
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: footprint.cpp:1274

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 2472 of file kicad_plugin.cpp.

2474 {
2475  LOCALE_IO toggle; // toggles on, then off, the C locale.
2476 
2477  init( aProperties );
2478 
2479  // In this public PLUGIN API function, we can safely assume it was
2480  // called for saving into a library path.
2482 
2483  validateCache( aLibraryPath );
2484 
2485  if( !m_cache->IsWritable() )
2486  {
2487  if( !m_cache->Exists() )
2488  {
2489  const wxString msg = wxString::Format( _( "Library '%s' does not exist.\n"
2490  "Would you like to create it?"),
2491  aLibraryPath );
2492 
2493  if( wxMessageBox( msg, _( "Library Not Found"), wxYES_NO | wxICON_QUESTION ) != wxYES )
2494  return;
2495 
2496  // Save throws its own IO_ERROR on failure, so no need to recreate here
2497  m_cache->Save( nullptr );
2498  }
2499  else
2500  {
2501  wxString msg = wxString::Format( _( "Library '%s' is read only." ), aLibraryPath );
2502  THROW_IO_ERROR( msg );
2503  }
2504  }
2505 
2506  wxString footprintName = aFootprint->GetFPID().GetLibItemName();
2507 
2508  FOOTPRINT_MAP& footprints = m_cache->GetFootprints();
2509 
2510  // Quietly overwrite footprint and delete footprint file from path for any by same name.
2511  wxFileName fn( aLibraryPath, aFootprint->GetFPID().GetLibItemName(),
2513 
2514  // Write through symlinks, don't replace them
2516 
2517  if( !fn.IsOk() )
2518  {
2519  THROW_IO_ERROR( wxString::Format( _( "Footprint file name '%s' is not valid." ),
2520  fn.GetFullPath() ) );
2521  }
2522 
2523  if( fn.FileExists() && !fn.IsFileWritable() )
2524  {
2525  THROW_IO_ERROR( wxString::Format( _( "Insufficient permissions to delete '%s'." ),
2526  fn.GetFullPath() ) );
2527  }
2528 
2529  wxString fullPath = fn.GetFullPath();
2530  wxString fullName = fn.GetFullName();
2531  FOOTPRINT_MAP::const_iterator it = footprints.find( footprintName );
2532 
2533  if( it != footprints.end() )
2534  {
2535  wxLogTrace( traceKicadPcbPlugin, wxT( "Removing footprint file '%s'." ), fullPath );
2536  footprints.erase( footprintName );
2537  wxRemoveFile( fullPath );
2538  }
2539 
2540  // I need my own copy for the cache
2541  FOOTPRINT* footprint = static_cast<FOOTPRINT*>( aFootprint->Clone() );
2542 
2543  // It's orientation should be zero and it should be on the front layer.
2544  footprint->SetOrientation( 0 );
2545 
2546  if( footprint->GetLayer() != F_Cu )
2547  {
2548  PCBNEW_SETTINGS* cfg = dynamic_cast<PCBNEW_SETTINGS*>( Kiface().KifaceSettings() );
2549 
2550  if( cfg )
2551  footprint->Flip( footprint->GetPosition(), cfg->m_FlipLeftRight );
2552  else
2553  footprint->Flip( footprint->GetPosition(), false );
2554  }
2555 
2556  // Detach it from the board
2557  footprint->SetParent( nullptr );
2558 
2559  wxLogTrace( traceKicadPcbPlugin, wxT( "Creating s-expr footprint file '%s'." ), fullPath );
2560  footprints.insert( footprintName,
2561  new FP_CACHE_ITEM( footprint, WX_FILENAME( fn.GetPath(), fullName ) ) );
2562  m_cache->Save( footprint );
2563 }
FOOTPRINT_MAP & GetFootprints()
const UTF8 & GetLibItemName() const
Definition: lib_id.h:104
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.
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
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:116
void validateCache(const wxString &aLibraryPath, bool checkModified=true)
void SetOrientation(double aNewAngle)
Definition: footprint.cpp:1662
void Flip(const wxPoint &aCentre, bool aFlipLeftRight) override
Flip this object, i.e.
Definition: footprint.cpp:1472
static void ResolvePossibleSymlinks(wxFileName &aFilename)
Definition: wx_filename.cpp:85
const wxChar *const traceKicadPcbPlugin
Flag to enable GEDA PCB plugin debug output.
#define _(s)
const LIB_ID & GetFPID() const
Definition: footprint.h:194
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
std::map< wxString, FOOTPRINT * > FOOTPRINT_MAP
Definition: eagle_parser.h:50
Definition: layer_ids.h:71
wxPoint GetPosition() const override
Definition: footprint.h:186
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: footprint.cpp:1274
bool Exists() const
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:140
#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, WX_FILENAME::ResolvePossibleSymlinks(), FP_CACHE::Save(), FOOTPRINT::SetOrientation(), EDA_ITEM::SetParent(), THROW_IO_ERROR, 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 397 of file kicad_plugin.cpp.

398 {
399  LOCALE_IO toggle; // public API function, perform anything convenient for caller
400 
401  switch( aItem->Type() )
402  {
403  case PCB_T:
404  format( static_cast<const BOARD*>( aItem ), aNestLevel );
405  break;
406 
407  case PCB_DIM_ALIGNED_T:
408  case PCB_DIM_CENTER_T:
410  case PCB_DIM_LEADER_T:
411  format( static_cast<const PCB_DIMENSION_BASE*>( aItem ), aNestLevel );
412  break;
413 
414  case PCB_SHAPE_T:
415  format( static_cast<const PCB_SHAPE*>( aItem ), aNestLevel );
416  break;
417 
418  case PCB_FP_SHAPE_T:
419  format( static_cast<const FP_SHAPE*>( aItem ), aNestLevel );
420  break;
421 
422  case PCB_TARGET_T:
423  format( static_cast<const PCB_TARGET*>( aItem ), aNestLevel );
424  break;
425 
426  case PCB_FOOTPRINT_T:
427  format( static_cast<const FOOTPRINT*>( aItem ), aNestLevel );
428  break;
429 
430  case PCB_PAD_T:
431  format( static_cast<const PAD*>( aItem ), aNestLevel );
432  break;
433 
434  case PCB_TEXT_T:
435  format( static_cast<const PCB_TEXT*>( aItem ), aNestLevel );
436  break;
437 
438  case PCB_FP_TEXT_T:
439  format( static_cast<const FP_TEXT*>( aItem ), aNestLevel );
440  break;
441 
442  case PCB_GROUP_T:
443  format( static_cast<const PCB_GROUP*>( aItem ), aNestLevel );
444  break;
445 
446  case PCB_TRACE_T:
447  case PCB_ARC_T:
448  case PCB_VIA_T:
449  format( static_cast<const PCB_TRACK*>( aItem ), aNestLevel );
450  break;
451 
452  case PCB_FP_ZONE_T:
453  case PCB_ZONE_T:
454  format( static_cast<const ZONE*>( aItem ), aNestLevel );
455  break;
456 
457  default:
458  wxFAIL_MSG( wxT( "Cannot format item " ) + aItem->GetClass() );
459  }
460 }
void format(const BOARD *aBoard, int aNestLevel=0) const
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
Definition: typeinfo.h:100
class PCB_DIM_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 PCB_DIM_CENTER, a center point marking (graphic item)
Definition: typeinfo.h:102
class PCB_TEXT, text on a layer
Definition: typeinfo.h:91
class PCB_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 PCB_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 PCB_DIM_ORTHOGONAL, a linear dimension constrained to x/y
Definition: typeinfo.h:103
class PCB_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:113

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 649 of file kicad_plugin.cpp.

650 {
651  std::set<BOARD_ITEM*, BOARD_ITEM::ptr_cmp> sorted_footprints( aBoard->Footprints().begin(),
652  aBoard->Footprints().end() );
653  std::set<BOARD_ITEM*, BOARD_ITEM::ptr_cmp> sorted_drawings( aBoard->Drawings().begin(),
654  aBoard->Drawings().end() );
655  std::set<PCB_TRACK*, PCB_TRACK::cmp_tracks> sorted_tracks( aBoard->Tracks().begin(),
656  aBoard->Tracks().end() );
657  std::set<BOARD_ITEM*, BOARD_ITEM::ptr_cmp> sorted_zones( aBoard->Zones().begin(),
658  aBoard->Zones().end() );
659  std::set<BOARD_ITEM*, BOARD_ITEM::ptr_cmp> sorted_groups( aBoard->Groups().begin(),
660  aBoard->Groups().end() );
661  formatHeader( aBoard, aNestLevel );
662 
663  // Save the footprints.
664  for( BOARD_ITEM* footprint : sorted_footprints )
665  {
666  Format( footprint, aNestLevel );
667  m_out->Print( 0, "\n" );
668  }
669 
670  // Save the graphical items on the board (not owned by a footprint)
671  for( BOARD_ITEM* item : sorted_drawings )
672  Format( item, aNestLevel );
673 
674  if( sorted_drawings.size() )
675  m_out->Print( 0, "\n" );
676 
677  // Do not save PCB_MARKERs, they can be regenerated easily.
678 
679  // Save the tracks and vias.
680  for( PCB_TRACK* track : sorted_tracks )
681  Format( track, aNestLevel );
682 
683  if( sorted_tracks.size() )
684  m_out->Print( 0, "\n" );
685 
686  // Save the polygon (which are the newer technology) zones.
687  for( auto zone : sorted_zones )
688  Format( zone, aNestLevel );
689 
690  // Save the groups
691  for( BOARD_ITEM* group : sorted_groups )
692  Format( group, aNestLevel );
693 }
OUTPUTFORMATTER * m_out
output any Format()s to this, no ownership
ZONES & Zones()
Definition: board.h:239
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:49
GROUPS & Groups()
The groups must maintain the following invariants.
Definition: board.h:253
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:233
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:426
DRAWINGS & Drawings()
Definition: board.h:236
TRACKS & Tracks()
Definition: board.h:230

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 PCB_DIMENSION_BASE aDimension,
int  aNestLevel = 0 
) const
private

Definition at line 696 of file kicad_plugin.cpp.

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

References KIID::AsString(), Format(), FormatInternalUnits(), formatLayer(), PCB_DIMENSION_BASE::GetArrowLength(), PCB_DIMENSION_BASE::GetEnd(), PCB_DIM_ALIGNED::GetExtensionHeight(), PCB_DIMENSION_BASE::GetExtensionOffset(), PCB_DIM_ALIGNED::GetHeight(), PCB_DIMENSION_BASE::GetKeepTextAligned(), PCB_DIMENSION_BASE::GetLineThickness(), PCB_DIMENSION_BASE::GetOverrideText(), PCB_DIMENSION_BASE::GetOverrideTextEnabled(), PCB_DIMENSION_BASE::GetPrecision(), PCB_DIMENSION_BASE::GetPrefix(), PCB_DIMENSION_BASE::GetStart(), PCB_DIMENSION_BASE::GetSuffix(), PCB_DIMENSION_BASE::GetSuppressZeroes(), PCB_DIM_LEADER::GetTextFrame(), PCB_DIMENSION_BASE::GetTextPositionMode(), PCB_DIMENSION_BASE::GetUnitsFormat(), PCB_DIMENSION_BASE::GetUnitsMode(), BOARD_ITEM::IsLocked(), 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(), PCB_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 929 of file kicad_plugin.cpp.

930 {
931  std::string locked = aFPShape->IsLocked() ? " locked" : "";
932 
933  switch( aFPShape->GetShape() )
934  {
935  case SHAPE_T::SEGMENT:
936  m_out->Print( aNestLevel, "(fp_line%s (start %s) (end %s)",
937  locked.c_str(),
938  FormatInternalUnits( aFPShape->GetStart0() ).c_str(),
939  FormatInternalUnits( aFPShape->GetEnd0() ).c_str() );
940  break;
941 
942  case SHAPE_T::RECT:
943  m_out->Print( aNestLevel, "(fp_rect%s (start %s) (end %s)",
944  locked.c_str(),
945  FormatInternalUnits( aFPShape->GetStart0() ).c_str(),
946  FormatInternalUnits( aFPShape->GetEnd0() ).c_str() );
947  break;
948 
949  case SHAPE_T::CIRCLE:
950  m_out->Print( aNestLevel, "(fp_circle%s (center %s) (end %s)",
951  locked.c_str(),
952  FormatInternalUnits( aFPShape->GetStart0() ).c_str(),
953  FormatInternalUnits( aFPShape->GetEnd0() ).c_str() );
954  break;
955 
956  case SHAPE_T::ARC:
957  m_out->Print( aNestLevel, "(fp_arc%s (start %s) (mid %s) (end %s)",
958  locked.c_str(),
959  FormatInternalUnits( aFPShape->GetStart0() ).c_str(),
960  FormatInternalUnits( aFPShape->GetArcMid0() ).c_str(),
961  FormatInternalUnits( aFPShape->GetEnd0() ).c_str() );
962  break;
963 
964  case SHAPE_T::POLY:
965  if( aFPShape->IsPolyShapeValid() )
966  {
967  const SHAPE_POLY_SET& poly = aFPShape->GetPolyShape();
968  const SHAPE_LINE_CHAIN& outline = poly.Outline( 0 );
969 
970  m_out->Print( aNestLevel, "(fp_poly%s (pts",
971  locked.c_str() );
972 
973  bool need_newline = false;
974 
975  for( int ii = 0; ii < outline.PointCount(); ++ii )
976  {
977  int nestLevel = 0;
978 
979  if( !( ii % 4 ) || !ADVANCED_CFG::GetCfg().m_CompactSave )
980  {
981  // newline every 4 pts.
982  m_out->Print( 0, "\n" );
983  need_newline = false;
984  nestLevel = aNestLevel + 2;
985  }
986 
987  int ind = outline.ArcIndex( ii );
988 
989  if( ind < 0 )
990  {
991  m_out->Print( nestLevel, "%s(xy %s)",
992  nestLevel ? "" : " ",
993  FormatInternalUnits( outline.CPoint( ii ) ).c_str() );
994  need_newline = true;
995  }
996  else
997  {
998  auto& arc = outline.Arc( ind );
999  m_out->Print( nestLevel, "%s(arc (start %s) (mid %s) (end %s))",
1000  nestLevel ? "" : " ",
1001  FormatInternalUnits( arc.GetP0() ).c_str(),
1002  FormatInternalUnits( arc.GetArcMid() ).c_str(),
1003  FormatInternalUnits( arc.GetP1() ).c_str() );
1004  need_newline = true;
1005 
1006  do
1007  {
1008  ++ii;
1009  } while( ii < outline.PointCount() && outline.ArcIndex( ii ) == ind );
1010 
1011  --ii;
1012  }
1013  }
1014 
1015  if( need_newline )
1016  m_out->Print( 0, "\n" );
1017 
1018  m_out->Print( aNestLevel + 1, ")" );
1019  }
1020  else
1021  {
1022  wxFAIL_MSG( wxT( "Cannot format invalid polygon." ) );
1023  return;
1024  }
1025  break;
1026 
1027  case SHAPE_T::BEZIER:
1028  m_out->Print( aNestLevel, "(fp_curve%s (pts (xy %s) (xy %s) (xy %s) (xy %s))",
1029  locked.c_str(),
1030  FormatInternalUnits( aFPShape->GetStart0() ).c_str(),
1031  FormatInternalUnits( aFPShape->GetBezierC1_0() ).c_str(),
1032  FormatInternalUnits( aFPShape->GetBezierC2_0() ).c_str(),
1033  FormatInternalUnits( aFPShape->GetEnd0() ).c_str() );
1034  break;
1035 
1036  default:
1037  wxFAIL_MSG( "PCB_IO::format not implemented for " + aFPShape->SHAPE_T_asString() );
1038  return;
1039  };
1040 
1041  formatLayer( aFPShape );
1042 
1043  m_out->Print( 0, " (width %s)", FormatInternalUnits( aFPShape->GetWidth() ).c_str() );
1044 
1045  // The filled flag represents if a solid fill is present on circles, rectangles and polygons
1046  if( ( aFPShape->GetShape() == SHAPE_T::POLY )
1047  || ( aFPShape->GetShape() == SHAPE_T::RECT )
1048  || ( aFPShape->GetShape() == SHAPE_T::CIRCLE ) )
1049  {
1050  if( aFPShape->IsFilled() )
1051  m_out->Print( 0, " (fill solid)" );
1052  else
1053  m_out->Print( 0, " (fill none)" );
1054  }
1055 
1056  m_out->Print( 0, " (tstamp %s)", TO_UTF8( aFPShape->m_Uuid.AsString() ) );
1057 
1058  m_out->Print( 0, ")\n" );
1059 }
const SHAPE_ARC & Arc(size_t aArc) const
OUTPUTFORMATTER * m_out
output any Format()s to this, no ownership
int GetWidth() const
Definition: eda_shape.h:89
bool m_CompactSave
Save files in compact display mode When is is not specified, points are written one per line.
void formatLayer(const BOARD_ITEM *aItem) const
const wxPoint & GetStart0() const
Definition: fp_shape.h:112
wxString AsString() const
Definition: kiid.cpp:218
bool IsPolyShapeValid() const
Definition: eda_shape.cpp:1146
virtual bool IsLocked() const
Definition: board_item.cpp:64
int PointCount() const
Return the number of points (vertices) in this line chain.
bool IsFilled() const
Definition: eda_shape.h:81
ssize_t ArcIndex(size_t aSegment) const
Return the arc index for the given segment index.
wxPoint GetArcMid0() const
Definition: fp_shape.cpp:176
#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
Return a reference to a given point in the line chain.
Represent a set of closed polygons.
SHAPE_LINE_CHAIN & Outline(int aIndex)
wxString SHAPE_T_asString() const
Definition: eda_shape.cpp:68
SHAPE_POLY_SET & GetPolyShape()
Definition: eda_shape.h:207
const KIID m_Uuid
Definition: eda_item.h:475
Represent a polyline (an zero-thickness chain of connected line segments).
const wxPoint & GetEnd0() const
Definition: fp_shape.h:115
const wxPoint & GetBezierC2_0() const
Definition: fp_shape.h:121
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
SHAPE_T GetShape() const
Definition: eda_shape.h:92
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:426
const wxPoint & GetBezierC1_0() const
Definition: fp_shape.h:118
std::string FormatInternalUnits(int aValue)
Function FormatInternalUnits converts aValue from internal units to a string appropriate for writing ...
Definition: base_units.cpp:485

References ARC, SHAPE_LINE_CHAIN::Arc(), SHAPE_LINE_CHAIN::ArcIndex(), KIID::AsString(), BEZIER, CIRCLE, SHAPE_LINE_CHAIN::CPoint(), FormatInternalUnits(), formatLayer(), FP_SHAPE::GetArcMid0(), FP_SHAPE::GetBezierC1_0(), FP_SHAPE::GetBezierC2_0(), ADVANCED_CFG::GetCfg(), FP_SHAPE::GetEnd0(), EDA_SHAPE::GetPolyShape(), EDA_SHAPE::GetShape(), FP_SHAPE::GetStart0(), EDA_SHAPE::GetWidth(), EDA_SHAPE::IsFilled(), BOARD_ITEM::IsLocked(), EDA_SHAPE::IsPolyShapeValid(), locked, ADVANCED_CFG::m_CompactSave, m_out, EDA_ITEM::m_Uuid, SHAPE_POLY_SET::Outline(), SHAPE_LINE_CHAIN::PointCount(), POLY, OUTPUTFORMATTER::Print(), RECT, SEGMENT, EDA_SHAPE::SHAPE_T_asString(), and TO_UTF8.

◆ format() [4/12]

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

Definition at line 1757 of file kicad_plugin.cpp.

1758 {
1759  // Don't write empty groups
1760  if( aGroup->GetItems().empty() )
1761  return;
1762 
1763  m_out->Print( aNestLevel, "(group %s%s (id %s)\n",
1764  m_out->Quotew( aGroup->GetName() ).c_str(),
1765  aGroup->IsLocked() ? " locked" : "",
1766  TO_UTF8( aGroup->m_Uuid.AsString() ) );
1767 
1768  m_out->Print( aNestLevel + 1, "(members\n" );
1769 
1770  wxArrayString memberIds;
1771 
1772  for( BOARD_ITEM* member : aGroup->GetItems() )
1773  memberIds.Add( member->m_Uuid.AsString() );
1774 
1775  memberIds.Sort();
1776 
1777  for( const wxString& memberId : memberIds )
1778  m_out->Print( aNestLevel + 2, "%s\n", TO_UTF8( memberId ) );
1779 
1780  m_out->Print( aNestLevel + 1, ")\n" ); // Close `members` token.
1781  m_out->Print( aNestLevel, ")\n" ); // Close `group` token.
1782 }
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:49
wxString AsString() const
Definition: kiid.cpp:218
virtual bool IsLocked() const
Definition: board_item.cpp:64
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:475
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:426
std::string Quotew(const wxString &aWrapee) const
Definition: richio.cpp:494

References KIID::AsString(), PCB_GROUP::GetItems(), PCB_GROUP::GetName(), BOARD_ITEM::IsLocked(), 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 795 of file kicad_plugin.cpp.

796 {
797  std::string locked = aShape->IsLocked() ? " locked" : "";
798 
799  switch( aShape->GetShape() )
800  {
801  case SHAPE_T::SEGMENT:
802  m_out->Print( aNestLevel, "(gr_line%s (start %s) (end %s)",
803  locked.c_str(),
804  FormatInternalUnits( aShape->GetStart() ).c_str(),
805  FormatInternalUnits( aShape->GetEnd() ).c_str() );
806  break;
807 
808  case SHAPE_T::RECT:
809  m_out->Print( aNestLevel, "(gr_rect%s (start %s) (end %s)",
810  locked.c_str(),
811  FormatInternalUnits( aShape->GetStart() ).c_str(),
812  FormatInternalUnits( aShape->GetEnd() ).c_str() );
813  break;
814 
815  case SHAPE_T::CIRCLE:
816  m_out->Print( aNestLevel, "(gr_circle%s (center %s) (end %s)",
817  locked.c_str(),
818  FormatInternalUnits( aShape->GetStart() ).c_str(),
819  FormatInternalUnits( aShape->GetEnd() ).c_str() );
820  break;
821 
822  case SHAPE_T::ARC:
823  m_out->Print( aNestLevel, "(gr_arc%s (start %s) (mid %s) (end %s)",
824  locked.c_str(),
825  FormatInternalUnits( aShape->GetStart() ).c_str(),
826  FormatInternalUnits( aShape->GetArcMid() ).c_str(),
827  FormatInternalUnits( aShape->GetEnd() ).c_str() );
828  break;
829 
830  case SHAPE_T::POLY:
831  if( aShape->IsPolyShapeValid() )
832  {
833  const SHAPE_POLY_SET& poly = aShape->GetPolyShape();
834  const SHAPE_LINE_CHAIN& outline = poly.Outline( 0 );
835 
836  m_out->Print( aNestLevel, "(gr_poly%s\n", locked.c_str() );
837  m_out->Print( aNestLevel+1, "(pts\n" );
838 
839  bool need_newline = false;
840 
841  for( int ii = 0; ii < outline.PointCount(); ++ii )
842  {
843  int nestLevel = 0;
844 
845  if( !( ii % 4 ) || !ADVANCED_CFG::GetCfg().m_CompactSave )
846  {
847  // newline every 4 pts.
848  nestLevel = aNestLevel + 2;
849  m_out->Print( 0, "\n" );
850  need_newline = false;
851  }
852 
853  int ind = outline.ArcIndex( ii );
854 
855  if( ind < 0 )
856  {
857  m_out->Print( nestLevel, "%s(xy %s)",
858  nestLevel ? "" : " ",
859  FormatInternalUnits( outline.CPoint( ii ) ).c_str() );
860  need_newline = true;
861  }
862  else
863  {
864  const SHAPE_ARC& arc = outline.Arc( ind );
865  m_out->Print( nestLevel, "%s(arc (start %s) (mid %s) (end %s))",
866  nestLevel ? "" : " ",
867  FormatInternalUnits( arc.GetP0() ).c_str(),
868  FormatInternalUnits( arc.GetArcMid() ).c_str(),
869  FormatInternalUnits( arc.GetP1() ).c_str() );
870  need_newline = true;
871 
872  do
873  {
874  ++ii;
875  } while( ii < outline.PointCount() && outline.ArcIndex( ii ) == ind );
876 
877  --ii;
878  }
879  }
880 
881  if( need_newline )
882  m_out->Print( 0, "\n" );
883 
884  m_out->Print( aNestLevel+1, ")" );
885  }
886  else
887  {
888  wxFAIL_MSG( wxT( "Cannot format invalid polygon." ) );
889  return;
890  }
891 
892  break;
893 
894  case SHAPE_T::BEZIER:
895  m_out->Print( aNestLevel, "(gr_curve%s (pts (xy %s) (xy %s) (xy %s) (xy %s))",
896  locked.c_str(),
897  FormatInternalUnits( aShape->GetStart() ).c_str(),
898  FormatInternalUnits( aShape->GetBezierC1() ).c_str(),
899  FormatInternalUnits( aShape->GetBezierC2() ).c_str(),
900  FormatInternalUnits( aShape->GetEnd() ).c_str() );
901  break;
902 
903  default:
904  UNIMPLEMENTED_FOR( aShape->SHAPE_T_asString() );
905  return;
906  };
907 
908  formatLayer( aShape );
909 
910  m_out->Print( 0, " (width %s)", FormatInternalUnits( aShape->GetWidth() ).c_str() );
911 
912  // The filled flag represents if a solid fill is present on circles, rectangles and polygons
913  if( ( aShape->GetShape() == SHAPE_T::POLY )
914  || ( aShape->GetShape() == SHAPE_T::RECT )
915  || ( aShape->GetShape() == SHAPE_T::CIRCLE ) )
916  {
917  if( aShape->IsFilled() )
918  m_out->Print( 0, " (fill solid)" );
919  else
920  m_out->Print( 0, " (fill none)" );
921  }
922 
923  m_out->Print( 0, " (tstamp %s)", TO_UTF8( aShape->m_Uuid.AsString() ) );
924 
925  m_out->Print( 0, ")\n" );
926 }
const SHAPE_ARC & Arc(size_t aArc) const
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.
void formatLayer(const BOARD_ITEM *aItem) const
int PointCount() const
Return the number of points (vertices) in this line chain.
ssize_t ArcIndex(size_t aSegment) const
Return the arc index for the given segment index.
#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
Return a reference to a given point in the line chain.
Represent a set of closed polygons.
SHAPE_LINE_CHAIN & Outline(int aIndex)
const VECTOR2I & GetP0() const
Definition: shape_arc.h:111
const VECTOR2I & GetArcMid() const
Definition: shape_arc.h:113
#define UNIMPLEMENTED_FOR(type)
Definition: macros.h:120
Represent a polyline (an zero-thickness chain of connected line segments).
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:426
const VECTOR2I & GetP1() const
Definition: shape_arc.h:112
std::string FormatInternalUnits(int aValue)
Function FormatInternalUnits converts aValue from internal units to a string appropriate for writing ...
Definition: base_units.cpp:485

References ARC, SHAPE_LINE_CHAIN::Arc(), SHAPE_LINE_CHAIN::ArcIndex(), KIID::AsString(), BEZIER, CIRCLE, SHAPE_LINE_CHAIN::CPoint(), FormatInternalUnits(), formatLayer(), SHAPE_ARC::GetArcMid(), EDA_SHAPE::GetArcMid(), EDA_SHAPE::GetBezierC1(), EDA_SHAPE::GetBezierC2(), ADVANCED_CFG::GetCfg(), EDA_SHAPE::GetEnd(), SHAPE_ARC::GetP0(), SHAPE_ARC::GetP1(), EDA_SHAPE::GetPolyShape(), EDA_SHAPE::GetShape(), EDA_SHAPE::GetStart(), EDA_SHAPE::GetWidth(), EDA_SHAPE::IsFilled(), BOARD_ITEM::IsLocked(), EDA_SHAPE::IsPolyShapeValid(), locked, ADVANCED_CFG::m_CompactSave, m_out, EDA_ITEM::m_Uuid, SHAPE_POLY_SET::Outline(), SHAPE_LINE_CHAIN::PointCount(), POLY, OUTPUTFORMATTER::Print(), RECT, SEGMENT, EDA_SHAPE::SHAPE_T_asString(), TO_UTF8, and UNIMPLEMENTED_FOR.

◆ format() [6/12]

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

Definition at line 1062 of file kicad_plugin.cpp.

1063 {
1064  m_out->Print( aNestLevel, "(target %s (at %s) (size %s)",
1065  ( aTarget->GetShape() ) ? "x" : "plus",
1066  FormatInternalUnits( aTarget->GetPosition() ).c_str(),
1067  FormatInternalUnits( aTarget->GetSize() ).c_str() );
1068 
1069  if( aTarget->GetWidth() != 0 )
1070  m_out->Print( 0, " (width %s)", FormatInternalUnits( aTarget->GetWidth() ).c_str() );
1071 
1072  formatLayer( aTarget );
1073 
1074  m_out->Print( 0, " (tstamp %s)", TO_UTF8( aTarget->m_Uuid.AsString() ) );
1075 
1076  m_out->Print( 0, ")\n" );
1077 }
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:62
wxString AsString() const
Definition: kiid.cpp:218
wxPoint GetPosition() const override
Definition: pcb_target.h:56
#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:65
const KIID m_Uuid
Definition: eda_item.h:475
int GetShape() const
Definition: pcb_target.h:59
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:426
std::string FormatInternalUnits(int aValue)
Function FormatInternalUnits converts aValue from internal units to a string appropriate for writing ...
Definition: base_units.cpp:485

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 1080 of file kicad_plugin.cpp.

1081 {
1082  if( !( m_ctl & CTL_OMIT_INITIAL_COMMENTS ) )
1083  {
1084  const wxArrayString* initial_comments = aFootprint->GetInitialComments();
1085 
1086  if( initial_comments )
1087  {
1088  for( unsigned i = 0; i < initial_comments->GetCount(); ++i )
1089  m_out->Print( aNestLevel, "%s\n", TO_UTF8( (*initial_comments)[i] ) );
1090 
1091  m_out->Print( 0, "\n" ); // improve readability?
1092  }
1093  }
1094 
1095  if( m_ctl & CTL_OMIT_LIBNAME )
1096  m_out->Print( aNestLevel, "(footprint %s",
1097  m_out->Quotes( aFootprint->GetFPID().GetLibItemName() ).c_str() );
1098  else
1099  m_out->Print( aNestLevel, "(footprint %s",
1100  m_out->Quotes( aFootprint->GetFPID().Format() ).c_str() );
1101 
1102  if( !( m_ctl & CTL_OMIT_FOOTPRINT_VERSION ) )
1103  m_out->Print( 0, " (version %d) (generator pcbnew)", SEXPR_BOARD_FILE_VERSION );
1104 
1105  if( aFootprint->IsLocked() )
1106  m_out->Print( 0, " locked" );
1107 
1108  if( aFootprint->IsPlaced() )
1109  m_out->Print( 0, " placed" );
1110 
1111  formatLayer( aFootprint );
1112 
1113  m_out->Print( 0, "\n" );
1114  m_out->Print( aNestLevel+1, "(tedit %lX)", (unsigned long)aFootprint->GetLastEditTime() );
1115 
1116  if( !( m_ctl & CTL_OMIT_TSTAMPS ) )
1117  m_out->Print( 0, " (tstamp %s)", TO_UTF8( aFootprint->m_Uuid.AsString() ) );
1118 
1119  m_out->Print( 0, "\n" );
1120 
1121  if( !( m_ctl & CTL_OMIT_AT ) )
1122  {
1123  m_out->Print( aNestLevel+1, "(at %s",
1124  FormatInternalUnits( aFootprint->GetPosition() ).c_str() );
1125 
1126  if( aFootprint->GetOrientation() != 0.0 )
1127  m_out->Print( 0, " %s", FormatAngle( aFootprint->GetOrientation() ).c_str() );
1128 
1129  m_out->Print( 0, ")\n" );
1130  }
1131 
1132  if( !aFootprint->GetDescription().IsEmpty() )
1133  m_out->Print( aNestLevel+1, "(descr %s)\n",
1134  m_out->Quotew( aFootprint->GetDescription() ).c_str() );
1135 
1136  if( !aFootprint->GetKeywords().IsEmpty() )
1137  m_out->Print( aNestLevel+1, "(tags %s)\n",
1138  m_out->Quotew( aFootprint->GetKeywords() ).c_str() );
1139 
1140  const std::map<wxString, wxString>& props = aFootprint->GetProperties();
1141 
1142  for( const std::pair<const wxString, wxString>& prop : props )
1143  {
1144  m_out->Print( aNestLevel+1, "(property %s %s)\n",
1145  m_out->Quotew( prop.first ).c_str(),
1146  m_out->Quotew( prop.second ).c_str() );
1147  }
1148 
1149  if( !( m_ctl & CTL_OMIT_PATH ) && !aFootprint->GetPath().empty() )
1150  m_out->Print( aNestLevel+1, "(path %s)\n",
1151  m_out->Quotew( aFootprint->GetPath().AsString() ).c_str() );
1152 
1153  if( aFootprint->GetPlacementCost90() != 0 )
1154  m_out->Print( aNestLevel+1, "(autoplace_cost90 %d)\n", aFootprint->GetPlacementCost90() );
1155 
1156  if( aFootprint->GetPlacementCost180() != 0 )
1157  m_out->Print( aNestLevel+1, "(autoplace_cost180 %d)\n", aFootprint->GetPlacementCost180() );
1158 
1159  if( aFootprint->GetLocalSolderMaskMargin() != 0 )
1160  m_out->Print( aNestLevel+1, "(solder_mask_margin %s)\n",
1161  FormatInternalUnits( aFootprint->GetLocalSolderMaskMargin() ).c_str() );
1162 
1163  if( aFootprint->GetLocalSolderPasteMargin() != 0 )
1164  m_out->Print( aNestLevel+1, "(solder_paste_margin %s)\n",
1165  FormatInternalUnits( aFootprint->GetLocalSolderPasteMargin() ).c_str() );
1166 
1167  if( aFootprint->GetLocalSolderPasteMarginRatio() != 0 )
1168  m_out->Print( aNestLevel+1, "(solder_paste_ratio %s)\n",
1169  Double2Str( aFootprint->GetLocalSolderPasteMarginRatio() ).c_str() );
1170 
1171  if( aFootprint->GetLocalClearance() != 0 )
1172  m_out->Print( aNestLevel+1, "(clearance %s)\n",
1173  FormatInternalUnits( aFootprint->GetLocalClearance() ).c_str() );
1174 
1175  if( aFootprint->GetZoneConnection() != ZONE_CONNECTION::INHERITED )
1176  m_out->Print( aNestLevel+1, "(zone_connect %d)\n",
1177  static_cast<int>( aFootprint->GetZoneConnection() ) );
1178 
1179  if( aFootprint->GetThermalWidth() != 0 )
1180  m_out->Print( aNestLevel+1, "(thermal_width %s)\n",
1181  FormatInternalUnits( aFootprint->GetThermalWidth() ).c_str() );
1182 
1183  if( aFootprint->GetThermalGap() != 0 )
1184  m_out->Print( aNestLevel+1, "(thermal_gap %s)\n",
1185  FormatInternalUnits( aFootprint->GetThermalGap() ).c_str() );
1186 
1187  // Attributes
1188  if( aFootprint->GetAttributes() )
1189  {
1190  m_out->Print( aNestLevel+1, "(attr" );
1191 
1192  if( aFootprint->GetAttributes() & FP_SMD )
1193  m_out->Print( 0, " smd" );
1194 
1195  if( aFootprint->GetAttributes() & FP_THROUGH_HOLE )
1196  m_out->Print( 0, " through_hole" );
1197 
1198  if( aFootprint->GetAttributes() & FP_BOARD_ONLY )
1199  m_out->Print( 0, " board_only" );
1200 
1201  if( aFootprint->GetAttributes() & FP_EXCLUDE_FROM_POS_FILES )
1202  m_out->Print( 0, " exclude_from_pos_files" );
1203 
1204  if( aFootprint->GetAttributes() & FP_EXCLUDE_FROM_BOM )
1205  m_out->Print( 0, " exclude_from_bom" );
1206 
1207  m_out->Print( 0, ")\n" );
1208  }
1209 
1210  Format( (BOARD_ITEM*) &aFootprint->Reference(), aNestLevel + 1 );
1211  Format( (BOARD_ITEM*) &aFootprint->Value(), aNestLevel + 1 );
1212 
1213  std::set<PAD*, FOOTPRINT::cmp_pads> sorted_pads( aFootprint->Pads().begin(),
1214  aFootprint->Pads().end() );
1215  std::set<BOARD_ITEM*, FOOTPRINT::cmp_drawings> sorted_drawings(
1216  aFootprint->GraphicalItems().begin(),
1217  aFootprint->GraphicalItems().end() );
1218  std::set<BOARD_ITEM*, BOARD_ITEM::ptr_cmp> sorted_zones( aFootprint->Zones().begin(),
1219  aFootprint->Zones().end() );
1220  std::set<BOARD_ITEM*, PCB_GROUP::ptr_cmp> sorted_groups( aFootprint->Groups().begin(),
1221  aFootprint->Groups().end() );
1222 
1223  // Save drawing elements.
1224 
1225  for( BOARD_ITEM* gr : sorted_drawings )
1226  Format( gr, aNestLevel+1 );
1227 
1228  // Save pads.
1229  for( PAD* pad : sorted_pads )
1230  Format( pad, aNestLevel+1 );
1231 
1232  // Save zones.
1233  for( BOARD_ITEM* zone : sorted_zones )
1234  Format( zone, aNestLevel + 1 );
1235 
1236  // Save groups.
1237  for( BOARD_ITEM* group : sorted_groups )
1238  Format( group, aNestLevel + 1 );
1239 
1240  // Save 3D info.
1241  auto bs3D = aFootprint->Models().begin();
1242  auto es3D = aFootprint->Models().end();
1243 
1244  while( bs3D != es3D )
1245  {
1246  if( !bs3D->m_Filename.IsEmpty() )
1247  {
1248  m_out->Print( aNestLevel+1, "(model %s%s\n",
1249  m_out->Quotew( bs3D->m_Filename ).c_str(),
1250  bs3D->m_Show ? "" : " hide" );
1251 
1252  if( bs3D->m_Opacity != 1.0 )
1253  m_out->Print( aNestLevel+2, "(opacity %0.4f)", bs3D->m_Opacity );
1254 
1255  m_out->Print( aNestLevel+2, "(offset (xyz %s %s %s))\n",
1256  Double2Str( bs3D->m_Offset.x ).c_str(),
1257  Double2Str( bs3D->m_Offset.y ).c_str(),
1258  Double2Str( bs3D->m_Offset.z ).c_str() );
1259 
1260  m_out->Print( aNestLevel+2, "(scale (xyz %s %s %s))\n",
1261  Double2Str( bs3D->m_Scale.x ).c_str(),
1262  Double2Str( bs3D->m_Scale.y ).c_str(),
1263  Double2Str( bs3D->m_Scale.z ).c_str() );
1264 
1265  m_out->Print( aNestLevel+2, "(rotate (xyz %s %s %s))\n",
1266  Double2Str( bs3D->m_Rotation.x ).c_str(),
1267  Double2Str( bs3D->m_Rotation.y ).c_str(),
1268  Double2Str( bs3D->m_Rotation.z ).c_str() );
1269 
1270  m_out->Print( aNestLevel+1, ")\n" );
1271  }
1272 
1273  ++bs3D;
1274  }
1275 
1276  m_out->Print( aNestLevel, ")\n" );
1277 }
bool IsLocked() const override
Definition: footprint.h:293
OUTPUTFORMATTER * m_out
output any Format()s to this, no ownership
const wxString & GetDescription() const
Definition: footprint.h:197
const UTF8 & GetLibItemName() const
Definition: lib_id.h:104
std::list< FP_3DMODEL > & Models()
Definition: footprint.h:182
void formatLayer(const BOARD_ITEM *aItem) const
#define CTL_OMIT_AT
Omit position and rotation.
const KIID_PATH & GetPath() const
Definition: footprint.h:203
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:49
int GetPlacementCost180() const
Definition: footprint.h:564
#define CTL_OMIT_TSTAMPS
Omit component time stamp (useless in library)
double GetOrientation() const
Definition: footprint.h:190
#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:455
timestamp_t GetLastEditTime() const
Definition: footprint.h:343
PADS & Pads()
Definition: footprint.h:168
#define CTL_OMIT_FOOTPRINT_VERSION
Omit the version string from the (footprint)
FP_TEXT & Value()
read/write accessors:
Definition: footprint.h:485
FP_TEXT & Reference()
Definition: footprint.h:486
#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:174
std::string FormatAngle(double aAngle)
Function FormatAngle converts aAngle from board units to a string appropriate for writing to file.
Definition: base_units.cpp:520
#define CTL_OMIT_LIBNAME
Omit lib alias when saving (used for.
int GetLocalClearance() const
Definition: footprint.h:209
DRAWINGS & GraphicalItems()
Definition: footprint.h:171
bool IsPlaced() const
Definition: footprint.h:311
const LIB_ID & GetFPID() const
Definition: footprint.h:194
const wxString & GetKeywords() const
Definition: footprint.h:200
int GetThermalWidth() const
Definition: footprint.h:230
UTF8 Format() const
Definition: lib_id.cpp:116
const KIID m_Uuid
Definition: eda_item.h:475
const wxArrayString * GetInitialComments() const
Definition: footprint.h:674
FP_GROUPS & Groups()
Definition: footprint.h:177
void Format(const BOARD_ITEM *aItem, int aNestLevel=0) const
Output aItem to aFormatter in s-expression format.
int GetLocalSolderMaskMargin() const
Definition: footprint.h:206
int GetAttributes() const
Definition: footprint.h:235
#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:277
std::string Double2Str(double aValue)
Print a float number without using scientific notation and no trailing 0 We want to avoid scientific ...
wxPoint GetPosition() const override
Definition: footprint.h:186
double GetLocalSolderPasteMarginRatio() const
Definition: footprint.h:223
const std::map< wxString, wxString > & GetProperties() const
Definition: footprint.h:492
ZONE_CONNECTION GetZoneConnection() const
Definition: footprint.h:227
int GetPlacementCost90() const
Definition: footprint.h:567
int GetLocalSolderPasteMargin() const
Definition: footprint.h:220
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:426
Definition: pad.h:57
int GetThermalGap() const
Definition: footprint.h:233
std::string FormatInternalUnits(int aValue)
Function FormatInternalUnits converts aValue from internal units to a string appropriate for writing ...
Definition: base_units.cpp:485
std::string Quotew(const wxString &aWrapee) const
Definition: richio.cpp:494

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::GetLibItemName(), 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 1366 of file kicad_plugin.cpp.

1367 {
1368  const char* shape;
1369 
1370  switch( aPad->GetShape() )
1371  {
1372  case PAD_SHAPE::CIRCLE: shape = "circle"; break;
1373  case PAD_SHAPE::RECT: shape = "rect"; break;
1374  case PAD_SHAPE::OVAL: shape = "oval"; break;
1375  case PAD_SHAPE::TRAPEZOID: shape = "trapezoid"; break;
1377  case PAD_SHAPE::ROUNDRECT: shape = "roundrect"; break;
1378  case PAD_SHAPE::CUSTOM: shape = "custom"; break;
1379 
1380  default:
1381  THROW_IO_ERROR( wxString::Format( _( "unknown pad type: %d"), aPad->GetShape() ) );
1382  }
1383 
1384  const char* type;
1385 
1386  switch( aPad->GetAttribute() )
1387  {
1388  case PAD_ATTRIB::PTH: type = "thru_hole"; break;
1389  case PAD_ATTRIB::SMD: type = "smd"; break;
1390  case PAD_ATTRIB::CONN: type = "connect"; break;
1391  case PAD_ATTRIB::NPTH: type = "np_thru_hole"; break;
1392 
1393  default:
1394  THROW_IO_ERROR( wxString::Format( "unknown pad attribute: %d", aPad->GetAttribute() ) );
1395  }
1396 
1397  const char* property = nullptr;
1398 
1399  switch( aPad->GetProperty() )
1400  {
1401  case PAD_PROP::NONE: break; // could be "none"
1402  case PAD_PROP::BGA: property = "pad_prop_bga"; break;
1403  case PAD_PROP::FIDUCIAL_GLBL: property = "pad_prop_fiducial_glob"; break;
1404  case PAD_PROP::FIDUCIAL_LOCAL: property = "pad_prop_fiducial_loc"; break;
1405  case PAD_PROP::TESTPOINT: property = "pad_prop_testpoint"; break;
1406  case PAD_PROP::HEATSINK: property = "pad_prop_heatsink"; break;
1407  case PAD_PROP::CASTELLATED: property = "pad_prop_castellated"; break;
1408 
1409  default:
1410  THROW_IO_ERROR( wxString::Format( "unknown pad property: %d", aPad->GetProperty() ) );
1411  }
1412 
1413  m_out->Print( aNestLevel, "(pad %s %s %s",
1414  m_out->Quotew( aPad->GetNumber() ).c_str(),
1415  type,
1416  shape );
1417 
1418  if( aPad->IsLocked() )
1419  m_out->Print( 0, " locked" );
1420 
1421  m_out->Print( 0, " (at %s", FormatInternalUnits( aPad->GetPos0() ).c_str() );
1422 
1423  if( aPad->GetOrientation() != 0.0 )
1424  m_out->Print( 0, " %s", FormatAngle( aPad->GetOrientation() ).c_str() );
1425 
1426  m_out->Print( 0, ")" );
1427 
1428  m_out->Print( 0, " (size %s)", FormatInternalUnits( aPad->GetSize() ).c_str() );
1429 
1430  if( (aPad->GetDelta().GetWidth()) != 0 || (aPad->GetDelta().GetHeight() != 0 ) )
1431  m_out->Print( 0, " (rect_delta %s)", FormatInternalUnits( aPad->GetDelta() ).c_str() );
1432 
1433  wxSize sz = aPad->GetDrillSize();
1434  wxPoint shapeoffset = aPad->GetOffset();
1435 
1436  if( (sz.GetWidth() > 0) || (sz.GetHeight() > 0) ||
1437  (shapeoffset.x != 0) || (shapeoffset.y != 0) )
1438  {
1439  m_out->Print( 0, " (drill" );
1440 
1441  if( aPad->GetDrillShape() == PAD_DRILL_SHAPE_OBLONG )
1442  m_out->Print( 0, " oval" );
1443 
1444  if( sz.GetWidth() > 0 )
1445  m_out->Print( 0, " %s", FormatInternalUnits( sz.GetWidth() ).c_str() );
1446 
1447  if( sz.GetHeight() > 0 && sz.GetWidth() != sz.GetHeight() )
1448  m_out->Print( 0, " %s", FormatInternalUnits( sz.GetHeight() ).c_str() );
1449 
1450  if( (shapeoffset.x != 0) || (shapeoffset.y != 0) )
1451  m_out->Print( 0, " (offset %s)", FormatInternalUnits( aPad->GetOffset() ).c_str() );
1452 
1453  m_out->Print( 0, ")" );
1454  }
1455 
1456  // Add pad property, if exists.
1457  if( property )
1458  m_out->Print( 0, " (property %s)", property );
1459 
1460  formatLayers( aPad->GetLayerSet() );
1461 
1462  if( aPad->GetAttribute() == PAD_ATTRIB::PTH )
1463  {
1464  if( aPad->GetRemoveUnconnected() )
1465  {
1466  m_out->Print( 0, " (remove_unused_layers)" );
1467 
1468  if( aPad->GetKeepTopBottom() )
1469  m_out->Print( 0, " (keep_end_layers)" );
1470  }
1471  }
1472 
1473  // Output the radius ratio for rounded and chamfered rect pads
1474  if( aPad->GetShape() == PAD_SHAPE::ROUNDRECT || aPad->GetShape() == PAD_SHAPE::CHAMFERED_RECT)
1475  {
1476  m_out->Print( 0, " (roundrect_rratio %s)",
1477  Double2Str( aPad->GetRoundRectRadiusRatio() ).c_str() );
1478  }
1479 
1480  // Output the chamfer corners for chamfered rect pads
1481  if( aPad->GetShape() == PAD_SHAPE::CHAMFERED_RECT)
1482  {
1483  m_out->Print( 0, "\n" );
1484 
1485  m_out->Print( aNestLevel+1, "(chamfer_ratio %s)",
1486  Double2Str( aPad->GetChamferRectRatio() ).c_str() );
1487 
1488  m_out->Print( 0, " (chamfer" );
1489 
1490  if( ( aPad->GetChamferPositions() & RECT_CHAMFER_TOP_LEFT ) )
1491  m_out->Print( 0, " top_left" );
1492 
1493  if( ( aPad->GetChamferPositions() & RECT_CHAMFER_TOP_RIGHT ) )
1494  m_out->Print( 0, " top_right" );
1495 
1496  if( ( aPad->GetChamferPositions() & RECT_CHAMFER_BOTTOM_LEFT ) )
1497  m_out->Print( 0, " bottom_left" );
1498 
1500  m_out->Print( 0, " bottom_right" );
1501 
1502  m_out->Print( 0, ")" );
1503  }
1504 
1505  std::string output;
1506 
1507  // Unconnected pad is default net so don't save it.
1508  if( !( m_ctl & CTL_OMIT_PAD_NETS ) && aPad->GetNetCode() != NETINFO_LIST::UNCONNECTED )
1509  {
1510  StrPrintf( &output, " (net %d %s)", m_mapping->Translate( aPad->GetNetCode() ),
1511  m_out->Quotew( aPad->GetNetname() ).c_str() );
1512  }
1513 
1514  // Pin functions and types are closely related to nets, so if CTL_OMIT_NETS is set, omit
1515  // them as well (for instance when saved from library editor).
1516  if( !( m_ctl & CTL_OMIT_PAD_NETS ) )
1517  {
1518  if( !aPad->GetPinFunction().IsEmpty() )
1519  {
1520  StrPrintf( &output, " (pinfunction %s)",
1521  m_out->Quotew( aPad->GetPinFunction() ).c_str() );
1522  }
1523 
1524  if( !aPad->GetPinType().IsEmpty() )
1525  {
1526  StrPrintf( &output, " (pintype %s)",
1527  m_out->Quotew( aPad->GetPinType() ).c_str() );
1528  }
1529  }
1530 
1531  if( aPad->GetPadToDieLength() != 0 )
1532  {
1533  StrPrintf( &output, " (die_length %s)",
1534  FormatInternalUnits( aPad->GetPadToDieLength() ).c_str() );
1535  }
1536 
1537  if( aPad->GetLocalSolderMaskMargin() != 0 )
1538  {
1539  StrPrintf( &output, " (solder_mask_margin %s)",
1540  FormatInternalUnits( aPad->GetLocalSolderMaskMargin() ).c_str() );
1541  }
1542 
1543  if( aPad->GetLocalSolderPasteMargin() != 0 )
1544  {
1545  StrPrintf( &output, " (solder_paste_margin %s)",
1546  FormatInternalUnits( aPad->GetLocalSolderPasteMargin() ).c_str() );
1547  }
1548 
1549  if( aPad->GetLocalSolderPasteMarginRatio() != 0 )
1550  {
1551  StrPrintf( &output, " (solder_paste_margin_ratio %s)",
1552  Double2Str( aPad->GetLocalSolderPasteMarginRatio() ).c_str() );
1553  }
1554 
1555  if( aPad->GetLocalClearance() != 0 )
1556  {
1557  StrPrintf( &output, " (clearance %s)",
1558  FormatInternalUnits( aPad->GetLocalClearance() ).c_str() );
1559  }
1560 
1562  {
1563  StrPrintf( &output, " (zone_connect %d)",
1564  static_cast<int>( aPad->GetZoneConnection() ) );
1565  }
1566 
1567  if( aPad->GetThermalSpokeWidth() != 0 )
1568  {
1569  StrPrintf( &output, " (thermal_width %s)",
1570  FormatInternalUnits( aPad->GetThermalSpokeWidth() ).c_str() );
1571  }
1572 
1573  if( aPad->GetThermalGap() != 0 )
1574  {
1575  StrPrintf( &output, " (thermal_gap %s)",
1576  FormatInternalUnits( aPad->GetThermalGap() ).c_str() );
1577  }
1578 
1579  if( output.size() )
1580  {
1581  m_out->Print( 0, "\n" );
1582  m_out->Print( aNestLevel+1, "%s", output.c_str()+1 ); // +1 skips 1st space on 1st element
1583  }
1584 
1585  if( aPad->GetShape() == PAD_SHAPE::CUSTOM )
1586  {
1587  m_out->Print( 0, "\n");
1588  m_out->Print( aNestLevel+1, "(options" );
1589 
1591  m_out->Print( 0, " (clearance convexhull)" );
1592  #if 1 // Set to 1 to output the default option
1593  else
1594  m_out->Print( 0, " (clearance outline)" );
1595  #endif
1596 
1597  // Output the anchor pad shape (circle/rect)
1598  if( aPad->GetAnchorPadShape() == PAD_SHAPE::RECT )
1599  shape = "rect";
1600  else
1601  shape = "circle";
1602 
1603  m_out->Print( 0, " (anchor %s)", shape );
1604 
1605  m_out->Print( 0, ")"); // end of (options ...
1606 
1607  // Output graphic primitive of the pad shape
1608  m_out->Print( 0, "\n");
1609  m_out->Print( aNestLevel+1, "(primitives" );
1610 
1611  int nested_level = aNestLevel+2;
1612 
1613  // Output all basic shapes
1614  for( const std::shared_ptr<PCB_SHAPE>& primitive : aPad->GetPrimitives() )
1615  {
1616  m_out->Print( 0, "\n");
1617 
1618  switch( primitive->GetShape() )
1619  {
1620  case SHAPE_T::SEGMENT:
1621  m_out->Print( nested_level, "(gr_line (start %s) (end %s)",
1622  FormatInternalUnits( primitive->GetStart() ).c_str(),
1623  FormatInternalUnits( primitive->GetEnd() ).c_str() );
1624  break;
1625 
1626  case SHAPE_T::RECT:
1627  m_out->Print( nested_level, "(gr_rect (start %s) (end %s)",
1628  FormatInternalUnits( primitive->GetStart() ).c_str(),
1629  FormatInternalUnits( primitive->GetEnd() ).c_str() );
1630  break;
1631 
1632  case SHAPE_T::ARC:
1633  m_out->Print( aNestLevel, "(gr_arc (start %s) (mid %s) (end %s)",
1634  FormatInternalUnits( primitive->GetStart() ).c_str(),
1635  FormatInternalUnits( primitive->GetArcMid() ).c_str(),
1636  FormatInternalUnits( primitive->GetEnd() ).c_str() );
1637  break;
1638 
1639  case SHAPE_T::CIRCLE:
1640  m_out->Print( nested_level, "(gr_circle (center %s) (end %s)",
1641  FormatInternalUnits( primitive->GetStart() ).c_str(),
1642  FormatInternalUnits( primitive->GetEnd() ).c_str() );
1643  break;
1644 
1645  case SHAPE_T::BEZIER:
1646  m_out->Print( nested_level, "(gr_curve (pts (xy %s) (xy %s) (xy %s) (xy %s))",
1647  FormatInternalUnits( primitive->GetStart() ).c_str(),
1648  FormatInternalUnits( primitive->GetBezierC1() ).c_str(),
1649  FormatInternalUnits( primitive->GetBezierC2() ).c_str(),
1650  FormatInternalUnits( primitive->GetEnd() ).c_str() );
1651  break;
1652 
1653  case SHAPE_T::POLY:
1654  if( primitive->IsPolyShapeValid() )
1655  {
1656  const SHAPE_POLY_SET& poly = primitive->GetPolyShape();
1657  const SHAPE_LINE_CHAIN& outline = poly.Outline( 0 );
1658 
1659  m_out->Print( nested_level, "(gr_poly (pts" );
1660 
1661  bool need_newline = false;
1662 
1663  for( int ii = 0; ii < outline.PointCount(); ++ii )
1664  {
1665  nested_level = 0;
1666 
1667  if( !( ii % 4 ) || !ADVANCED_CFG::GetCfg().m_CompactSave )
1668  {
1669  // newline every 4 pts.
1670  m_out->Print( 0, "\n" );
1671  need_newline = false;
1672  nested_level = aNestLevel + 4;
1673  }
1674 
1675  int ind = outline.ArcIndex( ii );
1676 
1677  if( ind < 0 )
1678  {
1679  m_out->Print( nested_level, "%s(xy %s)",
1680  nested_level ? "" : " ",
1681  FormatInternalUnits( outline.CPoint( ii ) ).c_str() );
1682  need_newline = true;
1683  }
1684  else
1685  {
1686  const SHAPE_ARC& arc = outline.Arc( ind );
1687  m_out->Print( nested_level, "%s(arc (start %s) (mid %s) (end %s))",
1688  nested_level ? "" : " ",
1689  FormatInternalUnits( arc.GetP0() ).c_str(),
1690  FormatInternalUnits( arc.GetArcMid() ).c_str(),
1691  FormatInternalUnits( arc.GetP1() ).c_str() );
1692  need_newline = true;
1693 
1694  do
1695  {
1696  ++ii;
1697  } while( ii < outline.PointCount() && outline.ArcIndex( ii ) == ind );
1698 
1699  --ii;
1700  }
1701  }
1702 
1703  if( need_newline )
1704  m_out->Print( 0, "\n" );
1705 
1706  m_out->Print( aNestLevel + 3, ")" );
1707  }
1708  break;
1709 
1710  default:
1711  break;
1712  }
1713 
1714  m_out->Print( 0, " (width %s)",
1715  FormatInternalUnits( primitive->GetWidth() ).c_str() );
1716 
1717  if( primitive->IsFilled() )
1718  m_out->Print( 0, " (fill yes)" );
1719 
1720  m_out->Print( 0, ")" );
1721  }
1722 
1723  m_out->Print( 0, "\n");
1724  m_out->Print( aNestLevel+1, ")" ); // end of (basic_shapes
1725  }
1726 
1727  m_out->Print( 0, " (tstamp %s)", TO_UTF8( aPad->m_Uuid.AsString() ) );
1728 
1729  m_out->Print( 0, ")\n" );
1730 }
int GetLocalSolderMaskMargin() const
Definition: pad.h:386
const SHAPE_ARC & Arc(size_t aArc) const
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.
int GetLocalSolderPasteMargin() const
Definition: pad.h:393
double GetRoundRectRadiusRatio() const
Definition: pad.h:523
PAD_PROP GetProperty() const
Definition: pad.h:374
Like smd, does not appear on the solder paste layer (default)
Smd pad, appears on the solder paste layer (default)
bool IsLocked() const override
Definition: pad.cpp:159
wxString AsString() const
Definition: kiid.cpp:218
a test point pad
int PointCount() const
Return the number of points (vertices) in this line chain.
int GetThermalGap() const
Definition: pad.h:499
bool GetKeepTopBottom() const
Definition: pad.h:563
Plated through hole pad.
a pad used as heat sink, usually in SMD footprints
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:79
ssize_t ArcIndex(size_t aSegment) const
Return the arc index for the given segment index.
ZONE_CONNECTION GetZoneConnection() const
Definition: pad.h:476
#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
Return a reference to a given point in the line chain.
const wxPoint & GetOffset() const
Definition: pad.h:250
const wxSize & GetDrillSize() const
Definition: pad.h:243
like PAD_PTH, but not plated
std::string FormatAngle(double aAngle)
Function FormatAngle converts aAngle from board units to a string appropriate for writing to file.
Definition: base_units.cpp:520
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
Represent a set of closed polygons.
SHAPE_LINE_CHAIN & Outline(int aIndex)
const VECTOR2I & GetP0() const
Definition: shape_arc.h:111
const wxSize & GetSize() const
Definition: pad.h:233
Smd pad, used in BGA footprints.
const VECTOR2I & GetArcMid() const
Definition: shape_arc.h:113
const wxString & GetNumber() const
Definition: pad.h:129
const wxString & GetPinType() const
Definition: pad.h:146
PAD_SHAPE GetShape() const
Definition: pad.h:170
a fiducial (usually a smd) local to the parent footprint
#define _(s)
LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
Definition: pad.h:368
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:702
double GetLocalSolderPasteMarginRatio() const
Definition: pad.h:396
const KIID m_Uuid
Definition: eda_item.h:475
const wxSize & GetDelta() const
Definition: pad.h:240
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:227
CUST_PAD_SHAPE_IN_ZONE GetCustomShapeInZoneOpt() const
Definition: pad.h:188
a fiducial (usually a smd) for the full board
double GetChamferRectRatio() const
Definition: pad.h:532
PAD_DRILL_SHAPE_T GetDrillShape() const
Definition: pad.h:354
no special fabrication property
Represent a polyline (an zero-thickness chain of connected line segments).
PAD_ATTRIB GetAttribute() const
Definition: pad.h:371
#define CTL_OMIT_PAD_NETS
Omit pads net names (useless in library)
std::string Double2Str(double aValue)
Print a float number without using scientific notation and no trailing 0 We want to avoid scientific ...
int GetChamferPositions() const
Definition: pad.h:542
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
a pad with a castellated through hole
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:426
int GetPadToDieLength() const
Definition: pad.h:384
const wxString & GetPinFunction() const
Definition: pad.h:140
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 VECTOR2I & GetP1() const
Definition: shape_arc.h:112
const std::vector< std::shared_ptr< PCB_SHAPE > > & GetPrimitives() const
Accessor to the basic shape list for custom-shaped pads.
Definition: pad.h:301
PAD_SHAPE GetAnchorPadShape() const
Definition: pad.h:183
std::string FormatInternalUnits(int aValue)
Function FormatInternalUnits converts aValue from internal units to a string appropriate for writing ...
Definition: base_units.cpp:485
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:494

References _, ARC, SHAPE_LINE_CHAIN::Arc(), SHAPE_LINE_CHAIN::ArcIndex(), KIID::AsString(), BEZIER, BGA, CASTELLATED, CHAMFERED_RECT, CIRCLE, CONN, SHAPE_LINE_CHAIN::CPoint(), CTL_OMIT_PAD_NETS, CUST_PAD_SHAPE_IN_ZONE_CONVEXHULL, CUSTOM, Double2Str(), FIDUCIAL_GLBL, FIDUCIAL_LOCAL, Format(), FormatAngle(), FormatInternalUnits(), formatLayers(), PAD::GetAnchorPadShape(), SHAPE_ARC::GetArcMid(), PAD::GetAttribute(), ADVANCED_CFG::GetCfg(), PAD::GetChamferPositions(), PAD::GetChamferRectRatio(), PAD::GetCustomShapeInZoneOpt(), PAD::GetDelta(), PAD::GetDrillShape(), PAD::GetDrillSize(), PAD::GetKeepTopBottom(), PAD::GetLayerSet(), PAD::GetLocalClearance(), PAD::GetLocalSolderMaskMargin(), PAD::GetLocalSolderPasteMargin(), PAD::GetLocalSolderPasteMarginRatio(), BOARD_CONNECTED_ITEM::GetNetCode(), BOARD_CONNECTED_ITEM::GetNetname(), PAD::GetNumber(), PAD::GetOffset(), PAD::GetOrientation(), SHAPE_ARC::GetP0(), SHAPE_ARC::GetP1(), PAD::GetPadToDieLength(), PAD::GetPinFunction(), PAD::GetPinType(), PAD::GetPos0(), PAD::GetPrimitives(), PAD::GetProperty(), PAD::GetRemoveUnconnected(), PAD::GetRoundRectRadiusRatio(), PAD::GetShape(), PAD::GetSize(), PAD::GetThermalGap(), PAD::GetThermalSpokeWidth(), PAD::GetZoneConnection(), HEATSINK, INHERITED, PAD::IsLocked(), ADVANCED_CFG::m_CompactSave, m_ctl, m_mapping, m_out, EDA_ITEM::m_Uuid, NONE, NPTH, SHAPE_POLY_SET::Outline(), OVAL, PAD_DRILL_SHAPE_OBLONG, SHAPE_LINE_CHAIN::PointCount(), POLY, OUTPUTFORMATTER::Print(), PTH, OUTPUTFORMATTER::Quotew(), RECT, RECT_CHAMFER_BOTTOM_LEFT, RECT_CHAMFER_BOTTOM_RIGHT, RECT_CHAMFER_TOP_LEFT, RECT_CHAMFER_TOP_RIGHT, ROUNDRECT, SEGMENT, SMD, StrPrintf(), TESTPOINT, THROW_IO_ERROR, TO_UTF8, NETINFO_MAPPING::Translate(), TRAPEZOID, and NETINFO_LIST::UNCONNECTED.

◆ format() [9/12]

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

Definition at line 1733 of file kicad_plugin.cpp.

1734 {
1735  m_out->Print( aNestLevel, "(gr_text %s (at %s",
1736  m_out->Quotew( aText->GetText() ).c_str(),
1737  FormatInternalUnits( aText->GetTextPos() ).c_str() );
1738 
1739  if( aText->GetTextAngle() != 0.0 )
1740  m_out->Print( 0, " %s", FormatAngle( aText->GetTextAngle() ).c_str() );
1741 
1742  m_out->Print( 0, ")" );
1743 
1744  formatLayer( aText );
1745 
1746  m_out->Print( 0, " (tstamp %s)", TO_UTF8( aText->m_Uuid.AsString() ) );
1747 
1748  m_out->Print( 0, "\n" );
1749 
1750  // PCB_TEXTS are never hidden, so always omit "hide" attribute
1751  aText->EDA_TEXT::Format( m_out, aNestLevel, m_ctl | CTL_OMIT_HIDE );
1752 
1753  m_out->Print( aNestLevel, ")\n" );
1754 }
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:174
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:520
const KIID m_Uuid
Definition: eda_item.h:475
const wxPoint & GetTextPos() const
Definition: eda_text.h:247
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:426
#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:485
std::string Quotew(const wxString &aWrapee) const
Definition: richio.cpp:494

References KIID::AsString(), CTL_OMIT_HIDE, 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 1785 of file kicad_plugin.cpp.

1786 {
1787  std::string type;
1788 
1789  switch( aText->GetType() )
1790  {
1791  case FP_TEXT::TEXT_is_REFERENCE: type = "reference"; break;
1792  case FP_TEXT::TEXT_is_VALUE: type = "value"; break;
1793  case FP_TEXT::TEXT_is_DIVERS: type = "user";
1794  }
1795 
1796  std::string locked = aText->IsLocked() ? " locked" : "";
1797 
1798  m_out->Print( aNestLevel, "(fp_text %s%s %s (at %s",
1799  type.c_str(),
1800  locked.c_str(),
1801  m_out->Quotew( aText->GetText() ).c_str(),
1802  FormatInternalUnits( aText->GetPos0() ).c_str() );
1803 
1804  // Due to Pcbnew history, fp_text angle is saved as an absolute on screen angle,
1805  // but internally the angle is held relative to its parent footprint. parent
1806  // may be NULL when saving a footprint outside a BOARD.
1807  double orient = aText->GetTextAngle();
1808  FOOTPRINT* parent = (FOOTPRINT*) aText->GetParent();
1809 
1810  if( parent )
1811  {
1812  // GetTextAngle() is always in -360..+360 range because of
1813  // FP_TEXT::SetTextAngle(), but summing that angle with an
1814  // additional board angle could kick sum up >= 360 or <= -360, so to have
1815  // consistent results, normalize again for the BOARD save. A footprint
1816  // save does not use this code path since parent is NULL.
1817 #if 0
1818  // This one could be considered reasonable if you like positive angles
1819  // in your board text.
1820  orient = NormalizeAnglePos( orient + parent->GetOrientation() );
1821 #else
1822  // Choose compatibility for now, even though this is only a 720 degree clamp
1823  // with two possible values for every angle.
1824  orient = NormalizeAngle360Min( orient + parent->GetOrientation() );
1825 #endif
1826  }
1827 
1828  if( orient != 0.0 )
1829  m_out->Print( 0, " %s", FormatAngle( orient ).c_str() );
1830 
1831  if( !aText->IsKeepUpright() )
1832  m_out->Print( 0, " unlocked" );
1833 
1834  m_out->Print( 0, ")" );
1835  formatLayer( aText );
1836 
1837  if( !aText->IsVisible() )
1838  m_out->Print( 0, " hide" );
1839 
1840  m_out->Print( 0, "\n" );
1841 
1842  aText->EDA_TEXT::Format( m_out, aNestLevel, m_ctl | CTL_OMIT_HIDE );
1843 
1844  m_out->Print( aNestLevel + 1, "(tstamp %s)\n", TO_UTF8( aText->m_Uuid.AsString() ) );
1845 
1846  m_out->Print( aNestLevel, ")\n" );
1847 }
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
double GetOrientation() const
Definition: footprint.h:190
double GetTextAngle() const
Definition: eda_text.h:174
wxString AsString() const
Definition: kiid.cpp:218
virtual bool IsLocked() const
Definition: board_item.cpp:64
#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:520
TEXT_TYPE GetType() const
Definition: fp_text.h:141
virtual bool IsVisible() const
Definition: eda_text.h:186
const KIID m_Uuid
Definition: eda_item.h:475
const wxPoint & GetPos0() const
Definition: fp_text.h:166
T NormalizeAnglePos(T Angle)
Normalize angle to be in the 0.0 .. 360.0 range: angle is in 1/10 degrees.
Definition: trigo.h:281
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:426
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:135
#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:485
std::string Quotew(const wxString &aWrapee) const
Definition: richio.cpp:494

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(), BOARD_ITEM::IsLocked(), EDA_TEXT::IsVisible(), locked, 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 PCB_TRACK aTrack,
int  aNestLevel = 0 
) const
private

Definition at line 1850 of file kicad_plugin.cpp.

1851 {
1852  if( aTrack->Type() == PCB_VIA_T )
1853  {
1854  PCB_LAYER_ID layer1, layer2;
1855 
1856  const PCB_VIA* via = static_cast<const PCB_VIA*>( aTrack );
1857  BOARD* board = (BOARD*) via->GetParent();
1858 
1859  wxCHECK_RET( board != nullptr, wxT( "Via " ) +
1860  via->GetSelectMenuText( EDA_UNITS::MILLIMETRES ) + wxT( " has no parent." ) );
1861 
1862  m_out->Print( aNestLevel, "(via" );
1863 
1864  via->LayerPair( &layer1, &layer2 );
1865 
1866  switch( via->GetViaType() )
1867  {
1868  case VIATYPE::THROUGH: // Default shape not saved.
1869  break;
1870 
1871  case VIATYPE::BLIND_BURIED:
1872  m_out->Print( 0, " blind" );
1873  break;
1874 
1875  case VIATYPE::MICROVIA:
1876  m_out->Print( 0, " micro" );
1877  break;
1878 
1879  default:
1880  THROW_IO_ERROR( wxString::Format( _( "unknown via type %d" ), via->GetViaType() ) );
1881  }
1882 
1883  if( via->IsLocked() )
1884  m_out->Print( 0, " locked" );
1885 
1886  m_out->Print( 0, " (at %s) (size %s)",
1887  FormatInternalUnits( aTrack->GetStart() ).c_str(),
1888  FormatInternalUnits( aTrack->GetWidth() ).c_str() );
1889 
1890  // Old boards were using UNDEFINED_DRILL_DIAMETER value in file for via drill when
1891  // via drill was the netclass value.
1892  // recent boards always set the via drill to the actual value, but now we need to
1893  // always store the drill value, because netclass value is not stored in the board file.
1894  // Otherwise the drill value of some (old) vias can be unknown
1895  if( via->GetDrill() != UNDEFINED_DRILL_DIAMETER )
1896  m_out->Print( 0, " (drill %s)", FormatInternalUnits( via->GetDrill() ).c_str() );
1897  else // Probably old board!
1898  m_out->Print( 0, " (drill %s)", FormatInternalUnits( via->GetDrillValue() ).c_str() );
1899 
1900  m_out->Print( 0, " (layers %s %s)",
1901  m_out->Quotew( LSET::Name( layer1 ) ).c_str(),
1902  m_out->Quotew( LSET::Name( layer2 ) ).c_str() );
1903 
1904  if( via->GetRemoveUnconnected() )
1905  {
1906  m_out->Print( 0, " (remove_unused_layers)" );
1907 
1908  if( via->GetKeepTopBottom() )
1909  m_out->Print( 0, " (keep_end_layers)" );
1910  }
1911 
1912  if( via->GetIsFree() )
1913  m_out->Print( 0, " (free)" );
1914  }
1915  else if( aTrack->Type() == PCB_ARC_T )
1916  {
1917  const PCB_ARC* arc = static_cast<const PCB_ARC*>( aTrack );
1918  std::string locked = arc->IsLocked() ? " locked" : "";
1919 
1920  m_out->Print( aNestLevel, "(arc%s (start %s) (mid %s) (end %s) (width %s)",
1921  locked.c_str(),
1922  FormatInternalUnits( arc->GetStart() ).c_str(),
1923  FormatInternalUnits( arc->GetMid() ).c_str(),
1924  FormatInternalUnits( arc->GetEnd() ).c_str(),
1925  FormatInternalUnits( arc->GetWidth() ).c_str() );
1926 
1927  m_out->Print( 0, " (layer %s)", m_out->Quotew( LSET::Name( arc->GetLayer() ) ).c_str() );
1928  }
1929  else
1930  {
1931  std::string locked = aTrack->IsLocked() ? " locked" : "";
1932 
1933  m_out->Print( aNestLevel, "(segment%s (start %s) (end %s) (width %s)",
1934  locked.c_str(),
1935  FormatInternalUnits( aTrack->GetStart() ).c_str(),
1936  FormatInternalUnits( aTrack->GetEnd() ).c_str(),
1937  FormatInternalUnits( aTrack->GetWidth() ).c_str() );
1938 
1939  m_out->Print( 0, " (layer %s)", m_out->Quotew( LSET::Name( aTrack->GetLayer() ) ).c_str() );
1940  }
1941 
1942  m_out->Print( 0, " (net %d)", m_mapping->Translate( aTrack->GetNetCode() ) );
1943 
1944  m_out->Print( 0, " (tstamp %s)", TO_UTF8( aTrack->m_Uuid.AsString() ) );
1945 
1946  m_out->Print( 0, ")\n" );
1947 }
OUTPUTFORMATTER * m_out
output any Format()s to this, no ownership
const wxPoint & GetEnd() const
Definition: pcb_track.h:105
class PCB_ARC, an arc track segment on a copper layer
Definition: typeinfo.h:97
wxString AsString() const
Definition: kiid.cpp:218
int GetWidth() const
Definition: pcb_track.h:102
virtual bool IsLocked() const
Definition: board_item.cpp:64
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
static const wxChar * Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
Definition: lset.cpp:82
#define UNDEFINED_DRILL_DIAMETER
Definition: pcb_track.h:69
#define _(s)
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:475
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
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:190
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:65
class PCB_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:426
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:140
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
const wxPoint & GetMid() const
Definition: pcb_track.h:273
std::string FormatInternalUnits(int aValue)
Function FormatInternalUnits converts aValue from internal units to a string appropriate for writing ...
Definition: base_units.cpp:485
const wxPoint & GetStart() const
Definition: pcb_track.h:108
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:113
std::string Quotew(const wxString &aWrapee) const
Definition: richio.cpp:494

References _, KIID::AsString(), BLIND_BURIED, Format(), FormatInternalUnits(), PCB_TRACK::GetEnd(), BOARD_ITEM::GetLayer(), PCB_ARC::GetMid(), BOARD_CONNECTED_ITEM::GetNetCode(), PCB_TRACK::GetStart(), PCB_TRACK::GetWidth(), BOARD_ITEM::IsLocked(), locked, 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 1950 of file kicad_plugin.cpp.

1951 {
1952  std::string locked = aZone->IsLocked() ? " locked" : "";
1953 
1954  // Save the NET info; For keepout zones, net code and net name are irrelevant
1955  // so be sure a dummy value is stored, just for ZONE compatibility
1956  // (perhaps netcode and netname should be not stored)
1957  m_out->Print( aNestLevel, "(zone%s (net %d) (net_name %s)",
1958  locked.c_str(),
1959  aZone->GetIsRuleArea() ? 0 : m_mapping->Translate( aZone->GetNetCode() ),
1960  m_out->Quotew( aZone->GetIsRuleArea() ? wxT("") : aZone->GetNetname() ).c_str() );
1961 
1962  // If a zone exists on multiple layers, format accordingly
1963  if( aZone->GetLayerSet().count() > 1 )
1964  {
1965  formatLayers( aZone->GetLayerSet() );
1966  }
1967  else
1968  {
1969  formatLayer( aZone );
1970  }
1971 
1972  m_out->Print( 0, " (tstamp %s)", TO_UTF8( aZone->m_Uuid.AsString() ) );
1973 
1974  if( !aZone->GetZoneName().empty() )
1975  m_out->Print( 0, " (name %s)", m_out->Quotew( aZone->GetZoneName() ).c_str() );
1976 
1977  // Save the outline aux info
1978  std::string hatch;
1979 
1980  switch( aZone->GetHatchStyle() )
1981  {
1982  default:
1983  case ZONE_BORDER_DISPLAY_STYLE::NO_HATCH: hatch = "none"; break;
1984  case ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_EDGE: hatch = "edge"; break;
1985  case ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_FULL: hatch = "full"; break;
1986  }
1987 
1988  m_out->Print( 0, " (hatch %s %s)\n", hatch.c_str(),
1989  FormatInternalUnits( aZone->GetBorderHatchPitch() ).c_str() );
1990 
1991  if( aZone->GetPriority() > 0 )
1992  m_out->Print( aNestLevel+1, "(priority %d)\n", aZone->GetPriority() );
1993 
1994  m_out->Print( aNestLevel+1, "(connect_pads" );
1995 
1996  switch( aZone->GetPadConnection() )
1997  {
1998  default:
1999  case ZONE_CONNECTION::THERMAL: // Default option not saved or loaded.
2000  break;
2001 
2003  m_out->Print( 0, " thru_hole_only" );
2004  break;
2005 
2006  case ZONE_CONNECTION::FULL:
2007  m_out->Print( 0, " yes" );
2008  break;
2009 
2010  case ZONE_CONNECTION::NONE:
2011  m_out->Print( 0, " no" );
2012  break;
2013  }
2014 
2015  m_out->Print( 0, " (clearance %s))\n",
2016  FormatInternalUnits( aZone->GetLocalClearance() ).c_str() );
2017 
2018  m_out->Print( aNestLevel+1, "(min_thickness %s)",
2019  FormatInternalUnits( aZone->GetMinThickness() ).c_str() );
2020 
2021  // write it only if V 6.O version option is used (i.e. do not write if the "legacy"
2022  // algorithm is used)
2023  if( !aZone->GetFilledPolysUseThickness() )
2024  m_out->Print( 0, " (filled_areas_thickness no)" );
2025 
2026  m_out->Print( 0, "\n" );
2027 
2028  if( aZone->GetIsRuleArea() )
2029  {
2030  m_out->Print( aNestLevel + 1,
2031  "(keepout (tracks %s) (vias %s) (pads %s ) (copperpour %s) "
2032  "(footprints %s))\n",
2033  aZone->GetDoNotAllowTracks() ? "not_allowed" : "allowed",
2034  aZone->GetDoNotAllowVias() ? "not_allowed" : "allowed",
2035  aZone->GetDoNotAllowPads() ? "not_allowed" : "allowed",
2036  aZone->GetDoNotAllowCopperPour() ? "not_allowed" : "allowed",
2037  aZone->GetDoNotAllowFootprints() ? "not_allowed" : "allowed" );
2038  }
2039 
2040  m_out->Print( aNestLevel + 1, "(fill" );
2041 
2042  // Default is not filled.
2043  if( aZone->IsFilled() )
2044  m_out->Print( 0, " yes" );
2045 
2046  // Default is polygon filled.
2047  if( aZone->GetFillMode() == ZONE_FILL_MODE::HATCH_PATTERN )
2048  m_out->Print( 0, " (mode hatch)" );
2049 
2050  m_out->Print( 0, " (thermal_gap %s) (thermal_bridge_width %s)",
2051  FormatInternalUnits( aZone->GetThermalReliefGap() ).c_str(),
2052  FormatInternalUnits( aZone->GetThermalReliefSpokeWidth() ).c_str() );
2053 
2055  {
2056  m_out->Print( 0, " (smoothing" );
2057 
2058  switch( aZone->GetCornerSmoothingType() )
2059  {
2061  m_out->Print( 0, " chamfer" );
2062  break;
2063 
2065  m_out->Print( 0, " fillet" );
2066  break;
2067 
2068  default:
2069  THROW_IO_ERROR( wxString::Format( _( "unknown zone corner smoothing type %d" ),
2070  aZone->GetCornerSmoothingType() ) );
2071  }
2072  m_out->Print( 0, ")" );
2073 
2074  if( aZone->GetCornerRadius() != 0 )
2075  m_out->Print( 0, " (radius %s)",
2076  FormatInternalUnits( aZone->GetCornerRadius() ).c_str() );
2077  }
2078 
2080  {
2081  m_out->Print( 0, " (island_removal_mode %d) (island_area_min %s)",
2082  static_cast<int>( aZone->GetIslandRemovalMode() ),
2083  FormatInternalUnits( aZone->GetMinIslandArea() / IU_PER_MM ).c_str() );
2084  }
2085 
2086  if( aZone->GetFillMode() == ZONE_FILL_MODE::HATCH_PATTERN )
2087  {
2088  m_out->Print( 0, "\n" );
2089  m_out->Print( aNestLevel+2, "(hatch_thickness %s) (hatch_gap %s) (hatch_orientation %s)",
2090  FormatInternalUnits( aZone->GetHatchThickness() ).c_str(),
2091  FormatInternalUnits( aZone->GetHatchGap() ).c_str(),
2092  Double2Str( aZone->GetHatchOrientation() ).c_str() );
2093 
2094  if( aZone->GetHatchSmoothingLevel() > 0 )
2095  {
2096  m_out->Print( 0, "\n" );
2097  m_out->Print( aNestLevel+2, "(hatch_smoothing_level %d) (hatch_smoothing_value %s)",
2098  aZone->GetHatchSmoothingLevel(),
2099  Double2Str( aZone->GetHatchSmoothingValue() ).c_str() );
2100  }
2101 
2102  m_out->Print( 0, "\n" );
2103  m_out->Print( aNestLevel+2, "(hatch_border_algorithm %s) (hatch_min_hole_area %s)",
2104  aZone->GetHatchBorderAlgorithm() ? "hatch_thickness" : "min_thickness",
2105  Double2Str( aZone->GetHatchHoleMinArea() ).c_str() );
2106  }
2107 
2108  m_out->Print( 0, ")\n" );
2109 
2110  if( aZone->GetNumCorners() )
2111  {
2112  SHAPE_POLY_SET::POLYGON poly = aZone->Outline()->Polygon(0);
2113 
2114  for( auto& chain : poly )
2115  {
2116  m_out->Print( aNestLevel + 1, "(polygon\n" );
2117  m_out->Print( aNestLevel + 2, "(pts" );
2118 
2119  bool need_newline = true;
2120 
2121  for( int ii = 0; ii < chain.PointCount(); ++ii )
2122  {
2123  int nestLevel = 0;
2124 
2125  if( !( ii % 4 ) || !ADVANCED_CFG::GetCfg().m_CompactSave ) // newline every 4 pts
2126  {
2127  m_out->Print( 0, "\n" );
2128  need_newline = false;
2129  nestLevel = aNestLevel + 3;
2130  }
2131 
2132  int ind = chain.ArcIndex( ii );
2133 
2134  if( ind < 0 )
2135  {
2136  m_out->Print( nestLevel, "%s(xy %s)",
2137  nestLevel ? "" : " ",
2138  FormatInternalUnits( chain.CPoint( ii ) ).c_str() );
2139  need_newline = true;
2140  }
2141  else
2142  {
2143  auto& arc = chain.Arc( ind );
2144  m_out->Print( nestLevel, "%s(arc (start %s) (mid %s) (end %s))",
2145  nestLevel ? "" : " ",
2146  FormatInternalUnits( arc.GetP0() ).c_str(),
2147  FormatInternalUnits( arc.GetArcMid() ).c_str(),
2148  FormatInternalUnits( arc.GetP1() ).c_str() );
2149  need_newline = true;
2150 
2151  do
2152  {
2153  ++ii;
2154  } while( ii < chain.PointCount() && chain.ArcIndex( ii ) == ind );
2155 
2156  --ii;
2157  }
2158  }
2159 
2160  if( need_newline )
2161  m_out->Print( 0, "\n" );
2162 
2163  m_out->Print( aNestLevel + 2, ")\n" );
2164  m_out->Print( aNestLevel + 1, ")\n" );
2165 
2166  }
2167  }
2168 
2169  // Save the PolysList (filled areas)
2170  for( PCB_LAYER_ID layer : aZone->GetLayerSet().Seq() )
2171  {
2172  const SHAPE_POLY_SET& fv = aZone->GetFilledPolysList( layer );
2173 
2174  for( int ii = 0; ii < fv.OutlineCount(); ++ii )
2175  {
2176  m_out->Print( aNestLevel + 1, "(filled_polygon\n" );
2177  m_out->Print( aNestLevel + 2, "(layer %s)\n",
2178  m_out->Quotew( LSET::Name( layer ) ).c_str() );
2179 
2180  if( aZone->IsIsland( layer, ii ) )
2181  m_out->Print( aNestLevel + 2, "(island)\n" );
2182 
2183  m_out->Print( aNestLevel + 2, "(pts" );
2184 
2185  const SHAPE_LINE_CHAIN& chain = fv.COutline( ii );
2186 
2187  bool need_newline = true;
2188 
2189  for( int jj = 0; jj < chain.PointCount(); ++jj )
2190  {
2191  int nestLevel = 0;
2192 
2193  if( !( jj%4 ) || !ADVANCED_CFG::GetCfg().m_CompactSave ) // newline every 4 pts
2194  {
2195  m_out->Print( 0, "\n" );
2196  need_newline = false;
2197  nestLevel = aNestLevel + 3;
2198  }
2199 
2200  int ind = chain.ArcIndex( jj );
2201 
2202  if( ind < 0 )
2203  {
2204  m_out->Print( nestLevel, "%s(xy %s)",
2205  nestLevel ? "" : " ",
2206  FormatInternalUnits( chain.CPoint( jj ) ).c_str() );
2207  need_newline = true;
2208  }
2209  else
2210  {
2211  auto& arc = chain.Arc( ind );
2212  m_out->Print( nestLevel, "%s(arc (start %s) (mid %s) (end %s))",
2213  nestLevel ? "" : " ",
2214  FormatInternalUnits( arc.GetP0() ).c_str(),
2215  FormatInternalUnits( arc.GetArcMid() ).c_str(),
2216  FormatInternalUnits( arc.GetP1() ).c_str() );
2217  need_newline = true;
2218 
2219  do
2220  {
2221  ++jj;
2222  } while( jj < chain.PointCount() && chain.ArcIndex( jj ) == ind );
2223 
2224  --jj;
2225  }
2226  }
2227 
2228  if( need_newline )
2229  m_out->Print( 0, "\n" );
2230 
2231  m_out->Print( aNestLevel+2, ")\n" );
2232  m_out->Print( aNestLevel+1, ")\n" );
2233  }
2234 
2235  // Save the filling segments list
2236  const std::vector<SEG>& segs = aZone->FillSegments( layer );
2237 
2238  if( segs.size() )
2239  {
2240  m_out->Print( aNestLevel + 1, "(fill_segments\n" );
2241  m_out->Print( aNestLevel + 2, "(layer %s)\n",
2242  TO_UTF8( BOARD::GetStandardLayerName( layer ) ) );
2243 
2244  for( const SEG& seg : segs )
2245  {
2246  m_out->Print( aNestLevel + 2, "(pts (xy %s) (xy %s))\n",
2247  FormatInternalUnits( wxPoint( seg.A ) ).c_str(),
2248  FormatInternalUnits( wxPoint( seg.B ) ).c_str() );
2249  }
2250 
2251  m_out->Print( aNestLevel + 1, ")\n" );
2252  }
2253  }
2254 
2255  m_out->Print( aNestLevel, ")\n" );
2256 }
std::vector< SHAPE_LINE_CHAIN > POLYGON
< represents a single polygon outline with holes.
int GetNumCorners(void) const
Access to m_Poly parameters.
Definition: zone.h:523
const SHAPE_ARC & Arc(size_t aArc) const
int GetHatchGap() const
Definition: zone.h:256
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.
int OutlineCount() const
Return the number of vertices in a given outline/hole.
bool GetDoNotAllowFootprints() const
Definition: zone.h:738
void formatLayer(const BOARD_ITEM *aItem) const
int GetHatchThickness() const
Definition: zone.h:253
unsigned GetPriority() const
Definition: zone.h:122
bool GetIsRuleArea() const
Accessors to parameters used in Rule Area zones:
Definition: zone.h:733
static constexpr double IU_PER_MM
Mock up a conversion function.
int GetBorderHatchPitch() const
HatchBorder related methods.
Definition: zone.cpp:894
SHAPE_POLY_SET * Outline()
Definition: zone.h:320
bool GetDoNotAllowVias() const
Definition: zone.h:735
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
Definition: zone.cpp:295
double GetHatchSmoothingValue() const
Definition: zone.h:265
wxString AsString() const
Definition: kiid.cpp:218
const SHAPE_POLY_SET & GetFilledPolysList(PCB_LAYER_ID aLayer) const
Definition: zone.h:635
bool IsFilled() const
Definition: zone.h:234
virtual bool IsLocked() const
Definition: board_item.cpp:64
int PointCount() const
Return the number of points (vertices) in this line chain.
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:191
ssize_t ArcIndex(size_t aSegment) const
Return the arc index for the given segment index.
#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:268
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
bool GetDoNotAllowPads() const
Definition: zone.h:737
bool GetDoNotAllowCopperPour() const
Definition: zone.h:734
pads are covered by copper
int GetMinThickness() const
Definition: zone.h:244
int GetHatchSmoothingLevel() const
Definition: zone.h:262
static const wxChar * Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
Definition: lset.cpp:82
std::vector< SEG > & FillSegments(PCB_LAYER_ID aLayer)
Definition: zone.h:308
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:498
bool GetDoNotAllowTracks() const
Definition: zone.h:736
#define _(s)
ZONE_BORDER_DISPLAY_STYLE GetHatchStyle() const
Definition: zone.h:613
NETINFO_MAPPING * m_mapping
mapping for net codes, so only not empty net codes are stored with consecutive integers as net codes
Thermal relief only for THT pads.
const KIID m_Uuid
Definition: eda_item.h:475
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
Definition: seg.h:40
double GetHatchOrientation() const
Definition: zone.h:259
Use thermal relief for pads.
unsigned int GetCornerRadius() const
Definition: zone.h:687
int GetHatchBorderAlgorithm() const
Definition: zone.h:271
const ISLAND_REMOVAL_MODE GetIslandRemovalMode() const
Definition: zone.h:749
bool IsIsland(PCB_LAYER_ID aLayer, int aPolyIdx) const
Check if a given filled polygon is an insulated island.
Definition: zone.cpp:1127
Represent a polyline (an zero-thickness chain of connected line segments).
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:65
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
std::string Double2Str(double aValue)
Print a float number without using scientific notation and no trailing 0 We want to avoid scientific ...
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:753
int GetThermalReliefSpokeWidth() const
Definition: zone.h:202
POLYGON & Polygon(int aIndex)
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:426
ZONE_CONNECTION GetPadConnection(PAD *aPad, wxString *aSource=nullptr) const
Definition: zone.cpp:778
wxString GetZoneName() const
Definition: zone.h:129
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
int GetCornerSmoothingType() const
Definition: zone.h:683
std::string FormatInternalUnits(int aValue)
Function FormatInternalUnits converts aValue from internal units to a string appropriate for writing ...
Definition: base_units.cpp:485
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:494
static wxString GetStandardLayerName(PCB_LAYER_ID aLayerId)
Return an "English Standard" name of a PCB layer when given aLayerNumber.
Definition: board.h:605
bool GetFilledPolysUseThickness() const
Definition: zone.h:689

References _, ALWAYS, SHAPE_LINE_CHAIN::Arc(), SHAPE_LINE_CHAIN::ArcIndex(), KIID::AsString(), SHAPE_POLY_SET::COutline(), SHAPE_LINE_CHAIN::CPoint(), 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, ZONE::IsFilled(), ZONE::IsIsland(), BOARD_ITEM::IsLocked(), IU_PER_MM, locked, ADVANCED_CFG::m_CompactSave, m_mapping, m_out, EDA_ITEM::m_Uuid, LSET::Name(), NO_HATCH, NONE, ZONE::Outline(), SHAPE_POLY_SET::OutlineCount(), SHAPE_LINE_CHAIN::PointCount(), SHAPE_POLY_SET::Polygon(), 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 531 of file kicad_plugin.cpp.

532 {
533  m_out->Print( aNestLevel, "(layers\n" );
534 
535  // Save only the used copper layers from front to back.
536 
537  for( LSEQ cu = aBoard->GetEnabledLayers().CuStack(); cu; ++cu )
538  {
539  PCB_LAYER_ID layer = *cu;
540 
541  m_out->Print( aNestLevel+1, "(%d %s %s", layer,
542  m_out->Quotew( LSET::Name( layer ) ).c_str(),
543  LAYER::ShowType( aBoard->GetLayerType( layer ) ) );
544 
545  if( LSET::Name( layer ) != m_board->GetLayerName( layer ) )
546  m_out->Print( 0, " %s", m_out->Quotew( m_board->GetLayerName( layer ) ).c_str() );
547 
548  m_out->Print( 0, ")\n" );
549  }
550 
551  // Save used non-copper layers in the order they are defined.
552  // desired sequence for non Cu BOARD layers.
553  static const PCB_LAYER_ID non_cu[] =
554  {
555  B_Adhes, // 32
556  F_Adhes,
557  B_Paste,
558  F_Paste,
559  B_SilkS,
560  F_SilkS,
561  B_Mask,
562  F_Mask,
563  Dwgs_User,
564  Cmts_User,
565  Eco1_User,
566  Eco2_User,
567  Edge_Cuts,
568  Margin,
569  B_CrtYd,
570  F_CrtYd,
571  B_Fab,
572  F_Fab,
573  User_1,
574  User_2,
575  User_3,
576  User_4,
577  User_5,
578  User_6,
579  User_7,
580  User_8,
581  User_9
582  };
583 
584  for( LSEQ seq = aBoard->GetEnabledLayers().Seq( non_cu, arrayDim( non_cu ) ); seq; ++seq )
585  {
586  PCB_LAYER_ID layer = *seq;
587 
588  m_out->Print( aNestLevel+1, "(%d %s user", layer,
589  m_out->Quotew( LSET::Name( layer ) ).c_str() );
590 
591  if( m_board->GetLayerName( layer ) != LSET::Name( layer ) )
592  m_out->Print( 0, " %s", m_out->Quotew( m_board->GetLayerName( layer ) ).c_str() );
593 
594  m_out->Print( 0, ")\n" );
595  }
596 
597  m_out->Print( aNestLevel, ")\n\n" );
598 }
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:362
LSET GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition: board.cpp:467
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:427
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.
Definition: layer_ids.h:465
LAYER_T GetLayerType(PCB_LAYER_ID aLayer) const
Return the type of the copper layer given by aLayer.
Definition: board.cpp:396
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:65
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:426
std::string Quotew(const wxString &aWrapee) const
Definition: richio.cpp:494

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 515 of file kicad_plugin.cpp.

516 {
517  const BOARD_DESIGN_SETTINGS& dsnSettings = aBoard->GetDesignSettings();
518 
519  m_out->Print( 0, "\n" );
520  m_out->Print( aNestLevel, "(general\n" );
521  m_out->Print( aNestLevel+1, "(thickness %s)\n",
522  FormatInternalUnits( dsnSettings.GetBoardThickness() ).c_str() );
523 
524  m_out->Print( aNestLevel, ")\n\n" );
525 
526  aBoard->GetPageSettings().Format( m_out, aNestLevel, m_ctl );
527  aBoard->GetTitleBlock().Format( m_out, aNestLevel, m_ctl );
528 }
OUTPUTFORMATTER * m_out
output any Format()s to this, no ownership
const PAGE_INFO & GetPageSettings() const
Definition: board.h:535
void Format(OUTPUTFORMATTER *aFormatter, int aNestLevel, int aControlBits) const
Output the page class to aFormatter in s-expression form.
Definition: page_info.cpp:271
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:590
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:541
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:426
std::string FormatInternalUnits(int aValue)
Function FormatInternalUnits converts aValue from internal units to a string appropriate for writing ...
Definition: base_units.cpp:485
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 631 of file kicad_plugin.cpp.

632 {
633  formatGeneral( aBoard, aNestLevel );
634 
635  // Layers list.
636  formatBoardLayers( aBoard, aNestLevel );
637 
638  // Setup
639  formatSetup( aBoard, aNestLevel );
640 
641  // Properties
642  formatProperties( aBoard, aNestLevel );
643 
644  // Save net codes and names
645  formatNetInformation( aBoard, aNestLevel );
646 }
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 463 of file kicad_plugin.cpp.

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

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 1280 of file kicad_plugin.cpp.

1281 {
1282  std::string output;
1283 
1284  if( aNestLevel == 0 )
1285  output += ' ';
1286 
1287  output += "(layers";
1288 
1289  static const LSET cu_all( LSET::AllCuMask() );
1290  static const LSET fr_bk( 2, B_Cu, F_Cu );
1291  static const LSET adhes( 2, B_Adhes, F_Adhes );
1292  static const LSET paste( 2, B_Paste, F_Paste );
1293  static const LSET silks( 2, B_SilkS, F_SilkS );
1294  static const LSET mask( 2, B_Mask, F_Mask );
1295  static const LSET crt_yd( 2, B_CrtYd, F_CrtYd );
1296  static const LSET fab( 2, B_Fab, F_Fab );
1297 
1298  LSET cu_mask = cu_all;
1299 
1300  // output copper layers first, then non copper
1301 
1302  if( ( aLayerMask & cu_mask ) == cu_mask )
1303  {
1304  output += " *.Cu";
1305  aLayerMask &= ~cu_all; // clear bits, so they are not output again below
1306  }
1307  else if( ( aLayerMask & cu_mask ) == fr_bk )
1308  {
1309  output += " F&B.Cu";
1310  aLayerMask &= ~fr_bk;
1311  }
1312 
1313  if( ( aLayerMask & adhes ) == adhes )
1314  {
1315  output += " *.Adhes";
1316  aLayerMask &= ~adhes;
1317  }
1318 
1319  if( ( aLayerMask & paste ) == paste )
1320  {
1321  output += " *.Paste";
1322  aLayerMask &= ~paste;
1323  }
1324 
1325  if( ( aLayerMask & silks ) == silks )
1326  {
1327  output += " *.SilkS";
1328  aLayerMask &= ~silks;
1329  }
1330 
1331  if( ( aLayerMask & mask ) == mask )
1332  {
1333  output += " *.Mask";
1334  aLayerMask &= ~mask;
1335  }
1336 
1337  if( ( aLayerMask & crt_yd ) == crt_yd )
1338  {
1339  output += " *.CrtYd";
1340  aLayerMask &= ~crt_yd;
1341  }
1342 
1343  if( ( aLayerMask & fab ) == fab )
1344  {
1345  output += " *.Fab";
1346  aLayerMask &= ~fab;
1347  }
1348 
1349  // output any individual layers not handled in wildcard combos above
1350  wxString layerName;
1351 
1352  for( LAYER_NUM layer = 0; layer < PCB_LAYER_ID_COUNT; ++layer )
1353  {
1354  if( aLayerMask[layer] )
1355  {
1356  layerName = LSET::Name( PCB_LAYER_ID( layer ) );
1357  output += ' ';
1358  output += m_out->Quotew( layerName );
1359  }
1360  }
1361 
1362  m_out->Print( aNestLevel, "%s)", output.c_str() );
1363 }
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
int LAYER_NUM
This can be replaced with int and removed.
Definition: layer_ids.h:41
LSET is a set of PCB_LAYER_IDs.
Definition: layer_ids.h:504
static const wxChar * Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
Definition: lset.cpp:82
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:65
Definition: layer_ids.h:71
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:426
std::string Quotew(const wxString &aWrapee) const
Definition: richio.cpp:494

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 601 of file kicad_plugin.cpp.

602 {
603  for( NETINFO_ITEM* net : *m_mapping )
604  {
605  if( net == nullptr ) // Skip not actually existing nets (orphan nets)
606  continue;
607 
608  m_out->Print( aNestLevel, "(net %d %s)\n",
609  m_mapping->Translate( net->GetNetCode() ),
610  m_out->Quotew( net->GetNetname() ).c_str() );
611  }
612 
613  m_out->Print( 0, "\n" );
614 }
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:426
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:494

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 617 of file kicad_plugin.cpp.

618 {
619  for( const std::pair<const wxString, wxString>& prop : aBoard->GetProperties() )
620  {
621  m_out->Print( aNestLevel, "(property %s %s)\n",
622  m_out->Quotew( prop.first ).c_str(),
623  m_out->Quotew( prop.second ).c_str() );
624  }
625 
626  if( !aBoard->GetProperties().empty() )
627  m_out->Print( 0, "\n" );
628 }
OUTPUTFORMATTER * m_out
output any Format()s to this, no ownership
const std::map< wxString, wxString > & GetProperties() const
Definition: board.h:258
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:426
std::string Quotew(const wxString &aWrapee) const
Definition: richio.cpp:494

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 471 of file kicad_plugin.cpp.

472 {
473  // Setup
474  m_out->Print( aNestLevel, "(setup\n" );
475 
476  // Save the board physical stackup structure
477  const BOARD_STACKUP& stackup = aBoard->GetDesignSettings().GetStackupDescriptor();
478 
479  if( aBoard->GetDesignSettings().m_HasStackup )
480  stackup.FormatBoardStackup( m_out, aBoard, aNestLevel+1 );
481 
482  BOARD_DESIGN_SETTINGS& dsnSettings = aBoard->GetDesignSettings();
483 
484  m_out->Print( aNestLevel+1, "(pad_to_mask_clearance %s)\n",
485  FormatInternalUnits( dsnSettings.m_SolderMaskMargin ).c_str() );
486 
487  if( dsnSettings.m_SolderMaskMinWidth )
488  m_out->Print( aNestLevel+1, "(solder_mask_min_width %s)\n",
489  FormatInternalUnits( dsnSettings.m_SolderMaskMinWidth ).c_str() );
490 
491  if( dsnSettings.m_SolderPasteMargin != 0 )
492  m_out->Print( aNestLevel+1, "(pad_to_paste_clearance %s)\n",
493  FormatInternalUnits( dsnSettings.m_SolderPasteMargin ).c_str() );
494 
495  if( dsnSettings.m_SolderPasteMarginRatio != 0 )
496  m_out->Print( aNestLevel+1, "(pad_to_paste_clearance_ratio %s)\n",
497  Double2Str( dsnSettings.m_SolderPasteMarginRatio ).c_str() );
498 
499  if( dsnSettings.m_AuxOrigin != wxPoint( 0, 0 ) )
500  m_out->Print( aNestLevel+1, "(aux_axis_origin %s %s)\n",
501  FormatInternalUnits( dsnSettings.m_AuxOrigin.x ).c_str(),
502  FormatInternalUnits( dsnSettings.m_AuxOrigin.y ).c_str() );
503 
504  if( dsnSettings.m_GridOrigin != wxPoint( 0, 0 ) )
505  m_out->Print( aNestLevel+1, "(grid_origin %s %s)\n",
506  FormatInternalUnits( dsnSettings.m_GridOrigin.x ).c_str(),
507  FormatInternalUnits( dsnSettings.m_GridOrigin.y ).c_str() );
508 
509  aBoard->GetPlotOptions().Format( m_out, aNestLevel+1 );
510 
511  m_out->Print( aNestLevel, ")\n\n" );
512 }
OUTPUTFORMATTER * m_out
output any Format()s to this, no ownership
const PCB_PLOT_PARAMS & GetPlotOptions() const
Definition: board.h:538
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.cpp:590
BOARD_STACKUP & GetStackupDescriptor()
void FormatBoardStackup(OUTPUTFORMATTER *aFormatter, const BOARD *aBoard, int aNestLevel) const
Write the stackup info on board file.
std::string Double2Str(double aValue)
Print a float number without using scientific notation and no trailing 0 We want to avoid scientific ...
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:426
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:485
Container for design settings for a BOARD object.

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 2424 of file kicad_plugin.cpp.

2427 {
2428  return getFootprint( aLibraryPath, aFootprintName, aProperties, false );
2429 }
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 149 of file pcbnew/plugins/kicad/kicad_plugin.h.

150  {
151  // Would have used wildcards_and_files_ext.cpp's KiCadPcbFileExtension,
152  // but to be pure, a plugin should not assume that it will always be linked
153  // with the core of the Pcbnew code. (Might someday be a DLL/DSO.) Besides,
154  // file extension policy should be controlled by the plugin.
155  return wxT( "kicad_pcb" );
156  }

◆ getFootprint()

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

Definition at line 2396 of file kicad_plugin.cpp.

2400 {
2401  LOCALE_IO toggle; // toggles on, then off, the C locale.
2402 
2403  init( aProperties );
2404 
2405  try
2406  {
2407  validateCache( aLibraryPath, checkModified );
2408  }
2409  catch( const IO_ERROR& )
2410  {
2411  // do nothing with the error
2412  }
2413 
2414  FOOTPRINT_MAP& footprints = m_cache->GetFootprints();
2415  FOOTPRINT_MAP::const_iterator it = footprints.find( aFootprintName );
2416 
2417  if( it == footprints.end() )
2418  return nullptr;
2419 
2420  return it->second->GetFootprint();
2421 }
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 2586 of file kicad_plugin.cpp.

2587 {
2588  return FP_CACHE::GetTimestamp( aLibraryPath );
2589 }
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 211 of file pcbnew/plugins/kicad/kicad_plugin.h.

212  {
213  std::string ret = m_sf.GetString();
214 
215  if( doClear )
216  m_sf.Clear();
217 
218  return ret;
219  }
const std::string & GetString()
Definition: richio.h:438
void Clear()
Clear the buffer and empties the internal string.
Definition: richio.h:428

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 2347 of file kicad_plugin.cpp.

2348 {
2349  m_board = nullptr;
2350  m_reader = nullptr;
2351  m_props = aProperties;
2352 }
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 2687 of file kicad_plugin.cpp.

2688 {
2689  LOCALE_IO toggle;
2690 
2691  init( nullptr );
2692 
2693  validateCache( aLibraryPath );
2694 
2695  return m_cache->IsWritable();
2696 }
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,
PROGRESS_REPORTER aProgressReporter = 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.
aProgressReporteran optional progress reporter
aLineCounta line count (necessary if a progress reporter is supplied)
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 2278 of file kicad_plugin.cpp.

2280 {
2281  FILE_LINE_READER reader( aFileName );
2282 
2283  unsigned lineCount = 0;
2284 
2285  if( aProgressReporter )
2286  {
2287  aProgressReporter->Report( wxString::Format( _( "Loading %s..." ), aFileName ) );
2288 
2289  if( !aProgressReporter->KeepRefreshing() )
2290  THROW_IO_ERROR( _( "Open cancelled by user." ) );
2291 
2292  while( reader.ReadLine() )
2293  lineCount++;
2294 
2295  reader.Rewind();
2296  }
2297 
2298  BOARD* board = DoLoad( reader, aAppendToMe, aProperties, aProgressReporter, lineCount );
2299 
2300  // Give the filename to the board if it's new
2301  if( !aAppendToMe )
2302  board->SetFileName( aFileName );
2303 
2304  return board;
2305 }
virtual void Report(const wxString &aMessage)=0
Display aMessage in the progress bar dialog.
A LINE_READER that reads from an open file.
Definition: richio.h:172
#define _(s)
void SetFileName(const wxString &aFileName)
Definition: board.h:226
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
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:190
virtual bool KeepRefreshing(bool aWait=false)=0
Update the UI (if any).
BOARD * DoLoad(LINE_READER &aReader, BOARD *aAppendToMe, const PROPERTIES *aProperties, PROGRESS_REPORTER *aProgressReporter, unsigned aLineCount)
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38

References _, DoLoad(), Format(), PROGRESS_REPORTER::KeepRefreshing(), FILE_LINE_READER::ReadLine(), PROGRESS_REPORTER::Report(), FILE_LINE_READER::Rewind(), BOARD::SetFileName(), and THROW_IO_ERROR.

Referenced by PNS_LOG_FILE::Load().

◆ Parse()

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

Definition at line 375 of file kicad_plugin.cpp.

376 {
377  std::string input = TO_UTF8( aClipboardSourceInput );
378 
379  STRING_LINE_READER reader( input, wxT( "clipboard" ) );
380 
381  m_parser->SetLineReader( &reader );
382 
383  try
384  {
385  return m_parser->Parse();
386  }
387  catch( const PARSE_ERROR& parse_error )
388  {
389  if( m_parser->IsTooRecent() )
390  throw FUTURE_FORMAT_ERROR( parse_error, m_parser->GetRequiredVersion() );
391  else
392  throw;
393  }
394 }
#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:246
BOARD_ITEM * Parse()
Definition: pcb_parser.cpp:626
LINE_READER * SetLineReader(LINE_READER *aReader)
Set aLineReader into the parser, and returns the previous one, if any.
Definition: pcb_parser.h:94
bool IsTooRecent()
Return whether a version number, if any was parsed, was too recent.
Definition: pcb_parser.h:132
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:240

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 144 of file pcbnew/plugins/kicad/kicad_plugin.h.

145  {
146  return wxT( "KiCad" );
147  }

◆ 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 }

◆ 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 335 of file kicad_plugin.cpp.

336 {
337  LOCALE_IO toggle; // toggles on, then off, the C locale.
338 
339  wxString sanityResult = aBoard->GroupsSanityCheck();
340 
341  if( sanityResult != wxEmptyString )
342  {
343  KIDIALOG dlg( nullptr, wxString::Format(
344  _( "Please report this bug. Error validating group structure: %s"
345  "\n\nSave anyway?" ), sanityResult ),
346  _( "Internal group data structure corrupt" ),
347  wxOK | wxCANCEL | wxICON_ERROR );
348  dlg.SetOKLabel( _( "Save Anyway" ) );
349 
350  if( dlg.ShowModal() == wxID_CANCEL )
351  return;
352  }
353 
354  init( aProperties );
355 
356  m_board = aBoard; // after init()
357 
358  // Prepare net mapping that assures that net codes saved in a file are consecutive integers
359  m_mapping->SetBoard( aBoard );
360 
361  FILE_OUTPUTFORMATTER formatter( aFileName );
362 
363  m_out = &formatter; // no ownership
364 
365  m_out->Print( 0, "(kicad_pcb (version %d) (generator pcbnew)\n", SEXPR_BOARD_FILE_VERSION );
366 
367  Format( aBoard, 1 );
368 
369  m_out->Print( 0, ")\n" );
370 
371  m_out = nullptr;
372 }
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
#define _(s)
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.
BOARD * m_board
which BOARD, no ownership here
Used for text file output.
Definition: richio.h:456
wxString GroupsSanityCheck(bool repair=false)
Consistency check of internal m_groups structure.
Definition: board.cpp:2023
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:426

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 221 of file pcbnew/plugins/kicad/kicad_plugin.h.

221 { 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 2355 of file kicad_plugin.cpp.

2356 {
2357  if( !m_cache || !m_cache->IsPath( aLibraryPath ) || ( checkModified && m_cache->IsModified() ) )
2358  {
2359  // a spectacular episode in memory management:
2360  delete m_cache;
2361  m_cache = new FP_CACHE( this, aLibraryPath );
2362  m_cache->Load();
2363  }
2364 }
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 280 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 295 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 283 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 291 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 297 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 287 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 290 of file pcbnew/plugins/kicad/kicad_plugin.h.

Referenced by init().

◆ m_sf

STRING_FORMATTER PCB_IO::m_sf
protected

Definition at line 293 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: