27#include <boost/property_tree/ptree.hpp>
45 bool aProcessFootprints,
bool aProcessValues,
46 bool aProcessReferences,
bool aProcessNetNames,
47 bool aProcessAttributes,
bool aProcessOtherFields,
76 m_reporter.ReportTail(
_(
"Select at least one property to back annotate." ),
101 "in stand-alone mode.\n"
102 "You must launch the KiCad project manager and create "
111 wxFileName fn(
m_frame->Prj().GetProjectFullName() );
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 )
299 refIndex =
m_refs.FindRef( pcbPath );
301 refIndex =
m_refs.FindRefByFullPath( pcbPath );
311 wxString msg = wxString::Format(
_(
"Cannot find symbol for footprint '%s'." ),
325 return SCH_REFERENCE_LIST::sortByTimeStamp( a.first, b.first );
334 while( i <
m_refs.GetCount() &&
m_refs[i].GetPath() != item.first.GetPath() )
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" );
391 msg.Printf(
_(
"Change %s reference designator to '%s'." ),
405 msg.Printf(
_(
"Change %s footprint assignment from '%s' to '%s'." ),
420 msg.Printf(
_(
"Change %s value from '%s' to '%s'." ),
434 msg.Printf(
_(
"Change %s 'Do not populate' from '%s' to '%s'." ),
436 boolString( oldDNP ),
437 boolString( fpData.
m_DNP ) );
448 msg.Printf(
_(
"Change %s 'Exclude from bill of materials' from '%s' to '%s'." ),
450 boolString( oldExBOM ),
461 for(
const std::pair<const wxString, wxString>& entry : fpData.
m_pinMap )
463 const wxString& pinNumber = entry.first;
464 const wxString& shortNetName = entry.second;
469 msg.Printf(
_(
"Cannot find %s pin '%s'." ),
479 if( connection && connection->
Name(
true ) != shortNetName )
482 connection->
Name(
true ), shortNetName );
490 for(
const std::pair<const wxString, wxString>& field : fpData.
m_fieldsMap )
492 const wxString& fpFieldName = field.first;
493 const wxString& fpFieldValue = field.second;
512 msg.Printf(
_(
"Change %s field '%s' value to '%s'." ),
518 symField->
SetText( fpFieldValue );
524 if( symField ==
nullptr )
527 msg.Printf(
_(
"Add %s field '%s' with value '%s'." ),
535 newField.
SetText( fpFieldValue );
550 if( field.IsMandatory() )
557 msg.Printf(
_(
"Delete %s field '%s.'" ),
575 m_frame->UpdateNetHighlightStatus();
577 commit.
Push(
_(
"Update Schematic from PCB" ) );
620 ORIENT o = orientations[ 0 ];
629 for(
const ORIENT& i : orientations )
631 if( i.flag == symbolOrientation )
638 for(
int i = 0; i < o.n_rots; i++ )
652 std::set<SCH_ITEM*>& connectedItems )
654 if( connectedItems.insert( aItem ).second )
664 const wxString& aOldName,
const wxString& aNewName )
672 std::set<SCH_ITEM*> connectedItems;
678 for(
SCH_ITEM* item : connectedItems )
682 if( priority > driverPriority )
685 driverPriority = priority;
689 switch( driver->
Type() )
697 msg.Printf(
_(
"Change %s pin %s net label from '%s' to '%s'." ),
719 msg.Printf(
_(
"Net %s cannot be changed to %s because it is driven by a power pin." ),
728 msg.Printf(
_(
"Add label '%s' to %s pin %s net." ),
743 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
std::pair< SCH_REFERENCE, std::shared_ptr< PCB_FP_DATA > > CHANGELIST_ITEM
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
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, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
COMMIT & Add(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Add a new item to the model.
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)
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
void SetTextPos(const VECTOR2I &aPoint)
bool HasTextVars() const
Indicates the ShownText has text var references which need to be processed.
virtual void SetVisible(bool aVisible)
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.
A pure virtual class used to derive REPORTER objects from.
These are loaded from Eeschema settings but then overwritten by the project settings.
virtual void Push(const wxString &aMessage=wxT("A commit"), int aCommitFlags=0) override
Execute the changes.
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.
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
SCH_PIN * GetLibPin() const
PIN_ORIENTATION GetOrientation() const
bool IsPower() const
Check if the pin is either a global or local power pin.
Container to create a flattened list of symbols because in a complex hierarchy, a symbol can be used ...
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()
void SetValueFieldText(const wxString &aValue)
void RemoveField(const wxString &aFieldName)
Remove a user field from the symbol.
void SetRef(const SCH_SHEET_PATH *aSheet, const wxString &aReference)
Set the reference for the given sheet path for this symbol.
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly) const override
Populate a std::vector with SCH_FIELDs, sorted in ordinal order.
void SetFootprintFieldText(const wxString &aFootprint)
VECTOR2I GetPosition() const override
SCH_FIELD * AddField(const SCH_FIELD &aField)
Add a field to the symbol.
SCH_PIN * GetPin(const wxString &number) const
Find a symbol pin by number.
int GetOrientation() const override
Get the display symbol orientation.
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this symbol.
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.
void SetDNP(bool aDNP) override
bool GetExcludedFromBoard() const override
void SetExcludedFromBOM(bool aExcludeFromBOM) override
Set or clear the exclude from schematic bill of materials flag.
bool GetDNP() const override
Set or clear the 'Do Not Populate' flag.
bool GetExcludedFromBOM() const override
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
@ USER
The field ID hasn't been set yet; field is invalid.
@ FOOTPRINT
Field Name Module PCB, i.e. "16DIP300".
@ REFERENCE
Field Reference of part, i.e. "IC21".
@ VALUE
Field Value of part, i.e. "3.3K".
wxString GetCanonicalFieldName(FIELD_T aFieldType)
VECTOR2< int32_t > VECTOR2I
Definition of file extensions used in Kicad.