KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcb_io_easypc.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
23
26
27#include <footprint.h>
28#include <ki_exception.h>
29#include <lib_id.h>
30#include <progress_reporter.h>
31#include <reporter.h>
32#include <string_utils.h>
33
34#include <wx/filename.h>
35
36
38 PCB_IO( wxS( "Easy-PC / DesignSpark PCB" ) )
39{
40}
41
42
44
45
46static bool isKind( const wxString& aFileName, EASYPC::FILE_KIND aKind )
47{
49 return info.FileKind == aKind;
50}
51
52
53bool PCB_IO_EASYPC::CanReadBoard( const wxString& aFileName ) const
54{
55 return PCB_IO::CanReadBoard( aFileName ) && isKind( aFileName, EASYPC::FILE_KIND::PCB_DESIGN );
56}
57
58
59bool PCB_IO_EASYPC::CanReadLibrary( const wxString& aFileName ) const
60{
61 return PCB_IO::CanReadLibrary( aFileName ) && isKind( aFileName, EASYPC::FILE_KIND::PCB_SYMBOL_LIBRARY );
62}
63
64
65long long PCB_IO_EASYPC::GetLibraryTimestamp( const wxString& aLibraryPath ) const
66{
67 return EASYPC::LIBRARY_FILE::Timestamp( aLibraryPath );
68}
69
70
71PCB_IO_EASYPC::LIBRARY& PCB_IO_EASYPC::library( const wxString& aLibraryPath )
72{
73 const long long stamp = EASYPC::LIBRARY_FILE::Timestamp( aLibraryPath );
74 auto it = m_libraries.find( aLibraryPath );
75
76 if( it != m_libraries.end() && it->second.Timestamp == stamp )
77 return it->second;
78
79 std::unique_ptr<EASYPC::LIBRARY_FILE> file = std::make_unique<EASYPC::LIBRARY_FILE>( aLibraryPath );
80
81 // A component library only names its footprints, which live in a .psl
82 if( file->Kind() != EASYPC::FILE_KIND::PCB_SYMBOL_LIBRARY )
83 THROW_IO_ERROR( wxString::Format( _( "'%s' is not an Easy-PC PCB symbol library" ), aLibraryPath ) );
84
85 for( const wxString& warning : file->Warnings() )
86 {
87 if( m_reporter )
88 m_reporter->Report( warning, RPT_SEVERITY_WARNING );
89 }
90
91 // A changed file drops the footprints converted from the old one
92 return m_libraries[aLibraryPath] = LIBRARY{ stamp, std::move( file ), {} };
93}
94
95
96void PCB_IO_EASYPC::FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aLibraryPath, bool aBestEfforts,
97 const std::map<std::string, UTF8>* aProperties )
98{
99 try
100 {
101 // KiCad names carry the characters a LIB_ID forbids escaped, and lookups take them back the same way
102 for( const wxString& name : library( aLibraryPath ).File->ItemNames() )
103 aFootprintNames.Add( EscapeString( name, CTX_LIBID ) );
104 }
105 catch( const IO_ERROR& )
106 {
107 if( !aBestEfforts )
108 throw;
109 }
110}
111
112
113bool PCB_IO_EASYPC::FootprintExists( const wxString& aLibraryPath, const wxString& aFootprintName,
114 const std::map<std::string, UTF8>* aProperties )
115{
116 return library( aLibraryPath ).File->HasItem( UnescapeString( aFootprintName ) );
117}
118
119
120const FOOTPRINT* PCB_IO_EASYPC::GetEnumeratedFootprint( const wxString& aLibraryPath, const wxString& aFootprintName,
121 const std::map<std::string, UTF8>* aProperties )
122{
123 LIBRARY& lib = library( aLibraryPath );
124
125 if( auto it = lib.Footprints.find( aFootprintName ); it != lib.Footprints.end() )
126 return it->second.get();
127
128 const wxString itemName = UnescapeString( aFootprintName );
129
130 if( !lib.File->HasItem( itemName ) )
131 return nullptr;
132
133 std::unique_ptr<EASYPC::LIBRARY_ITEM> item = lib.File->LoadItem( itemName );
134 const EASYPC::SOURCE_SYMBOL* symbol = nullptr;
135
136 if( !item->Streams.empty() )
137 symbol = dynamic_cast<const EASYPC::SOURCE_SYMBOL*>( item->Streams.front().Item );
138
139 if( !symbol )
140 {
142 wxString::Format( _( "Easy-PC library item '%s' in '%s' is not a symbol" ), itemName, aLibraryPath ) );
143 }
144
145 // A library item carries the layers its items use, introduced in place; their load order stands for the stack
146 std::vector<const EASYPC::SOURCE_LAYER*> layers;
147
148 for( const std::unique_ptr<EASYPC::OBJECT>& obj : item->Objects )
149 {
150 if( const EASYPC::SOURCE_LAYER* layer = dynamic_cast<const EASYPC::SOURCE_LAYER*>( obj.get() ) )
151 layers.push_back( layer );
152 }
153
154 LIB_ID id( wxFileName( aLibraryPath ).GetName(), EscapeString( itemName, CTX_LIBID ) );
155
156 std::unique_ptr<FOOTPRINT> footprint =
158 return ( lib.Footprints[aFootprintName] = std::move( footprint ) ).get();
159}
160
161
162std::unique_ptr<FOOTPRINT> PCB_IO_EASYPC::FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName,
163 bool aKeepUUID,
164 const std::map<std::string, UTF8>* aProperties )
165{
166 const FOOTPRINT* cached = GetEnumeratedFootprint( aLibraryPath, aFootprintName );
167
168 if( !cached )
169 return nullptr;
170
171 if( aKeepUUID )
172 return std::make_unique<FOOTPRINT>( *cached );
173
174 return std::unique_ptr<FOOTPRINT>( static_cast<FOOTPRINT*>( cached->Duplicate( IGNORE_PARENT_GROUP ) ) );
175}
176
177
178void PCB_IO_EASYPC::loadBoard( const wxString& aFileName, BOARD& aBoard, bool aIsNewLoad,
179 const std::map<std::string, UTF8>* aProperties, PROJECT* aProject )
180{
181 m_props = aProperties;
182 m_board = &aBoard;
183
185 {
186 m_progressReporter->Report( wxString::Format( _( "Loading %s..." ), aFileName ) );
187
188 if( !m_progressReporter->KeepRefreshing() )
190 }
191
192 std::unique_ptr<EASYPC::DESIGN_DOCUMENT> doc = EASYPC::LoadDesign( aFileName );
194}
const char * name
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:410
std::unique_ptr< LIBRARY_ITEM > LoadItem(const wxString &aItemName) const
Throws IO_ERROR if no item has that name.
bool HasItem(const wxString &aItemName) const
static long long Timestamp(const wxString &aPath)
A library file's modification time, 0 when it does not exist.
Layer mapping for one layer table, copper in stack order and other layers by their type.
BOARD_ITEM * Duplicate(bool addToParentGroup, BOARD_COMMIT *aCommit=nullptr) const override
Create a copy of this BOARD_ITEM.
const wxString & GetName() const
Return a brief hard coded name for this IO interface.
Definition io_base.h:79
REPORTER * m_reporter
Reporter to log errors/warnings to, may be nullptr.
Definition io_base.h:238
PROGRESS_REPORTER * m_progressReporter
Progress reporter to track the progress of the operation, may be nullptr.
Definition io_base.h:241
virtual bool CanReadLibrary(const wxString &aFileName) const
Checks if this IO object can read the specified library file/directory.
Definition io_base.cpp:71
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
LAYER_MAPPING_HANDLER m_layer_mapping_handler
Callback to get layer mapping.
A logical library item identifier and consists of various portions much like a URI.
Definition lib_id.h:45
bool CanReadBoard(const wxString &aFileName) const override
bool FootprintExists(const wxString &aLibraryPath, const wxString &aFootprintName, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Check for the existence of a footprint.
~PCB_IO_EASYPC() override
void FootprintEnumerate(wxArrayString &aFootprintNames, const wxString &aLibraryPath, bool aBestEfforts, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Return a list of footprint names contained within the library at aLibraryPath.
LIBRARY & library(const wxString &aLibraryPath)
The parsed library, reread when its modification time changes.
const FOOTPRINT * GetEnumeratedFootprint(const wxString &aLibraryPath, const wxString &aFootprintName, const std::map< std::string, UTF8 > *aProperties=nullptr) override
A version of FootprintLoad() for use after FootprintEnumerate() for more efficient cache management i...
bool CanReadLibrary(const wxString &aFileName) const override
Checks if this IO object can read the specified library file/directory.
void loadBoard(const wxString &aFileName, BOARD &aBoard, bool aIsNewLoad, const std::map< std::string, UTF8 > *aProperties=nullptr, PROJECT *aProject=nullptr) override
Parse aFileName into aBoard.
wxString m_importedDesignRules
long long GetLibraryTimestamp(const wxString &aLibraryPath) const override
Generate a timestamp representing all the files in the library (including the library directory).
std::unique_ptr< FOOTPRINT > FootprintLoad(const wxString &aLibraryPath, const wxString &aFootprintName, bool aKeepUUID=false, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Load a footprint having aFootprintName from the aLibraryPath containing a library format that this PC...
std::map< wxString, LIBRARY > m_libraries
BOARD * m_board
The board BOARD being worked on, no ownership here.
Definition pcb_io.h:393
virtual bool CanReadBoard(const wxString &aFileName) const
Definition pcb_io.cpp:40
PCB_IO(const wxString &aName)
Definition pcb_io.h:372
const std::map< std::string, UTF8 > * m_props
Properties passed via Save() or Load(), no ownership, may be NULL.
Definition pcb_io.h:396
Container for project specific data.
Definition project.h:63
Symbols, components and gates, embedded in designs or the single object of a library item stream.
Loading designs, library items and projects.
Easy-PC / DesignSpark items to KiCad board items, shared by the board builder and the ....
#define _(s)
#define IGNORE_PARENT_GROUP
Definition eda_item.h:55
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
#define THROW_IO_CANCELLED()
std::unique_ptr< FOOTPRINT > ConvertFootprint(const SOURCE_SYMBOL &aSymbol, const LAYER_MAPPER &aLayers, const LIB_ID &aId, const SOURCE_PCB_COMPONENT *aComponent, std::map< const SOURCE_FREE_PAD *, PAD * > *aPadMap)
A footprint in symbol coordinates.
wxString BuildBoard(const DESIGN_DOCUMENT &aDocument, BOARD &aBoard, REPORTER *aReporter, const LAYER_MAPPING_HANDLER &aLayerMapping)
Fill aBoard from a loaded Easy-PC / DesignSpark PCB design.
FILE_INFO Probe(const wxString &aPath)
Identify a file; projects are parsed fully, while designs and libraries are only inspected....
std::unique_ptr< DESIGN_DOCUMENT > LoadDesign(const wxString &aPath)
FILE_KIND
The FileType strings the importer reads.
Definition easypc_file.h:44
static bool isKind(const wxString &aFileName, EASYPC::FILE_KIND aKind)
PCB_IO for Number One Systems Easy-PC and RS DesignSpark PCB boards and symbol libraries (....
@ RPT_SEVERITY_WARNING
wxString UnescapeString(const wxString &aSource)
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
@ CTX_LIBID
Footprints and schematic symbols alike.
std::unique_ptr< EASYPC::LIBRARY_FILE > File
std::map< wxString, std::unique_ptr< FOOTPRINT > > Footprints