KiCad PCB EDA Suite
eeschema/cross-probing.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 (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
5  * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
6  * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
30 #include <fctsys.h>
31 #include <pgm_base.h>
32 #include <kiface_i.h>
33 #include <kiway_express.h>
34 #include <macros.h>
35 #include <eda_dde.h>
36 #include <class_drawpanel.h>
37 
38 #include <sch_edit_frame.h>
39 #include <general.h>
40 #include <eeschema_id.h>
41 #include <lib_draw_item.h>
42 #include <lib_pin.h>
43 #include <sch_component.h>
44 #include <sch_sheet.h>
45 
46 
63 void SCH_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline )
64 {
65  char line[1024];
66 
67  strncpy( line, cmdline, sizeof(line) - 1 );
68  line[ sizeof(line) - 1 ] = '\0';
69 
70  char* idcmd = strtok( line, " \n\r" );
71  char* text = strtok( NULL, "\"\n\r" );
72 
73  if( idcmd == NULL )
74  return;
75 
76  if( strcmp( idcmd, "$NET:" ) == 0 )
77  {
78  if( GetToolId() == ID_HIGHLIGHT )
79  {
80  m_SelectedNetName = FROM_UTF8( text );
81 
82  SetStatusText( _( "Selected net: " ) + m_SelectedNetName );
84  m_canvas->Refresh();
85  }
86 
87  return;
88  }
89 
90  if( text == NULL )
91  return;
92 
93  if( strcmp( idcmd, "$PART:" ) != 0 )
94  return;
95 
96  wxString part_ref = FROM_UTF8( text );
97 
98  /* look for a complement */
99  idcmd = strtok( NULL, " \n\r" );
100 
101  if( idcmd == NULL ) // component only
102  {
103  FindComponentAndItem( part_ref, true, FIND_COMPONENT_ONLY, wxEmptyString, false );
104  return;
105  }
106 
107  text = strtok( NULL, "\"\n\r" );
108 
109  if( text == NULL )
110  return;
111 
112  wxString msg = FROM_UTF8( text );
113 
114  if( strcmp( idcmd, "$REF:" ) == 0 )
115  {
116  FindComponentAndItem( part_ref, true, FIND_REFERENCE, msg, false );
117  }
118  else if( strcmp( idcmd, "$VAL:" ) == 0 )
119  {
120  FindComponentAndItem( part_ref, true, FIND_VALUE, msg, false );
121  }
122  else if( strcmp( idcmd, "$PAD:" ) == 0 )
123  {
124  FindComponentAndItem( part_ref, true, FIND_PIN, msg, false );
125  }
126  else
127  {
128  FindComponentAndItem( part_ref, true, FIND_COMPONENT_ONLY, wxEmptyString, false );
129  }
130 }
131 
132 
133 std::string FormatProbeItem( EDA_ITEM* aItem, SCH_COMPONENT* aPart )
134 {
135  // Cross probing to Pcbnew if a pin or a component is found
136  switch( aItem->Type() )
137  {
138  case SCH_FIELD_T:
139  case LIB_FIELD_T:
140  if( aPart )
141  return StrPrintf( "$PART: %s", TO_UTF8( aPart->GetField( REFERENCE )->GetText() ) );
142  break;
143 
144  case SCH_COMPONENT_T:
145  aPart = (SCH_COMPONENT*) aItem;
146  return StrPrintf( "$PART: %s", TO_UTF8( aPart->GetField( REFERENCE )->GetText() ) );
147 
148  case SCH_SHEET_T:
149  {
150  SCH_SHEET* sheet = (SCH_SHEET*)aItem;
151  return StrPrintf( "$SHEET: %8.8lX", (unsigned long) sheet->GetTimeStamp() );
152  }
153 
154  case LIB_PIN_T:
155  {
156  if( !aPart )
157  break;
158 
159  LIB_PIN* pin = (LIB_PIN*) aItem;
160 
161  if( !pin->GetNumber().IsEmpty() )
162  {
163  return StrPrintf( "$PIN: %s $PART: %s", TO_UTF8( pin->GetNumber() ),
164  TO_UTF8( aPart->GetField( REFERENCE )->GetText() ) );
165  }
166  else
167  {
168  return StrPrintf( "$PART: %s", TO_UTF8( aPart->GetField( REFERENCE )->GetText() ) );
169  }
170  }
171  break;
172 
173  default:
174  break;
175  }
176 
177  return "";
178 }
179 
180 
182 {
183  wxASSERT( aObjectToSync ); // fix the caller
184 
185  if( !aObjectToSync )
186  return;
187 
188  std::string packet = FormatProbeItem( aObjectToSync, aLibItem );
189 
190  if( packet.size() )
191  {
192  if( Kiface().IsSingle() )
193  SendCommand( MSG_TO_PCB, packet.c_str() );
194  else
195  {
196  // Typically ExpressMail is going to be s-expression packets, but since
197  // we have existing interpreter of the cross probe packet on the other
198  // side in place, we use that here.
199  Kiway().ExpressMail( FRAME_PCB, MAIL_CROSS_PROBE, packet, this );
200  }
201  }
202 }
203 
204 
205 void SCH_EDIT_FRAME::SendCrossProbeNetName( const wxString& aNetName )
206 {
207  std::string packet = StrPrintf( "$NET: %s", TO_UTF8( aNetName ) );
208 
209  if( packet.size() )
210  {
211  if( Kiface().IsSingle() )
212  SendCommand( MSG_TO_PCB, packet.c_str() );
213  else
214  {
215  // Typically ExpressMail is going to be s-expression packets, but since
216  // we have existing interpreter of the cross probe packet on the other
217  // side in place, we use that here.
218  Kiway().ExpressMail( FRAME_PCB, MAIL_CROSS_PROBE, packet, this );
219  }
220  }
221 }
222 
223 
225 {
226  const std::string& payload = mail.GetPayload();
227 
228  switch( mail.Command() )
229  {
230  case MAIL_CROSS_PROBE:
231  ExecuteRemoteCommand( payload.c_str() );
232  break;
233 
235  doUpdatePcb( payload );
236  break;
237 
239  try
240  {
241  backAnnotateFootprints( payload );
242  }
243  catch( const IO_ERROR& DBG( ioe ) )
244  {
245  DBG( printf( "%s: ioe:%s\n", __func__, TO_UTF8( ioe.What() ) );)
246  }
247  break;
248 
249  case MAIL_SCH_REFRESH:
250  GetCanvas()->Refresh();
251  break;
252 
253  case MAIL_IMPORT_FILE:
254  {
255  // Extract file format type and path (plugin type and path separated with \n)
256  size_t split = payload.find( '\n' );
257  wxCHECK( split != std::string::npos, /*void*/ );
258  int importFormat;
259 
260  try
261  {
262  importFormat = std::stoi( payload.substr( 0, split ) );
263  }
264  catch( std::invalid_argument& )
265  {
266  wxFAIL;
267  importFormat = -1;
268  }
269 
270  std::string path = payload.substr( split + 1 );
271  wxASSERT( !path.empty() );
272 
273  if( importFormat >= 0 )
274  importFile( path, importFormat );
275  }
276  break;
277 
278  case MAIL_SCH_SAVE:
279  if( SaveProject() )
280  Kiway().ExpressMail( FRAME_CVPCB, MAIL_STATUS, _( "Schematic saved" ).ToStdString() );
281  break;
282 
283  default:
284  ;
285  }
286 }
Definition of the SCH_SHEET class for Eeschema.
KICAD_T Type() const
Function Type()
Definition: base_struct.h:198
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.
int StrPrintf(std::string *aResult, const char *aFormat,...)
Function StrPrintf is like sprintf() but the output is appended to a std::string instead of to a char...
Definition: richio.cpp:74
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
void SendCrossProbeNetName(const wxString &aNetName)
Sends a net name to eeschema for highlighting.
virtual void Refresh(bool eraseBackground=true, const wxRect *rect=NULL) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
Definition: draw_panel.cpp:321
CVPCB->SCH footprint stuffing.
Definition: mail_type.h:40
EDA_DRAW_PANEL * GetCanvas()
Definition: draw_frame.h:377
Find a component in the schematic.
Find an item by it&#39;s value field.
bool SendCommand(int service, const char *cmdline)
Definition: eda_dde.cpp:132
CVPCB->SCH save the schematic.
Definition: mail_type.h:41
bool importFile(const wxString &aFileName, int aFileType)
Load the given filename but sets the path to the current project path.
Field Reference of part, i.e. "IC21".
Find a component pin in the schematic.
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
Definition: kicad.cpp:52
const wxString & GetNumber() const
Definition: lib_pin.h:194
This file contains miscellaneous commonly used macros and functions.
VTBL_ENTRY void ExpressMail(FRAME_T aDestination, MAIL_T aCommand, std::string aPayload, wxWindow *aSource=NULL)
Function ExpressMail send aPayload to aDestination from aSource.
Definition: kiway.cpp:386
#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 SendMessageToPCBNEW(EDA_ITEM *aObjectToSync, SCH_COMPONENT *aPart)
Send a message to Pcbnew via a socket connection.
SCH_FIELD * GetField(int aFieldNdx) const
Returns a field in this symbol.
const wxString & GetText() const
Function GetText returns the string associated with the text object.
Definition: eda_text.h:128
SCH_ITEM * FindComponentAndItem(const wxString &aReference, bool aSearchHierarchy, SCH_SEARCH_T aSearchType, const wxString &aSearchText, bool aWarpMouse)
Finds a component in the schematic and an item in this component.
Definition: find.cpp:108
std::string FormatProbeItem(EDA_ITEM *aItem, SCH_COMPONENT *aPart)
void KiwayMailIn(KIWAY_EXPRESS &aEvent) override
Function KiwayMailIn receives KIWAY_EXPRESS messages from other players.
void backAnnotateFootprints(const std::string &aChangedSetOfReferences)
Definition: backanno.cpp:51
The the schematic editor to refresh the display.
Definition: mail_type.h:49
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:209
void doUpdatePcb(const wxString &aUpdateOptions="")
Updates netlist and sends it to pcbnew.
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
bool IsSingle() const
Function IsSingle is this KIFACE_I running under single_top?
Definition: kiface_i.h:115
wxString m_SelectedNetName
EDA_DRAW_PANEL * m_canvas
The area to draw on.
Definition: draw_frame.h:107
Definition the SCH_COMPONENT class for Eeschema.
see class PGM_BASE
Import a different format file.
Definition: mail_type.h:44
int GetToolId() const
Definition: draw_frame.h:514
Find an item by it&#39;s reference designator.
#define MSG_TO_PCB
Definition: eda_dde.h:45
Class SCH_COMPONENT describes a real schematic component.
Definition: sch_component.h:69
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:151
virtual void ExecuteRemoteCommand(const char *cmdline) override
Execute a remote command send by Pcbnew via a socket, port KICAD_SCH_PORT_SERVICE_NUMBER (currently 4...
PCB<->SCH, CVPCB->SCH cross-probing.
Definition: mail_type.h:39
#define DBG(x)
Definition: fctsys.h:33
MAIL_T Command()
Function Command returns the MAIL_T associated with this mail.
Definition: kiway_express.h:52
Struct IO_ERROR is a class used to hold an error message and may be used when throwing exceptions con...
Definition: ki_exception.h:76
bool SetCurrentSheetHighlightFlags()
Set or reset the BRIGHTENED of connected objects inside the current sheet, according to the highlight...
timestamp_t GetTimeStamp() const
Definition: base_struct.h:204