27#include <boost/property_tree/ptree.hpp>
45 bool aProcessFootprints,
bool aProcessValues,
46 bool aProcessReferences,
bool aProcessNetNames,
47 bool aProcessAttributes,
bool aProcessOtherFields,
49 m_reporter( aReporter ),
50 m_matchByReference( aRelinkFootprints ),
51 m_processFootprints( aProcessFootprints ),
52 m_processValues( aProcessValues ),
53 m_processReferences( aProcessReferences ),
54 m_processNetNames( aProcessNetNames ),
55 m_processAttributes( aProcessAttributes ),
56 m_processOtherFields( aProcessOtherFields ),
101 "in stand-alone mode.\n"
102 "You must launch the KiCad project manager and create "
112 fn.SetExt( FILEEXT::PcbFileExtension );
125 std::string nullPayload;
133 auto getStr = [](
const PTREE& pt ) -> wxString
135 return UTF8( pt.front().first );
145 Scan( &doc, &lexer );
147 PTREE& tree = doc.get_child(
"pcb_netlist" );
151 for(
const std::pair<const std::string, PTREE>& item : tree )
153 wxString
path, value, footprint;
154 bool dnp =
false, exBOM =
false;
155 std::map<wxString, wxString> pinNetMap, fieldsMap;
156 wxASSERT( item.first ==
"ref" );
157 wxString ref = getStr( item.second );
164 path = getStr( item.second.get_child(
"timestamp" ) );
168 msg.Printf(
_(
"Footprint '%s' has no assigned symbol." ), ref );
173 footprint = getStr( item.second.get_child(
"fpid" ) );
174 value = getStr( item.second.get_child(
"value" ) );
177 boost::optional<const PTREE&> fields = item.second.get_child_optional(
"fields" );
182 for(
const std::pair<const std::string, PTREE>& field : fields.get() )
184 if( field.first !=
"field" )
188 const auto& fieldName = field.second.get_child_optional(
"name" );
189 const std::string& fieldValue = field.second.back().first;
194 fieldsMap[getStr( fieldName.get() )] = wxString::FromUTF8( fieldValue );
200 for(
const auto& child : item.second )
202 if( child.first !=
"property" )
205 auto property = child.second;
206 auto name =
property.get_child_optional(
"name" );
211 if(
name.get().front().first ==
"dnp" )
215 else if(
name.get().front().first ==
"exclude_from_bom" )
221 boost::optional<const PTREE&> nets = item.second.get_child_optional(
"nets" );
225 for(
const std::pair<const std::string, PTREE>& pin_net : nets.get() )
227 wxASSERT( pin_net.first ==
"pin_net" );
228 wxString pinNumber =
UTF8( pin_net.second.front().first );
229 wxString netName =
UTF8( pin_net.second.back().first );
230 pinNetMap[ pinNumber ] = netName;
236 wxLogWarning(
"Cannot parse PCB netlist for back-annotation." );
245 msg.Printf(
_(
"Footprints '%s' and '%s' linked to same symbol." ),
246 nearestItem->second->m_ref,
253 auto data = std::make_shared<PCB_FP_DATA>( ref, footprint, value, dnp, exBOM,
254 pinNetMap, fieldsMap );
263 for( std::pair<
const wxString, std::shared_ptr<PCB_FP_DATA>>& fpData :
m_pcbFootprints )
265 const wxString& pcbPath = fpData.first;
266 auto& pcbData = fpData.second;
268 bool foundInMultiunit =
false;
270 for( std::pair<const wxString, SCH_REFERENCE_LIST>& item :
m_multiUnitsRefs )
275 refIndex = refList.
FindRef( pcbPath );
283 foundInMultiunit =
true;
285 for(
size_t i = 0; i < refList.
GetCount(); ++i )
287 refList[ i ].GetSymbol()->ClearFlags(
SKIP_STRUCT );
295 if( foundInMultiunit )
311 wxString msg = wxString::Format(
_(
"Cannot find symbol for footprint '%s'." ),
325 return SCH_REFERENCE_LIST::sortByTimeStamp( a.first, b.first );
340 wxString msg = wxString::Format(
_(
"Footprint '%s' is not present on PCB. "
341 "Corresponding symbols in schematic must be "
342 "manually deleted (if desired)." ),
354 "annotated schematic." ) ) )
380 [](
bool b ) -> wxString
382 return b ?
_(
"true" ) :
_(
"false" );
388 msg.Printf(
_(
"Change %s reference designator to '%s'." ),
394 commit.
Modify( symbol, screen );
404 msg.Printf(
_(
"Change %s footprint assignment from '%s' to '%s'." ),
411 commit.
Modify( symbol, screen );
421 msg.Printf(
_(
"Change %s value from '%s' to '%s'." ),
428 commit.
Modify( symbol, screen );
438 msg.Printf(
_(
"Change %s 'Do not populate' from '%s' to '%s'." ),
440 boolString( oldDNP ),
441 boolString( fpData.
m_DNP ) );
445 commit.
Modify( symbol, screen );
455 msg.Printf(
_(
"Change %s 'Exclude from bill of materials' from '%s' to '%s'." ),
457 boolString( oldExBOM ),
462 commit.
Modify( symbol, screen );
471 for(
const std::pair<const wxString, wxString>& entry : fpData.
m_pinMap )
473 const wxString& pinNumber = entry.first;
474 const wxString& shortNetName = entry.second;
479 msg.Printf(
_(
"Cannot find %s pin '%s'." ),
489 if( connection && connection->
Name(
true ) != shortNetName )
492 connection->
Name(
true ), shortNetName );
500 for(
const std::pair<const wxString, wxString>& field : fpData.
m_fieldsMap )
502 const wxString& fpFieldName = field.first;
503 const wxString& fpFieldValue = field.second;
522 msg.Printf(
_(
"Change %s field '%s' value to '%s'." ),
529 commit.
Modify( symbol, screen );
530 symField->
SetText( fpFieldValue );
537 if( symField ==
nullptr )
540 msg.Printf(
_(
"Add %s field '%s' with value '%s'." ),
547 commit.
Modify( symbol, screen );
551 newField.
SetText( fpFieldValue );
564 if( field.IsMandatory() )
567 if( fpData.
m_fieldsMap.find( field.GetCanonicalName() )
572 msg.Printf(
_(
"Delete %s field '%s.'" ),
578 commit.
Modify( symbol, screen );
595 commit.
Push(
_(
"Update Schematic from PCB" ) );
638 ORIENT o = orientations[ 0 ];
647 for(
const ORIENT& i : orientations )
649 if( i.flag == symbolOrientation )
656 for(
int i = 0; i < o.n_rots; i++ )
670 std::set<SCH_ITEM*>& connectedItems )
672 if( connectedItems.insert( aItem ).second )
682 const wxString& aOldName,
const wxString& aNewName )
690 std::set<SCH_ITEM*> connectedItems;
696 for(
SCH_ITEM* item : connectedItems )
700 if( priority > driverPriority )
703 driverPriority = priority;
707 switch( driver->
Type() )
715 msg.Printf(
_(
"Change %s pin %s net label from '%s' to '%s'." ),
737 msg.Printf(
_(
"Net %s cannot be changed to %s because it is driven by a power pin." ),
746 msg.Printf(
_(
"Add label '%s' to %s pin %s net." ),
761 aCommit->
Add( label, screen );
void addConnections(SCH_ITEM *aItem, const SCH_SHEET_PATH &aSheetPath, std::set< SCH_ITEM * > &connectedItems)
static SPIN_STYLE orientLabel(SCH_PIN *aPin)
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
bool BackAnnotateSymbols(const std::string &aNetlist)
Run back annotation algorithm.
SCH_MULTI_UNIT_REFERENCE_MAP m_multiUnitsRefs
std::deque< CHANGELIST_ITEM > m_changelist
BACK_ANNOTATE(SCH_EDIT_FRAME *aFrame, REPORTER &aReporter, bool aRelinkFootprints, bool aProcessFootprints, bool aProcessValues, bool aProcessReferences, bool aProcessNetNames, bool aProcessAttributes, bool aProcessOtherFields, bool aDryRun)
bool m_processOtherFields
void getPcbModulesFromString(const std::string &aPayload)
Parse netlist sent over KiWay express mail interface and fill m_pcbModules.
void checkForUnusedSymbols()
Check if some symbols are not represented in PCB footprints and vice versa.
SCH_REFERENCE_LIST m_refs
bool FetchNetlistFromPCB(std::string &aNetlist)
Get netlist from the Pcbnew.
PCB_FOOTPRINTS_MAP m_pcbFootprints
std::pair< SCH_REFERENCE, std::shared_ptr< PCB_FP_DATA > > CHANGELIST_ITEM
void processNetNameChange(SCH_COMMIT *aCommit, const wxString &aRef, SCH_PIN *aPin, const SCH_CONNECTION *aConnection, const wxString &aOldName, const wxString &aNewName)
void applyChangelist()
Apply changelist to the schematic.
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Create an undo entry for an item that has been already modified.
COMMIT & Add(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Notify observers that aItem has been added.
PRIORITY GetDriverPriority()
Implement a lexical analyzer for the SPECCTRA DSN file format.
virtual VECTOR2I GetPosition() const
void SetFlags(EDA_ITEM_FLAGS aMask)
KICAD_T Type() const
Returns the type of object.
virtual void SetParent(EDA_ITEM *aParent)
EDA_ITEM_FLAGS GetFlags() const
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
KIWAY & Kiway() const
Return a reference to the KIWAY that this object has an opportunity to participate in.
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
virtual bool OpenProjectFiles(const std::vector< wxString > &aFileList, int aCtl=0)
Open a project or set of files given by aFileList.
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
virtual void ExpressMail(FRAME_T aDestination, MAIL_T aCommand, std::string &aPayload, wxWindow *aSource=nullptr)
Send aPayload to aDestination from aSource.
virtual const wxString GetProjectFullName() const
Return the full path and name of the project.
A pure virtual class used to derive REPORTER objects from.
virtual REPORTER & ReportHead(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Places the report at the beginning of the list for objects that support ordering.
virtual REPORTER & ReportTail(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Places the report at the end of the list, for objects that support report ordering.
These are loaded from Eeschema settings but then overwritten by the project settings.
SCHEMATIC_SETTINGS & Settings() const
SCH_SHEET_LIST Hierarchy() const override
Return the full schematic flattened hierarchical sheet list.
virtual void Push(const wxString &aMessage=wxT("A commit"), int aCommitFlags=0) override
Revert the commit by restoring the modified items state.
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
SCH_SHEET_PATH Sheet() const
wxString Name(bool aIgnoreSheet=false) const
Schematic editor (Eeschema) main window.
bool ReadyToNetlist(const wxString &aAnnotateMessage)
Check if we are ready to write a netlist file for the current schematic.
SCHEMATIC & Schematic() const
void RecalculateConnections(SCH_COMMIT *aCommit, SCH_CLEANUP_FLAGS aCleanupFlags)
Generate the connection data for the entire schematic hierarchy.
void UpdateNetHighlightStatus()
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
wxString GetCanonicalName() const
Get a non-language-specific name for a field which can be used for storage, variable look-up,...
wxString GetShownText(const SCH_SHEET_PATH *aPath, bool aAllowExtraText, int aDepth=0) const
void SetText(const wxString &aText) override
Base class for any item which can be embedded within the SCHEMATIC container class,...
const SCH_ITEM_VEC & ConnectedItems(const SCH_SHEET_PATH &aPath)
Retrieve the set of items connected to this item on the given sheet.
const SYMBOL * GetParentSymbol() const
virtual void SetSpinStyle(SPIN_STYLE aSpinStyle)
wxString GetShownNumber() const
bool IsGlobalPower() const
Return whether this pin forms a global power connection: i.e., is part of a power symbol and of type ...
SCH_PIN * GetLibPin() const
PIN_ORIENTATION GetOrientation() const
Container to create a flattened list of symbols because in a complex hierarchy, a symbol can be used ...
void SortByTimeStamp()
Sort the flat list by Time Stamp (sheet path + timestamp).
int FindRef(const wxString &aPath) const
Search the list for a symbol with a given reference.
int FindRefByFullPath(const wxString &aFullPath) const
Search the list for a symbol with the given KIID path (as string).
A helper to define a symbol's reference designator in a schematic.
const SCH_SHEET_PATH & GetSheetPath() const
const wxString GetFootprint() const
SCH_SYMBOL * GetSymbol() const
const wxString GetValue() const
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
void GetMultiUnitSymbols(SCH_MULTI_UNIT_REFERENCE_MAP &aRefList, bool aIncludePowerSymbols=true) const
Add a SCH_REFERENCE_LIST object to aRefList for each same-reference set of multi-unit parts in the li...
void GetSymbols(SCH_REFERENCE_LIST &aReferences, bool aIncludePowerSymbols=true, bool aForceIncludeOrphanSymbols=false) const
Add a SCH_REFERENCE object to aReferences for each symbol in the list of sheets.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
SCH_SCREEN * LastScreen()
int GetFieldCount() const
Return the number of fields in this symbol.
void SetValueFieldText(const wxString &aValue)
void RemoveField(const wxString &aFieldName)
Remove a user field from the symbol.
SCH_FIELD * FindField(const wxString &aFieldName, bool aIncludeDefaultFields=true, bool aCaseInsensitive=false)
Search for a SCH_FIELD with aFieldName.
void SetRef(const SCH_SHEET_PATH *aSheet, const wxString &aReference)
Set the reference for the given sheet path for this symbol.
void SetFootprintFieldText(const wxString &aFootprint)
SCH_FIELD * AddField(const SCH_FIELD &aField)
Add a field to the symbol.
int GetOrientation() const
Get the display symbol orientation.
SCH_PIN * GetPin(const wxString &number) const
Find a symbol pin by number.
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly)
Populate a std::vector with SCH_FIELDs.
SPIN_STYLE MirrorX()
Mirror the label spin style across the X axis or simply swaps up and bottom.
SPIN_STYLE MirrorY()
Mirror the label spin style across the Y axis or simply swaps left and right.
bool GetExcludedFromBoard() const
bool GetExcludedFromBOM() const
bool GetDNP() const
Set or clear the 'Do Not Populate' flaga.
void SetExcludedFromBOM(bool aExcludeFromBOM)
Set or clear the exclude from schematic bill of materials flag.
An 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to and fro...
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
This file is part of the common library.
#define IS_NEW
New item, just created.
#define SKIP_STRUCT
flag indicating that the structure should be ignored
@ PIN_UP
The pin extends upwards from the connection point: Probably on the bottom side of the symbol.
@ PIN_RIGHT
The pin extends rightwards from the connection point.
@ PIN_LEFT
The pin extends leftwards from the connection point: Probably on the right side of the symbol.
@ PIN_DOWN
The pin extends downwards from the connection: Probably on the top side of the symbol.
void Scan(PTREE *aTree, DSNLEXER *aLexer)
Fill an empty PTREE with information from a KiCad s-expression stream.
boost::property_tree::ptree PTREE
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
wxString EscapeHTML(const wxString &aString)
Return a new wxString escaped for embedding in HTML.
wxString From_UTF8(const char *cstring)
Container for Pcbnew footprint data.Map to hold NETLIST footprints data.
std::map< wxString, wxString > m_pinMap
std::map< wxString, wxString > m_fieldsMap
wxString GetCanonicalFieldName(int idx)
@ FOOTPRINT_FIELD
Field Name Module PCB, i.e. "16DIP300".
@ VALUE_FIELD
Field Value of part, i.e. "3.3K".
@ REFERENCE_FIELD
Field Reference of part, i.e. "IC21".
VECTOR2< int32_t > VECTOR2I
Definition of file extensions used in Kicad.