KiCad PCB EDA Suite
readwrite_dlgs.cpp
Go to the documentation of this file.
1 
5 /*
6  * This program source code file is part of KiCad, a free EDA CAD application.
7  *
8  * Copyright (C) 2015 Jean-Pierre Charras, jean-pierre.charras
9  * Copyright (C) 2011-2016 Wayne Stambaugh <stambaughw@verizon.net>
10  * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, you may find one here:
24  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
25  * or you may search the http://www.gnu.org website for the version 2 license,
26  * or you may write to the Free Software Foundation, Inc.,
27  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
28  */
29 #include <fctsys.h>
30 #include <kiway.h>
31 #include <common.h>
32 #include <confirm.h>
33 #include <build_version.h>
34 #include <macros.h>
35 #include <lib_id.h>
36 #include <fp_lib_table.h>
37 #include <reporter.h>
38 #include <html_messagebox.h>
39 
40 #include <cvpcb.h>
41 #include <cvpcb_mainframe.h>
42 #include <listview_classes.h>
45 
46 
47 void CVPCB_MAINFRAME::SetNewPkg( const wxString& aFootprintName )
48 {
49  COMPONENT* component;
50  int componentIndex;
51 
52  if( m_netlist.IsEmpty() )
53  return;
54 
55  // If no component is selected, select the first one
56  if( m_compListBox->GetFirstSelected() < 0 )
57  {
58  componentIndex = 0;
59  m_compListBox->SetSelection( componentIndex, true );
60  }
61 
62  // iterate over the selection
63  while( m_compListBox->GetFirstSelected() != -1 )
64  {
65  // Get the component for the current iteration
66  componentIndex = m_compListBox->GetFirstSelected();
67  component = m_netlist.GetComponent( componentIndex );
68 
69  if( component == NULL )
70  return;
71 
72  SetNewPkg( aFootprintName, componentIndex );
73 
74  m_compListBox->SetSelection( componentIndex, false );
75  }
76 
77  // select the next component, if there is one
78  if( componentIndex < (m_compListBox->GetCount() - 1) )
79  componentIndex++;
80 
81  m_compListBox->SetSelection( componentIndex, true );
82 
83  // update the statusbar
84  DisplayStatus();
85 }
86 
87 
88 void CVPCB_MAINFRAME::SetNewPkg( const wxString& aFootprintName, int aIndex )
89 {
90  COMPONENT* component;
91 
92  if( m_netlist.IsEmpty() )
93  return;
94 
95  component = m_netlist.GetComponent( aIndex );
96 
97  if( component == NULL )
98  return;
99 
100  // Check to see if the component has already a footprint set.
101  bool hasFootprint = !component->GetFPID().empty();
102 
103  LIB_ID fpid;
104 
105  if( !aFootprintName.IsEmpty() )
106  {
107  wxCHECK_RET( fpid.Parse( aFootprintName ) < 0,
108  wxString::Format( wxT( "<%s> is not a valid LIB_ID." ),
109  GetChars( aFootprintName ) ) );
110  }
111 
112  component->SetFPID( fpid );
113 
114  // create the new component description
115  wxString description = wxString::Format( CMP_FORMAT, aIndex + 1,
116  GetChars( component->GetReference() ),
117  GetChars( component->GetValue() ),
118  GetChars( FROM_UTF8( component->GetFPID().Format().c_str() ) ) );
119 
120  // If the component hasn't had a footprint associated with it
121  // it now has, so we decrement the count of components without
122  // a footprint assigned.
123  if( !hasFootprint )
125 
126  // Set the new description and deselect the processed component
127  m_compListBox->SetString( aIndex, description );
128 
129  // Mark this "session" as modified
130  m_modified = true;
131 
132  // update the statusbar
133  DisplayStatus();
134 }
135 
136 
140 static int guessNickname( FP_LIB_TABLE* aTbl, LIB_ID* aFootprintId )
141 {
142  if( aFootprintId->GetLibNickname().size() )
143  return 0;
144 
145  wxString nick;
146  wxString fpname = aFootprintId->GetLibItemName();
147 
148  std::vector<wxString> nicks = aTbl->GetLogicalLibs();
149 
150  // Search each library going through libraries alphabetically.
151  for( unsigned libNdx = 0; libNdx<nicks.size(); ++libNdx )
152  {
153  wxArrayString fpnames;
154 
155  aTbl->FootprintEnumerate( fpnames, nicks[libNdx] );
156 
157  for( unsigned nameNdx = 0; nameNdx<fpnames.size(); ++nameNdx )
158  {
159  if( fpname == fpnames[nameNdx] )
160  {
161  if( !nick )
162  nick = nicks[libNdx];
163  else
164  return 2; // duplicate, the guess would not be certain
165  }
166  }
167  }
168 
169  if( nick.size() )
170  {
171  aFootprintId->SetLibNickname( nick );
172  return 0;
173  }
174 
175  return 1;
176 }
177 
178 
179 bool CVPCB_MAINFRAME::ReadNetListAndFpFiles( const std::string& aNetlist )
180 {
181  wxString msg;
182  bool hasMissingNicks = false;
183 
184  ReadSchematicNetlist( aNetlist );
185 
186  if( m_compListBox == NULL )
187  return false;
188 
189  LoadProjectFile();
191 
194 
195  m_compListBox->Clear();
197 
199  {
200  for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
201  {
202  COMPONENT* component = m_netlist.GetComponent( i );
203 
204  if( component->GetFPID().empty() )
205  continue;
206 
207  if( component->GetFPID().IsLegacy() )
208  hasMissingNicks = true;
209  }
210  }
211 
212  // Check if footprint links were generated before the footprint library table was implemented.
213  if( hasMissingNicks )
214  {
215  msg = _(
216  "Some of the assigned footprints are legacy entries (are missing lib nicknames). "
217  "Would you like CvPcb to attempt to convert them to the new required LIB_ID format? "
218  "(If you answer no, then these assignments will be cleared out and you will "
219  "have to re-assign these footprints yourself.)"
220  );
221 
222  if( IsOK( this, msg ) )
223  {
224  msg.Clear();
225 
226  try
227  {
228  for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
229  {
230  COMPONENT* component = m_netlist.GetComponent( i );
231 
232  if( component->GetFPID().IsLegacy() )
233  {
234  // get this first here, it's possibly obsoleted if we get it too soon.
235  FP_LIB_TABLE* tbl = Prj().PcbFootprintLibs( Kiway() );
236 
237  int guess = guessNickname( tbl, (LIB_ID*) &component->GetFPID() );
238 
239  switch( guess )
240  {
241  case 0:
242  DBG(printf("%s: guessed OK ref:%s fpid:%s\n", __func__,
243  TO_UTF8( component->GetReference() ), component->GetFPID().Format().c_str() );)
244  m_modified = true;
245  break;
246 
247  case 1:
248  msg += wxString::Format( _(
249  "Component '%s' footprint '%s' was <b>not found</b> in any library.\n" ),
250  GetChars( component->GetReference() ),
251  GetChars( component->GetFPID().GetLibItemName() )
252  );
253  break;
254 
255  case 2:
256  msg += wxString::Format( _(
257  "Component '%s' footprint '%s' was found in <b>multiple</b> libraries.\n" ),
258  GetChars( component->GetReference() ),
259  GetChars( component->GetFPID().GetLibItemName() )
260  );
261  break;
262  }
263  }
264  }
265  }
266  catch( const IO_ERROR& ioe )
267  {
268  msg = ioe.What();
269  msg += wxT( "\n\n" );
270  msg += _( "First check your footprint library table entries." );
271 
272  wxMessageBox( msg, _( "Problematic Footprint Library Tables" ) );
273  return false;
274  }
275 
276  if( msg.size() )
277  {
278  HTML_MESSAGE_BOX dlg( this, wxEmptyString );
279 
280  dlg.MessageSet( _( "The following errors occurred attempting to convert the "
281  "footprint assignments:\n\n" ) );
282  dlg.ListSet( msg );
283  dlg.MessageSet( _( "\nYou will need to reassign them manually if you want them "
284  "to be updated correctly the next time you import the "
285  "netlist in Pcbnew." ) );
286 
287 #if 1
288  dlg.ShowModal();
289 #else
290  dlg.Fit();
291  dlg.Show( true ); // modeless lets user watch while fixing the problems, but its not working.
292 #endif
293  }
294  }
295  else
296  {
297  // Clear the legacy footprint assignments.
298  for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
299  {
300  COMPONENT* component = m_netlist.GetComponent( i );
301 
302  if( component->GetFPID().IsLegacy() )
303  {
304  component->SetFPID( LIB_ID() /* empty */ );
305  m_modified = true;
306  }
307  }
308  }
309  }
310 
311 
312  // Display a dialog to select footprint selection, if the netlist
313  // and the .cmp file give 2 different valid footprints
314  std::vector <int > m_indexes; // indexes of footprints in netlist
315 
316  for( unsigned ii = 0; ii < m_netlist.GetCount(); ii++ )
317  {
318  COMPONENT* component = m_netlist.GetComponent( ii );
319 
320  if( component->GetAltFPID().empty() )
321  continue;
322 
323  if( component->GetFPID().IsLegacy() || component->GetAltFPID().IsLegacy())
324  continue;
325 
326  m_indexes.push_back( ii );
327  }
328 
329  // If a n assignment conflict is found,
330  // open a dialog to chose between schematic assignment
331  // and .cmp file assignment:
332  if( m_indexes.size() > 0 )
333  {
335 
336  for( unsigned ii = 0; ii < m_indexes.size(); ii++ )
337  {
338  COMPONENT* component = m_netlist.GetComponent( m_indexes[ii] );
339 
340  wxString cmpfpid = component->GetFPID().Format();
341  wxString schfpid = component->GetAltFPID().Format();
342 
343  dlg.Add( component->GetReference(), schfpid, cmpfpid );
344  }
345 
346  if( dlg.ShowModal() == wxID_OK )
347  {
348 
349  // Update the fp selection:
350  for( unsigned ii = 0; ii < m_indexes.size(); ii++ )
351  {
352  COMPONENT* component = m_netlist.GetComponent( m_indexes[ii] );
353 
354  int choice = dlg.GetSelection( component->GetReference() );
355 
356  if( choice == 0 ) // the schematic (alt fpid) is chosen:
357  component->SetFPID( component->GetAltFPID() );
358  }
359  }
360  }
361 
362  // Populates the component list box:
363  for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
364  {
365  COMPONENT* component = m_netlist.GetComponent( i );
366 
367  msg.Printf( CMP_FORMAT, m_compListBox->GetCount() + 1,
368  GetChars( component->GetReference() ),
369  GetChars( component->GetValue() ),
370  GetChars( FROM_UTF8( component->GetFPID().Format().c_str() ) ) );
371 
372  m_compListBox->AppendLine( msg );
373 
374  if( component->GetFPID().empty() )
375  {
377  continue;
378  }
379  }
380 
381  if( !m_netlist.IsEmpty() )
382  m_compListBox->SetSelection( 0, true );
383 
384  DisplayStatus();
385 
386  UpdateTitle();
387  return true;
388 }
389 
390 
392 {
393  STRING_FORMATTER sf;
394 
396 
398 
399  SetStatusText( _("Footprint association sent to Eeschema") );
400 }
bool empty() const
Function empty.
Definition: lib_id.h:198
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
const LIB_ID & GetFPID() const
Definition: pcb_netlist.h:164
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
bool AnyFootprintsLinked() const
Function AnyFootprintsLinked.
void SetFPID(const LIB_ID &aFPID)
Definition: pcb_netlist.h:153
CVPCB->SCH footprint stuffing at cvpcb termination.
Definition: mail_type.h:40
This file is part of the common library.
COMPONENTS_LISTBOX * m_compListBox
bool IsLegacy() const
Function IsLegacy.
Definition: lib_id.h:184
void SetSelection(int index, bool State=true)
void SetNewPkg(const wxString &aFootprintName)
Function SetNewPkg set the footprint name for all selected components in component list and selects t...
void UpdateTitle()
Function UpdateTitle sets the main window title bar text.
int ReadSchematicNetlist(const std::string &aNetlist)
Function ReadSchematicNetlist read the netlist (.net) file built on the fly by Eeschema.
int Parse(const UTF8 &aId)
Function Parse.
Definition: lib_id.cpp:122
std::string::size_type size() const
Definition: utf8.h:115
bool IsEmpty() const
Function IsEmpty()
Definition: pcb_netlist.h:235
Class LIB_ID.
Definition: lib_id.h:56
bool LoadFootprintFiles()
Function LoadFootprintFiles reads the list of footprint (*.mod files) and generate the list of footpr...
static int guessNickname(FP_LIB_TABLE *aTbl, LIB_ID *aFootprintId)
Return true if the resultant LIB_ID has a certain nickname.
void AppendLine(const wxString &text)
This file contains miscellaneous commonly used macros and functions.
const wxString & GetReference() const
Definition: pcb_netlist.h:149
#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
const wxString & GetValue() const
Definition: pcb_netlist.h:151
PROJECT & Prj() const
Function Prj returns a reference to the PROJECT "associated with" this KIWAY.
const UTF8 & GetLibItemName() const
Function GetLibItemName.
Definition: lib_id.h:129
void Add(const wxString &aRef, const wxString &aFpSchName, const wxString &aFpCmpName)
Add a line to the selection list.
void ListSet(const wxString &aList)
Function ListSet Add a list of items.
Subclass of DIALOG_DISPLAY_HTML_TEXT_BASE, which is generated by wxFormBuilder.
The common library.
const std::string & GetString()
Definition: richio.h:475
void BuildFOOTPRINTS_LISTBOX()
Class HTML_MESSAGE_BOX.
void FormatBackAnnotation(OUTPUTFORMATTER *aOut)
Definition: pcb_netlist.h:346
void MessageSet(const wxString &message)
Function MessageSet adds a message (in bold) to message list.
bool Show(bool show) override
Class COMPONENT is used to store components and all of their related information found in a netlist...
Definition: pcb_netlist.h:83
VTBL_ENTRY FP_LIB_TABLE * PcbFootprintLibs(KIWAY &aKiway)
Return the table of footprint libraries.
int SetLibNickname(const UTF8 &aNickname)
Function SetLibNickname.
Definition: lib_id.cpp:219
COMPONENT * GetComponent(unsigned aIndex)
Function GetComponent returns the COMPONENT at aIndex.
Definition: pcb_netlist.h:256
#define CMP_FORMAT
Definition: cvpcb.h:32
const LIB_ID & GetAltFPID() const
Definition: pcb_netlist.h:166
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:33
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
bool ReadNetListAndFpFiles(const std::string &aNetlist)
Function ReadNetListAndFpFiles loads the netlist file built on the fly by Eeschema and loads footprin...
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
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
const char * c_str() const
Definition: utf8.h:107
void SetString(unsigned linecount, const wxString &text)
The common library.
UTF8 Format() const
Function Format.
Definition: lib_id.cpp:263
#define DBG(x)
Definition: fctsys.h:33
void FootprintEnumerate(wxArrayString &aFootprintNames, const wxString &aNickname)
Return a list of footprint names contained within the library given by aNickname. ...
const UTF8 & GetLibNickname() const
Function GetLibNickname.
Definition: lib_id.h:108
void SaveFootprintAssociation()
Function SaveFootprintAssociation saves the edits that the user has done by sending them back to eesc...
unsigned GetCount() const
Function GetCount.
Definition: pcb_netlist.h:247
Class STRING_FORMATTER implements OUTPUTFORMATTER to a memory buffer.
Definition: richio.h:445
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
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Function IsOK displays a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:129
void DisplayStatus()
Function DisplayStatus updates the information displayed on the status bar at bottom of the main fram...
void LoadProjectFile()
Function LoadProjectFile reads the CvPcb configuration parameter from the project (...
Definition: cfg.cpp:59
std::vector< wxString > GetLogicalLibs()
Function GetLogicalLibs.