KiCad PCB EDA Suite
LEGACY_PLUGIN Class Reference

A PLUGIN derivation which could possibly be put into a DLL/DSO. More...

#include <legacy_plugin.h>

Inheritance diagram for LEGACY_PLUGIN:
PLUGIN

Public Types

typedef int BIU
 

Public Member Functions

 LEGACY_PLUGIN ()
 
 ~LEGACY_PLUGIN ()
 
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...
 
BOARDLoad (const wxString &aFileName, BOARD *aAppendToMe, const STRING_UTF8_MAP *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...
 
void FootprintEnumerate (wxArrayString &aFootprintNames, const wxString &aLibraryPath, bool aBestEfforts, const STRING_UTF8_MAP *aProperties=nullptr) override
 Return a list of footprint names contained within the library at aLibraryPath. More...
 
FOOTPRINTFootprintLoad (const wxString &aLibraryPath, const wxString &aFootprintName, bool aKeepUUID=false, const STRING_UTF8_MAP *aProperties=nullptr) override
 Load a footprint having aFootprintName from the aLibraryPath containing a library format that this PLUGIN knows about. More...
 
bool FootprintLibDelete (const wxString &aLibraryPath, const STRING_UTF8_MAP *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...
 
long long GetLibraryTimestamp (const wxString &aLibraryPath) const override
 Generate a timestamp representing all the files in the library (including the library directory). More...
 
bool IsFootprintLibWritable (const wxString &aLibraryPath) override
 Return true if the library at aLibraryPath is writable. More...
 
void SetReader (LINE_READER *aReader)
 
virtual void SetQueryUserCallback (std::function< bool(wxString aTitle, int aIcon, wxString aMessage, wxString aAction)> aCallback)
 Registers a KIDIALOG callback for collecting info from the user. More...
 
virtual std::vector< FOOTPRINT * > GetImportedCachedLibraryFootprints ()
 Return a container with the cached library footprints generated in the last call to Load. More...
 
virtual void Save (const wxString &aFileName, BOARD *aBoard, const STRING_UTF8_MAP *aProperties=nullptr)
 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...
 
virtual void PrefetchLib (const wxString &aLibraryPath, const STRING_UTF8_MAP *aProperties=nullptr)
 If possible, prefetches the specified library (e.g. More...
 
virtual const FOOTPRINTGetEnumeratedFootprint (const wxString &aLibraryPath, const wxString &aFootprintName, const STRING_UTF8_MAP *aProperties=nullptr)
 A version of FootprintLoad() for use after FootprintEnumerate() for more efficient cache management. More...
 
virtual bool FootprintExists (const wxString &aLibraryPath, const wxString &aFootprintName, const STRING_UTF8_MAP *aProperties=nullptr)
 Check for the existence of a footprint. More...
 
virtual void FootprintSave (const wxString &aLibraryPath, const FOOTPRINT *aFootprint, const STRING_UTF8_MAP *aProperties=nullptr)
 Write aFootprint to an existing library located at aLibraryPath. More...
 
virtual void FootprintDelete (const wxString &aLibraryPath, const wxString &aFootprintName, const STRING_UTF8_MAP *aProperties=nullptr)
 Delete aFootprintName from the library at aLibraryPath. More...
 
virtual void FootprintLibCreate (const wxString &aLibraryPath, const STRING_UTF8_MAP *aProperties=nullptr)
 Create a new empty footprint library at aLibraryPath empty. More...
 
virtual void FootprintLibOptions (STRING_UTF8_MAP *aListToAppendTo) const
 Append supported PLUGIN options to aListToAppenTo along with internationalized descriptions. More...
 

Static Public Member Functions

static PCB_LAYER_ID leg_layer2new (int cu_count, int aLayerNum)
 
static LSET leg_mask2new (int cu_count, unsigned aMask)
 

Protected Member Functions

void init (const STRING_UTF8_MAP *aProperties)
 initialize PLUGIN like a constructor would, and futz with fresh BOARD if needed. More...
 
void checkpoint ()
 Converts net code using the mapping table if available, otherwise returns unchanged net code. More...
 
int getNetCode (int aNetCode)
 
BIU biuParse (const char *aValue, const char **nptrptr=nullptr)
 Parse an ASCII decimal floating point value and scales it into a BIU according to the current value of diskToBui. More...
 
EDA_ANGLE degParse (const char *aValue, const char **nptrptr=nullptr)
 Parse an ASCII decimal floating point value which is certainly an angle in tenths of a degree. More...
 
void checkVersion ()
 
void loadAllSections (bool doAppend)
 
void loadGENERAL ()
 
void loadSETUP ()
 
void loadSHEET ()
 
void load3D (FOOTPRINT *aFootprint)
 
void loadPAD (FOOTPRINT *aFootprint)
 
void loadMODULE_TEXT (FP_TEXT *aText)
 
void loadFP_SHAPE (FOOTPRINT *aFootprint)
 
void loadPCB_LINE ()
 
void loadNETINFO_ITEM ()
 
void loadPCB_TEXT ()
 
void loadNETCLASS ()
 
void loadFOOTPRINT (FOOTPRINT *aFootprint)
 
void loadTrackList (int aStructType)
 Read a list of segments (Tracks and Vias, or Segzones) More...
 
void loadZONE_CONTAINER ()
 
void loadDIMENSION ()
 
void loadPCB_TARGET ()
 
void cacheLib (const wxString &aLibraryPath)
 we only cache one footprint library for now, this determines which one. More...
 

Protected Attributes

int m_cu_count
 
wxString m_error
 for throwing exceptions More...
 
BOARDm_board
 which BOARD, no ownership here More...
 
const STRING_UTF8_MAPm_props
 passed via Save() or Load(), no ownership, More...
 
PROGRESS_REPORTERm_progressReporter
 may be NULL, no ownership More...
 
unsigned m_lastProgressLine
 
unsigned m_lineCount
 for progress reporting More...
 
LINE_READERm_reader
 no ownership here. More...
 
FILE * m_fp
 no ownership here. More...
 
wxString m_field
 reused to stuff FOOTPRINT fields. More...
 
int m_loading_format_version
 which BOARD_FORMAT_VERSION am I Load()ing? More...
 
LP_CACHEm_cache
 
bool m_showLegacySegmentZoneWarning
 
std::vector< int > m_netCodes
 net codes mapping for boards being loaded More...
 
double biuToDisk
 convert from BIUs to disk engineering units with this scale factor More...
 
double diskToBiu
 convert from disk engineering units to BIUs with this scale factor More...
 

Friends

struct LP_CACHE
 

Detailed Description

A PLUGIN derivation which could possibly be put into a DLL/DSO.

As with any PLUGIN, there is no UI, i.e. windowing calls allowed.

Definition at line 59 of file legacy_plugin.h.

Member Typedef Documentation

◆ BIU

typedef int LEGACY_PLUGIN::BIU

Definition at line 96 of file legacy_plugin.h.

Constructor & Destructor Documentation

◆ LEGACY_PLUGIN()

LEGACY_PLUGIN::LEGACY_PLUGIN ( )

Definition at line 3252 of file legacy_plugin.cpp.

3252 :
3253 m_cu_count( 16 ), // for FootprintLoad()
3254 m_board( nullptr ),
3255 m_props( nullptr ),
3256 m_progressReporter( nullptr ),
3257 m_lastProgressLine( 0 ),
3258 m_lineCount( 0 ),
3259 m_reader( nullptr ),
3260 m_fp( nullptr ),
3261 m_cache( nullptr )
3262{
3263 init( nullptr );
3264}
unsigned m_lastProgressLine
void init(const STRING_UTF8_MAP *aProperties)
initialize PLUGIN like a constructor would, and futz with fresh BOARD if needed.
PROGRESS_REPORTER * m_progressReporter
may be NULL, no ownership
unsigned m_lineCount
for progress reporting
FILE * m_fp
no ownership here.
LP_CACHE * m_cache
const STRING_UTF8_MAP * m_props
passed via Save() or Load(), no ownership,
LINE_READER * m_reader
no ownership here.
BOARD * m_board
which BOARD, no ownership here

References init().

◆ ~LEGACY_PLUGIN()

LEGACY_PLUGIN::~LEGACY_PLUGIN ( )

Definition at line 3267 of file legacy_plugin.cpp.

3268{
3269 delete m_cache;
3270}

References m_cache.

Member Function Documentation

◆ biuParse()

BIU LEGACY_PLUGIN::biuParse ( const char *  aValue,
const char **  nptrptr = nullptr 
)
protected

Parse an ASCII decimal floating point value and scales it into a BIU according to the current value of diskToBui.

This function is the complement of #fmtBIU(). One has to know what the other is doing.

Parameters
aValueis the ASCII value in C locale form with possible leading whitespace
nptrptrmay be NULL, but if not, then it tells where to put a pointer to the next unconsumed input text. See "man strtod" for more information.
Returns
the converted Board Internal Unit.

Definition at line 2795 of file legacy_plugin.cpp.

2796{
2797 char* nptr;
2798
2799 errno = 0;
2800
2801 double fval = strtod( aValue, &nptr );
2802
2803 if( errno )
2804 {
2805 m_error.Printf( _( "Invalid floating point number in file: '%s'\nline: %d, offset: %d" ),
2806 m_reader->GetSource().GetData(),
2808 aValue - m_reader->Line() + 1 );
2809
2811 }
2812
2813 if( aValue == nptr )
2814 {
2815 m_error.Printf( _( "Missing floating point number in file: '%s'\nline: %d, offset: %d" ),
2816 m_reader->GetSource().GetData(),
2818 aValue - m_reader->Line() + 1 );
2819
2821 }
2822
2823 if( nptrptr )
2824 *nptrptr = nptr;
2825
2826 fval *= diskToBiu;
2827
2828 // fval is up into the whole number realm here, and should be bounded
2829 // within INT_MIN to INT_MAX since BIU's are nanometers.
2830 return KiROUND( fval );
2831}
double diskToBiu
convert from disk engineering units to BIUs with this scale factor
wxString m_error
for throwing exceptions
virtual const wxString & GetSource() const
Returns the name of the source of the lines in an abstract sense.
Definition: richio.h:109
virtual unsigned LineNumber() const
Return the line number of the last line read from this LINE_READER.
Definition: richio.h:135
char * Line() const
Return a pointer to the last line that was read in.
Definition: richio.h:117
#define _(s)
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:85

References _, diskToBiu, LINE_READER::GetSource(), KiROUND(), LINE_READER::Line(), LINE_READER::LineNumber(), m_error, m_reader, and THROW_IO_ERROR.

Referenced by loadDIMENSION(), loadFOOTPRINT(), loadFP_SHAPE(), loadGENERAL(), loadMODULE_TEXT(), loadNETCLASS(), loadPAD(), loadPCB_LINE(), loadPCB_TARGET(), loadPCB_TEXT(), loadSETUP(), loadTrackList(), and loadZONE_CONTAINER().

◆ cacheLib()

void LEGACY_PLUGIN::cacheLib ( const wxString &  aLibraryPath)
protected

we only cache one footprint library for now, this determines which one.

Definition at line 3145 of file legacy_plugin.cpp.

3146{
3147 if( !m_cache || m_cache->m_lib_path != aLibraryPath || m_cache->IsModified() )
3148 {
3149 // a spectacular episode in memory management:
3150 delete m_cache;
3151 m_cache = new LP_CACHE( this, aLibraryPath );
3152 m_cache->Load();
3153 }
3154}
friend struct LP_CACHE
Definition: legacy_plugin.h:61
wxString m_lib_path
bool IsModified()

References LP_CACHE::IsModified(), LP_CACHE::Load(), LP_CACHE, m_cache, and LP_CACHE::m_lib_path.

Referenced by FootprintEnumerate(), FootprintLoad(), and IsFootprintLibWritable().

◆ checkpoint()

void LEGACY_PLUGIN::checkpoint ( )
protected

Converts net code using the mapping table if available, otherwise returns unchanged net code.

Definition at line 199 of file legacy_plugin.cpp.

200{
201 const unsigned PROGRESS_DELTA = 250;
202
204 {
205 unsigned curLine = m_reader->LineNumber();
206
207 if( curLine > m_lastProgressLine + PROGRESS_DELTA )
208 {
209 m_progressReporter->SetCurrentProgress( ( (double) curLine )
210 / std::max( 1U, m_lineCount ) );
211
213 THROW_IO_ERROR( _( "Open cancelled by user." ) );
214
215 m_lastProgressLine = curLine;
216 }
217 }
218}
virtual bool KeepRefreshing(bool aWait=false)=0
Update the UI (if any).
virtual void SetCurrentProgress(double aProgress)=0
Set the progress value to aProgress (0..1).

References _, PROGRESS_REPORTER::KeepRefreshing(), LINE_READER::LineNumber(), m_lastProgressLine, m_lineCount, m_progressReporter, m_reader, PROGRESS_REPORTER::SetCurrentProgress(), and THROW_IO_ERROR.

Referenced by loadAllSections(), and loadTrackList().

◆ checkVersion()

void LEGACY_PLUGIN::checkVersion ( )
protected

Definition at line 566 of file legacy_plugin.cpp.

567{
568 // Read first line and TEST if it is a PCB file format header like this:
569 // "PCBNEW-BOARD Version 1 ...."
570
572
573 char* line = m_reader->Line();
574
575 if( !TESTLINE( "PCBNEW-BOARD" ) )
576 {
577 THROW_IO_ERROR( wxT( "Unknown file type" ) );
578 }
579
580 int ver = 1; // if sccanf fails
581 sscanf( line, "PCBNEW-BOARD Version %d", &ver );
582
583#if !defined(DEBUG)
584 if( ver > LEGACY_BOARD_FILE_VERSION )
585 {
586 m_error.Printf( _( "File '%s' has an unrecognized version: %d." ),
587 m_reader->GetSource().GetData(),
588 ver );
590 }
591#endif
592
595}
void SetFileFormatVersionAtLoad(int aVersion)
Definition: board.h:362
int m_loading_format_version
which BOARD_FORMAT_VERSION am I Load()ing?
virtual char * ReadLine()=0
Read a line of text into the buffer and increments the line number counter.
#define TESTLINE(x)
C string compare test for a specific length of characters.

References _, LINE_READER::GetSource(), LINE_READER::Line(), m_board, m_error, m_loading_format_version, m_reader, LINE_READER::ReadLine(), BOARD::SetFileFormatVersionAtLoad(), TESTLINE, and THROW_IO_ERROR.

Referenced by Load().

◆ degParse()

EDA_ANGLE LEGACY_PLUGIN::degParse ( const char *  aValue,
const char **  nptrptr = nullptr 
)
protected

Parse an ASCII decimal floating point value which is certainly an angle in tenths of a degree.

Parameters
aValueis the ASCII value in C locale form with possible leading whitespace.
nptrptrmay be NULL, but if not, then it tells where to put a pointer to the next unconsumed input text. See "man strtod" for more information.

Definition at line 2834 of file legacy_plugin.cpp.

2835{
2836 char* nptr;
2837
2838 errno = 0;
2839
2840 double fval = strtod( aValue, &nptr );
2841
2842 if( errno )
2843 {
2844 m_error.Printf( _( "Invalid floating point number in file: '%s'\nline: %d, offset: %d" ),
2845 m_reader->GetSource().GetData(),
2847 aValue - m_reader->Line() + 1 );
2848
2850 }
2851
2852 if( aValue == nptr )
2853 {
2854 m_error.Printf( _( "Missing floating point number in file: '%s'\nline: %d, offset: %d" ),
2855 m_reader->GetSource().GetData(),
2857 aValue - m_reader->Line() + 1 );
2858
2860 }
2861
2862 if( nptrptr )
2863 *nptrptr = nptr;
2864
2865 return EDA_ANGLE( fval, TENTHS_OF_A_DEGREE_T );
2866}
@ TENTHS_OF_A_DEGREE_T
Definition: eda_angle.h:30

References _, LINE_READER::GetSource(), LINE_READER::Line(), LINE_READER::LineNumber(), m_error, m_reader, TENTHS_OF_A_DEGREE_T, and THROW_IO_ERROR.

Referenced by loadDIMENSION(), loadFP_SHAPE(), loadMODULE_TEXT(), loadPAD(), loadPCB_LINE(), and loadPCB_TEXT().

◆ FootprintDelete()

void PLUGIN::FootprintDelete ( const wxString &  aLibraryPath,
const wxString &  aFootprintName,
const STRING_UTF8_MAP aProperties = nullptr 
)
virtualinherited

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 in GPCB_PLUGIN, and PCB_PLUGIN.

Definition at line 114 of file plugin.cpp.

116{
117 // not pure virtual so that plugins only have to implement subset of the PLUGIN interface.
118 not_implemented( this, __FUNCTION__ );
119}
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 FP_LIB_TABLE::FootprintDelete().

◆ FootprintEnumerate()

void LEGACY_PLUGIN::FootprintEnumerate ( wxArrayString &  aFootprintNames,
const wxString &  aLibraryPath,
bool  aBestEfforts,
const STRING_UTF8_MAP 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 3157 of file legacy_plugin.cpp.

3159{
3160 LOCALE_IO toggle; // toggles on, then off, the C locale.
3161 wxString errorMsg;
3162
3163 init( aProperties );
3164
3165 try
3166 {
3167 cacheLib( aLibPath );
3168 }
3169 catch( const IO_ERROR& ioe )
3170 {
3171 errorMsg = ioe.What();
3172 }
3173
3174 // Some of the files may have been parsed correctly so we want to add the valid files to
3175 // the library.
3176
3177 for( const auto& footprint : m_cache->m_footprints )
3178 aFootprintNames.Add( FROM_UTF8( footprint.first.c_str() ) );
3179
3180 if( !errorMsg.IsEmpty() && !aBestEfforts )
3181 THROW_IO_ERROR( errorMsg );
3182}
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:76
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
void cacheLib(const wxString &aLibraryPath)
we only cache one footprint library for now, this determines which one.
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:41
static wxString FROM_UTF8(const char *cstring)
Convert a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:110
FOOTPRINT_MAP m_footprints

References cacheLib(), FROM_UTF8(), init(), m_cache, LP_CACHE::m_footprints, THROW_IO_ERROR, and IO_ERROR::What().

◆ FootprintExists()

bool PLUGIN::FootprintExists ( const wxString &  aLibraryPath,
const wxString &  aFootprintName,
const STRING_UTF8_MAP aProperties = nullptr 
)
virtualinherited

Check for the existence of a footprint.

Reimplemented in PCB_PLUGIN.

Definition at line 89 of file plugin.cpp.

91{
92 // default implementation
93 return FootprintLoad( aLibraryPath, aFootprintName, true, aProperties ) != nullptr;
94}
virtual FOOTPRINT * FootprintLoad(const wxString &aLibraryPath, const wxString &aFootprintName, bool aKeepUUID=false, const STRING_UTF8_MAP *aProperties=nullptr)
Load a footprint having aFootprintName from the aLibraryPath containing a library format that this PL...
Definition: plugin.cpp:97

References PLUGIN::FootprintLoad().

Referenced by FP_LIB_TABLE::FootprintExists().

◆ FootprintLibCreate()

void PLUGIN::FootprintLibCreate ( const wxString &  aLibraryPath,
const STRING_UTF8_MAP aProperties = nullptr 
)
virtualinherited

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 in PCB_PLUGIN.

Definition at line 122 of file plugin.cpp.

123{
124 // not pure virtual so that plugins only have to implement subset of the PLUGIN interface.
125 not_implemented( this, __FUNCTION__ );
126}

References not_implemented().

Referenced by PCB_BASE_EDIT_FRAME::createNewLibrary(), and FP_LIB_TABLE::FootprintLibCreate().

◆ FootprintLibDelete()

bool LEGACY_PLUGIN::FootprintLibDelete ( const wxString &  aLibraryPath,
const STRING_UTF8_MAP 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 3210 of file legacy_plugin.cpp.

3212{
3213 wxFileName fn = aLibraryPath;
3214
3215 if( !fn.FileExists() )
3216 return false;
3217
3218 // Some of the more elaborate wxRemoveFile() crap puts up its own wxLog dialog
3219 // we don't want that. we want bare metal portability with no UI here.
3220 if( wxRemove( aLibraryPath ) )
3221 {
3222 THROW_IO_ERROR( wxString::Format( _( "Footprint library '%s' cannot be deleted." ),
3223 aLibraryPath.GetData() ) );
3224 }
3225
3226 if( m_cache && m_cache->m_lib_path == aLibraryPath )
3227 {
3228 delete m_cache;
3229 m_cache = nullptr;
3230 }
3231
3232 return true;
3233}
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

References _, Format(), m_cache, LP_CACHE::m_lib_path, and THROW_IO_ERROR.

◆ FootprintLibOptions()

void PLUGIN::FootprintLibOptions ( STRING_UTF8_MAP 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 145 of file plugin.cpp.

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

References _.

Referenced by DIALOG_FP_PLUGIN_OPTIONS::DIALOG_FP_PLUGIN_OPTIONS(), and EAGLE_PLUGIN::FootprintLibOptions().

◆ FootprintLoad()

FOOTPRINT * LEGACY_PLUGIN::FootprintLoad ( const wxString &  aLibraryPath,
const wxString &  aFootprintName,
bool  aKeepUUID = false,
const STRING_UTF8_MAP 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 3185 of file legacy_plugin.cpp.

3188{
3189 LOCALE_IO toggle; // toggles on, then off, the C locale.
3190
3191 init( aProperties );
3192
3193 cacheLib( aLibraryPath );
3194
3195 const FOOTPRINT_MAP& footprints = m_cache->m_footprints;
3196 FOOTPRINT_MAP::const_iterator it = footprints.find( TO_UTF8( aFootprintName ) );
3197
3198 if( it == footprints.end() )
3199 {
3200 return nullptr;
3201 }
3202
3203 // Return copy of already loaded FOOTPRINT
3204 FOOTPRINT* copy = (FOOTPRINT*) it->second->Duplicate();
3205 copy->SetParent( nullptr );
3206 return copy;
3207}
std::map< wxString, FOOTPRINT * > FOOTPRINT_MAP
Definition: eagle_parser.h:50
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96

References cacheLib(), copy, init(), m_cache, LP_CACHE::m_footprints, and TO_UTF8.

◆ FootprintSave()

void PLUGIN::FootprintSave ( const wxString &  aLibraryPath,
const FOOTPRINT aFootprint,
const STRING_UTF8_MAP aProperties = nullptr 
)
virtualinherited

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 in PCB_PLUGIN.

Definition at line 106 of file plugin.cpp.

108{
109 // not pure virtual so that plugins only have to implement subset of the PLUGIN interface.
110 not_implemented( this, __FUNCTION__ );
111}

References not_implemented().

Referenced by PCB_EDIT_FRAME::ExportFootprintsToLibrary(), FP_LIB_TABLE::FootprintSave(), PCB_EDIT_FRAME::OpenProjectFiles(), and FOOTPRINT_EDIT_FRAME::SaveLibraryAs().

◆ GetEnumeratedFootprint()

const FOOTPRINT * PLUGIN::GetEnumeratedFootprint ( const wxString &  aLibraryPath,
const wxString &  aFootprintName,
const STRING_UTF8_MAP aProperties = nullptr 
)
virtualinherited

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

Reimplemented in GPCB_PLUGIN, and PCB_PLUGIN.

Definition at line 80 of file plugin.cpp.

83{
84 // default implementation
85 return FootprintLoad( aLibraryPath, aFootprintName, false, aProperties );
86}

References PLUGIN::FootprintLoad().

Referenced by FP_LIB_TABLE::GetEnumeratedFootprint(), and FOOTPRINT_EDIT_FRAME::SaveLibraryAs().

◆ GetFileExtension()

const wxString LEGACY_PLUGIN::GetFileExtension ( ) const
inlineoverridevirtual

Returns the file extension for the PLUGIN.

Implements PLUGIN.

Definition at line 72 of file legacy_plugin.h.

73 {
74 return wxT( "brd" );
75 }

◆ 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 CADSTAR_PCB_ARCHIVE_PLUGIN, and EAGLE_PLUGIN.

Definition at line 54 of file plugin.cpp.

55{
56 not_implemented( this, __FUNCTION__ );
57 return std::vector<FOOTPRINT*>();
58}

References not_implemented().

Referenced by PCB_EDIT_FRAME::OpenProjectFiles().

◆ GetLibraryTimestamp()

long long LEGACY_PLUGIN::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 3139 of file legacy_plugin.cpp.

3140{
3141 return LP_CACHE::GetTimestamp( aLibraryPath );
3142}
static long long GetTimestamp(const wxString &aLibPath)

References LP_CACHE::GetTimestamp().

◆ getNetCode()

int LEGACY_PLUGIN::getNetCode ( int  aNetCode)
inlineprotected

Definition at line 113 of file legacy_plugin.h.

114 {
115 if( (unsigned int) aNetCode < m_netCodes.size() )
116 return m_netCodes[aNetCode];
117
118 return aNetCode;
119 }
std::vector< int > m_netCodes
net codes mapping for boards being loaded

References m_netCodes.

Referenced by loadPAD(), loadTrackList(), and loadZONE_CONTAINER().

◆ init()

void LEGACY_PLUGIN::init ( const STRING_UTF8_MAP aProperties)
protected

initialize PLUGIN like a constructor would, and futz with fresh BOARD if needed.

Definition at line 2869 of file legacy_plugin.cpp.

2870{
2872 m_cu_count = 16;
2873 m_board = nullptr;
2875 m_props = aProperties;
2876
2877 // conversion factor for saving RAM BIUs to KICAD legacy file format.
2878 biuToDisk = 1.0 / pcbIUScale.IU_PER_MM; // BIUs are nanometers & file is mm
2879
2880 // Conversion factor for loading KICAD legacy file format into BIUs in RAM
2881 // Start by assuming the *.brd file is in deci-mils.
2882 // If we see "Units mm" in the $GENERAL section, set diskToBiu to 1000000.0
2883 // then, during the file loading process, to start a conversion from
2884 // mm to nanometers. The deci-mil legacy files have no such "Units" marker
2885 // so we must assume the file is in deci-mils until told otherwise.
2886
2887 diskToBiu = pcbIUScale.IU_PER_MILS / 10; // BIUs are nanometers
2888}
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:109
bool m_showLegacySegmentZoneWarning
double biuToDisk
convert from BIUs to disk engineering units with this scale factor
const double IU_PER_MM
Definition: base_units.h:77
const double IU_PER_MILS
Definition: base_units.h:78

References biuToDisk, diskToBiu, EDA_IU_SCALE::IU_PER_MILS, EDA_IU_SCALE::IU_PER_MM, m_board, m_cu_count, m_loading_format_version, m_props, m_showLegacySegmentZoneWarning, and pcbIUScale.

Referenced by FootprintEnumerate(), FootprintLoad(), IsFootprintLibWritable(), LEGACY_PLUGIN(), and Load().

◆ IsFootprintLibWritable()

bool LEGACY_PLUGIN::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 3236 of file legacy_plugin.cpp.

3237{
3238#if 0 // no support for 32 Cu layers in legacy format
3239 return false;
3240#else
3241 LOCALE_IO toggle;
3242
3243 init( nullptr );
3244
3245 cacheLib( aLibraryPath );
3246
3247 return m_cache->m_writable;
3248#endif
3249}

References cacheLib(), init(), m_cache, and LP_CACHE::m_writable.

◆ leg_layer2new()

PCB_LAYER_ID LEGACY_PLUGIN::leg_layer2new ( int  cu_count,
int  aLayerNum 
)
static

Definition at line 302 of file legacy_plugin.cpp.

303{
304 int newid;
305 unsigned old = aLayerNum;
306
307 // this is a speed critical function, be careful.
308
309 if( unsigned( old ) <= unsigned( LAYER_N_FRONT ) )
310 {
311 // In .brd files, the layers are numbered from back to front
312 // (the opposite of the .kicad_pcb files)
313 if( old == LAYER_N_FRONT )
314 {
315 newid = F_Cu;
316 }
317 else if( old == LAYER_N_BACK )
318 {
319 newid = B_Cu;
320 }
321 else
322 {
323 newid = cu_count - 1 - old;
324 wxASSERT( newid >= 0 );
325
326 // This is of course incorrect, but at least it avoid crashing pcbnew:
327 if( newid < 0 )
328 newid = 0;
329 }
330 }
331 else
332 {
333 switch( old )
334 {
335 case ADHESIVE_N_BACK: newid = B_Adhes; break;
336 case ADHESIVE_N_FRONT: newid = F_Adhes; break;
337 case SOLDERPASTE_N_BACK: newid = B_Paste; break;
338 case SOLDERPASTE_N_FRONT: newid = F_Paste; break;
339 case SILKSCREEN_N_BACK: newid = B_SilkS; break;
340 case SILKSCREEN_N_FRONT: newid = F_SilkS; break;
341 case SOLDERMASK_N_BACK: newid = B_Mask; break;
342 case SOLDERMASK_N_FRONT: newid = F_Mask; break;
343 case DRAW_N: newid = Dwgs_User; break;
344 case COMMENT_N: newid = Cmts_User; break;
345 case ECO1_N: newid = Eco1_User; break;
346 case ECO2_N: newid = Eco2_User; break;
347 case EDGE_N: newid = Edge_Cuts; break;
348 default:
349 // Remap all illegal non copper layers to comment layer
350 newid = Cmts_User;
351 }
352 }
353
354 return PCB_LAYER_ID( newid );
355}
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:59
@ B_Adhes
Definition: layer_ids.h:97
@ Edge_Cuts
Definition: layer_ids.h:113
@ Dwgs_User
Definition: layer_ids.h:109
@ F_Paste
Definition: layer_ids.h:101
@ Cmts_User
Definition: layer_ids.h:110
@ F_Adhes
Definition: layer_ids.h:98
@ B_Mask
Definition: layer_ids.h:106
@ B_Cu
Definition: layer_ids.h:95
@ Eco1_User
Definition: layer_ids.h:111
@ F_Mask
Definition: layer_ids.h:107
@ B_Paste
Definition: layer_ids.h:100
@ F_SilkS
Definition: layer_ids.h:104
@ Eco2_User
Definition: layer_ids.h:112
@ B_SilkS
Definition: layer_ids.h:103
@ F_Cu
Definition: layer_ids.h:64
#define SILKSCREEN_N_BACK
#define ECO2_N
#define DRAW_N
#define ADHESIVE_N_FRONT
#define ECO1_N
#define SOLDERMASK_N_FRONT
#define SOLDERMASK_N_BACK
#define EDGE_N
#define SOLDERPASTE_N_BACK
#define SOLDERPASTE_N_FRONT
#define COMMENT_N
#define LAYER_N_FRONT
#define ADHESIVE_N_BACK
#define SILKSCREEN_N_FRONT
#define LAYER_N_BACK

References ADHESIVE_N_BACK, ADHESIVE_N_FRONT, B_Adhes, B_Cu, B_Mask, B_Paste, B_SilkS, Cmts_User, COMMENT_N, DRAW_N, Dwgs_User, ECO1_N, Eco1_User, ECO2_N, Eco2_User, Edge_Cuts, EDGE_N, F_Adhes, F_Cu, F_Mask, F_Paste, F_SilkS, LAYER_N_BACK, LAYER_N_FRONT, SILKSCREEN_N_BACK, SILKSCREEN_N_FRONT, SOLDERMASK_N_BACK, SOLDERMASK_N_FRONT, SOLDERPASTE_N_BACK, and SOLDERPASTE_N_FRONT.

Referenced by leg_mask2new(), loadDIMENSION(), loadFOOTPRINT(), loadFP_SHAPE(), loadMODULE_TEXT(), loadPCB_LINE(), loadPCB_TARGET(), loadPCB_TEXT(), loadSETUP(), loadTrackList(), and loadZONE_CONTAINER().

◆ leg_mask2new()

LSET LEGACY_PLUGIN::leg_mask2new ( int  cu_count,
unsigned  aMask 
)
static

Definition at line 358 of file legacy_plugin.cpp.

359{
360 LSET ret;
361
362 if( ( aMask & ALL_CU_LAYERS ) == ALL_CU_LAYERS )
363 {
364 ret = LSET::AllCuMask();
365
366 aMask &= ~ALL_CU_LAYERS;
367 }
368
369 for( int i=0; aMask; ++i, aMask >>= 1 )
370 {
371 if( aMask & 1 )
372 ret.set( leg_layer2new( cu_count, i ) );
373 }
374
375 return ret;
376}
static PCB_LAYER_ID leg_layer2new(int cu_count, int aLayerNum)
LSET is a set of PCB_LAYER_IDs.
Definition: layer_ids.h:530
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:773
#define ALL_CU_LAYERS

References ALL_CU_LAYERS, LSET::AllCuMask(), and leg_layer2new().

Referenced by loadGENERAL(), and loadPAD().

◆ Load()

BOARD * LEGACY_PLUGIN::Load ( const wxString &  aFileName,
BOARD aAppendToMe,
const STRING_UTF8_MAP 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 405 of file legacy_plugin.cpp.

408{
409 LOCALE_IO toggle; // toggles on, then off, the C locale.
410
411 init( aProperties );
412
413 std::unique_ptr<BOARD> boardDeleter;
414
415 if( aAppendToMe )
416 {
417 m_board = aAppendToMe;
418 }
419 else
420 {
421 boardDeleter = std::make_unique<BOARD>();
422 m_board = boardDeleter.get();
423 }
424
425 // Give the filename to the board if it's new
426 if( !aAppendToMe )
427 m_board->SetFileName( aFileName );
428
429 FILE_LINE_READER reader( aFileName );
430
431 m_reader = &reader;
432 m_progressReporter = aProgressReporter;
433
434 checkVersion();
435
437 {
438 m_lineCount = 0;
439
440 m_progressReporter->Report( wxString::Format( _( "Loading %s..." ), aFileName ) );
441
443 THROW_IO_ERROR( _( "Open cancelled by user." ) );
444
445 while( reader.ReadLine() )
446 m_lineCount++;
447
448 reader.Rewind();
449 }
450
451 loadAllSections( bool( aAppendToMe ) );
452
453 ignore_unused( boardDeleter.release() ); // give it up so we dont delete it on exit
454 m_progressReporter = nullptr;
455 return m_board;
456}
void SetFileName(const wxString &aFileName)
Definition: board.h:300
A LINE_READER that reads from an open file.
Definition: richio.h:173
void loadAllSections(bool doAppend)
virtual void Report(const wxString &aMessage)=0
Display aMessage in the progress bar dialog.
void ignore_unused(const T &)
Definition: ignore.h:24

References _, checkVersion(), Format(), ignore_unused(), init(), PROGRESS_REPORTER::KeepRefreshing(), loadAllSections(), m_board, m_lineCount, m_progressReporter, m_reader, FILE_LINE_READER::ReadLine(), PROGRESS_REPORTER::Report(), FILE_LINE_READER::Rewind(), BOARD::SetFileName(), and THROW_IO_ERROR.

◆ load3D()

void LEGACY_PLUGIN::load3D ( FOOTPRINT aFootprint)
protected

Definition at line 1752 of file legacy_plugin.cpp.

1753{
1754 FP_3DMODEL t3D;
1755
1756 char* line;
1757
1758 while( ( line = READLINE( m_reader ) ) != nullptr )
1759 {
1760 if( TESTLINE( "Na" ) ) // Shape File Name
1761 {
1762 char buf[512];
1763 ReadDelimitedText( buf, line + SZ( "Na" ), sizeof(buf) );
1764 t3D.m_Filename = buf;
1765 }
1766 else if( TESTLINE( "Sc" ) ) // Scale
1767 {
1768 sscanf( line + SZ( "Sc" ), "%lf %lf %lf\n", &t3D.m_Scale.x, &t3D.m_Scale.y,
1769 &t3D.m_Scale.z );
1770 }
1771 else if( TESTLINE( "Of" ) ) // Offset
1772 {
1773 sscanf( line + SZ( "Of" ), "%lf %lf %lf\n", &t3D.m_Offset.x, &t3D.m_Offset.y,
1774 &t3D.m_Offset.z );
1775 }
1776 else if( TESTLINE( "Ro" ) ) // Rotation
1777 {
1778 sscanf( line + SZ( "Ro" ), "%lf %lf %lf\n", &t3D.m_Rotation.x, &t3D.m_Rotation.y,
1779 &t3D.m_Rotation.z );
1780 }
1781 else if( TESTLINE( "$EndSHAPE3D" ) )
1782 {
1783 aFootprint->Models().push_back( t3D );
1784 return; // preferred exit
1785 }
1786 }
1787
1788 THROW_IO_ERROR( wxT( "Missing '$EndSHAPE3D'" ) );
1789}
std::vector< FP_3DMODEL > & Models()
Definition: footprint.h:184
VECTOR3D m_Offset
3D model offset (mm)
Definition: footprint.h:93
VECTOR3D m_Rotation
3D model rotation (degrees)
Definition: footprint.h:92
VECTOR3D m_Scale
3D model scaling factor (dimensionless)
Definition: footprint.h:91
wxString m_Filename
The 3D shape filename in 3D library.
Definition: footprint.h:95
T y
Definition: vector3.h:62
T z
Definition: vector3.h:63
T x
Definition: vector3.h:61
#define SZ(x)
Get the length of a string constant, at compile time.
#define READLINE(rdr)
int ReadDelimitedText(wxString *aDest, const char *aSource)
Copy bytes from aSource delimited string segment to aDest wxString.

References FP_3DMODEL::m_Filename, FP_3DMODEL::m_Offset, m_reader, FP_3DMODEL::m_Rotation, FP_3DMODEL::m_Scale, FOOTPRINT::Models(), ReadDelimitedText(), READLINE, SZ, TESTLINE, THROW_IO_ERROR, VECTOR3< T >::x, VECTOR3< T >::y, and VECTOR3< T >::z.

Referenced by loadFOOTPRINT().

◆ loadAllSections()

void LEGACY_PLUGIN::loadAllSections ( bool  doAppend)
protected

Definition at line 459 of file legacy_plugin.cpp.

460{
461 // $GENERAL section is first
462
463 // $SHEETDESCR section is next
464
465 // $SETUP section is next
466
467 // Then follows $EQUIPOT and all the rest
468 char* line;
469
470 while( ( line = READLINE( m_reader ) ) != nullptr )
471 {
472 checkpoint();
473
474 // put the more frequent ones at the top, but realize TRACKs are loaded as a group
475
476 if( TESTLINE( "$MODULE" ) )
477 {
478 std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>( m_board );
479
480 LIB_ID fpid;
481 std::string fpName = StrPurge( line + SZ( "$MODULE" ) );
482
483 // The footprint names in legacy libraries can contain the '/' and ':'
484 // characters which will cause the FPID parser to choke.
486
487 if( !fpName.empty() )
488 fpid.Parse( fpName, true );
489
490 footprint->SetFPID( fpid );
491
492 loadFOOTPRINT( footprint.get());
493 m_board->Add( footprint.release(), ADD_MODE::APPEND );
494 }
495 else if( TESTLINE( "$DRAWSEGMENT" ) )
496 {
497 loadPCB_LINE();
498 }
499 else if( TESTLINE( "$EQUIPOT" ) )
500 {
502 }
503 else if( TESTLINE( "$TEXTPCB" ) )
504 {
505 loadPCB_TEXT();
506 }
507 else if( TESTLINE( "$TRACK" ) )
508 {
510 }
511 else if( TESTLINE( "$NCLASS" ) )
512 {
513 loadNETCLASS();
514 }
515 else if( TESTLINE( "$CZONE_OUTLINE" ) )
516 {
518 }
519 else if( TESTLINE( "$COTATION" ) )
520 {
522 }
523 else if( TESTLINE( "$PCB_TARGET" ) || TESTLINE( "$MIREPCB" ) )
524 {
526 }
527 else if( TESTLINE( "$ZONE" ) )
528 {
529 // No longer supported; discard segment fills
531 }
532 else if( TESTLINE( "$GENERAL" ) )
533 {
534 loadGENERAL();
535 }
536 else if( TESTLINE( "$SHEETDESCR" ) )
537 {
538 loadSHEET();
539 }
540 else if( TESTLINE( "$SETUP" ) )
541 {
542 if( !doAppend )
543 {
544 loadSETUP();
545 }
546 else
547 {
548 while( ( line = READLINE( m_reader ) ) != nullptr )
549 {
550 // gobble until $EndSetup
551 if( TESTLINE( "$EndSETUP" ) )
552 break;
553 }
554 }
555 }
556 else if( TESTLINE( "$EndBOARD" ) )
557 {
558 return; // preferred exit
559 }
560 }
561
562 THROW_IO_ERROR( wxT( "Missing '$EndBOARD'" ) );
563}
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition: board.cpp:711
void loadTrackList(int aStructType)
Read a list of segments (Tracks and Vias, or Segzones)
void loadFOOTPRINT(FOOTPRINT *aFootprint)
void checkpoint()
Converts net code using the mapping table if available, otherwise returns unchanged net code.
void loadZONE_CONTAINER()
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:49
int Parse(const UTF8 &aId, bool aFix=false)
Parse LIB_ID with the information from aId.
Definition: lib_id.cpp:50
bool ReplaceIllegalFileNameChars(std::string *aName, int aReplaceChar)
Checks aName for illegal file name characters.
char * StrPurge(char *text)
Remove leading and training spaces, tabs and end of line chars in text.
@ NOT_USED
the 3d code uses this value
Definition: typeinfo.h:79
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:101

References BOARD::Add(), APPEND, checkpoint(), loadDIMENSION(), loadFOOTPRINT(), loadGENERAL(), loadNETCLASS(), loadNETINFO_ITEM(), loadPCB_LINE(), loadPCB_TARGET(), loadPCB_TEXT(), loadSETUP(), loadSHEET(), loadTrackList(), loadZONE_CONTAINER(), m_board, m_reader, NOT_USED, LIB_ID::Parse(), PCB_TRACE_T, READLINE, ReplaceIllegalFileNameChars(), StrPurge(), SZ, TESTLINE, and THROW_IO_ERROR.

Referenced by Load().

◆ loadDIMENSION()

void LEGACY_PLUGIN::loadDIMENSION ( )
protected

Definition at line 2617 of file legacy_plugin.cpp.

2618{
2619 std::unique_ptr<PCB_DIM_ALIGNED> dim = std::make_unique<PCB_DIM_ALIGNED>( m_board,
2621 VECTOR2I crossBarO;
2622 VECTOR2I crossBarF;
2623
2624 char* line;
2625
2626 while( ( line = READLINE( m_reader ) ) != nullptr )
2627 {
2628 const char* data;
2629
2630 if( TESTLINE( "$endCOTATION" ) )
2631 {
2632 dim->UpdateHeight( crossBarF, crossBarO );
2633
2634 m_board->Add( dim.release(), ADD_MODE::APPEND );
2635 return; // preferred exit
2636 }
2637 else if( TESTLINE( "Va" ) )
2638 {
2639 BIU value = biuParse( line + SZ( "Va" ) );
2640
2641 // unused; dimension value is calculated from coordinates
2642 ( void )value;
2643 }
2644 else if( TESTLINE( "Ge" ) )
2645 {
2646 // e.g. "Ge 1 21 68183921-93a5-49ac-91b0-49d05a0e1647\r\n"
2647 int shape = intParse( line + SZ( "De" ), (const char**) &data );
2648 int layer_num = intParse( data, &data );
2649 char* uuid = strtok_r( (char*) data, delims, (char**) &data );
2650
2651 dim->SetLayer( leg_layer2new( m_cu_count, layer_num ) );
2652 const_cast<KIID&>( dim->m_Uuid ) = KIID( uuid );
2653
2654 // not used
2655 ( void )shape;
2656 }
2657 else if( TESTLINE( "Te" ) )
2658 {
2659 char buf[2048];
2660
2661 ReadDelimitedText( buf, line + SZ( "Te" ), sizeof(buf) );
2662 dim->SetOverrideText( FROM_UTF8( buf ) );
2663 dim->SetOverrideTextEnabled( true );
2664 dim->SetUnitsFormat( DIM_UNITS_FORMAT::NO_SUFFIX );
2665 dim->SetAutoUnits();
2666 }
2667 else if( TESTLINE( "Po" ) )
2668 {
2669 BIU pos_x = biuParse( line + SZ( "Po" ), &data );
2670 BIU pos_y = biuParse( data, &data );
2671 BIU width = biuParse( data, &data );
2672 BIU height = biuParse( data, &data );
2673 BIU thickn = biuParse( data, &data );
2674 EDA_ANGLE orient = degParse( data, &data );
2675 char* mirror = strtok_r( (char*) data, delims, (char**) &data );
2676
2677 dim->Text().SetTextPos( VECTOR2I( pos_x, pos_y ) );
2678 dim->Text().SetTextSize( wxSize( width, height ) );
2679 dim->Text().SetMirrored( mirror && *mirror == '0' );
2680 dim->Text().SetTextThickness( thickn );
2681 dim->Text().SetTextAngle( orient );
2682 }
2683 else if( TESTLINE( "Sb" ) )
2684 {
2685 ignore_unused( biuParse( line + SZ( "Sb" ), &data ) );
2686 BIU crossBarOx = biuParse( data, &data );
2687 BIU crossBarOy = biuParse( data, &data );
2688 BIU crossBarFx = biuParse( data, &data );
2689 BIU crossBarFy = biuParse( data, &data );
2690 BIU width = biuParse( data );
2691
2692 dim->SetLineThickness( width );
2693 crossBarO = VECTOR2I( crossBarOx, crossBarOy );
2694 crossBarF = VECTOR2I( crossBarFx, crossBarFy );
2695 }
2696 else if( TESTLINE( "Sd" ) )
2697 {
2698 ignore_unused( intParse( line + SZ( "Sd" ), &data ) );
2699 BIU featureLineDOx = biuParse( data, &data );
2700 BIU featureLineDOy = biuParse( data, &data );
2701
2702 ignore_unused( biuParse( data, &data ) );
2703 ignore_unused( biuParse( data ) );
2704
2705 dim->SetStart( VECTOR2I( featureLineDOx, featureLineDOy ) );
2706 }
2707 else if( TESTLINE( "Sg" ) )
2708 {
2709 ignore_unused( intParse( line + SZ( "Sg" ), &data ) );
2710 BIU featureLineGOx = biuParse( data, &data );
2711 BIU featureLineGOy = biuParse( data, &data );
2712
2713 ignore_unused( biuParse( data, &data ) );
2714 ignore_unused( biuParse( data ) );
2715
2716 dim->SetEnd( VECTOR2I( featureLineGOx, featureLineGOy ) );
2717 }
2718 else if( TESTLINE( "S1" ) ) // Arrow: no longer imported
2719 {
2720 ignore_unused( intParse( line + SZ( "S1" ), &data ) );
2721 biuParse( data, &data ); // skipping excessive data
2722 biuParse( data, &data ); // skipping excessive data
2723 biuParse( data, &data );
2724 biuParse( data );
2725 }
2726 else if( TESTLINE( "S2" ) ) // Arrow: no longer imported
2727 {
2728 ignore_unused( intParse( line + SZ( "S2" ), &data ) );
2729 biuParse( data, &data ); // skipping excessive data
2730 biuParse( data, &data ); // skipping excessive data
2731 biuParse( data, &data );
2732 biuParse( data, &data );
2733 }
2734 else if( TESTLINE( "S3" ) ) // Arrow: no longer imported
2735 {
2736 ignore_unused( intParse( line + SZ( "S3" ), &data ) );
2737 biuParse( data, &data ); // skipping excessive data
2738 biuParse( data, &data ); // skipping excessive data
2739 biuParse( data, &data );
2740 biuParse( data, &data );
2741 }
2742 else if( TESTLINE( "S4" ) ) // Arrow: no longer imported
2743 {
2744 ignore_unused( intParse( line + SZ( "S4" ), &data ) );
2745 biuParse( data, &data ); // skipping excessive data
2746 biuParse( data, &data ); // skipping excessive data
2747 biuParse( data, &data );
2748 biuParse( data, &data );
2749 }
2750 }
2751
2752 THROW_IO_ERROR( wxT( "Missing '$endCOTATION'" ) );
2753}
Definition: kiid.h:48
BIU biuParse(const char *aValue, const char **nptrptr=nullptr)
Parse an ASCII decimal floating point value and scales it into a BIU according to the current value o...
EDA_ANGLE degParse(const char *aValue, const char **nptrptr=nullptr)
Parse an ASCII decimal floating point value which is certainly an angle in tenths of a degree.
static int intParse(const char *next, const char **out=nullptr)
Parse an ASCII integer string with possible leading whitespace into an integer and updates the pointe...
static const char delims[]
LEGACY_PLUGIN::BIU BIU
char * strtok_r(char *str, const char *delim, char **nextp)
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
Definition: typeinfo.h:106
VECTOR2< int > VECTOR2I
Definition: vector2d.h:618

References BOARD::Add(), APPEND, biuParse(), degParse(), delims, FROM_UTF8(), ignore_unused(), intParse(), leg_layer2new(), m_board, m_cu_count, m_reader, NO_SUFFIX, PCB_DIM_ALIGNED_T, ReadDelimitedText(), READLINE, strtok_r(), SZ, TESTLINE, and THROW_IO_ERROR.

Referenced by loadAllSections().

◆ loadFOOTPRINT()

void LEGACY_PLUGIN::loadFOOTPRINT ( FOOTPRINT aFootprint)
protected

Definition at line 1128 of file legacy_plugin.cpp.

1129{
1130 char* line;
1131
1132 while( ( line = READLINE( m_reader ) ) != nullptr )
1133 {
1134 const char* data;
1135
1136 // most frequently encountered ones at the top
1137
1138 if( TESTSUBSTR( "D" ) && strchr( "SCAP", line[1] ) ) // read a drawing item, e.g. "DS"
1139 {
1140 loadFP_SHAPE( aFootprint );
1141 }
1142 else if( TESTLINE( "$PAD" ) )
1143 {
1144 loadPAD( aFootprint );
1145 }
1146 else if( TESTSUBSTR( "T" ) ) // Read a footprint text description (ref, value, or drawing)
1147 {
1148 // e.g. "T1 6940 -16220 350 300 900 60 M I 20 N "CFCARD"\r\n"
1149 int tnum = intParse( line + SZ( "T" ) );
1150
1151 FP_TEXT* text = nullptr;
1152
1153 switch( tnum )
1154 {
1156 text = &aFootprint->Reference();
1157 break;
1158
1160 text = &aFootprint->Value();
1161 break;
1162
1163 // All other fields greater than 1.
1164 default:
1165 text = new FP_TEXT( aFootprint );
1166 aFootprint->Add( text );
1167 }
1168
1170 }
1171 else if( TESTLINE( "Po" ) )
1172 {
1173 // e.g. "Po 19120 39260 900 0 4E823D06 68183921-93a5-49ac-91b0-49d05a0e1647 ~~\r\n"
1174 BIU pos_x = biuParse( line + SZ( "Po" ), &data );
1175 BIU pos_y = biuParse( data, &data );
1176 int orient = intParse( data, &data );
1177 int layer_num = intParse( data, &data );
1178 PCB_LAYER_ID layer_id = leg_layer2new( m_cu_count, layer_num );
1179
1180 [[maybe_unused]] long edittime = hexParse( data, &data );
1181
1182 char* uuid = strtok_r( (char*) data, delims, (char**) &data );
1183
1184 data = strtok_r( (char*) data+1, delims, (char**) &data );
1185
1186 // data is now a two character long string
1187 // Note: some old files do not have this field
1188 if( data && data[0] == 'F' )
1189 aFootprint->SetLocked( true );
1190
1191 if( data && data[1] == 'P' )
1192 aFootprint->SetIsPlaced( true );
1193
1194 aFootprint->SetPosition( VECTOR2I( pos_x, pos_y ) );
1195 aFootprint->SetLayer( layer_id );
1196 aFootprint->SetOrientation( EDA_ANGLE( orient, TENTHS_OF_A_DEGREE_T ) );
1197 const_cast<KIID&>( aFootprint->m_Uuid ) = KIID( uuid );
1198 }
1199 else if( TESTLINE( "Sc" ) ) // timestamp
1200 {
1201 char* uuid = strtok_r( (char*) line + SZ( "Sc" ), delims, (char**) &data );
1202 const_cast<KIID&>( aFootprint->m_Uuid ) = KIID( uuid );
1203 }
1204 else if( TESTLINE( "Op" ) ) // (Op)tions for auto placement (no longer supported)
1205 {
1206 hexParse( line + SZ( "Op" ), &data );
1207 hexParse( data );
1208 }
1209 else if( TESTLINE( "At" ) ) // (At)tributes of footprint
1210 {
1211 int attrs = 0;
1212
1213 data = line + SZ( "At" );
1214
1215 if( strstr( data, "SMD" ) )
1216 attrs |= FP_SMD;
1217 else if( strstr( data, "VIRTUAL" ) )
1219 else
1221
1222 aFootprint->SetAttributes( attrs );
1223 }
1224 else if( TESTLINE( "AR" ) ) // Alternate Reference
1225 {
1226 // e.g. "AR /68183921-93a5-49ac-e164-49d05a0e1647/93a549d0-49d0-e164-91b0-49d05a0e1647"
1227 data = strtok_r( line + SZ( "AR" ), delims, (char**) &data );
1228
1229 if( data )
1230 aFootprint->SetPath( KIID_PATH( FROM_UTF8( data ) ) );
1231 }
1232 else if( TESTLINE( "$SHAPE3D" ) )
1233 {
1234 load3D( aFootprint );
1235 }
1236 else if( TESTLINE( "Cd" ) )
1237 {
1238 // e.g. "Cd Double rangee de contacts 2 x 4 pins\r\n"
1239 aFootprint->SetDescription( FROM_UTF8( StrPurge( line + SZ( "Cd" ) ) ) );
1240 }
1241 else if( TESTLINE( "Kw" ) ) // Key words
1242 {
1243 aFootprint->SetKeywords( FROM_UTF8( StrPurge( line + SZ( "Kw" ) ) ) );
1244 }
1245 else if( TESTLINE( ".SolderPasteRatio" ) )
1246 {
1247 double tmp = atof( line + SZ( ".SolderPasteRatio" ) );
1248
1249 // Due to a bug in dialog editor in Footprint Editor, fixed in BZR version 3565
1250 // this parameter can be broken.
1251 // It should be >= -50% (no solder paste) and <= 0% (full area of the pad)
1252
1253 if( tmp < -0.50 )
1254 tmp = -0.50;
1255
1256 if( tmp > 0.0 )
1257 tmp = 0.0;
1258
1259 aFootprint->SetLocalSolderPasteMarginRatio( tmp );
1260 }
1261 else if( TESTLINE( ".SolderPaste" ) )
1262 {
1263 BIU tmp = biuParse( line + SZ( ".SolderPaste" ) );
1264 aFootprint->SetLocalSolderPasteMargin( tmp );
1265 }
1266 else if( TESTLINE( ".SolderMask" ) )
1267 {
1268 BIU tmp = biuParse( line + SZ( ".SolderMask" ) );
1269 aFootprint->SetLocalSolderMaskMargin( tmp );
1270 }
1271 else if( TESTLINE( ".LocalClearance" ) )
1272 {
1273 BIU tmp = biuParse( line + SZ( ".LocalClearance" ) );
1274 aFootprint->SetLocalClearance( tmp );
1275 }
1276 else if( TESTLINE( ".ZoneConnection" ) )
1277 {
1278 int tmp = intParse( line + SZ( ".ZoneConnection" ) );
1279 aFootprint->SetZoneConnection((ZONE_CONNECTION) tmp );
1280 }
1281 else if( TESTLINE( ".ThermalWidth" ) )
1282 {
1283 BIU tmp = biuParse( line + SZ( ".ThermalWidth" ) );
1284 ignore_unused( tmp );
1285 }
1286 else if( TESTLINE( ".ThermalGap" ) )
1287 {
1288 BIU tmp = biuParse( line + SZ( ".ThermalGap" ) );
1289 ignore_unused( tmp );
1290 }
1291 else if( TESTLINE( "$EndMODULE" ) )
1292 {
1293 return; // preferred exit
1294 }
1295 }
1296
1297 wxString msg = wxString::Format( _( "Missing '$EndMODULE' for MODULE '%s'." ),
1298 aFootprint->GetFPID().GetLibItemName().wx_str() );
1299 THROW_IO_ERROR( msg );
1300}
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:214
const KIID m_Uuid
Definition: eda_item.h:494
void SetPosition(const VECTOR2I &aPos) override
Definition: footprint.cpp:1658
void SetLocked(bool isLocked) override
Set the #MODULE_is_LOCKED bit in the m_ModuleStatus.
Definition: footprint.h:350
void SetIsPlaced(bool isPlaced)
Definition: footprint.h:364
void SetOrientation(const EDA_ANGLE &aNewAngle)
Definition: footprint.cpp:1790
void SetDescription(const wxString &aDoc)
Definition: footprint.h:219
void SetPath(const KIID_PATH &aPath)
Definition: footprint.h:225
void SetKeywords(const wxString &aKeywords)
Definition: footprint.h:222
void SetAttributes(int aAttributes)
Definition: footprint.h:251
void SetLocalSolderPasteMarginRatio(double aRatio)
Definition: footprint.h:245
void SetLocalSolderPasteMargin(int aMargin)
Definition: footprint.h:242
void SetLocalClearance(int aClearance)
Definition: footprint.h:231
const LIB_ID & GetFPID() const
Definition: footprint.h:212
void SetLocalSolderMaskMargin(int aMargin)
Definition: footprint.h:228
FP_TEXT & Value()
read/write accessors:
Definition: footprint.h:567
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition: footprint.cpp:561
void SetZoneConnection(ZONE_CONNECTION aType)
Definition: footprint.h:247
FP_TEXT & Reference()
Definition: footprint.h:568
@ TEXT_is_REFERENCE
Definition: fp_text.h:49
@ TEXT_is_VALUE
Definition: fp_text.h:50
void loadFP_SHAPE(FOOTPRINT *aFootprint)
void loadPAD(FOOTPRINT *aFootprint)
void load3D(FOOTPRINT *aFootprint)
void loadMODULE_TEXT(FP_TEXT *aText)
const UTF8 & GetLibItemName() const
Definition: lib_id.h:101
wxString wx_str() const
Definition: utf8.cpp:46
@ FP_SMD
Definition: footprint.h:69
@ FP_EXCLUDE_FROM_POS_FILES
Definition: footprint.h:70
@ FP_EXCLUDE_FROM_BOM
Definition: footprint.h:71
@ FP_THROUGH_HOLE
Definition: footprint.h:68
#define TESTSUBSTR(x)
C sub-string compare test for a specific length of characters.
static long hexParse(const char *next, const char **out=nullptr)
Parse an ASCII hex integer string with possible leading whitespace into a long integer and updates th...
ZONE_CONNECTION
How pads are covered by copper in zone.
Definition: zones.h:50

References _, FOOTPRINT::Add(), biuParse(), delims, Format(), FP_EXCLUDE_FROM_BOM, FP_EXCLUDE_FROM_POS_FILES, FP_SMD, FP_THROUGH_HOLE, FROM_UTF8(), FOOTPRINT::GetFPID(), LIB_ID::GetLibItemName(), hexParse(), ignore_unused(), intParse(), leg_layer2new(), load3D(), loadFP_SHAPE(), loadMODULE_TEXT(), loadPAD(), m_cu_count, m_reader, EDA_ITEM::m_Uuid, READLINE, FOOTPRINT::Reference(), FOOTPRINT::SetAttributes(), FOOTPRINT::SetDescription(), FOOTPRINT::SetIsPlaced(), FOOTPRINT::SetKeywords(), BOARD_ITEM::SetLayer(), FOOTPRINT::SetLocalClearance(), FOOTPRINT::SetLocalSolderMaskMargin(), FOOTPRINT::SetLocalSolderPasteMargin(), FOOTPRINT::SetLocalSolderPasteMarginRatio(), FOOTPRINT::SetLocked(), FOOTPRINT::SetOrientation(), FOOTPRINT::SetPath(), FOOTPRINT::SetPosition(), FOOTPRINT::SetZoneConnection(), StrPurge(), strtok_r(), SZ, TENTHS_OF_A_DEGREE_T, TESTLINE, TESTSUBSTR, text, FP_TEXT::TEXT_is_REFERENCE, FP_TEXT::TEXT_is_VALUE, THROW_IO_ERROR, FOOTPRINT::Value(), and UTF8::wx_str().

Referenced by loadAllSections(), and LP_CACHE::LoadModules().

◆ loadFP_SHAPE()

void LEGACY_PLUGIN::loadFP_SHAPE ( FOOTPRINT aFootprint)
protected

Definition at line 1534 of file legacy_plugin.cpp.

1535{
1536 SHAPE_T shape;
1537 char* line = m_reader->Line(); // obtain current (old) line
1538
1539 switch( line[1] )
1540 {
1541 case 'S': shape = SHAPE_T::SEGMENT; break;
1542 case 'C': shape = SHAPE_T::CIRCLE; break;
1543 case 'A': shape = SHAPE_T::ARC; break;
1544 case 'P': shape = SHAPE_T::POLY; break;
1545 default:
1546 m_error.Printf( _( "Unknown FP_SHAPE type:'%c=0x%02x' on line %d of footprint '%s'." ),
1547 (unsigned char) line[1], (unsigned char) line[1], m_reader->LineNumber(),
1548 aFootprint->GetFPID().GetLibItemName().wx_str() );
1550 }
1551
1552 std::unique_ptr<FP_SHAPE> dwg = std::make_unique<FP_SHAPE>( aFootprint, shape ); // a drawing
1553
1554 const char* data;
1555
1556 // common to all cases, and we have to check their values uniformly at end
1557 BIU width = 1;
1558 int layer = FIRST_NON_COPPER_LAYER;
1559
1560 switch( shape )
1561 {
1562 case SHAPE_T::ARC:
1563 {
1564 BIU center0_x = biuParse( line + SZ( "DA" ), &data );
1565 BIU center0_y = biuParse( data, &data );
1566 BIU start0_x = biuParse( data, &data );
1567 BIU start0_y = biuParse( data, &data );
1568 EDA_ANGLE angle = degParse( data, &data );
1569
1570 width = biuParse( data, &data );
1571 layer = intParse( data );
1572
1573 dwg->SetCenter0( VECTOR2I( center0_x, center0_y ) );
1574 dwg->SetStart0( VECTOR2I( start0_x, start0_y ) );
1575 dwg->SetArcAngleAndEnd0( angle, true );
1576 break;
1577 }
1578
1579 case SHAPE_T::SEGMENT:
1580 case SHAPE_T::CIRCLE:
1581 {
1582 // e.g. "DS -7874 -10630 7874 -10630 50 20\r\n"
1583 BIU start0_x = biuParse( line + SZ( "DS" ), &data );
1584 BIU start0_y = biuParse( data, &data );
1585 BIU end0_x = biuParse( data, &data );
1586 BIU end0_y = biuParse( data, &data );
1587
1588 width = biuParse( data, &data );
1589 layer = intParse( data );
1590
1591 dwg->SetStart0( VECTOR2I( start0_x, start0_y ) );
1592 dwg->SetEnd0( VECTOR2I( end0_x, end0_y ) );
1593 break;
1594 }
1595
1596 case SHAPE_T::POLY:
1597 {
1598 // e.g. "DP %d %d %d %d %d %d %d\n"
1599 BIU start0_x = biuParse( line + SZ( "DP" ), &data );
1600 BIU start0_y = biuParse( data, &data );
1601 BIU end0_x = biuParse( data, &data );
1602 BIU end0_y = biuParse( data, &data );
1603 int ptCount = intParse( data, &data );
1604
1605 width = biuParse( data, &data );
1606 layer = intParse( data );
1607
1608 dwg->SetStart0( VECTOR2I( start0_x, start0_y ) );
1609 dwg->SetEnd0( VECTOR2I( end0_x, end0_y ) );
1610
1611 std::vector<VECTOR2I> pts;
1612 pts.reserve( ptCount );
1613
1614 for( int ii = 0; ii < ptCount; ++ii )
1615 {
1616 if( ( line = READLINE( m_reader ) ) == nullptr )
1617 {
1618 THROW_IO_ERROR( wxT( "S_POLGON point count mismatch." ) );
1619 }
1620
1621 // e.g. "Dl 23 44\n"
1622
1623 if( !TESTLINE( "Dl" ) )
1624 {
1625 THROW_IO_ERROR( wxT( "Missing Dl point def" ) );
1626 }
1627
1628 BIU x = biuParse( line + SZ( "Dl" ), &data );
1629 BIU y = biuParse( data );
1630
1631 pts.emplace_back( x, y );
1632 }
1633
1634 dwg->SetPolyPoints( pts );
1635 break;
1636 }
1637
1638 default:
1639 // first switch code above prevents us from getting here.
1640 break;
1641 }
1642
1643 // Check for a reasonable layer:
1644 // layer must be >= FIRST_NON_COPPER_LAYER, but because microwave footprints can use the
1645 // copper layers, layer < FIRST_NON_COPPER_LAYER is allowed.
1646 if( layer < FIRST_LAYER || layer > LAST_NON_COPPER_LAYER )
1647 layer = SILKSCREEN_N_FRONT;
1648
1649 dwg->SetStroke( STROKE_PARAMS( width, PLOT_DASH_TYPE::SOLID ) );
1650 dwg->SetLayer( leg_layer2new( m_cu_count, layer ) );
1651
1652 FP_SHAPE* fpShape = dwg.release();
1653
1654 aFootprint->Add( fpShape );
1655
1656 // this had been done at the FOOTPRINT level before, presumably because the FP_SHAPE needs
1657 // to be already added to a footprint before this function will work.
1658 fpShape->SetDrawCoord();
1659}
virtual void SetDrawCoord()
Set draw coordinates (absolute values ) from relative coordinates.
Definition: fp_shape.cpp:80
Simple container to manage line stroke parameters.
Definition: stroke_params.h:88
SHAPE_T
Definition: eda_shape.h:41
#define LAST_NON_COPPER_LAYER
#define FIRST_NON_COPPER_LAYER
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)

References _, FOOTPRINT::Add(), PNS::angle(), ARC, biuParse(), CIRCLE, degParse(), FIRST_NON_COPPER_LAYER, FOOTPRINT::GetFPID(), LIB_ID::GetLibItemName(), intParse(), LAST_NON_COPPER_LAYER, leg_layer2new(), LINE_READER::Line(), LINE_READER::LineNumber(), m_cu_count, m_error, m_reader, POLY, READLINE, SEGMENT, FP_SHAPE::SetDrawCoord(), SILKSCREEN_N_FRONT, SOLID, SZ, TESTLINE, THROW_IO_ERROR, and UTF8::wx_str().

Referenced by loadFOOTPRINT().

◆ loadGENERAL()

void LEGACY_PLUGIN::loadGENERAL ( )
protected

Definition at line 598 of file legacy_plugin.cpp.

599{
600 char* line;
601 char* saveptr;
602 bool saw_LayerCount = false;
603
604 while( ( line = READLINE( m_reader ) ) != nullptr )
605 {
606 const char* data;
607
608 if( TESTLINE( "Units" ) )
609 {
610 // what are the engineering units of the lengths in the BOARD?
611 data = strtok_r( line + SZ("Units"), delims, &saveptr );
612
613 if( !strcmp( data, "mm" ) )
614 {
616 }
617 }
618 else if( TESTLINE( "LayerCount" ) )
619 {
620 int tmp = intParse( line + SZ( "LayerCount" ) );
621
623
624 // This has to be set early so that leg_layer2new() works OK, and
625 // that means before parsing "EnabledLayers" and "VisibleLayers".
626 m_cu_count = tmp;
627
628 saw_LayerCount = true;
629 }
630 else if( TESTLINE( "EnabledLayers" ) )
631 {
632 if( !saw_LayerCount )
633 THROW_IO_ERROR( wxT( "Missing '$GENERAL's LayerCount" ) );
634
635 LEG_MASK enabledLayers = hexParse( line + SZ( "EnabledLayers" ) );
636 LSET new_mask = leg_mask2new( m_cu_count, enabledLayers );
637
638 m_board->SetEnabledLayers( new_mask );
639
640 // layer visibility equals layer usage, unless overridden later via "VisibleLayers"
641 // Must call SetEnabledLayers() before calling SetVisibleLayers().
642 m_board->SetVisibleLayers( new_mask );
643
644 // Ensure copper layers count is not modified:
646 }
647 else if( TESTLINE( "VisibleLayers" ) )
648 {
649 // Keep all enabled layers visible.
650 // the old visibility control does not make sense in current Pcbnew version
651 // However, this code works.
652 #if 0
653 if( !saw_LayerCount )
654 THROW_IO_ERROR( wxT( "Missing '$GENERAL's LayerCount" ) );
655
656 LEG_MASK visibleLayers = hexParse( line + SZ( "VisibleLayers" ) );
657
658 LSET new_mask = leg_mask2new( m_cu_count, visibleLayers );
659
660 m_board->SetVisibleLayers( new_mask );
661 #endif
662 }
663 else if( TESTLINE( "Ly" ) ) // Old format for Layer count
664 {
665 if( !saw_LayerCount )
666 {
667 LEG_MASK layer_mask = hexParse( line + SZ( "Ly" ) );
668
671
672 saw_LayerCount = true;
673 }
674 }
675 else if( TESTLINE( "BoardThickness" ) )
676 {
677 BIU thickn = biuParse( line + SZ( "BoardThickness" ) );
679 }
680 else if( TESTLINE( "NoConn" ) )
681 {
682 // ignore
683 intParse( line + SZ( "NoConn" ) );
684 }
685 else if( TESTLINE( "Di" ) )
686 {
687 biuParse( line + SZ( "Di" ), &data );
688 biuParse( data, &data );
689 biuParse( data, &data );
690 biuParse( data );
691 }
692 else if( TESTLINE( "Nnets" ) )
693 {
694 m_netCodes.resize( intParse( line + SZ( "Nnets" ) ) );
695 }
696 else if( TESTLINE( "Nn" ) ) // id "Nnets" for old .brd files
697 {
698 m_netCodes.resize( intParse( line + SZ( "Nn" ) ) );
699 }
700 else if( TESTLINE( "$EndGENERAL" ) )
701 {
702 return; // preferred exit
703 }
704 }
705
706 THROW_IO_ERROR( wxT( "Missing '$EndGENERAL'" ) );
707}
void SetBoardThickness(int aThickness)
void SetEnabledLayers(LSET aLayerMask)
A proxy function that calls the correspondent function in m_BoardSettings.
Definition: board.cpp:546
void SetVisibleLayers(LSET aLayerMask)
A proxy function that calls the correspondent function in m_BoardSettings changes the bit-mask of vis...
Definition: board.cpp:558
void SetCopperLayerCount(int aCount)
Definition: board.cpp:508
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:643
static LSET leg_mask2new(int cu_count, unsigned aMask)
unsigned LEG_MASK
int layerMaskCountSet(LEG_MASK aMask)
Count the number of set layers in the mask.

References ALL_CU_LAYERS, biuParse(), delims, diskToBiu, BOARD::GetDesignSettings(), hexParse(), intParse(), EDA_IU_SCALE::IU_PER_MM, layerMaskCountSet(), leg_mask2new(), m_board, m_cu_count, m_netCodes, m_reader, pcbIUScale, READLINE, BOARD_DESIGN_SETTINGS::SetBoardThickness(), BOARD::SetCopperLayerCount(), BOARD::SetEnabledLayers(), BOARD::SetVisibleLayers(), strtok_r(), SZ, TESTLINE, and THROW_IO_ERROR.

Referenced by loadAllSections().

◆ loadMODULE_TEXT()

void LEGACY_PLUGIN::loadMODULE_TEXT ( FP_TEXT aText)
protected

Definition at line 1662 of file legacy_plugin.cpp.

1663{
1664 const char* data;
1665 const char* txt_end;
1666 const char* line = m_reader->Line(); // current (old) line
1667
1668 // e.g. "T1 6940 -16220 350 300 900 60 M I 20 N "CFCARD"\r\n"
1669 // or T1 0 500 600 400 900 80 M V 20 N"74LS245"
1670 // ouch, the last example has no space between N and "74LS245" !
1671 // that is an older version.
1672
1673 int type = intParse( line+1, &data );
1674 BIU pos0_x = biuParse( data, &data );
1675 BIU pos0_y = biuParse( data, &data );
1676 BIU size0_y = biuParse( data, &data );
1677 BIU size0_x = biuParse( data, &data );
1678 EDA_ANGLE orient = degParse( data, &data );
1679 BIU thickn = biuParse( data, &data );
1680
1681 // read the quoted text before the first call to strtok() which introduces
1682 // NULs into the string and chops it into multiple C strings, something
1683 // ReadDelimitedText() cannot traverse.
1684
1685 // convert the "quoted, escaped, UTF8, text" to a wxString, find it by skipping
1686 // as far forward as needed until the first double quote.
1687 txt_end = data + ReadDelimitedText( &m_field, data );
1688 m_field.Replace( wxT( "%V" ), wxT( "${VALUE}" ) );
1689 m_field.Replace( wxT( "%R" ), wxT( "${REFERENCE}" ) );
1691 aText->SetText( m_field );
1692
1693 // after switching to strtok, there's no easy coming back because of the
1694 // embedded nul(s?) placed to the right of the current field.
1695 // (that's the reason why strtok was deprecated...)
1696 char* mirror = strtok_r( (char*) data, delims, (char**) &data );
1697 char* hide = strtok_r( nullptr, delims, (char**) &data );
1698 char* tmp = strtok_r( nullptr, delims, (char**) &data );
1699
1700 int layer_num = tmp ? intParse( tmp ) : SILKSCREEN_N_FRONT;
1701
1702 char* italic = strtok_r( nullptr, delims, (char**) &data );
1703
1704 char* hjust = strtok_r( (char*) txt_end, delims, (char**) &data );
1705 char* vjust = strtok_r( nullptr, delims, (char**) &data );
1706
1707 if( type != FP_TEXT::TEXT_is_REFERENCE && type != FP_TEXT::TEXT_is_VALUE )
1709
1710 aText->SetType( static_cast<FP_TEXT::TEXT_TYPE>( type ) );
1711
1712 aText->SetPos0( VECTOR2I( pos0_x, pos0_y ) );
1713 aText->SetTextSize( wxSize( size0_x, size0_y ) );
1714
1715 orient -= ( static_cast<FOOTPRINT*>( aText->GetParentFootprint() ) )->GetOrientation();
1716
1717 aText->SetTextAngle( orient );
1718
1719 aText->SetTextThickness( thickn < 1 ? 0 : thickn );
1720
1721 aText->SetMirrored( mirror && *mirror == 'M' );
1722
1723 aText->SetVisible( !(hide && *hide == 'I') );
1724
1725 aText->SetItalic( italic && *italic == 'I' );
1726
1727 if( hjust )
1728 aText->SetHorizJustify( horizJustify( hjust ) );
1729
1730 if( vjust )
1731 aText->SetVertJustify( vertJustify( vjust ) );
1732
1733 // A protection against mal formed (or edited by hand) files:
1734 if( layer_num < FIRST_LAYER )
1735 layer_num = FIRST_LAYER;
1736 else if( layer_num > LAST_NON_COPPER_LAYER )
1737 layer_num = LAST_NON_COPPER_LAYER;
1738 else if( layer_num == LAYER_N_BACK )
1739 layer_num = SILKSCREEN_N_BACK;
1740 else if( layer_num == LAYER_N_FRONT )
1741 layer_num = SILKSCREEN_N_FRONT;
1742 else if( layer_num < LAYER_N_FRONT ) // this case is a internal layer
1743 layer_num = SILKSCREEN_N_FRONT;
1744
1745 aText->SetLayer( leg_layer2new( m_cu_count, layer_num ) );
1746
1747 // Calculate the actual position.
1748 aText->SetDrawCoord();
1749}
BOARD_ITEM_CONTAINER * GetParentFootprint() const
Definition: board_item.cpp:239
void SetMirrored(bool isMirrored)
Definition: eda_text.cpp:224
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
Definition: eda_text.cpp:248
virtual void SetVisible(bool aVisible)
Definition: eda_text.cpp:217
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition: eda_text.cpp:185
void SetTextSize(const VECTOR2I &aNewSize)
Definition: eda_text.cpp:347
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:163
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition: eda_text.cpp:193
void SetItalic(bool aItalic)
Definition: eda_text.cpp:201
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition: eda_text.cpp:240
void SetType(TEXT_TYPE aType)
Definition: fp_text.h:119
void SetDrawCoord()
Set relative coordinates.
Definition: fp_text.cpp:203
TEXT_TYPE
Footprint text type: there must be only one (and only one) for each of the reference value texts in o...
Definition: fp_text.h:48
@ TEXT_is_DIVERS
Definition: fp_text.h:51
void SetPos0(const VECTOR2I &aPos)
Definition: fp_text.h:123
wxString m_field
reused to stuff FOOTPRINT fields.
static GR_TEXT_V_ALIGN_T vertJustify(const char *vertical)
static GR_TEXT_H_ALIGN_T horizJustify(const char *horizontal)
#define FIRST_LAYER
wxString ConvertToNewOverbarNotation(const wxString &aOldStr)
Convert the old ~...~ overbar notation to the new ~{...} one.

References biuParse(), ConvertToNewOverbarNotation(), degParse(), delims, FIRST_LAYER, BOARD_ITEM::GetParentFootprint(), horizJustify(), intParse(), LAST_NON_COPPER_LAYER, LAYER_N_BACK, LAYER_N_FRONT, leg_layer2new(), LINE_READER::Line(), m_cu_count, m_field, m_reader, ReadDelimitedText(), FP_TEXT::SetDrawCoord(), EDA_TEXT::SetHorizJustify(), EDA_TEXT::SetItalic(), BOARD_ITEM::SetLayer(), EDA_TEXT::SetMirrored(), FP_TEXT::SetPos0(), EDA_TEXT::SetText(), EDA_TEXT::SetTextAngle(), EDA_TEXT::SetTextSize(), EDA_TEXT::SetTextThickness(), FP_TEXT::SetType(), EDA_TEXT::SetVertJustify(), EDA_TEXT::SetVisible(), SILKSCREEN_N_BACK, SILKSCREEN_N_FRONT, strtok_r(), FP_TEXT::TEXT_is_DIVERS, FP_TEXT::TEXT_is_REFERENCE, FP_TEXT::TEXT_is_VALUE, and vertJustify().

Referenced by loadFOOTPRINT().

◆ loadNETCLASS()

void LEGACY_PLUGIN::loadNETCLASS ( )
protected

Definition at line 2245 of file legacy_plugin.cpp.

2246{
2247 char buf[1024];
2248 wxString netname;
2249 char* line;
2250
2251 // create an empty NETCLASS without a name, but do not add it to the BOARD
2252 // yet since that would bypass duplicate netclass name checking within the BOARD.
2253 // store it temporarily in an unique_ptr until successfully inserted into the BOARD
2254 // just before returning.
2255 std::shared_ptr<NETCLASS> nc = std::make_shared<NETCLASS>( wxEmptyString );
2256
2257 while( ( line = READLINE( m_reader ) ) != nullptr )
2258 {
2259 if( TESTLINE( "AddNet" ) ) // most frequent type of line
2260 {
2261 // e.g. "AddNet "V3.3D"\n"
2262 ReadDelimitedText( buf, line + SZ( "AddNet" ), sizeof(buf) );
2263 netname = ConvertToNewOverbarNotation( FROM_UTF8( buf ) );
2264
2265 m_board->GetDesignSettings().m_NetSettings->m_NetClassPatternAssignments.push_back(
2266 {
2267 std::make_unique<EDA_COMBINED_MATCHER>( netname, CTX_NETCLASS ),
2268 nc->GetName()
2269 } );
2270 }
2271 else if( TESTLINE( "Clearance" ) )
2272 {
2273 BIU tmp = biuParse( line + SZ( "Clearance" ) );
2274 nc->SetClearance( tmp );
2275 }
2276 else if( TESTLINE( "TrackWidth" ) )
2277 {
2278 BIU tmp = biuParse( line + SZ( "TrackWidth" ) );
2279 nc->SetTrackWidth( tmp );
2280 }
2281 else if( TESTLINE( "ViaDia" ) )
2282 {
2283 BIU tmp = biuParse( line + SZ( "ViaDia" ) );
2284 nc->SetViaDiameter( tmp );
2285 }
2286 else if( TESTLINE( "ViaDrill" ) )
2287 {
2288 BIU tmp = biuParse( line + SZ( "ViaDrill" ) );
2289 nc->SetViaDrill( tmp );
2290 }
2291 else if( TESTLINE( "uViaDia" ) )
2292 {
2293 BIU tmp = biuParse( line + SZ( "uViaDia" ) );
2294 nc->SetuViaDiameter( tmp );
2295 }
2296 else if( TESTLINE( "uViaDrill" ) )
2297 {
2298 BIU tmp = biuParse( line + SZ( "uViaDrill" ) );
2299 nc->SetuViaDrill( tmp );
2300 }
2301 else if( TESTLINE( "Name" ) )
2302 {
2303 ReadDelimitedText( buf, line + SZ( "Name" ), sizeof(buf) );
2304 nc->SetName( FROM_UTF8( buf ) );
2305 }
2306 else if( TESTLINE( "Desc" ) )
2307 {
2308 ReadDelimitedText( buf, line + SZ( "Desc" ), sizeof(buf) );
2309 nc->SetDescription( FROM_UTF8( buf ) );
2310 }
2311 else if( TESTLINE( "$EndNCLASS" ) )
2312 {
2313 if( m_board->GetDesignSettings().m_NetSettings->m_NetClasses.count( nc->GetName() ) )
2314 {
2315 // Must have been a name conflict, this is a bad board file.
2316 // User may have done a hand edit to the file.
2317
2318 // unique_ptr will delete nc on this code path
2319
2320 m_error.Printf( _( "Duplicate NETCLASS name '%s'." ), nc->GetName() );
2322 }
2323 else
2324 {
2325 m_board->GetDesignSettings().m_NetSettings->m_NetClasses[ nc->GetName() ] = nc;
2326 }
2327
2328 return; // preferred exit
2329 }
2330 }
2331
2332 THROW_IO_ERROR( wxT( "Missing '$EndNCLASS'" ) );
2333}
std::shared_ptr< NET_SETTINGS > m_NetSettings
@ CTX_NETCLASS

References _, biuParse(), ConvertToNewOverbarNotation(), CTX_NETCLASS, FROM_UTF8(), BOARD::GetDesignSettings(), m_board, m_error, BOARD_DESIGN_SETTINGS::m_NetSettings, m_reader, ReadDelimitedText(), READLINE, SZ, TESTLINE, and THROW_IO_ERROR.

Referenced by loadAllSections().

◆ loadNETINFO_ITEM()

void LEGACY_PLUGIN::loadNETINFO_ITEM ( )
protected

Definition at line 1913 of file legacy_plugin.cpp.

1914{
1915 /* a net description is something like
1916 * $EQUIPOT
1917 * Na 5 "/BIT1"
1918 * St ~
1919 * $EndEQUIPOT
1920 */
1921
1922 char buf[1024];
1923
1924 NETINFO_ITEM* net = nullptr;
1925 char* line;
1926 int netCode = 0;
1927
1928 while( ( line = READLINE( m_reader ) ) != nullptr )
1929 {
1930 const char* data;
1931
1932 if( TESTLINE( "Na" ) )
1933 {
1934 // e.g. "Na 58 "/cpu.sch/PAD7"\r\n"
1935
1936 netCode = intParse( line + SZ( "Na" ), &data );
1937
1938 ReadDelimitedText( buf, data, sizeof(buf) );
1939
1940 if( net == nullptr )
1941 {
1943 netCode );
1944 }
1945 else
1946 {
1947 THROW_IO_ERROR( wxT( "Two net definitions in '$EQUIPOT' block" ) );
1948 }
1949 }
1950 else if( TESTLINE( "$EndEQUIPOT" ) )
1951 {
1952 // net 0 should be already in list, so store this net
1953 // if it is not the net 0, or if the net 0 does not exists.
1954 if( net && ( net->GetNetCode() > 0 || m_board->FindNet( 0 ) == nullptr ) )
1955 {
1956 m_board->Add( net );
1957
1958 // Be sure we have room to store the net in m_netCodes
1959 if( (int)m_netCodes.size() <= netCode )
1960 m_netCodes.resize( netCode+1 );
1961
1962 m_netCodes[netCode] = net->GetNetCode();
1963 net = nullptr;
1964 }
1965 else
1966 {
1967 delete net;
1968 net = nullptr; // Avoid double deletion.
1969 }
1970
1971 return; // preferred exit
1972 }
1973 }
1974
1975 // If we are here, there is an error.
1976 delete net;
1977 THROW_IO_ERROR( wxT( "Missing '$EndEQUIPOT'" ) );
1978}
NETINFO_ITEM * FindNet(int aNetcode) const
Search for a net with the given netcode.
Definition: board.cpp:1417
Handle the data for a net.
Definition: netinfo.h:66
int GetNetCode() const
Definition: netinfo.h:113

References BOARD::Add(), ConvertToNewOverbarNotation(), BOARD::FindNet(), FROM_UTF8(), NETINFO_ITEM::GetNetCode(), intParse(), m_board, m_netCodes, m_reader, ReadDelimitedText(), READLINE, SZ, TESTLINE, and THROW_IO_ERROR.

Referenced by loadAllSections().

◆ loadPAD()

void LEGACY_PLUGIN::loadPAD ( FOOTPRINT aFootprint)
protected

Definition at line 1303 of file legacy_plugin.cpp.

1304{
1305 std::unique_ptr<PAD> pad = std::make_unique<PAD>( aFootprint );
1306 char* line;
1307 char* saveptr;
1308
1309 while( ( line = READLINE( m_reader ) ) != nullptr )
1310 {
1311 const char* data;
1312
1313 if( TESTLINE( "Sh" ) ) // (Sh)ape and padname
1314 {
1315 // e.g. "Sh "A2" C 520 520 0 0 900"
1316 // or "Sh "1" R 157 1378 0 0 900"
1317
1318 // mypadnumber is LATIN1/CRYLIC for BOARD_FORMAT_VERSION 1, but for
1319 // BOARD_FORMAT_VERSION 2, it is UTF8 from disk.
1320 // Moving forward padnumbers will be in UTF8 on disk, as are all KiCad strings on disk.
1321 char mypadnumber[50];
1322
1323 data = line + SZ( "Sh" ) + 1; // +1 skips trailing whitespace
1324
1325 // +1 trailing whitespace.
1326 data = data + ReadDelimitedText( mypadnumber, data, sizeof( mypadnumber ) ) + 1;
1327
1328 while( isSpace( *data ) )
1329 ++data;
1330
1331 unsigned char padchar = (unsigned char) *data++;
1332 int padshape;
1333
1334 BIU size_x = biuParse( data, &data );
1335 BIU size_y = biuParse( data, &data );
1336 BIU delta_x = biuParse( data, &data );
1337 BIU delta_y = biuParse( data, &data );
1338 EDA_ANGLE orient = degParse( data );
1339
1340 switch( padchar )
1341 {
1342 case 'C': padshape = static_cast<int>( PAD_SHAPE::CIRCLE ); break;
1343 case 'R': padshape = static_cast<int>( PAD_SHAPE::RECT ); break;
1344 case 'O': padshape = static_cast<int>( PAD_SHAPE::OVAL ); break;
1345 case 'T': padshape = static_cast<int>( PAD_SHAPE::TRAPEZOID ); break;
1346 default:
1347 m_error.Printf( _( "Unknown padshape '%c=0x%02x' on line: %d of footprint: '%s'." ),
1348 padchar, padchar, m_reader->LineNumber(),
1349 aFootprint->GetFPID().GetLibItemName().wx_str() );
1351 }
1352
1353 // go through a wxString to establish a universal character set properly
1354 wxString padNumber;
1355
1356 if( m_loading_format_version == 1 )
1357 {
1358 // add 8 bit bytes, file format 1 was KiCad font type byte,
1359 // simply promote those 8 bit bytes up into UNICODE. (subset of LATIN1)
1360 const unsigned char* cp = (unsigned char*) mypadnumber;
1361
1362 while( *cp )
1363 padNumber += *cp++; // unsigned, ls 8 bits only
1364 }
1365 else
1366 {
1367 // version 2, which is UTF8.
1368 padNumber = FROM_UTF8( mypadnumber );
1369 }
1370
1371 // chances are both were ASCII, but why take chances?
1372
1373 pad->SetNumber( padNumber );
1374 pad->SetShape( static_cast<PAD_SHAPE>( padshape ) );
1375 pad->SetSize( wxSize( size_x, size_y ) );
1376 pad->SetDelta( wxSize( delta_x, delta_y ) );
1377 pad->SetOrientation( orient );
1378 }
1379 else if( TESTLINE( "Dr" ) ) // (Dr)ill
1380 {
1381 // e.g. "Dr 350 0 0" or "Dr 0 0 0 O 0 0"
1382 BIU drill_x = biuParse( line + SZ( "Dr" ), &data );
1383 BIU drill_y = drill_x;
1384 BIU offs_x = biuParse( data, &data );
1385 BIU offs_y = biuParse( data, &data );
1386
1388
1389 data = strtok_r( (char*) data, delims, &saveptr );
1390
1391 if( data ) // optional shape
1392 {
1393 if( data[0] == 'O' )
1394 {
1395 drShape = PAD_DRILL_SHAPE_OBLONG;
1396
1397 data = strtok_r( nullptr, delims, &saveptr );
1398 drill_x = biuParse( data );
1399
1400 data = strtok_r( nullptr, delims, &saveptr );
1401 drill_y = biuParse( data );
1402 }
1403 }
1404
1405 pad->SetDrillShape( drShape );
1406 pad->SetOffset( VECTOR2I( offs_x, offs_y ) );
1407 pad->SetDrillSize( wxSize( drill_x, drill_y ) );
1408 }
1409 else if( TESTLINE( "At" ) ) // (At)tribute
1410 {
1411 // e.g. "At SMD N 00888000"
1412 // sscanf( PtLine, "%s %s %X", BufLine, BufCar, &m_layerMask );
1413
1414 PAD_ATTRIB attribute;
1415
1416 data = strtok_r( line + SZ( "At" ), delims, &saveptr );
1417
1418 if( !strcmp( data, "SMD" ) )
1419 attribute = PAD_ATTRIB::SMD;
1420 else if( !strcmp( data, "CONN" ) )
1421 attribute = PAD_ATTRIB::CONN;
1422 else if( !strcmp( data, "HOLE" ) )
1423 attribute = PAD_ATTRIB::NPTH;
1424 else
1425 attribute = PAD_ATTRIB::PTH;
1426
1427 strtok_r( nullptr, delims, &saveptr ); // skip unused prm
1428 data = strtok_r( nullptr, delims, &saveptr );
1429
1430 LEG_MASK layer_mask = hexParse( data );
1431
1432 pad->SetLayerSet( leg_mask2new( m_cu_count, layer_mask ) );
1433 pad->SetAttribute( attribute );
1434 }
1435 else if( TESTLINE( "Ne" ) ) // (Ne)tname
1436 {
1437 // e.g. "Ne 461 "V5.0"
1438
1439 char buf[1024]; // can be fairly long
1440 int netcode = intParse( line + SZ( "Ne" ), &data );
1441
1442 // Store the new code mapping
1443 pad->SetNetCode( getNetCode( netcode ) );
1444
1445 // read Netname
1446 ReadDelimitedText( buf, data, sizeof(buf) );
1447
1448 if( m_board )
1449 {
1450 wxASSERT( m_board->FindNet( getNetCode( netcode ) )->GetNetname()
1452 }
1453 }
1454 else if( TESTLINE( "Po" ) ) // (Po)sition
1455 {
1456 // e.g. "Po 500 -500"
1457 VECTOR2I pos;
1458
1459 pos.x = biuParse( line + SZ( "Po" ), &data );
1460 pos.y = biuParse( data );
1461
1462 pad->SetPos0( pos );
1463 // pad->SetPosition( pos ); set at function return
1464 }
1465 else if( TESTLINE( "Le" ) )
1466 {
1467 BIU tmp = biuParse( line + SZ( "Le" ) );
1468 pad->SetPadToDieLength( tmp );
1469 }
1470 else if( TESTLINE( ".SolderMask" ) )
1471 {
1472 BIU tmp = biuParse( line + SZ( ".SolderMask" ) );
1473 pad->SetLocalSolderMaskMargin( tmp );
1474 }
1475 else if( TESTLINE( ".SolderPasteRatio" ) )
1476 {
1477 double tmp = atof( line + SZ( ".SolderPasteRatio" ) );
1478 pad->SetLocalSolderPasteMarginRatio( tmp );
1479 }
1480 else if( TESTLINE( ".SolderPaste" ) )
1481 {
1482 BIU tmp = biuParse( line + SZ( ".SolderPaste" ) );
1483 pad->SetLocalSolderPasteMargin( tmp );
1484 }
1485 else if( TESTLINE( ".LocalClearance" ) )
1486 {
1487 BIU tmp = biuParse( line + SZ( ".LocalClearance" ) );
1488 pad->SetLocalClearance( tmp );
1489 }
1490 else if( TESTLINE( ".ZoneConnection" ) )
1491 {
1492 int tmp = intParse( line + SZ( ".ZoneConnection" ) );
1493 pad->SetZoneConnection( (ZONE_CONNECTION) tmp );
1494 }
1495 else if( TESTLINE( ".ThermalWidth" ) )
1496 {
1497 BIU tmp = biuParse( line + SZ( ".ThermalWidth" ) );
1498 pad->SetThermalSpokeWidth( tmp );
1499 }
1500 else if( TESTLINE( ".ThermalGap" ) )
1501 {
1502 BIU tmp = biuParse( line + SZ( ".ThermalGap" ) );
1503 pad->SetThermalGap( tmp );
1504 }
1505 else if( TESTLINE( "$EndPAD" ) )
1506 {
1507 // pad's "Position" is not relative to the footprint's, whereas Pos0 is relative
1508 // to the footprint's but is the unrotated coordinate.
1509
1510 VECTOR2I padpos = pad->GetPos0();
1511
1512 RotatePoint( padpos, aFootprint->GetOrientation() );
1513
1514 pad->SetPosition( padpos + aFootprint->GetPosition() );
1515
1516 if( pad->GetSizeX() > 0 && pad->GetSizeY() > 0 )
1517 {
1518 aFootprint->Add( pad.release() );
1519 }
1520 else
1521 {
1522 wxLogError( _( "Invalid zero-sized pad ignored in\nfile: %s" ),
1523 m_reader->GetSource() );
1524 }
1525
1526 return; // preferred exit
1527 }
1528 }
1529
1530 THROW_IO_ERROR( wxT( "Missing '$EndPAD'" ) );
1531}
EDA_ANGLE GetOrientation() const
Definition: footprint.h:191
VECTOR2I GetPosition() const override
Definition: footprint.h:188
int getNetCode(int aNetCode)
static bool isSpace(int c)
PAD_ATTRIB
The set of pad shapes, used with PAD::{Set,Get}Attribute().
Definition: pad_shapes.h:81
@ NPTH
like PAD_PTH, but not plated
@ SMD
Smd pad, appears on the solder paste layer (default)
@ PTH
Plated through hole pad.
@ CONN
Like smd, does not appear on the solder paste layer (default)
PAD_DRILL_SHAPE_T
The set of pad drill shapes, used with PAD::{Set,Get}DrillShape()
Definition: pad_shapes.h:69
@ PAD_DRILL_SHAPE_CIRCLE
Definition: pad_shapes.h:70
@ PAD_DRILL_SHAPE_OBLONG
Definition: pad_shapes.h:71
PAD_SHAPE
The set of pad shapes, used with PAD::{Set,Get}Shape()
Definition: pad_shapes.h:35
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Definition: trigo.cpp:183

References _, FOOTPRINT::Add(), biuParse(), CIRCLE, CONN, ConvertToNewOverbarNotation(), degParse(), delims, BOARD::FindNet(), FROM_UTF8(), FOOTPRINT::GetFPID(), LIB_ID::GetLibItemName(), getNetCode(), FOOTPRINT::GetOrientation(), FOOTPRINT::GetPosition(), LINE_READER::GetSource(), hexParse(), intParse(), isSpace(), leg_mask2new(), LINE_READER::LineNumber(), m_board, m_cu_count, m_error, m_loading_format_version, m_reader, NPTH, OVAL, pad, PAD_DRILL_SHAPE_CIRCLE, PAD_DRILL_SHAPE_OBLONG, PTH, ReadDelimitedText(), READLINE, RECT, RotatePoint(), SMD, StrPurge(), strtok_r(), SZ, TESTLINE, THROW_IO_ERROR, TRAPEZOID, UTF8::wx_str(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by loadFOOTPRINT().

◆ loadPCB_LINE()

void LEGACY_PLUGIN::loadPCB_LINE ( )
protected

Definition at line 1792 of file legacy_plugin.cpp.

1793{
1794 /* example:
1795 $DRAWSEGMENT
1796 Po 0 57500 -1000 57500 0 150
1797 De 24 0 900 0 0
1798 $EndDRAWSEGMENT
1799 */
1800
1801 std::unique_ptr<PCB_SHAPE> dseg = std::make_unique<PCB_SHAPE>( m_board );
1802
1803 char* line;
1804 char* saveptr;
1805
1806 while( ( line = READLINE( m_reader ) ) != nullptr )
1807 {
1808 const char* data;
1809
1810 if( TESTLINE( "Po" ) )
1811 {
1812 int shape = intParse( line + SZ( "Po" ), &data );
1813 BIU start_x = biuParse( data, &data );
1814 BIU start_y = biuParse( data, &data );
1815 BIU end_x = biuParse( data, &data );
1816 BIU end_y = biuParse( data, &data );
1817 BIU width = biuParse( data );
1818
1819 if( width < 0 )
1820 width = 0;
1821
1822 dseg->SetShape( static_cast<SHAPE_T>( shape ) );
1823 dseg->SetFilled( false );
1824 dseg->SetStroke( STROKE_PARAMS( width, PLOT_DASH_TYPE::SOLID ) );
1825
1826 if( dseg->GetShape() == SHAPE_T::ARC )
1827 {
1828 dseg->SetCenter( VECTOR2I( start_x, start_y ) );
1829 dseg->SetStart( VECTOR2I( end_x, end_y ) );
1830 }
1831 else
1832 {
1833 dseg->SetStart( VECTOR2I( start_x, start_y ) );
1834 dseg->SetEnd( VECTOR2I( end_x, end_y ) );
1835 }
1836 }
1837 else if( TESTLINE( "De" ) )
1838 {
1839 BIU x = 0;
1840 BIU y;
1841
1842 data = strtok_r( line + SZ( "De" ), delims, &saveptr );
1843
1844 for( int i = 0; data; ++i, data = strtok_r( nullptr, delims, &saveptr ) )
1845 {
1846 switch( i )
1847 {
1848 case 0:
1849 int layer;
1850 layer = intParse( data );
1851
1852 if( layer < FIRST_NON_COPPER_LAYER )
1853 layer = FIRST_NON_COPPER_LAYER;
1854
1855 else if( layer > LAST_NON_COPPER_LAYER )
1856 layer = LAST_NON_COPPER_LAYER;
1857
1858 dseg->SetLayer( leg_layer2new( m_cu_count, layer ) );
1859 break;
1860 case 1:
1861 ignore_unused( intParse( data ) );
1862 break;
1863 case 2:
1864 {
1865 EDA_ANGLE angle = degParse( data );
1866
1867 if( dseg->GetShape() == SHAPE_T::ARC )
1868 dseg->SetArcAngleAndEnd( angle );
1869
1870 break;
1871 }
1872 case 3:
1873 const_cast<KIID&>( dseg->m_Uuid ) = KIID( data );
1874 break;
1875 case 4:
1876 {
1877 EDA_ITEM_FLAGS state;
1878 state = static_cast<EDA_ITEM_FLAGS>( hexParse( data ) );
1879 dseg->SetState( state, true );
1880 break;
1881 }
1882 // Bezier Control Points
1883 case 5:
1884 x = biuParse( data );
1885 break;
1886 case 6:
1887 y = biuParse( data );
1888 dseg->SetBezierC1( VECTOR2I( x, y ) );
1889 break;
1890 case 7:
1891 x = biuParse( data );
1892 break;
1893 case 8:
1894 y = biuParse( data );
1895 dseg->SetBezierC2( VECTOR2I( x, y ) );
1896 break;
1897
1898 default:
1899 break;
1900 }
1901 }
1902 }
1903 else if( TESTLINE( "$EndDRAWSEGMENT" ) )
1904 {
1905 m_board->Add( dseg.release(), ADD_MODE::APPEND );
1906 return; // preferred exit
1907 }
1908 }
1909
1910 THROW_IO_ERROR( wxT( "Missing '$EndDRAWSEGMENT'" ) );
1911}
std::uint32_t EDA_ITEM_FLAGS

References BOARD::Add(), PNS::angle(), APPEND, ARC, biuParse(), degParse(), delims, FIRST_NON_COPPER_LAYER, hexParse(), ignore_unused(), intParse(), LAST_NON_COPPER_LAYER, leg_layer2new(), m_board, m_cu_count, m_reader, READLINE, SOLID, strtok_r(), SZ, TESTLINE, and THROW_IO_ERROR.

Referenced by loadAllSections().

◆ loadPCB_TARGET()

void LEGACY_PLUGIN::loadPCB_TARGET ( )
protected

Definition at line 2756 of file legacy_plugin.cpp.

2757{
2758 char* line;
2759
2760 while( ( line = READLINE( m_reader ) ) != nullptr )
2761 {
2762 const char* data;
2763
2764 if( TESTLINE( "$EndPCB_TARGET" ) || TESTLINE( "$EndMIREPCB" ) )
2765 {
2766 return; // preferred exit
2767 }
2768 else if( TESTLINE( "Po" ) )
2769 {
2770 int shape = intParse( line + SZ( "Po" ), &data );
2771 int layer_num = intParse( data, &data );
2772 BIU pos_x = biuParse( data, &data );
2773 BIU pos_y = biuParse( data, &data );
2774 BIU size = biuParse( data, &data );
2775 BIU width = biuParse( data, &data );
2776 char* uuid = strtok_r( (char*) data, delims, (char**) &data );
2777
2778 if( layer_num < FIRST_NON_COPPER_LAYER )
2779 layer_num = FIRST_NON_COPPER_LAYER;
2780 else if( layer_num > LAST_NON_COPPER_LAYER )
2781 layer_num = LAST_NON_COPPER_LAYER;
2782
2783 PCB_TARGET* t = new PCB_TARGET( m_board, shape, leg_layer2new( m_cu_count, layer_num ),
2784 VECTOR2I( pos_x, pos_y ), size, width );
2786
2787 const_cast<KIID&>( t->m_Uuid ) = KIID( uuid );
2788 }
2789 }
2790
2791 THROW_IO_ERROR( wxT( "Missing '$EndDIMENSION'" ) );
2792}

References BOARD::Add(), APPEND, biuParse(), delims, FIRST_NON_COPPER_LAYER, intParse(), LAST_NON_COPPER_LAYER, leg_layer2new(), m_board, m_cu_count, m_reader, EDA_ITEM::m_Uuid, READLINE, strtok_r(), SZ, TESTLINE, and THROW_IO_ERROR.

Referenced by loadAllSections().

◆ loadPCB_TEXT()

void LEGACY_PLUGIN::loadPCB_TEXT ( )
protected

Definition at line 1981 of file legacy_plugin.cpp.

1982{
1983 /* examples:
1984 For a single line text:
1985 ----------------------
1986 $TEXTPCB
1987 Te "Text example"
1988 Po 66750 53450 600 800 150 0
1989 De 24 1 0 Italic
1990 $EndTEXTPCB
1991
1992 For a multi line text:
1993 ---------------------
1994 $TEXTPCB
1995 Te "Text example"
1996 Nl "Line 2"
1997 Po 66750 53450 600 800 150 0
1998 De 24 1 0 Italic
1999 $EndTEXTPCB
2000 Nl "line nn" is a line added to the current text
2001 */
2002
2003 char text[1024];
2004
2005 // maybe someday a constructor that takes all this data in one call?
2006 PCB_TEXT* pcbtxt = new PCB_TEXT( m_board );
2007 m_board->Add( pcbtxt, ADD_MODE::APPEND );
2008
2009 char* line;
2010
2011 while( ( line = READLINE( m_reader ) ) != nullptr )
2012 {
2013 const char* data;
2014
2015 if( TESTLINE( "Te" ) ) // Text line (or first line for multi line texts)
2016 {
2017 ReadDelimitedText( text, line + SZ( "Te" ), sizeof(text) );
2019 }
2020 else if( TESTLINE( "nl" ) ) // next line of the current text
2021 {
2022 ReadDelimitedText( text, line + SZ( "nl" ), sizeof(text) );
2023 pcbtxt->SetText( pcbtxt->GetText() + wxChar( '\n' ) + FROM_UTF8( text ) );
2024 }
2025 else if( TESTLINE( "Po" ) )
2026 {
2027 wxSize size;
2028 BIU pos_x = biuParse( line + SZ( "Po" ), &data );
2029 BIU pos_y = biuParse( data, &data );
2030
2031 size.x = biuParse( data, &data );
2032 size.y = biuParse( data, &data );
2033
2034 BIU thickn = biuParse( data, &data );
2035 EDA_ANGLE angle = degParse( data );
2036
2037 pcbtxt->SetTextSize( size );
2038 pcbtxt->SetTextThickness( thickn );
2039 pcbtxt->SetTextAngle( angle );
2040
2041 pcbtxt->SetTextPos( VECTOR2I( pos_x, pos_y ) );
2042 }
2043 else if( TESTLINE( "De" ) )
2044 {
2045 // e.g. "De 21 1 68183921-93a5-49ac-91b0-49d05a0e1647 Normal C\r\n"
2046 int layer_num = intParse( line + SZ( "De" ), &data );
2047 int notMirrored = intParse( data, &data );
2048 char* uuid = strtok_r( (char*) data, delims, (char**) &data );
2049 char* style = strtok_r( nullptr, delims, (char**) &data );
2050 char* hJustify = strtok_r( nullptr, delims, (char**) &data );
2051 char* vJustify = strtok_r( nullptr, delims, (char**) &data );
2052
2053 pcbtxt->SetMirrored( !notMirrored );
2054 const_cast<KIID&>( pcbtxt->m_Uuid ) = KIID( uuid );
2055 pcbtxt->SetItalic( !strcmp( style, "Italic" ) );
2056
2057 if( hJustify )
2058 {
2059 pcbtxt->SetHorizJustify( horizJustify( hJustify ) );
2060 }
2061 else
2062 {
2063 // boom, somebody changed a constructor, I was relying on this:
2064 wxASSERT( pcbtxt->GetHorizJustify() == GR_TEXT_H_ALIGN_CENTER );
2065 }
2066
2067 if( vJustify )
2068 pcbtxt->SetVertJustify( vertJustify( vJustify ) );
2069
2070 if( layer_num < FIRST_COPPER_LAYER )
2071 layer_num = FIRST_COPPER_LAYER;
2072 else if( layer_num > LAST_NON_COPPER_LAYER )
2073 layer_num = LAST_NON_COPPER_LAYER;
2074
2075 if( layer_num >= FIRST_NON_COPPER_LAYER ||
2076 is_leg_copperlayer_valid( m_cu_count, layer_num ) )
2077 pcbtxt->SetLayer( leg_layer2new( m_cu_count, layer_num ) );
2078 else // not perfect, but putting this text on front layer is a workaround
2079 pcbtxt->SetLayer( F_Cu );
2080 }
2081 else if( TESTLINE( "$EndTEXTPCB" ) )
2082 {
2083 return; // preferred exit
2084 }
2085 }
2086
2087 THROW_IO_ERROR( wxT( "Missing '$EndTEXTPCB'" ) );
2088}
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:87
void SetTextPos(const VECTOR2I &aPoint)
Definition: eda_text.cpp:371
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition: eda_text.h:142
bool is_leg_copperlayer_valid(int aCu_Count, int aLegacyLayerNum)
#define FIRST_COPPER_LAYER
@ GR_TEXT_H_ALIGN_CENTER

References BOARD::Add(), PNS::angle(), APPEND, biuParse(), ConvertToNewOverbarNotation(), degParse(), delims, F_Cu, FIRST_COPPER_LAYER, FIRST_NON_COPPER_LAYER, FROM_UTF8(), EDA_TEXT::GetHorizJustify(), EDA_TEXT::GetText(), GR_TEXT_H_ALIGN_CENTER, horizJustify(), intParse(), is_leg_copperlayer_valid(), LAST_NON_COPPER_LAYER, leg_layer2new(), m_board, m_cu_count, m_reader, EDA_ITEM::m_Uuid, ReadDelimitedText(), READLINE, EDA_TEXT::SetHorizJustify(), EDA_TEXT::SetItalic(), BOARD_ITEM::SetLayer(), EDA_TEXT::SetMirrored(), EDA_TEXT::SetText(), EDA_TEXT::SetTextAngle(), EDA_TEXT::SetTextPos(), EDA_TEXT::SetTextSize(), EDA_TEXT::SetTextThickness(), EDA_TEXT::SetVertJustify(), strtok_r(), SZ, TESTLINE, text, THROW_IO_ERROR, and vertJustify().

Referenced by loadAllSections().

◆ loadSETUP()

void LEGACY_PLUGIN::loadSETUP ( )
protected

Definition at line 841 of file legacy_plugin.cpp.

842{
844 ZONE_SETTINGS zoneSettings = m_board->GetZoneSettings();
845 std::shared_ptr<NETCLASS> defaultNetclass = bds.m_NetSettings->m_DefaultNetClass;
846 char* line;
847 char* saveptr;
848
850
851 while( ( line = READLINE( m_reader ) ) != nullptr )
852 {
853 const char* data;
854
855 if( TESTLINE( "PcbPlotParams" ) )
856 {
857 PCB_PLOT_PARAMS plot_opts;
858
859 PCB_PLOT_PARAMS_PARSER parser( line + SZ( "PcbPlotParams" ), m_reader->GetSource() );
860
861 plot_opts.Parse( &parser );
862
863 m_board->SetPlotOptions( plot_opts );
864 }
865
866 else if( TESTLINE( "AuxiliaryAxisOrg" ) )
867 {
868 BIU gx = biuParse( line + SZ( "AuxiliaryAxisOrg" ), &data );
869 BIU gy = biuParse( data );
870
871 bds.SetAuxOrigin( VECTOR2I( gx, gy ) );
872 }
873 else if( TESTSUBSTR( "Layer[" ) )
874 {
875 // eg: "Layer[n] <a_Layer_name_with_no_spaces> <LAYER_T>"
876
877 int layer_num = intParse( line + SZ( "Layer[" ), &data );
878 PCB_LAYER_ID layer_id = leg_layer2new( m_cu_count, layer_num );
879
880 data = strtok_r( (char*) data+1, delims, &saveptr ); // +1 for ']'
881
882 if( data )
883 {
884 wxString layerName = FROM_UTF8( data );
885 m_board->SetLayerName( layer_id, layerName );
886
887 data = strtok_r( nullptr, delims, &saveptr );
888
889 if( data ) // optional in old board files
890 {
891 LAYER_T type = LAYER::ParseType( data );
892 m_board->SetLayerType( layer_id, type );
893 }
894 }
895 }
896 else if( TESTLINE( "TrackWidth" ) )
897 {
898 BIU tmp = biuParse( line + SZ( "TrackWidth" ) );
899 defaultNetclass->SetTrackWidth( tmp );
900 }
901 else if( TESTLINE( "TrackWidthList" ) )
902 {
903 BIU tmp = biuParse( line + SZ( "TrackWidthList" ) );
904 bds.m_TrackWidthList.push_back( tmp );
905 }
906 else if( TESTLINE( "TrackClearence" ) )
907 {
908 BIU tmp = biuParse( line + SZ( "TrackClearence" ) );
909 defaultNetclass->SetClearance( tmp );
910 }
911 else if( TESTLINE( "TrackMinWidth" ) )
912 {
913 BIU tmp = biuParse( line + SZ( "TrackMinWidth" ) );
914 bds.m_TrackMinWidth = tmp;
915 }
916 else if( TESTLINE( "ZoneClearence" ) )
917 {
918 BIU tmp = biuParse( line + SZ( "ZoneClearence" ) );
919 zoneSettings.m_ZoneClearance = tmp;
920 }
921 else if( TESTLINE( "Zone_45_Only" ) ) // No longer used
922 {
923 /* bool tmp = (bool) */ intParse( line + SZ( "Zone_45_Only" ) );
924 }
925 else if( TESTLINE( "DrawSegmWidth" ) )
926 {
927 BIU tmp = biuParse( line + SZ( "DrawSegmWidth" ) );
929 }
930 else if( TESTLINE( "EdgeSegmWidth" ) )
931 {
932 BIU tmp = biuParse( line + SZ( "EdgeSegmWidth" ) );
934 }
935 else if( TESTLINE( "ViaMinSize" ) )
936 {
937 BIU tmp = biuParse( line + SZ( "ViaMinSize" ) );
938 bds.m_ViasMinSize = tmp;
939 }
940 else if( TESTLINE( "MicroViaMinSize" ) )
941 {
942 BIU tmp = biuParse( line + SZ( "MicroViaMinSize" ) );
943 bds.m_MicroViasMinSize = tmp;
944 }
945 else if( TESTLINE( "ViaSizeList" ) )
946 {
947 // e.g. "ViaSizeList DIAMETER [DRILL]"
948
949 BIU drill = 0;
950 BIU diameter = biuParse( line + SZ( "ViaSizeList" ), &data );
951
952 data = strtok_r( (char*) data, delims, (char**) &data );
953 if( data ) // DRILL may not be present ?
954 drill = biuParse( data );
955
956 bds.m_ViasDimensionsList.emplace_back( diameter, drill );
957 }
958 else if( TESTLINE( "ViaSize" ) )
959 {
960 BIU tmp = biuParse( line + SZ( "ViaSize" ) );
961 defaultNetclass->SetViaDiameter( tmp );
962 }
963 else if( TESTLINE( "ViaDrill" ) )
964 {
965 BIU tmp = biuParse( line + SZ( "ViaDrill" ) );
966 defaultNetclass->SetViaDrill( tmp );
967 }
968 else if( TESTLINE( "ViaMinDrill" ) )
969 {
970 BIU tmp = biuParse( line + SZ( "ViaMinDrill" ) );
971 bds.m_MinThroughDrill = tmp;
972 }
973 else if( TESTLINE( "MicroViaSize" ) )
974 {
975 BIU tmp = biuParse( line + SZ( "MicroViaSize" ) );
976 defaultNetclass->SetuViaDiameter( tmp );
977 }
978 else if( TESTLINE( "MicroViaDrill" ) )
979 {
980 BIU tmp = biuParse( line + SZ( "MicroViaDrill" ) );
981 defaultNetclass->SetuViaDrill( tmp );
982 }
983 else if( TESTLINE( "MicroViaMinDrill" ) )
984 {
985 BIU tmp = biuParse( line + SZ( "MicroViaMinDrill" ) );
986 bds.m_MicroViasMinDrill = tmp;
987 }
988 else if( TESTLINE( "MicroViasAllowed" ) )
989 {
990 intParse( line + SZ( "MicroViasAllowed" ) );
991 }
992 else if( TESTLINE( "TextPcbWidth" ) )
993 {
994 BIU tmp = biuParse( line + SZ( "TextPcbWidth" ) );
996 }
997 else if( TESTLINE( "TextPcbSize" ) )
998 {
999 BIU x = biuParse( line + SZ( "TextPcbSize" ), &data );
1000 BIU y = biuParse( data );
1001
1002 bds.m_TextSize[ LAYER_CLASS_COPPER ] = wxSize( x, y );
1003 }
1004 else if( TESTLINE( "EdgeModWidth" ) )
1005 {
1006 BIU tmp = biuParse( line + SZ( "EdgeModWidth" ) );
1007 bds.m_LineThickness[ LAYER_CLASS_SILK ] = tmp;
1009 }
1010 else if( TESTLINE( "TextModWidth" ) )
1011 {
1012 BIU tmp = biuParse( line + SZ( "TextModWidth" ) );
1013 bds.m_TextThickness[ LAYER_CLASS_SILK ] = tmp;
1015 }
1016 else if( TESTLINE( "TextModSize" ) )
1017 {
1018 BIU x = biuParse( line + SZ( "TextModSize" ), &data );
1019 BIU y = biuParse( data );
1020
1021 bds.m_TextSize[ LAYER_CLASS_SILK ] = wxSize( x, y );
1022 bds.m_TextSize[ LAYER_CLASS_OTHERS ] = wxSize( x, y );
1023 }
1024 else if( TESTLINE( "PadSize" ) )
1025 {
1026 BIU x = biuParse( line + SZ( "PadSize" ), &data );
1027 BIU y = biuParse( data );
1028
1029 bds.m_Pad_Master->SetSize( wxSize( x, y ) );
1030 }
1031 else if( TESTLINE( "PadDrill" ) )
1032 {
1033 BIU tmp = biuParse( line + SZ( "PadDrill" ) );
1034 bds.m_Pad_Master->SetDrillSize( wxSize( tmp, tmp ) );
1035 }
1036 else if( TESTLINE( "Pad2MaskClearance" ) )
1037 {
1038 BIU tmp = biuParse( line + SZ( "Pad2MaskClearance" ) );
1039 bds.m_SolderMaskExpansion = tmp;
1040 }
1041 else if( TESTLINE( "SolderMaskMinWidth" ) )
1042 {
1043 BIU tmp = biuParse( line + SZ( "SolderMaskMinWidth" ) );
1044 bds.m_SolderMaskMinWidth = tmp;
1045 }
1046 else if( TESTLINE( "Pad2PasteClearance" ) )
1047 {
1048 BIU tmp = biuParse( line + SZ( "Pad2PasteClearance" ) );
1049 bds.m_SolderPasteMargin = tmp;
1050 }
1051 else if( TESTLINE( "Pad2PasteClearanceRatio" ) )
1052 {
1053 double ratio = atof( line + SZ( "Pad2PasteClearanceRatio" ) );
1054 bds.m_SolderPasteMarginRatio = ratio;
1055 }
1056
1057 else if( TESTLINE( "GridOrigin" ) )
1058 {
1059 BIU x = biuParse( line + SZ( "GridOrigin" ), &data );
1060 BIU y = biuParse( data );
1061
1062 bds.SetGridOrigin( VECTOR2I( x, y ) );
1063 }
1064 else if( TESTLINE( "VisibleElements" ) )
1065 {
1066 // Keep all elements visible.
1067 // the old visibility control does not make sense in current Pcbnew version,
1068 // and this code does not work.
1069#if 0
1070 int visibleElements = hexParse( line + SZ( "VisibleElements" ) );
1071
1072 // Does not work: each old item should be tested one by one to set
1073 // visibility of new item list
1074 GAL_SET visibles;
1075
1076 for( size_t i = 0; i < visibles.size(); i++ )
1077 visibles.set( i, visibleElements & ( 1u << i ) );
1078
1079 m_board->SetVisibleElements( visibles );
1080#endif
1081 }
1082 else if( TESTLINE( "$EndSETUP" ) )
1083 {
1084 m_board->SetZoneSettings( zoneSettings );
1085
1086 // Very old *.brd file does not have NETCLASSes
1087 // "TrackWidth", "ViaSize", "ViaDrill", "ViaMinSize", and "TrackClearence" were
1088 // defined in SETUP; these values are put into the default NETCLASS until later board
1089 // load code should override them. *.brd files which have been saved with knowledge
1090 // of NETCLASSes will override these defaults, very old boards (before 2009) will not
1091 // and use the setup values.
1092 // However these values should be the same as default NETCLASS.
1093
1094 return; // preferred exit
1095 }
1096 }
1097
1098 /*
1099 * Ensure tracks and vias sizes lists are ok:
1100 * Sort lists by by increasing value and remove duplicates
1101 * (the first value is not tested, because it is the netclass value)
1102 */
1103 BOARD_DESIGN_SETTINGS& designSettings = m_board->GetDesignSettings();
1104 sort( designSettings.m_ViasDimensionsList.begin() + 1,
1105 designSettings.m_ViasDimensionsList.end() );
1106 sort( designSettings.m_TrackWidthList.begin() + 1, designSettings.m_TrackWidthList.end() );
1107
1108 for( unsigned ii = 1; ii < designSettings.m_ViasDimensionsList.size() - 1; ii++ )
1109 {
1110 if( designSettings.m_ViasDimensionsList[ii] == designSettings.m_ViasDimensionsList[ii + 1] )
1111 {
1112 designSettings.m_ViasDimensionsList.erase( designSettings.m_ViasDimensionsList.begin() + ii );
1113 ii--;
1114 }
1115 }
1116
1117 for( unsigned ii = 1; ii < designSettings.m_TrackWidthList.size() - 1; ii++ )
1118 {
1119 if( designSettings.m_TrackWidthList[ii] == designSettings.m_TrackWidthList[ii + 1] )
1120 {
1121 designSettings.m_TrackWidthList.erase( designSettings.m_TrackWidthList.begin() + ii );
1122 ii--;
1123 }
1124 }
1125}
LAYER_T
The allowed types of layers, same as Specctra DSN spec.
Definition: board.h:143
@ LAYER_CLASS_OTHERS
@ LAYER_CLASS_SILK
@ LAYER_CLASS_COPPER
@ LAYER_CLASS_EDGES
Container for design settings for a BOARD object.
void SetGridOrigin(const VECTOR2I &aOrigin)
std::unique_ptr< PAD > m_Pad_Master
void SetAuxOrigin(const VECTOR2I &aOrigin)
int m_TextThickness[LAYER_CLASS_COUNT]
std::vector< int > m_TrackWidthList
int m_LineThickness[LAYER_CLASS_COUNT]
wxSize m_TextSize[LAYER_CLASS_COUNT]
std::vector< VIA_DIMENSION > m_ViasDimensionsList
void SetPlotOptions(const PCB_PLOT_PARAMS &aOptions)
Definition: board.h:630
bool m_LegacyDesignSettingsLoaded
True if the legacy board design settings were loaded from a file.
Definition: board.h:342
void SetZoneSettings(const ZONE_SETTINGS &aSettings) override
Set the zone settings for this container.
Definition: board.cpp:655
const ZONE_SETTINGS & GetZoneSettings() const override
Fetch the zone settings for this container.
Definition: board.cpp:649
bool SetLayerName(PCB_LAYER_ID aLayer, const wxString &aLayerName)
Changes the name of the layer given by aLayer.
Definition: board.cpp:429
bool SetLayerType(PCB_LAYER_ID aLayer, LAYER_T aLayerType)
Change the type of the layer given by aLayer.
Definition: board.cpp:459
void SetVisibleElements(const GAL_SET &aMask)
A proxy function that calls the correspondent function in m_BoardSettings.
Definition: board.cpp:565
Helper for storing and iterating over GAL_LAYER_IDs.
Definition: layer_ids.h:296
GAL_SET & set()
Definition: layer_ids.h:311
The parser for PCB_PLOT_PARAMS.
Parameters and options when plotting/printing a board.
void Parse(PCB_PLOT_PARAMS_PARSER *aParser)
ZONE_SETTINGS handles zones parameters.
Definition: zone_settings.h:70
static LAYER_T ParseType(const char *aType)
Convert a string to a LAYER_T.
Definition: board.cpp:487

References biuParse(), delims, FROM_UTF8(), BOARD::GetDesignSettings(), LINE_READER::GetSource(), BOARD::GetZoneSettings(), hexParse(), intParse(), LAYER_CLASS_COPPER, LAYER_CLASS_EDGES, LAYER_CLASS_OTHERS, LAYER_CLASS_SILK, leg_layer2new(), m_board, m_cu_count, BOARD::m_LegacyDesignSettingsLoaded, BOARD_DESIGN_SETTINGS::m_LineThickness, BOARD_DESIGN_SETTINGS::m_MicroViasMinDrill, BOARD_DESIGN_SETTINGS::m_MicroViasMinSize, BOARD_DESIGN_SETTINGS::m_MinThroughDrill, BOARD_DESIGN_SETTINGS::m_NetSettings, BOARD_DESIGN_SETTINGS::m_Pad_Master, m_reader, BOARD_DESIGN_SETTINGS::m_SolderMaskExpansion, BOARD_DESIGN_SETTINGS::m_SolderMaskMinWidth, BOARD_DESIGN_SETTINGS::m_SolderPasteMargin, BOARD_DESIGN_SETTINGS::m_SolderPasteMarginRatio, BOARD_DESIGN_SETTINGS::m_TextSize, BOARD_DESIGN_SETTINGS::m_TextThickness, BOARD_DESIGN_SETTINGS::m_TrackMinWidth, BOARD_DESIGN_SETTINGS::m_TrackWidthList, BOARD_DESIGN_SETTINGS::m_ViasDimensionsList, BOARD_DESIGN_SETTINGS::m_ViasMinSize, ZONE_SETTINGS::m_ZoneClearance, PCB_PLOT_PARAMS::Parse(), LAYER::ParseType(), READLINE, GAL_SET::set(), BOARD_DESIGN_SETTINGS::SetAuxOrigin(), BOARD_DESIGN_SETTINGS::SetGridOrigin(), BOARD::SetLayerName(), BOARD::SetLayerType(), BOARD::SetPlotOptions(), BOARD::SetVisibleElements(), BOARD::SetZoneSettings(), strtok_r(), SZ, TESTLINE, and TESTSUBSTR.

Referenced by loadAllSections().

◆ loadSHEET()

void LEGACY_PLUGIN::loadSHEET ( )
protected

Definition at line 710 of file legacy_plugin.cpp.

711{
712 char buf[260];
713 TITLE_BLOCK tb;
714 char* line;
715 char* data;
716
717 while( ( line = READLINE( m_reader ) ) != nullptr )
718 {
719 if( TESTLINE( "Sheet" ) )
720 {
721 // e.g. "Sheet A3 16535 11700"
722 // width and height are in 1/1000th of an inch, always
723 PAGE_INFO page;
724 char* sname = strtok_r( line + SZ( "Sheet" ), delims, &data );
725
726 if( sname )
727 {
728 wxString wname = FROM_UTF8( sname );
729
730 if( !page.SetType( wname ) )
731 {
732 m_error.Printf( _( "Unknown sheet type '%s' on line: %d." ),
733 wname.GetData(),
734 m_reader->LineNumber() );
736 }
737
738 char* width = strtok_r( nullptr, delims, &data );
739 char* height = strtok_r( nullptr, delims, &data );
740 char* orient = strtok_r( nullptr, delims, &data );
741
742 // only parse the width and height if page size is custom ("User")
743 if( wname == PAGE_INFO::Custom )
744 {
745 if( width && height )
746 {
747 // legacy disk file describes paper in mils
748 // (1/1000th of an inch)
749 int w = intParse( width );
750 int h = intParse( height );
751
752 page.SetWidthMils( w );
753 page.SetHeightMils( h );
754 }
755 }
756
757 if( orient && !strcmp( orient, "portrait" ) )
758 {
759 page.SetPortrait( true );
760 }
761
762 m_board->SetPageSettings( page );
763 }
764 }
765 else if( TESTLINE( "Title" ) )
766 {
767 ReadDelimitedText( buf, line, sizeof(buf) );
768 tb.SetTitle( FROM_UTF8( buf ) );
769 }
770 else if( TESTLINE( "Date" ) )
771 {
772 ReadDelimitedText( buf, line, sizeof(buf) );
773 tb.SetDate( FROM_UTF8( buf ) );
774 }
775 else if( TESTLINE( "Rev" ) )
776 {
777 ReadDelimitedText( buf, line, sizeof(buf) );
778 tb.SetRevision( FROM_UTF8( buf ) );
779 }
780 else if( TESTLINE( "Comp" ) )
781 {
782 ReadDelimitedText( buf, line, sizeof(buf) );
783 tb.SetCompany( FROM_UTF8( buf ) );
784 }
785 else if( TESTLINE( "Comment1" ) )
786 {
787 ReadDelimitedText( buf, line, sizeof(buf) );
788 tb.SetComment( 0, FROM_UTF8( buf ) );
789 }
790 else if( TESTLINE( "Comment2" ) )
791 {
792 ReadDelimitedText( buf, line, sizeof(buf) );
793 tb.SetComment( 1, FROM_UTF8( buf ) );
794 }
795 else if( TESTLINE( "Comment3" ) )
796 {
797 ReadDelimitedText( buf, line, sizeof(buf) );
798 tb.SetComment( 2, FROM_UTF8( buf ) );
799 }
800 else if( TESTLINE( "Comment4" ) )
801 {
802 ReadDelimitedText( buf, line, sizeof(buf) );
803 tb.SetComment( 3, FROM_UTF8( buf ) );
804 }
805 else if( TESTLINE( "Comment5" ) )
806 {
807 ReadDelimitedText( buf, line, sizeof(buf) );
808 tb.SetComment( 4, FROM_UTF8( buf ) );
809 }
810 else if( TESTLINE( "Comment6" ) )
811 {
812 ReadDelimitedText( buf, line, sizeof(buf) );
813 tb.SetComment( 5, FROM_UTF8( buf ) );
814 }
815 else if( TESTLINE( "Comment7" ) )
816 {
817 ReadDelimitedText( buf, line, sizeof(buf) );
818 tb.SetComment( 6, FROM_UTF8( buf ) );
819 }
820 else if( TESTLINE( "Comment8" ) )
821 {
822 ReadDelimitedText( buf, line, sizeof(buf) );
823 tb.SetComment( 7, FROM_UTF8( buf ) );
824 }
825 else if( TESTLINE( "Comment9" ) )
826 {
827 ReadDelimitedText( buf, line, sizeof(buf) );
828 tb.SetComment( 8, FROM_UTF8( buf ) );
829 }
830 else if( TESTLINE( "$EndSHEETDESCR" ) )
831 {
832 m_board->SetTitleBlock( tb );
833 return; // preferred exit
834 }
835 }
836
837 THROW_IO_ERROR( wxT( "Missing '$EndSHEETDESCR'" ) );
838}
void SetPageSettings(const PAGE_INFO &aPageSettings)
Definition: board.h:627
void SetTitleBlock(const TITLE_BLOCK &aTitleBlock)
Definition: board.h:634
Describe the page size and margins of a paper page on which to eventually print or plot.
Definition: page_info.h:54
void SetWidthMils(int aWidthInMils)
Definition: page_info.cpp:244
void SetPortrait(bool aIsPortrait)
Rotate the paper page 90 degrees.
Definition: page_info.cpp:187
static const wxChar Custom[]
"User" defined page type
Definition: page_info.h:77
void SetHeightMils(int aHeightInMils)
Definition: page_info.cpp:258
bool SetType(const wxString &aStandardPageDescriptionName, bool aIsPortrait=false)
Set the name of the page type and also the sizes and margins commonly associated with that type name.
Definition: page_info.cpp:120
Hold the information shown in the lower right corner of a plot, printout, or editing view.
Definition: title_block.h:41
void SetRevision(const wxString &aRevision)
Definition: title_block.h:81
void SetComment(int aIdx, const wxString &aComment)
Definition: title_block.h:101
void SetTitle(const wxString &aTitle)
Definition: title_block.h:58
void SetCompany(const wxString &aCompany)
Definition: title_block.h:91
void SetDate(const wxString &aDate)
Set the date field, and defaults to the current time and date.
Definition: title_block.h:71

References _, PAGE_INFO::Custom, delims, FROM_UTF8(), intParse(), LINE_READER::LineNumber(), m_board, m_error, m_reader, ReadDelimitedText(), READLINE, TITLE_BLOCK::SetComment(), TITLE_BLOCK::SetCompany(), TITLE_BLOCK::SetDate(), PAGE_INFO::SetHeightMils(), BOARD::SetPageSettings(), PAGE_INFO::SetPortrait(), TITLE_BLOCK::SetRevision(), TITLE_BLOCK::SetTitle(), BOARD::SetTitleBlock(), PAGE_INFO::SetType(), PAGE_INFO::SetWidthMils(), strtok_r(), SZ, TESTLINE, and THROW_IO_ERROR.

Referenced by loadAllSections().

◆ loadTrackList()

void LEGACY_PLUGIN::loadTrackList ( int  aStructType)
protected

Read a list of segments (Tracks and Vias, or Segzones)

Parameters
aStructTypeis either PCB_TRACE_T to indicate tracks and vias, or NOT_USED to indicate oldschool zone segments (which are discarded).

Definition at line 2091 of file legacy_plugin.cpp.

2092{
2093 char* line;
2094
2095 while( ( line = READLINE( m_reader ) ) != nullptr )
2096 {
2097 checkpoint();
2098
2099 // read two lines per loop iteration, each loop is one TRACK or VIA
2100 // example first line:
2101 // e.g. "Po 0 23994 28800 24400 28800 150 -1" for a track
2102 // e.g. "Po 3 21086 17586 21086 17586 180 -1" for a via (uses sames start and end)
2103 const char* data;
2104
2105 if( line[0] == '$' ) // $EndTRACK
2106 return; // preferred exit
2107
2108 assert( TESTLINE( "Po" ) );
2109
2110 VIATYPE viatype = static_cast<VIATYPE>( intParse( line + SZ( "Po" ), &data ) );
2111 BIU start_x = biuParse( data, &data );
2112 BIU start_y = biuParse( data, &data );
2113 BIU end_x = biuParse( data, &data );
2114 BIU end_y = biuParse( data, &data );
2115 BIU width = biuParse( data, &data );
2116
2117 // optional 7th drill parameter (must be optional in an old format?)
2118 data = strtok_r( (char*) data, delims, (char**) &data );
2119
2120 BIU drill = data ? biuParse( data ) : -1; // SetDefault() if < 0
2121
2122 // Read the 2nd line to determine the exact type, one of:
2123 // PCB_TRACE_T, PCB_VIA_T, or PCB_SEGZONE_T. The type field in 2nd line
2124 // differentiates between PCB_TRACE_T and PCB_VIA_T. With virtual
2125 // functions in use, it is critical to instantiate the PCB_VIA_T
2126 // exactly.
2127 READLINE( m_reader );
2128
2129 line = m_reader->Line();
2130
2131 // example second line:
2132 // "De 0 0 463 0 800000\r\n"
2133
2134#if 1
2135 assert( TESTLINE( "De" ) );
2136#else
2137 if( !TESTLINE( "De" ) )
2138 {
2139 // mandatory 2nd line is missing
2140 THROW_IO_ERROR( wxT( "Missing 2nd line of a TRACK def" ) );
2141 }
2142#endif
2143
2144 int makeType;
2145
2146 // parse the 2nd line to determine the type of object
2147 // e.g. "De 15 1 7 68183921-93a5-49ac-91b0-49d05a0e1647 0" for a via
2148 int layer_num = intParse( line + SZ( "De" ), &data );
2149 int type = intParse( data, &data );
2150 int net_code = intParse( data, &data );
2151 char* uuid = strtok_r( (char*) data, delims, (char**) &data );
2152 int flags_int = intParse( data, (const char**) &data );
2153
2154 EDA_ITEM_FLAGS flags = static_cast<EDA_ITEM_FLAGS>( flags_int );
2155
2156 if( aStructType == PCB_TRACE_T )
2157 {
2158 makeType = ( type == 1 ) ? PCB_VIA_T : PCB_TRACE_T;
2159 }
2160 else if (aStructType == NOT_USED )
2161 {
2162 continue;
2163 }
2164 else
2165 {
2166 wxFAIL_MSG( wxT( "Segment type unknown" ) );
2167 continue;
2168 }
2169
2170 PCB_TRACK* newTrack;
2171
2172 switch( makeType )
2173 {
2174 default:
2175 case PCB_TRACE_T: newTrack = new PCB_TRACK( m_board ); break;
2176 case PCB_VIA_T: newTrack = new PCB_VIA( m_board ); break;
2177 }
2178
2179 const_cast<KIID&>( newTrack->m_Uuid ) = KIID( uuid );
2180 newTrack->SetPosition( VECTOR2I( start_x, start_y ) );
2181 newTrack->SetEnd( VECTOR2I( end_x, end_y ) );
2182
2183 newTrack->SetWidth( width );
2184
2185 if( makeType == PCB_VIA_T ) // Ensure layers are OK when possible:
2186 {
2187 PCB_VIA *via = static_cast<PCB_VIA*>( newTrack );
2188 via->SetViaType( viatype );
2189
2190 if( drill < 0 )
2191 via->SetDrillDefault();
2192 else
2193 via->SetDrill( drill );
2194
2195 if( via->GetViaType() == VIATYPE::THROUGH )
2196 {
2197 via->SetLayerPair( F_Cu, B_Cu );
2198 }
2199 else
2200 {
2201 PCB_LAYER_ID back = leg_layer2new( m_cu_count, (layer_num >> 4) & 0xf );
2202 PCB_LAYER_ID front = leg_layer2new( m_cu_count, layer_num & 0xf );
2203
2204 if( is_leg_copperlayer_valid( m_cu_count, back ) &&
2206 {
2207 via->SetLayerPair( front, back );
2208 }
2209 else
2210 {
2211 delete via;
2212 newTrack = nullptr;
2213 }
2214 }
2215 }
2216 else
2217 {
2218 // A few legacy boards can have tracks on non existent layers, because
2219 // reducing the number of layers does not remove tracks on removed layers
2220 // If happens, skip them
2221 if( is_leg_copperlayer_valid( m_cu_count, layer_num ) )
2222 {
2223 newTrack->SetLayer( leg_layer2new( m_cu_count, layer_num ) );
2224 }
2225 else
2226 {
2227 delete newTrack;
2228 newTrack = nullptr;
2229 }
2230 }
2231
2232 if( newTrack )
2233 {
2234 newTrack->SetNetCode( getNetCode( net_code ) );
2235 newTrack->SetState( flags, true );
2236
2237 m_board->Add( newTrack );
2238 }
2239 }
2240
2241 THROW_IO_ERROR( wxT( "Missing '$EndTRACK'" ) );
2242}
bool SetNetCode(int aNetCode, bool aNoAssert)
Set net using a net code.
void SetState(EDA_ITEM_FLAGS type, bool state)
Definition: eda_item.h:131
void SetWidth(int aWidth)
Definition: pcb_track.h:105
void SetEnd(const VECTOR2I &aEnd)
Definition: pcb_track.h:108
void SetPosition(const VECTOR2I &aPos) override
Definition: pcb_track.h:101
VIATYPE
Definition: pcb_track.h:63
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:102

References BOARD::Add(), B_Cu, biuParse(), checkpoint(), delims, F_Cu, getNetCode(), intParse(), is_leg_copperlayer_valid(), leg_layer2new(), LINE_READER::Line(), m_board, m_cu_count, m_reader, EDA_ITEM::m_Uuid, NOT_USED, PCB_TRACE_T, PCB_VIA_T, READLINE, PCB_TRACK::SetEnd(), BOARD_ITEM::SetLayer(), BOARD_CONNECTED_ITEM::SetNetCode(), PCB_TRACK::SetPosition(), EDA_ITEM::SetState(), PCB_TRACK::SetWidth(), strtok_r(), SZ, TESTLINE, THROUGH, THROW_IO_ERROR, and via.

Referenced by loadAllSections().

◆ loadZONE_CONTAINER()

void LEGACY_PLUGIN::loadZONE_CONTAINER ( )
protected

Definition at line 2336 of file legacy_plugin.cpp.

2337{
2338 std::unique_ptr<ZONE> zc = std::make_unique<ZONE>( m_board );
2339
2341 bool endContour = false;
2342 int holeIndex = -1; // -1 is the main outline; holeIndex >= 0 = hole index
2343 char buf[1024];
2344 char* line;
2345
2346 while( ( line = READLINE( m_reader ) ) != nullptr )
2347 {
2348 const char* data;
2349
2350 if( TESTLINE( "ZCorner" ) ) // new corner of the zone outlines found
2351 {
2352 // e.g. "ZCorner 25650 49500 0"
2353 BIU x = biuParse( line + SZ( "ZCorner" ), &data );
2354 BIU y = biuParse( data, &data );
2355
2356 if( endContour )
2357 {
2358 // the previous corner was the last corner of a contour.
2359 // so this corner is the first of a new hole
2360 endContour = false;
2361 zc->NewHole();
2362 holeIndex++;
2363 }
2364
2365 zc->AppendCorner( VECTOR2I( x, y ), holeIndex );
2366
2367 // Is this corner the end of current contour?
2368 // the next corner (if any) will be stored in a new contour (a hole)
2369 // intParse( data )returns 0 = usual corner, 1 = last corner of the current contour:
2370 endContour = intParse( data );
2371 }
2372 else if( TESTLINE( "ZInfo" ) ) // general info found
2373 {
2374 // e.g. 'ZInfo 68183921-93a5-49ac-91b0-49d05a0e1647 310 "COMMON"'
2375 char* uuid = strtok_r( (char*) line + SZ( "ZInfo" ), delims, (char**) &data );
2376 int netcode = intParse( data, &data );
2377
2378 if( ReadDelimitedText( buf, data, sizeof(buf) ) > (int) sizeof(buf) )
2379 THROW_IO_ERROR( wxT( "ZInfo netname too long" ) );
2380
2381 const_cast<KIID&>( zc->m_Uuid ) = KIID( uuid );
2382
2383 // Init the net code only, not the netname, to be sure
2384 // the zone net name is the name read in file.
2385 // (When mismatch, the user will be prompted in DRC, to fix the actual name)
2386 zc->BOARD_CONNECTED_ITEM::SetNetCode( getNetCode( netcode ) );
2387 }
2388 else if( TESTLINE( "ZLayer" ) ) // layer found
2389 {
2390 int layer_num = intParse( line + SZ( "ZLayer" ) );
2391 zc->SetLayer( leg_layer2new( m_cu_count, layer_num ) );
2392 }
2393 else if( TESTLINE( "ZAux" ) ) // aux info found
2394 {
2395 // e.g. "ZAux 7 E"
2396 ignore_unused( intParse( line + SZ( "ZAux" ), &data ) );
2397 char* hopt = strtok_r( (char*) data, delims, (char**) &data );
2398
2399 if( !hopt )
2400 {
2401 m_error.Printf( _( "Bad ZAux for CZONE_CONTAINER \"%s\"" ),
2402 zc->GetNetname().GetData() );
2404 }
2405
2406 switch( *hopt ) // upper case required
2407 {
2408 case 'N': outline_hatch = ZONE_BORDER_DISPLAY_STYLE::NO_HATCH; break;
2409 case 'E': outline_hatch = ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_EDGE; break;
2410 case 'F': outline_hatch = ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_FULL; break;
2411 default:
2412 m_error.Printf( _( "Bad ZAux for CZONE_CONTAINER \"%s\"" ),
2413 zc->GetNetname().GetData() );
2415 }
2416
2417 // Set hatch mode later, after reading corner outline data
2418 }
2419 else if( TESTLINE( "ZSmoothing" ) )
2420 {
2421 // e.g. "ZSmoothing 0 0"
2422 int smoothing = intParse( line + SZ( "ZSmoothing" ), &data );
2423 BIU cornerRadius = biuParse( data );
2424
2425 if( smoothing >= ZONE_SETTINGS::SMOOTHING_LAST || smoothing < 0 )
2426 {
2427 m_error.Printf( _( "Bad ZSmoothing for CZONE_CONTAINER \"%s\"" ),
2428 zc->GetNetname().GetData() );
2430 }
2431
2432 zc->SetCornerSmoothingType( smoothing );
2433 zc->SetCornerRadius( cornerRadius );
2434 }
2435 else if( TESTLINE( "ZKeepout" ) )
2436 {
2437 char* token;
2438 zc->SetIsRuleArea( true );
2439 zc->SetDoNotAllowPads( false ); // Not supported in legacy
2440 zc->SetDoNotAllowFootprints( false ); // Not supported in legacy
2441
2442 // e.g. "ZKeepout tracks N vias N pads Y"
2443 token = strtok_r( line + SZ( "ZKeepout" ), delims, (char**) &data );
2444
2445 while( token )
2446 {
2447 if( !strcmp( token, "tracks" ) )
2448 {
2449 token = strtok_r( nullptr, delims, (char**) &data );
2450 zc->SetDoNotAllowTracks( token && *token == 'N' );
2451 }
2452 else if( !strcmp( token, "vias" ) )
2453 {
2454 token = strtok_r( nullptr, delims, (char**) &data );
2455 zc->SetDoNotAllowVias( token && *token == 'N' );
2456 }
2457 else if( !strcmp( token, "copperpour" ) )
2458 {
2459 token = strtok_r( nullptr, delims, (char**) &data );
2460 zc->SetDoNotAllowCopperPour( token && *token == 'N' );
2461 }
2462
2463 token = strtok_r( nullptr, delims, (char**) &data );
2464 }
2465 }
2466 else if( TESTLINE( "ZOptions" ) )
2467 {
2468 // e.g. "ZOptions 0 32 F 200 200"
2469 int fillmode = intParse( line + SZ( "ZOptions" ), &data );
2470 ignore_unused( intParse( data, &data ) );
2471 char fillstate = data[1]; // here e.g. " F"
2472 BIU thermalReliefGap = biuParse( data += 2 , &data ); // +=2 for " F"
2473 BIU thermalReliefCopperBridge = biuParse( data );
2474
2475 if( fillmode)
2476 {
2477 // SEGMENT fill mode no longer supported. Make sure user is OK with converting
2478 // them.
2480 {
2481 KIDIALOG dlg( nullptr,
2482 _( "The legacy segment fill mode is no longer supported.\n"
2483 "Convert zones to smoothed polygon fills?" ),
2484 _( "Legacy Zone Warning" ),
2485 wxYES_NO | wxICON_WARNING );
2486
2487 dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
2488
2489 if( dlg.ShowModal() == wxID_NO )
2490 THROW_IO_ERROR( wxT( "CANCEL" ) );
2491
2493 }
2494
2495 // User OK'd; switch to polygon mode
2496 zc->SetFillMode( ZONE_FILL_MODE::POLYGONS );
2498 }
2499 else
2500 {
2501 zc->SetFillMode( ZONE_FILL_MODE::POLYGONS );
2502 }
2503
2504 zc->SetIsFilled( fillstate == 'S' );
2505 zc->SetThermalReliefGap( thermalReliefGap );
2506 zc->SetThermalReliefSpokeWidth( thermalReliefCopperBridge );
2507 }
2508 else if( TESTLINE( "ZClearance" ) ) // Clearance and pad options info found
2509 {
2510 // e.g. "ZClearance 40 I"
2511 BIU clearance = biuParse( line + SZ( "ZClearance" ), &data );
2512 char* padoption = strtok_r( (char*) data, delims, (char**) &data ); // data: " I"
2513
2514 ZONE_CONNECTION popt;
2515 switch( *padoption )
2516 {
2517 case 'I': popt = ZONE_CONNECTION::FULL; break;
2518 case 'T': popt = ZONE_CONNECTION::THERMAL; break;
2519 case 'H': popt = ZONE_CONNECTION::THT_THERMAL; break;
2520 case 'X': popt = ZONE_CONNECTION::NONE; break;
2521 default:
2522 m_error.Printf( _( "Bad ZClearance padoption for CZONE_CONTAINER \"%s\"" ),
2523 zc->GetNetname().GetData() );
2525 }
2526
2527 zc->SetLocalClearance( clearance );
2528 zc->SetPadConnection( popt );
2529 }
2530 else if( TESTLINE( "ZMinThickness" ) )
2531 {
2532 BIU thickness = biuParse( line + SZ( "ZMinThickness" ) );
2533 zc->SetMinThickness( thickness );
2534 }
2535 else if( TESTLINE( "ZPriority" ) )
2536 {
2537 int priority = intParse( line + SZ( "ZPriority" ) );
2538 zc->SetAssignedPriority( priority );
2539 }
2540 else if( TESTLINE( "$POLYSCORNERS" ) )
2541 {
2542 // Read the PolysList (polygons that are the solid areas in the filled zone)
2543 SHAPE_POLY_SET polysList;
2544
2545 bool makeNewOutline = true;
2546
2547 while( ( line = READLINE( m_reader ) ) != nullptr )
2548 {
2549 if( TESTLINE( "$endPOLYSCORNERS" ) )
2550 break;
2551
2552 // e.g. "39610 43440 0 0"
2553 BIU x = biuParse( line, &data );
2554 BIU y = biuParse( data, &data );
2555
2556 if( makeNewOutline )
2557 polysList.NewOutline();
2558
2559 polysList.Append( x, y );
2560
2561 // end_countour was a bool when file saved, so '0' or '1' here
2562 bool end_contour = intParse( data, &data );
2563 intParse( data ); // skip corner utility flag
2564
2565 makeNewOutline = end_contour;
2566 }
2567
2568 zc->SetFilledPolysList( zc->GetLayer(), polysList );
2569 }
2570 else if( TESTLINE( "$FILLSEGMENTS" ) )
2571 {
2572 while( ( line = READLINE( m_reader ) ) != nullptr )
2573 {
2574 if( TESTLINE( "$endFILLSEGMENTS" ) )
2575 break;
2576
2577 // e.g. ""%d %d %d %d\n"
2578 ignore_unused( biuParse( line, &data ) );
2579 ignore_unused( biuParse( data, &data ) );
2580 ignore_unused( biuParse( data, &data ) );
2581 ignore_unused( biuParse( data ) );
2582 }
2583 }
2584 else if( TESTLINE( "$endCZONE_OUTLINE" ) )
2585 {
2586 // Ensure keepout does not have a net
2587 // (which have no sense for a keepout zone)
2588 if( zc->GetIsRuleArea() )
2589 zc->SetNetCode( NETINFO_LIST::UNCONNECTED );
2590
2591 // should always occur, but who knows, a zone without two corners
2592 // is no zone at all, it's a spot?
2593
2594 if( zc->GetNumCorners() > 2 )
2595 {
2596 if( !zc->IsOnCopperLayer() )
2597 {
2598 zc->SetFillMode( ZONE_FILL_MODE::POLYGONS );
2599 zc->SetNetCode( NETINFO_LIST::UNCONNECTED );
2600 }
2601
2602 // HatchBorder here, after outlines corners are read
2603 // Set hatch here, after outlines corners are read
2604 zc->SetBorderDisplayStyle( outline_hatch, ZONE::GetDefaultHatchPitch(), true );
2605
2606 m_board->Add( zc.release() );
2607 }
2608
2609 return; // preferred exit
2610 }
2611 }
2612
2613 THROW_IO_ERROR( wxT( "Missing '$endCZONE_OUTLINE'" ) );
2614}
void SetModified()
Definition: eda_item.cpp:64
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
Definition: confirm.h:46
static const int UNCONNECTED
Constant that forces initialization of a netinfo item to the NETINFO_ITEM ORPHANED (typically -1) whe...
Definition: netinfo.h:373
Represent a set of closed polygons.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Add a new vertex to the contour indexed by aOutline and aHole (defaults to the outline of the last po...
int NewOutline()
Creates a new hole in a given outline.
static int GetDefaultHatchPitch()
Definition: zone.cpp:982
ZONE_BORDER_DISPLAY_STYLE
Zone border styles.
Definition: zone_settings.h:49
@ THERMAL
Use thermal relief for pads.
@ THT_THERMAL
Thermal relief only for THT pads.
@ NONE
Pads are not covered.
@ FULL
pads are covered by copper

References _, BOARD::Add(), SHAPE_POLY_SET::Append(), biuParse(), delims, DIAGONAL_EDGE, DIAGONAL_FULL, KIDIALOG::DoNotShowCheckbox(), FULL, ZONE::GetDefaultHatchPitch(), getNetCode(), ignore_unused(), intParse(), leg_layer2new(), m_board, m_cu_count, m_error, m_reader, m_showLegacySegmentZoneWarning, SHAPE_POLY_SET::NewOutline(), NO_HATCH, NONE, POLYGONS, ReadDelimitedText(), READLINE, EDA_ITEM::SetModified(), KIDIALOG::ShowModal(), ZONE_SETTINGS::SMOOTHING_LAST, strtok_r(), SZ, TESTLINE, THERMAL, THROW_IO_ERROR, THT_THERMAL, and NETINFO_LIST::UNCONNECTED.

Referenced by loadAllSections().

◆ PluginName()

const wxString LEGACY_PLUGIN::PluginName ( ) const
inlineoverridevirtual

Return a brief hard coded name for this PLUGIN.

Implements PLUGIN.

Definition at line 67 of file legacy_plugin.h.

68 {
69 return wxT( "KiCad-Legacy" );
70 }

◆ PrefetchLib()

void PLUGIN::PrefetchLib ( const wxString &  aLibraryPath,
const STRING_UTF8_MAP 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}

Referenced by FP_LIB_TABLE::PrefetchLib().

◆ Save()

void PLUGIN::Save ( const wxString &  aFileName,
BOARD aBoard,
const STRING_UTF8_MAP aProperties = nullptr 
)
virtualinherited

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 in CLIPBOARD_IO, and PCB_PLUGIN.

Definition at line 60 of file plugin.cpp.

61{
62 // not pure virtual so that plugins only have to implement subset of the PLUGIN interface.
63 not_implemented( this, __FUNCTION__ );
64}

References not_implemented().

Referenced by IO_MGR::Save(), PCB_EDIT_FRAME::SavePcbCopy(), and PCB_EDIT_FRAME::SavePcbFile().

◆ SetQueryUserCallback()

virtual void PLUGIN::SetQueryUserCallback ( std::function< bool(wxString aTitle, int aIcon, wxString aMessage, wxString aAction)>  aCallback)
inlinevirtualinherited

Registers a KIDIALOG callback for collecting info from the user.

Definition at line 285 of file io_mgr.h.

288 { }

Referenced by PCB_CONTROL::AppendBoard(), and PCB_EDIT_FRAME::OpenProjectFiles().

◆ SetReader()

void LEGACY_PLUGIN::SetReader ( LINE_READER aReader)
inline

Definition at line 98 of file legacy_plugin.h.

98{ m_reader = aReader; }

References m_reader.

Referenced by LP_CACHE::LoadModules().

Friends And Related Function Documentation

◆ LP_CACHE

friend struct LP_CACHE
friend

Definition at line 61 of file legacy_plugin.h.

Referenced by cacheLib().

Member Data Documentation

◆ biuToDisk

double LEGACY_PLUGIN::biuToDisk
protected

convert from BIUs to disk engineering units with this scale factor

Definition at line 200 of file legacy_plugin.h.

Referenced by init().

◆ diskToBiu

double LEGACY_PLUGIN::diskToBiu
protected

convert from disk engineering units to BIUs with this scale factor

Definition at line 203 of file legacy_plugin.h.

Referenced by biuParse(), init(), loadGENERAL(), and LP_CACHE::ReadAndVerifyHeader().

◆ m_board

◆ m_cache

LP_CACHE* LEGACY_PLUGIN::m_cache
protected

◆ m_cu_count

◆ m_error

wxString LEGACY_PLUGIN::m_error
protected

for throwing exceptions

Definition at line 182 of file legacy_plugin.h.

Referenced by biuParse(), checkVersion(), degParse(), loadFP_SHAPE(), loadNETCLASS(), loadPAD(), loadSHEET(), and loadZONE_CONTAINER().

◆ m_field

wxString LEGACY_PLUGIN::m_field
protected

reused to stuff FOOTPRINT fields.

Definition at line 193 of file legacy_plugin.h.

Referenced by loadMODULE_TEXT().

◆ m_fp

FILE* LEGACY_PLUGIN::m_fp
protected

no ownership here.

Definition at line 191 of file legacy_plugin.h.

◆ m_lastProgressLine

unsigned LEGACY_PLUGIN::m_lastProgressLine
protected

Definition at line 187 of file legacy_plugin.h.

Referenced by checkpoint().

◆ m_lineCount

unsigned LEGACY_PLUGIN::m_lineCount
protected

for progress reporting

Definition at line 188 of file legacy_plugin.h.

Referenced by checkpoint(), and Load().

◆ m_loading_format_version

int LEGACY_PLUGIN::m_loading_format_version
protected

which BOARD_FORMAT_VERSION am I Load()ing?

Definition at line 194 of file legacy_plugin.h.

Referenced by checkVersion(), init(), and loadPAD().

◆ m_netCodes

std::vector<int> LEGACY_PLUGIN::m_netCodes
protected

net codes mapping for boards being loaded

Definition at line 198 of file legacy_plugin.h.

Referenced by getNetCode(), loadGENERAL(), and loadNETINFO_ITEM().

◆ m_progressReporter

PROGRESS_REPORTER* LEGACY_PLUGIN::m_progressReporter
protected

may be NULL, no ownership

Definition at line 186 of file legacy_plugin.h.

Referenced by checkpoint(), and Load().

◆ m_props

const STRING_UTF8_MAP* LEGACY_PLUGIN::m_props
protected

passed via Save() or Load(), no ownership,

may be NULL.

Definition at line 184 of file legacy_plugin.h.

Referenced by init().

◆ m_reader

◆ m_showLegacySegmentZoneWarning

bool LEGACY_PLUGIN::m_showLegacySegmentZoneWarning
protected

Definition at line 196 of file legacy_plugin.h.

Referenced by init(), and loadZONE_CONTAINER().


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