26#include <wx/tokenzr.h>
56 const wxString& aSearchText )
64 if( !aSearchHierarchy )
65 sheetList.push_back(
m_frame->GetCurrentSheet() );
67 sheetList =
m_frame->Schematic().Hierarchy();
83 found = ( *aPath ==
path );
87 found = ( aReference && aReference->CmpNoCase( candidate->
GetRef( &sheet ) ) == 0 );
93 sheetWithSymbolFound = &sheet;
102 int unit =
pin->GetLibPin()->GetUnit();
104 if( unit != 0 && unit != symbol->
GetUnit() )
131 if( *sheetWithSymbolFound !=
m_frame->GetCurrentSheet() )
134 sheetWithSymbolFound );
149 m_frame->FocusOnItem( symbol );
158 displayRef = *aReference;
167 msg.Printf(
_(
"%s pin %s found" ), displayRef, aSearchText );
169 msg.Printf(
_(
"%s found but pin %s not found" ), displayRef, aSearchText );
173 msg.Printf(
_(
"%s found" ), displayRef );
178 msg.Printf(
_(
"%s not found" ), displayRef );
182 m_frame->GetCanvas()->Refresh();
207 strncpy( line, cmdline,
sizeof( line ) - 1 );
208 line[
sizeof( line ) - 1 ] =
'\0';
210 char* idcmd = strtok( line,
" \n\r" );
211 char*
text = strtok(
nullptr,
"\"\n\r" );
213 if( idcmd ==
nullptr )
218 if( strcmp( idcmd,
"$CONFIG" ) == 0 )
223 else if( strcmp( idcmd,
"$ERC" ) == 0 )
228 else if( strcmp( idcmd,
"$NET:" ) == 0 )
235 if(
auto sg =
Schematic().ConnectionGraph()->FindFirstSubgraphByName( netName ) )
243 SetStatusText(
_(
"Highlighted net:" ) + wxS(
" " ) +
UnescapeString( netName ) );
246 else if( strcmp( idcmd,
"$CLEAR:" ) == 0 )
255 if(
text ==
nullptr )
258 if( strcmp( idcmd,
"$PART:" ) != 0 )
264 idcmd = strtok(
nullptr,
" \n\r" );
266 if( idcmd ==
nullptr )
273 text = strtok(
nullptr,
"\"\n\r" );
275 if(
text ==
nullptr )
280 if( strcmp( idcmd,
"$REF:" ) == 0 )
286 else if( strcmp( idcmd,
"$VAL:" ) == 0 )
292 else if( strcmp( idcmd,
"$PAD:" ) == 0 )
305 std::vector<wxString> parts;
309 switch( item->Type() )
326 parts.push_back( wxT(
"S" ) + full_path );
349 std::string command =
"$SELECT: 0,";
351 for( wxString part : parts )
378 std::string packet = fmt::format(
"$NET: \"{}\"",
TO_UTF8( aNetName ) );
380 if( !packet.empty() )
405 if( aConnection->
IsNet() )
411 if( aConnection->
Members().empty() )
416 wxString nets = all_members[0]->Name();
418 if( all_members.size() == 1 )
428 for(
size_t i = 1; i < all_members.size(); i++ )
429 nets <<
"," << all_members[i]->Name();
431 std::string packet = fmt::format(
"$NETS: \"{}\"",
TO_UTF8( nets ) );
433 if( !packet.empty() )
450 std::string packet =
"$CLEAR\n";
468 std::unordered_map<wxString, std::vector<SCH_REFERENCE>>& aSyncSymMap,
469 std::unordered_map<wxString, std::unordered_map<wxString, SCH_PIN*>>& aSyncPinMap,
470 bool aRecursive =
false )
487 aSheetPath.
GetSymbols( references,
false,
true );
489 for(
unsigned ii = 0; ii < references.
GetCount(); ii++ )
498 wxString fullRef = schRef.
GetRef() + refNum;
501 if( fullRef.StartsWith( wxS(
"#" ) ) )
505 if( refNum.compare( wxS(
"?" ) ) == 0 )
509 auto symMatchIt = aSyncSymMap.find( fullRef );
511 if( symMatchIt != aSyncSymMap.end() )
513 symMatchIt->second.emplace_back( schRef );
520 auto symPinMatchIt = aSyncPinMap.find( fullRef );
522 if( symPinMatchIt != aSyncPinMap.end() )
524 std::unordered_map<wxString, SCH_PIN*>& pinMap = symPinMatchIt->second;
525 std::vector<SCH_PIN*> pinsOnSheet = symbol->
GetPins( &aSheetPath );
529 int pinUnit =
pin->GetLibPin()->GetUnit();
531 if( pinUnit > 0 && pinUnit != schRef.
GetUnit() )
534 auto pinIt = pinMap.find(
pin->GetNumber() );
536 if( pinIt != pinMap.end() )
548 std::unordered_map<wxString, std::vector<SCH_REFERENCE>>& aSyncSymMap,
549 std::unordered_map<wxString, std::unordered_map<wxString, SCH_PIN*>>& aSyncPinMap,
550 std::unordered_map<SCH_SHEET_PATH, bool>& aCache )
552 auto cacheIt = aCache.find( aSheetPath );
554 if( cacheIt != aCache.end() )
555 return cacheIt->second;
564 aSyncPinMap, aCache );
568 aCache.emplace( aSheetPath,
false );
574 aSheetPath.
GetSymbols( references,
false,
true );
578 aCache.emplace( aSheetPath,
false );
582 for(
unsigned ii = 0; ii < references.
GetCount(); ii++ )
590 wxString fullRef = schRef.
GetRef() + refNum;
593 if( fullRef.StartsWith( wxS(
"#" ) ) )
597 if( refNum.compare( wxS(
"?" ) ) == 0 )
600 if( aSyncSymMap.find( fullRef ) == aSyncSymMap.end() )
602 aCache.emplace( aSheetPath,
false );
606 if( aSyncPinMap.find( fullRef ) != aSyncPinMap.end() )
608 aCache.emplace( aSheetPath,
false );
613 aCache.emplace( aSheetPath,
true );
618std::optional<std::tuple<SCH_SHEET_PATH, SCH_ITEM*, std::vector<SCH_ITEM*>>>
622 wxArrayString syncArray = wxStringTokenize( aSyncStr, wxS(
"," ) );
624 std::unordered_map<wxString, std::vector<SCH_REFERENCE>> syncSymMap;
625 std::unordered_map<wxString, std::unordered_map<wxString, SCH_PIN*>> syncPinMap;
626 std::unordered_map<SCH_SHEET_PATH, double> symScores;
627 std::unordered_map<SCH_SHEET_PATH, bool> fullyWantedCache;
629 std::optional<wxString> focusSymbol;
630 std::optional<std::pair<wxString, wxString>> focusPin;
631 std::unordered_map<SCH_SHEET_PATH, std::vector<SCH_ITEM*>> focusItemResults;
636 std::vector<SCH_SHEET_PATH> orderedSheets;
637 orderedSheets.reserve( allSheetsList.size() );
643 orderedSheets.push_back( sheetPath );
647 for(
size_t i = 0; i < syncArray.size(); i++ )
649 wxString syncEntry = syncArray[i];
651 if( syncEntry.empty() )
654 wxString syncData = syncEntry.substr( 1 );
656 switch( syncEntry.GetChar( 0 ).GetValue() )
662 if( aFocusOnFirst && ( i == 0 ) )
663 focusSymbol = symRef;
665 syncSymMap[symRef] = std::vector<SCH_REFERENCE>();
674 if( aFocusOnFirst && ( i == 0 ) )
675 focusPin = std::make_pair( symRef, padNum );
677 syncPinMap[symRef][padNum] =
nullptr;
687 auto flattenSyncMaps =
688 [&syncSymMap, &syncPinMap]() -> std::vector<SCH_ITEM*>
690 std::vector<SCH_ITEM*> allVec;
692 for(
const auto& [symRef, symbols] : syncSymMap )
695 allVec.push_back( ref.GetSymbol() );
698 for(
const auto& [symRef, pinMap] : syncPinMap )
700 for(
const auto& [padNum,
pin] : pinMap )
703 allVec.push_back(
pin );
711 [&syncSymMap, &syncPinMap]()
713 for(
auto& [symRef, symbols] : syncSymMap )
716 for(
auto& [reference, pins] : syncPinMap )
718 for(
auto& [number,
pin] : pins )
723 auto syncMapsValuesEmpty =
724 [&syncSymMap, &syncPinMap]() ->
bool
726 for(
const auto& [symRef, symbols] : syncSymMap )
728 if( symbols.size() > 0 )
732 for(
const auto& [symRef, pins] : syncPinMap )
734 for(
const auto& [padNum,
pin] : pins )
744 auto checkFocusItems =
749 auto findIt = syncSymMap.find( *focusSymbol );
751 if( findIt != syncSymMap.end() )
753 if( findIt->second.size() > 0 )
754 focusItemResults[aSheet].push_back( findIt->second.front().GetSymbol() );
759 auto findIt = syncPinMap.find( focusPin->first );
761 if( findIt != syncPinMap.end() )
763 if( findIt->second[focusPin->second] )
764 focusItemResults[aSheet].push_back( findIt->second[focusPin->second] );
769 auto makeRetForSheet =
776 std::vector<SCH_ITEM*> itemsVector = flattenSyncMaps();
782 kiidPath.push_back( item->m_Uuid );
784 std::optional<SCH_SHEET_PATH> subsheetPath =
791 syncPinMap, fullyWantedCache ) )
793 itemsVector.push_back( item );
797 return std::make_tuple( aSheet, aFocusItem, itemsVector );
808 checkFocusItems( sheetPath );
811 if( focusItemResults.size() > 0 )
815 const std::vector<SCH_ITEM*>& items = focusItemResults[sheetPath];
818 return makeRetForSheet( sheetPath, items.front() );
830 if( !syncMapsValuesEmpty() )
833 return makeRetForSheet( sheetPath,
nullptr );
850 std::stringstream ss( payload );
858 wxCHECK_RET( optTable.has_value(),
"Could not load symbol lib table." );
864 std::string srcProjDir;
865 std::getline( ss, srcProjDir,
'\n' );
867 std::vector<wxString> toLoad;
869 while( std::getline( ss, file,
'\n' ) )
874 wxFileName fn( file );
878 if( type == SCH_IO_MGR::SCH_FILE_UNKNOWN )
880 wxLogTrace(
"KIWAY",
"Unknown file type: %s", fn.GetFullPath() );
884 pi.reset( SCH_IO_MGR::FindPlugin( type ) );
886 wxString libTableUri;
887 bool isProjectLocal = fn.GetFullPath().StartsWith( wxString( srcProjDir ) );
893 if( !fn.FileExists() )
896 wxFileName projectFn( projectPath, fn.GetFullName() );
898 if( fn.GetFullPath() != projectFn.GetFullPath() && !projectFn.FileExists() )
899 wxCopyFile( fn.GetFullPath(), projectFn.GetFullPath() );
901 libTableUri = wxS(
"${KIPRJMOD}/" ) + fn.GetFullName();
906 libTableUri = fn.GetFullPath();
909 if( !
table->HasRow( fn.GetName() ) )
913 row.
SetURI( libTableUri );
915 toLoad.emplace_back( fn.GetName() );
919 if( !toLoad.empty() )
923 table->Save().map_error(
926 wxLogError( wxT(
"Error saving project library table:\n\n" ) + aError.
message );
934 std::ranges::for_each( toLoad,
935 [adapter](
const wxString& aNick )
954 if( !
eeconfig()->m_CrossProbing.on_selection )
968 std::string prefix =
"$SELECT: ";
970 std::string paramStr = payload.substr( prefix.size() );
973 if( paramStr.size() < 2 )
976 std::string syncStr = paramStr.substr( 2 );
978 bool focusOnFirst = ( paramStr[0] ==
'1' );
980 std::optional<std::tuple<SCH_SHEET_PATH, SCH_ITEM*, std::vector<SCH_ITEM*>>> findRet =
985 auto& [sheetPath, focusItem, items] = *findRet;
994 if(
eeconfig()->m_CrossProbing.flash_selection )
996 wxLogTrace(
traceCrossProbeFlash,
"MAIL_SELECTION(_FORCE): flash enabled, items=%zu", items.size() );
1003 std::vector<SCH_ITEM*> itemPtrs;
1004 std::copy( items.begin(), items.end(), std::back_inserter( itemPtrs ) );
1020 if( !payload.empty() )
1022 wxString annotationMessage( payload );
1043 KIID uuid( payload );
1049 payload =
static_cast<SCH_SHEET*
>( item )->GetShownName(
false );
1051 payload =
static_cast<SCH_SYMBOL*
>( item )->GetRef( &
path,
true );
1053 payload = item->GetFriendlyName();
1083 std::stringstream ss( payload );
1086 std::string formatStr;
1087 wxCHECK( std::getline( ss, formatStr, delim ), );
1089 std::string fnameStr;
1090 wxCHECK( std::getline( ss, fnameStr, delim ), );
1096 importFormat = std::stoi( formatStr );
1098 catch( std::invalid_argument& )
1104 std::map<std::string, UTF8> props;
1108 std::string key, value;
1110 if( !std::getline( ss, key, delim ) )
1113 std::getline( ss, value, delim );
1115 props.emplace( key, value );
1119 if( importFormat >= 0 )
1120 importFile( fnameStr, importFormat, props.empty() ?
nullptr : &props );
1127 payload =
"success";
1149 if( !errors.IsEmpty() )
1150 statusBar->SetLoadWarningMessages( errors );
1158 wxString targetFile( payload );
1164 if( screen && screen->
GetFileName() == targetFile )
1167 payload =
"success";
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
static TOOL_ACTION showSymbolLibTable
static TOOL_ACTION updateSchematicFromPcb
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
CROSS_PROBING_SETTINGS m_CrossProbing
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
A base class for most all the KiCad significant classes used in schematics and boards.
EE_TYPE OfType(KICAD_T aType) const
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
void UpdateAllItems(int aUpdateFlags)
Update all items in the view according to the given flags.
wxString AsString() const
Carry a payload from one KIWAY_PLAYER to another within a PROJECT.
std::string & GetPayload()
Return the payload, which can be any text but it typically self identifying s-expression.
MAIL_T Command()
Returns the MAIL_T associated with this mail.
virtual void ExpressMail(FRAME_T aDestination, MAIL_T aCommand, std::string &aPayload, wxWindow *aSource=nullptr, bool aFromOtherThread=false)
Send aPayload to aDestination from aSource.
wxString GetLibraryLoadErrors() const
Returns all library load errors as newline-separated strings for display.
std::optional< LIBRARY_TABLE * > Table(LIBRARY_TABLE_TYPE aType, LIBRARY_TABLE_SCOPE aScope)
Retrieves a given table; creating a new empty project table if a valid project is loaded and the give...
void LoadProjectTables(std::initializer_list< LIBRARY_TABLE_TYPE > aTablesToLoad={})
(Re)loads the project library tables in the given list, or all tables if no list is given
void SetNickname(const wxString &aNickname)
void SetType(const wxString &aType)
void SetURI(const wxString &aUri)
Generate the KiCad netlist format supported by Pcbnew.
void Format(OUTPUTFORMATTER *aOutputFormatter, int aCtl)
Output this s-expression netlist into aOutputFormatter.
virtual LIBRARY_MANAGER & GetLibraryManager() const
static SYMBOL_LIBRARY_ADAPTER * SymbolLibAdapter(PROJECT *aProject)
Accessor for project symbol library manager adapter.
virtual const wxString GetProjectPath() const
Return the full path of the project.
Holds all the data relating to one schematic.
SCH_SHEET_LIST Hierarchy() const
Return the full schematic flattened hierarchical sheet list.
SCH_SHEET_PATH & CurrentSheet() const
static TOOL_ACTION runERC
Inspection and Editing.
static TOOL_ACTION changeSheet
static TOOL_ACTION updateNetHighlighting
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
void SyncView()
Mark all items for refresh.
EESCHEMA_SETTINGS * eeconfig() const
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
const std::vector< std::shared_ptr< SCH_CONNECTION > > AllMembers() const
wxString Name(bool aIgnoreSheet=false) const
const std::vector< std::shared_ptr< SCH_CONNECTION > > & Members() const
KIGFX::SCH_VIEW * GetView() const override
Return a pointer to the #VIEW instance used in the panel.
void AssignFootprints(const std::string &aChangedSetOfReferences)
SCH_ITEM * FindSymbolAndItem(const wxString *aPath, const wxString *aReference, bool aSearchHierarchy, SCH_SEARCH_T aSearchType, const wxString &aSearchText)
Find a symbol in the schematic and an item in this symbol and select it.
bool ReadyToNetlist(const wxString &aAnnotateMessage)
Check if we are ready to write a netlist file for the current schematic.
bool m_syncingPcbToSchSelection
friend class SCH_EDITOR_CONTROL
void SendSelectItemsToPcb(const std::vector< EDA_ITEM * > &aItems, bool aForce)
Send items to board editor for selection.
void SendCrossProbeClearHighlight()
Tell Pcbnew to clear the existing highlighted net, if one exists.
SCHEMATIC * m_schematic
The currently loaded schematic.
SCH_SHEET_PATH & GetCurrentSheet() const
void RecalculateConnections(SCH_COMMIT *aCommit, SCH_CLEANUP_FLAGS aCleanupFlags, PROGRESS_REPORTER *aProgressReporter=nullptr)
Generate the connection data for the entire schematic hierarchy.
SCHEMATIC & Schematic() const
void ExecuteRemoteCommand(const char *cmdline) override
Execute a remote command sent via a socket on port KICAD_SCH_PORT_SERVICE_NUMBER (which defaults to 4...
void RefreshNetNavigator(const NET_NAVIGATOR_ITEM_DATA *aSelection=nullptr)
SCH_DESIGN_BLOCK_PANE * m_designBlocksPane
bool importFile(const wxString &aFileName, int aFileType, const std::map< std::string, UTF8 > *aProperties=nullptr)
Load the given filename but sets the path to the current project path.
void SendCrossProbeNetName(const wxString &aNetName)
Send a net name to Pcbnew for highlighting.
void KiwayMailIn(KIWAY_MAIL_EVENT &aEvent) override
Receive #KIWAY_ROUTED_EVENT messages from other players.
void StartCrossProbeFlash(const std::vector< SCH_ITEM * > &aItems)
wxString m_highlightedConn
The highlighted net or bus or empty string.
void SetCrossProbeConnection(const SCH_CONNECTION *aConnection)
Send a connection (net or bus) to Pcbnew for highlighting.
void TestDanglingEnds()
Test all of the connectable objects in the schematic for unused connection points.
bool SaveProject(bool aSaveAs=false)
Save the currently-open schematic (including its hierarchy) and associated project.
virtual const wxString & GetText() const override
Return the string associated with the text object.
static const wxString ShowType(SCH_FILE_T aFileType)
Return a brief name for a plugin, given aFileType enum.
static SCH_FILE_T GuessPluginTypeFromLibPath(const wxString &aLibPath, int aCtl=0)
Return a plugin type given a symbol library using the file extension of aLibPath.
Base class for any item which can be embedded within the SCHEMATIC container class,...
Container to create a flattened list of symbols because in a complex hierarchy, a symbol can be used ...
A helper to define a symbol's reference designator in a schematic.
void Split()
Attempt to split the reference designator into a name (U) and number (1).
bool IsSplitNeeded()
Determine if this reference needs to be split or if it likely already has been.
SCH_SYMBOL * GetSymbol() const
wxString GetRefNumber() const
EE_RTREE & Items()
Get the full RTree, usually for iterating.
const wxString & GetFileName() const
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
std::optional< SCH_SHEET_PATH > GetSheetPathByKIIDPath(const KIID_PATH &aPath, bool aIncludeLastSheet=true) const
Finds a SCH_SHEET_PATH that matches the provided KIID_PATH.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
void GetSymbols(SCH_REFERENCE_LIST &aReferences, bool aIncludePowerSymbols=true, bool aForceIncludeOrphanSymbols=false) const
Adds SCH_REFERENCE object to aReferences for each symbol in the sheet.
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
SCH_SCREEN * LastScreen()
bool IsContainedWithin(const SCH_SHEET_PATH &aSheetPathToTest) const
Check if this path is contained inside aSheetPathToTest.
wxString PathAsString() const
Return the path of time stamps which do not changes even when editing sheet parameters.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
std::vector< const SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet) const
Retrieve a list of the SCH_PINs for the given sheet path.
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
SCH_PIN * GetPin(const wxString &number) const
Find a symbol pin by number.
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const override
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this symbol.
An interface to the global shared library manager that is schematic-specific and linked to one projec...
std::optional< LIB_STATUS > LoadOne(LIB_DATA *aLib) override
Loads or reloads the given library, if it exists.
A base class for LIB_SYMBOL and SCH_SYMBOL.
virtual const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const =0
bool SendCommand(int aService, const std::string &aMessage)
Used by a client to sent (by a socket connection) a data to a server.
std::optional< std::tuple< SCH_SHEET_PATH, SCH_ITEM *, std::vector< SCH_ITEM * > > > findItemsFromSyncSelection(const SCHEMATIC &aSchematic, const std::string aSyncStr, bool aFocusOnFirst)
bool findSymbolsAndPins(const SCH_SHEET_LIST &aSchematicSheetList, const SCH_SHEET_PATH &aSheetPath, std::unordered_map< wxString, std::vector< SCH_REFERENCE > > &aSyncSymMap, std::unordered_map< wxString, std::unordered_map< wxString, SCH_PIN * > > &aSyncPinMap, bool aRecursive=false)
bool sheetContainsOnlyWantedItems(const SCH_SHEET_LIST &aSchematicSheetList, const SCH_SHEET_PATH &aSheetPath, std::unordered_map< wxString, std::vector< SCH_REFERENCE > > &aSyncSymMap, std::unordered_map< wxString, std::unordered_map< wxString, SCH_PIN * > > &aSyncPinMap, std::unordered_map< SCH_SHEET_PATH, bool > &aCache)
@ FRAME_SCH_SYMBOL_EDITOR
const wxChar *const traceCrossProbeFlash
Flag to enable debug output for cross-probe flash operations.
std::unique_ptr< T > IO_RELEASER
Helper to hold and release an IO_BASE object when exceptions are thrown.
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
@ MAIL_SCH_NAVIGATE_TO_SHEET
@ ALL
All except INITIAL_ADD.
PGM_BASE & Pgm()
The global program "get" accessor.
SCH_SEARCH_T
Schematic search type used by the socket link with Pcbnew.
KIWAY Kiway(KFCTL_STANDALONE)
wxString UnescapeString(const wxString &aSource)
wxString From_UTF8(const char *cstring)
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
bool on_selection
Synchronize the selection for multiple items too.
bool zoom_to_fit
Zoom to fit items (ignored if center_on_items is off).
bool center_on_items
Automatically pan to cross-probed items.
bool auto_highlight
Automatically turn on highlight mode in the target frame.
@ REFERENCE
Field Reference of part, i.e. "IC21".
wxLogTrace helper definitions.