KiCad PCB EDA Suite
pcbnew/cross-probing.cpp
Go to the documentation of this file.
1 
13 #include <fctsys.h>
14 #include <pgm_base.h>
15 #include <kiface_i.h>
16 #include <kiway_express.h>
17 #include <wxPcbStruct.h>
18 #include <eda_dde.h>
19 #include <macros.h>
20 
21 #include <pcbnew_id.h>
22 #include <class_board.h>
23 #include <class_module.h>
24 
25 #include <collectors.h>
26 #include <pcbnew.h>
27 #include <netlist_reader.h>
28 #include <pcb_netlist.h>
30 
31 #include <tools/pcb_actions.h>
32 #include <tool/tool_manager.h>
33 #include <tools/selection_tool.h>
34 #include <pcb_draw_panel_gal.h>
35 
36 /* Execute a remote command send by Eeschema via a socket,
37  * port KICAD_PCB_PORT_SERVICE_NUMBER
38  * cmdline = received command from Eeschema
39  * Commands are
40  * $PART: "reference" put cursor on component
41  * $PIN: "pin name" $PART: "reference" put cursor on the footprint pin
42  */
43 void PCB_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline )
44 {
45  char line[1024];
46  wxString msg;
47  wxString modName;
48  char* idcmd;
49  char* text;
50  MODULE* module = NULL;
51  D_PAD* pad = NULL;
52  BOARD* pcb = GetBoard();
53  wxPoint pos;
54 
55  strncpy( line, cmdline, sizeof(line) - 1 );
56  line[sizeof(line) - 1] = 0;
57 
58  idcmd = strtok( line, " \n\r" );
59  text = strtok( NULL, " \n\r" );
60 
61  if( !idcmd || !text )
62  return;
63 
64  if( strcmp( idcmd, "$PART:" ) == 0 )
65  {
66  modName = FROM_UTF8( text );
67 
68  module = pcb->FindModuleByReference( modName );
69 
70  if( module )
71  msg.Printf( _( "%s found" ), GetChars( modName ) );
72  else
73  msg.Printf( _( "%s not found" ), GetChars( modName ) );
74 
75  SetStatusText( msg );
76 
77  if( module )
78  pos = module->GetPosition();
79  }
80  else if( strcmp( idcmd, "$SHEET:" ) == 0 )
81  {
82  msg.Printf( _( "Selecting all from sheet '%s'" ), FROM_UTF8( text ) );
83  wxString sheetStamp( FROM_UTF8( text ) );
84  SetStatusText( msg );
86  static_cast<void*>( &sheetStamp ) );
87  return;
88  }
89  else if( strcmp( idcmd, "$PIN:" ) == 0 )
90  {
91  wxString pinName;
92  int netcode = -1;
93 
94  pinName = FROM_UTF8( text );
95 
96  text = strtok( NULL, " \n\r" );
97  if( text && strcmp( text, "$PART:" ) == 0 )
98  text = strtok( NULL, "\n\r" );
99 
100  modName = FROM_UTF8( text );
101 
102  module = pcb->FindModuleByReference( modName );
103 
104  if( module )
105  pad = module->FindPadByName( pinName );
106 
107  if( pad )
108  {
109  netcode = pad->GetNetCode();
110 
111  // put cursor on the pad:
112  pos = pad->GetPosition();
113  }
114 
115  if( netcode > 0 ) // highlight the pad net
116  {
117  pcb->HighLightON();
118  pcb->SetHighLightNet( netcode );
119  }
120  else
121  {
122  pcb->HighLightOFF();
123  pcb->SetHighLightNet( -1 );
124  }
125 
126  if( module == NULL )
127  {
128  msg.Printf( _( "%s not found" ), GetChars( modName ) );
129  }
130  else if( pad == NULL )
131  {
132  msg.Printf( _( "%s pin %s not found" ), GetChars( modName ), GetChars( pinName ) );
133  SetCurItem( module );
134  }
135  else
136  {
137  msg.Printf( _( "%s pin %s found" ), GetChars( modName ), GetChars( pinName ) );
138  SetCurItem( pad );
139  }
140 
141  SetStatusText( msg );
142  }
143 
144  if( module ) // if found, center the module on screen, and redraw the screen.
145  {
146  if( IsGalCanvasActive() )
147  {
149  true,
150  pad ?
151  static_cast<BOARD_ITEM*>( pad ) :
152  static_cast<BOARD_ITEM*>( module )
153  );
154  }
155  else
156  {
157  SetCrossHairPosition( pos );
158  RedrawScreen( pos, false );
159  }
160  }
161 }
162 
163 
164 std::string FormatProbeItem( BOARD_ITEM* aItem )
165 {
166  MODULE* module;
167 
168  switch( aItem->Type() )
169  {
170  case PCB_MODULE_T:
171  module = (MODULE*) aItem;
172  return StrPrintf( "$PART: \"%s\"", TO_UTF8( module->GetReference() ) );
173 
174  case PCB_PAD_T:
175  {
176  module = (MODULE*) aItem->GetParent();
177  wxString pad = ((D_PAD*)aItem)->GetPadName();
178 
179  return StrPrintf( "$PART: \"%s\" $PAD: \"%s\"",
180  TO_UTF8( module->GetReference() ),
181  TO_UTF8( pad ) );
182  }
183 
184  case PCB_MODULE_TEXT_T:
185  {
186  module = static_cast<MODULE*>( aItem->GetParent() );
187 
188  TEXTE_MODULE* text_mod = static_cast<TEXTE_MODULE*>( aItem );
189 
190  const char* text_key;
191 
192  /* This can't be a switch since the break need to pull out
193  * from the outer switch! */
194  if( text_mod->GetType() == TEXTE_MODULE::TEXT_is_REFERENCE )
195  text_key = "$REF:";
196  else if( text_mod->GetType() == TEXTE_MODULE::TEXT_is_VALUE )
197  text_key = "$VAL:";
198  else
199  break;
200 
201  return StrPrintf( "$PART: \"%s\" %s \"%s\"",
202  TO_UTF8( module->GetReference() ),
203  text_key,
204  TO_UTF8( text_mod->GetText() ) );
205  }
206 
207  default:
208  break;
209  }
210 
211  return "";
212 }
213 
214 
215 /* Send a remote command to Eeschema via a socket,
216  * aSyncItem = item to be located on schematic (module, pin or text)
217  * Commands are
218  * $PART: "reference" put cursor on component anchor
219  * $PART: "reference" $PAD: "pad number" put cursor on the component pin
220  * $PART: "reference" $REF: "reference" put cursor on the component ref
221  * $PART: "reference" $VAL: "value" put cursor on the component value
222  */
224 {
225 #if 1
226  wxASSERT( aSyncItem ); // can't we fix the caller?
227 #else
228  if( !aSyncItem )
229  return;
230 #endif
231 
232  std::string packet = FormatProbeItem( aSyncItem );
233 
234  if( packet.size() )
235  {
236  if( Kiface().IsSingle() )
237  SendCommand( MSG_TO_SCH, packet.c_str() );
238  else
239  {
240  // Typically ExpressMail is going to be s-expression packets, but since
241  // we have existing interpreter of the cross probe packet on the other
242  // side in place, we use that here.
243  Kiway().ExpressMail( FRAME_SCH, MAIL_CROSS_PROBE, packet, this );
244  }
245  }
246 }
247 
248 
250 {
251  const std::string& payload = mail.GetPayload();
252 
253  switch( mail.Command() )
254  {
255  case MAIL_CROSS_PROBE:
256  ExecuteRemoteCommand( payload.c_str() );
257  break;
258 
259  case MAIL_SCH_PCB_UPDATE:
260  {
261  NETLIST netlist;
262 
263  try
264  {
265  STRING_LINE_READER* lineReader = new STRING_LINE_READER( payload, _( "EEschema netlist" ) );
266  KICAD_NETLIST_READER netlistReader( lineReader, &netlist );
267  netlistReader.LoadNetlist();
268  }
269  catch( const IO_ERROR& )
270  {
271  assert( false ); // should never happen
272  }
273 
274  DIALOG_UPDATE_PCB updateDialog( this, &netlist );
275 
276  updateDialog.PerformUpdate( true );
277  updateDialog.ShowModal();
278 
279  break;
280  }
281 
282  // many many others.
283  default:
284  ;
285  }
286 }
287 
KICAD_T Type() const
Function Type()
Definition: base_struct.h:198
BOARD_ITEM_CONTAINER * GetParent() const
Class KIWAY_EXPRESS carries a payload from one KIWAY_PLAYER to another within a PROJECT.
Definition: kiway_express.h:39
KIWAY & Kiway() const
Function Kiway returns a reference to the KIWAY that this object has an opportunity to participate in...
Definition: kiway_player.h:60
DDE server & client.
static wxString FROM_UTF8(const char *cstring)
function FROM_UTF8 converts a UTF8 encoded C string to a wxString for all wxWidgets build modes...
Definition: macros.h:53
Class KICAD_NETLIST_READER read the new s-expression based KiCad netlist format.
Class BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class...
TEXT_TYPE GetType() const
Class BOARD to handle a board.
const wxPoint & GetPosition() const override
Definition: class_module.h:143
#define MSG_TO_SCH
Definition: eda_dde.h:46
D_PAD * FindPadByName(const wxString &aPadName) const
Function FindPadByName returns a D_PAD* with a matching name.
void SetCurItem(BOARD_ITEM *aItem, bool aDisplayInfo=true)
Function SetCurItem sets the currently selected item and displays it in the MsgPanel.
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Function RunAction() Runs the specified action.
Definition: tool_manager.h:125
void HighLightOFF()
Function HighLightOFF Disable highlight.
Definition: class_board.h:376
MODULE * FindModuleByReference(const wxString &aReference) const
Function FindModuleByReference searches for a MODULE within this board with the given reference desig...
BOARD * GetBoard() const
class D_PAD, a pad in a footprint
Definition: typeinfo.h:102
bool SendCommand(int service, const char *cmdline)
Definition: eda_dde.cpp:134
static TOOL_ACTION crossProbeSchToPcb
Definition: pcb_actions.h:345
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
Definition: kicad.cpp:52
This file contains miscellaneous commonly used macros and functions.
int StrPrintf(std::string *result, const char *format,...)
Function StrPrintf is like sprintf() but the output is appended to a std::string instead of to a char...
Definition: richio.cpp:75
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes...
Definition: macros.h:47
void KiwayMailIn(KIWAY_EXPRESS &aEvent) override
Function KiwayMailIn receives KIWAY_EXPRESS messages from other players.
class MODULE, a footprint
Definition: typeinfo.h:101
virtual void LoadNetlist() override
Function LoadNetlist loads the contents of the netlist file into aNetlist.
Class NETLIST stores all of information read from a netlist along with the flags used to update the N...
Definition: pcb_netlist.h:205
virtual void ExecuteRemoteCommand(const char *cmdline) override
Execute a remote command send by Eeschema via a socket, port KICAD_PCB_PORT_SERVICE_NUMBER (currently...
const wxPoint & GetPosition() const override
Definition: class_pad.h:170
const wxString & GetText() const
Function GetText returns the string associated with the text object.
Definition: eda_text.h:130
Sch->PCB forward update.
Definition: mail_type.h:42
bool IsGalCanvasActive() const
Function IsGalCanvasActive is used to check which canvas (GAL-based or standard) is currently in use...
Definition: draw_frame.h:795
std::string FormatProbeItem(BOARD_ITEM *aItem)
void HighLightON()
Function HighLightON Enable highlight.
Definition: class_board.h:383
const std::string & GetPayload()
Function Payload returns the payload, which can be any text but it typicall self identifying s-expres...
Definition: kiway_express.h:62
int GetNetCode() const
Function GetNetCode.
class TEXTE_MODULE, text in a footprint
Definition: typeinfo.h:105
bool IsSingle() const
Function IsSingle is this KIFACE_I running under single_top?
Definition: kiface_i.h:113
void SetHighLightNet(int aNetCode)
Function SetHighLightNet.
Definition: class_board.h:361
void SendMessageToEESCHEMA(BOARD_ITEM *objectToSync)
Function SendMessageToEESCHEMA sends a message to the schematic editor so that it may move its cursor...
void RedrawScreen(const wxPoint &aCenterPoint, bool aWarpPointer)
Function RedrawScreen redraws the entire screen area by updating the scroll bars and mouse pointer in...
Definition: zoom.cpp:46
TOOL_MANAGER * GetToolManager() const
Function GetToolManager returns the tool manager instance, if any.
Definition: draw_frame.h:810
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
see class PGM_BASE
static TOOL_ACTION selectOnSheetFromEeschema
Selects all components on sheet from Eeschema crossprobing.
Definition: pcb_actions.h:71
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:166
const wxString & GetReference() const
Function GetReference.
Definition: class_module.h:411
VTBL_ENTRY void ExpressMail(FRAME_T aDestination, MAIL_T aCommand, const std::string &aPayload, wxWindow *aSource=NULL)
Function ExpressMail send aPayload to aDestination from aSource.
Definition: kiway.cpp:387
PCB<->SCH, CVPCB->SCH cross-probing.
Definition: mail_type.h:39
Module description (excepted pads)
MAIL_T Command()
Function Command returns the MAIL_T associated with this mail.
Definition: kiway_express.h:52
void SetCrossHairPosition(const wxPoint &aPosition, bool aSnapToGrid=true)
Function SetCrossHairPosition sets the screen cross hair position to aPosition in logical (drawing) u...
Class STRING_LINE_READER is a LINE_READER that reads from a multiline 8 bit wide std::string.
Definition: richio.h:254
Struct IO_ERROR is a class used to hold an error message and may be used when throwing exceptions con...
Definition: ki_exception.h:47
void PerformUpdate(bool aDryRun)