KiCad PCB EDA Suite
readwrite_dlgs.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) 2018 Jean-Pierre Charras, jean-pierre.charras
5  * Copyright (C) 2011 Wayne Stambaugh <stambaughw@gmail.com>
6  * Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.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 
26 #include <confirm.h>
27 #include <fp_lib_table.h>
29 #include <kiway.h>
30 #include <lib_id.h>
31 #include <macros.h>
32 
33 #include <cvpcb_mainframe.h>
35 
36 
44 static int guessNickname( FP_LIB_TABLE* aTbl, LIB_ID* aFootprintId )
45 {
46  if( aFootprintId->GetLibNickname().size() )
47  return 0;
48 
49  wxString nick;
50  wxString fpname = aFootprintId->GetLibItemName();
51 
52  std::vector<wxString> nicks = aTbl->GetLogicalLibs();
53 
54  // Search each library going through libraries alphabetically.
55  for( unsigned libNdx = 0; libNdx<nicks.size(); ++libNdx )
56  {
57  wxArrayString fpnames;
58 
59  aTbl->FootprintEnumerate( fpnames, nicks[libNdx], true );
60 
61  for( unsigned nameNdx = 0; nameNdx<fpnames.size(); ++nameNdx )
62  {
63  if( fpname == fpnames[nameNdx] )
64  {
65  if( !nick )
66  nick = nicks[libNdx];
67  else
68  return 2; // duplicate, the guess would not be certain
69  }
70  }
71  }
72 
73  if( nick.size() )
74  {
75  aFootprintId->SetLibNickname( nick );
76  return 0;
77  }
78 
79  return 1;
80 }
81 
82 
83 bool CVPCB_MAINFRAME::ReadNetListAndFpFiles( const std::string& aNetlist )
84 {
85  wxString msg;
86  bool hasMissingNicks = false;
87 
88  ReadSchematicNetlist( aNetlist );
89 
90  if( m_symbolsListBox == nullptr )
91  return false;
92 
93  wxSafeYield();
94 
96 
99 
101 
103  {
104  for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
105  {
106  COMPONENT* component = m_netlist.GetComponent( i );
107 
108  if( component->GetFPID().empty() )
109  continue;
110 
111  if( component->GetFPID().IsLegacy() )
112  hasMissingNicks = true;
113  }
114  }
115 
116  // Check if footprint links were generated before the footprint library table was implemented.
117  if( hasMissingNicks )
118  {
119  msg = _( "Some of the assigned footprints are legacy entries with no library names. Would "
120  "you like KiCad to attempt to convert them to the new required LIB_ID format? "
121  "(If you answer no, then these assignments will be cleared and you will need to "
122  "re-assign them manually.)" );
123 
124  if( IsOK( this, msg ) )
125  {
126  msg.Clear();
127 
128  try
129  {
130  for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
131  {
132  COMPONENT* component = m_netlist.GetComponent( i );
133 
134  if( component->GetFPID().IsLegacy() )
135  {
136  // get this first here, it's possibly obsoleted if we get it too soon.
137  FP_LIB_TABLE* tbl = Prj().PcbFootprintLibs();
138 
139  int guess = guessNickname( tbl, (LIB_ID*) &component->GetFPID() );
140 
141  switch( guess )
142  {
143  case 0:
144  m_modified = true;
145  break;
146 
147  case 1:
148  msg += wxString::Format( _( "Component '%s' footprint '%s' <b>not "
149  "found</b> in any library.\n" ),
150  component->GetReference(),
151  component->GetFPID().GetLibItemName().wx_str() );
152  break;
153 
154  case 2:
155  msg += wxString::Format( _( "Component '%s' footprint '%s' was found "
156  "in <b>multiple</b> libraries.\n" ),
157  component->GetReference(),
158  component->GetFPID().GetLibItemName().wx_str() );
159  break;
160  }
161  }
162  }
163  }
164  catch( const IO_ERROR& ioe )
165  {
166  msg = ioe.What();
167  msg += wxT( "\n\n" );
168  msg += _( "First check your footprint library table entries." );
169 
170  wxMessageBox( msg, _( "Problematic Footprint Library Tables" ) );
171  return false;
172  }
173 
174  if( msg.size() )
175  {
176  HTML_MESSAGE_BOX dlg( this, wxEmptyString );
177 
178  dlg.MessageSet( _( "The following errors occurred attempting to convert the "
179  "footprint assignments:\n\n" ) );
180  dlg.ListSet( msg );
181  dlg.MessageSet( _( "\nYou will need to reassign them manually if you want them "
182  "to be updated correctly the next time you import the "
183  "netlist in Pcbnew." ) );
184 
185 #if 1
186  dlg.ShowModal();
187 #else
188  dlg.Fit();
189 
190  // Modeless lets user watch while fixing the problems, but its not working.
191  dlg.Show( true );
192 #endif
193  }
194  }
195  else
196  {
197  // Clear the legacy footprint assignments.
198  for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
199  {
200  COMPONENT* component = m_netlist.GetComponent( i );
201 
202  if( component->GetFPID().IsLegacy() )
203  {
204  component->SetFPID( LIB_ID() );
205  m_modified = true;
206  }
207  }
208  }
209  }
210 
211 
212  // Display a dialog to select footprint selection, if the netlist
213  // and the .cmp file give 2 different valid footprints
214  std::vector <int > m_indexes; // indexes of footprints in netlist
215 
216  for( unsigned ii = 0; ii < m_netlist.GetCount(); ii++ )
217  {
218  COMPONENT* component = m_netlist.GetComponent( ii );
219 
220  if( component->GetAltFPID().empty() )
221  continue;
222 
223  if( component->GetFPID().IsLegacy() || component->GetAltFPID().IsLegacy() )
224  continue;
225 
226  m_indexes.push_back( ii );
227  }
228 
229  // If a n assignment conflict is found,
230  // open a dialog to chose between schematic assignment
231  // and .cmp file assignment:
232  if( m_indexes.size() > 0 )
233  {
235 
236  for( unsigned ii = 0; ii < m_indexes.size(); ii++ )
237  {
238  COMPONENT* component = m_netlist.GetComponent( m_indexes[ii] );
239 
240  wxString cmpfpid = component->GetFPID().Format();
241  wxString schfpid = component->GetAltFPID().Format();
242 
243  dlg.Add( component->GetReference(), schfpid, cmpfpid );
244  }
245 
246  if( dlg.ShowModal() == wxID_OK )
247  {
248  // Update the fp selection:
249  for( unsigned ii = 0; ii < m_indexes.size(); ii++ )
250  {
251  COMPONENT* component = m_netlist.GetComponent( m_indexes[ii] );
252 
253  int choice = dlg.GetSelection( component->GetReference() );
254 
255  if( choice == 0 ) // the schematic (alt fpid) is chosen:
256  component->SetFPID( component->GetAltFPID() );
257  }
258  }
259  }
260 
261  // Populates the component list box:
262  for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
263  {
264  COMPONENT* component = m_netlist.GetComponent( i );
265 
267  component->GetReference(),
268  component->GetValue(),
269  FROM_UTF8( component->GetFPID().Format().c_str() ) );
270 
272  }
273 
274  if( !m_netlist.IsEmpty() )
275  m_symbolsListBox->SetSelection( 0, true );
276 
277  DisplayStatus();
278 
279  return true;
280 }
281 
282 
283 bool CVPCB_MAINFRAME::SaveFootprintAssociation( bool doSaveSchematic )
284 {
285  std::string payload;
286  STRING_FORMATTER sf;
287 
289 
290  payload = sf.GetString();
292 
293  if( doSaveSchematic )
294  {
295  payload = "";
296  Kiway().ExpressMail( FRAME_SCH, MAIL_SCH_SAVE, payload );
297 
298  if( payload == "success" )
299  SetStatusText( _( "Schematic saved" ), 1 );
300  }
301 
302  // Changes are saved, so reset the flag
303  m_modified = false;
304 
305  return true;
306 }
const UTF8 & GetLibItemName() const
Definition: lib_id.h:104
KIWAY & Kiway() const
Return a reference to the KIWAY that this object has an opportunity to participate in.
Definition: kiway_holder.h:53
void AppendLine(const wxString &text)
static wxString FROM_UTF8(const char *cstring)
Convert a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:110
void FormatCvpcbNetlist(OUTPUTFORMATTER *aOut)
Definition: pcb_netlist.h:287
void SetFPID(const LIB_ID &aFPID)
Definition: pcb_netlist.h:132
This file is part of the common library.
bool AnyFootprintsLinked() const
void SetSelection(int index, bool State=true)
int ReadSchematicNetlist(const std::string &aNetlist)
Read the netlist (.net) file built on the fly by Eeschema.
unsigned GetCount() const
Definition: pcb_netlist.h:228
virtual void ExpressMail(FRAME_T aDestination, MAIL_T aCommand, std::string &aPayload, wxWindow *aSource=nullptr)
Send aPayload to aDestination from aSource.
Definition: kiway.cpp:477
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:51
bool LoadFootprintFiles()
Read the list of footprint (*.mod files) and generate the list of footprints.
static int guessNickname(FP_LIB_TABLE *aTbl, LIB_ID *aFootprintId)
Return true if the resultant LIB_ID has a certain nickname.
bool empty() const
Definition: lib_id.h:180
This file contains miscellaneous commonly used macros and functions.
const char * c_str() const
Definition: utf8.h:102
const LIB_ID & GetFPID() const
Definition: pcb_netlist.h:133
void FootprintEnumerate(wxArrayString &aFootprintNames, const wxString &aNickname, bool aBestEfforts)
Return a list of footprint names contained within the library given by aNickname.
const LIB_ID & GetAltFPID() const
Definition: pcb_netlist.h:136
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
void Add(const wxString &aRef, const wxString &aFpSchName, const wxString &aFpCmpName)
Add a line to the selection list.
void ListSet(const wxString &aList)
Add a list of items.
const wxString & GetReference() const
Definition: pcb_netlist.h:123
SYMBOLS_LISTBOX * m_symbolsListBox
void SetStatusText(const wxString &aText, int aNumber=0) override
#define _(s)
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:90
const std::string & GetString()
Definition: richio.h:438
void MessageSet(const wxString &message)
Add a message (in bold) to message list.
UTF8 Format() const
Definition: lib_id.cpp:116
bool Show(bool show) override
Store all of the related footprint information found in a netlist.
Definition: pcb_netlist.h:84
virtual FP_LIB_TABLE * PcbFootprintLibs(KIWAY &aKiway)
Return the table of footprint libraries.
Definition: project.cpp:283
int SetLibNickname(const UTF8 &aNickname)
Override the logical library name portion of the LIB_ID to aNickname.
Definition: lib_id.cpp:97
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
COMPONENT * GetComponent(unsigned aIndex)
Return the COMPONENT at aIndex.
Definition: pcb_netlist.h:236
bool ReadNetListAndFpFiles(const std::string &aNetlist)
Load the netlist file built on the fly by Eeschema and loads footprint libraries from fp lib tables.
wxString wx_str() const
Definition: utf8.cpp:46
bool IsEmpty() const
Definition: pcb_netlist.h:218
wxString formatSymbolDesc(int idx, const wxString &aReference, const wxString &aValue, const wxString &aFootprint)
const wxString & GetValue() const
Definition: pcb_netlist.h:124
bool IsLegacy() const
Definition: lib_id.h:167
std::string::size_type size() const
Definition: utf8.h:110
Implement an OUTPUTFORMATTER to a memory buffer.
Definition: richio.h:414
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:75
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:323
void DisplayStatus()
Update the information displayed on the status bar at bottom of the main frame.
std::vector< wxString > GetLogicalLibs()
Return the logical library names, all of them that are pertinent to a look up done on this LIB_TABLE.
bool SaveFootprintAssociation(bool doSaveSchematic)
Save the edits that the user has done by sending them back to Eeschema via the kiway.