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 <[email protected]>
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
44static 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
83bool 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.
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 FOOTPRINT_INFO* fp =
275
276 if( !fp )
277 {
279 }
280 }
281
282 if( !m_netlist.IsEmpty() )
283 m_symbolsListBox->SetSelection( 0, true );
284
286
287 return true;
288}
289
290
292{
293 std::string payload;
295
297
298 payload = sf.GetString();
300
301 if( doSaveSchematic )
302 {
303 payload = "";
305
306 if( payload == "success" )
307 SetStatusText( _( "Schematic saved" ), 1 );
308 }
309
310 // Changes are saved, so reset the flag
311 m_modified = false;
312
313 return true;
314}
Store all of the related footprint information found in a netlist.
Definition: pcb_netlist.h:85
const wxString & GetReference() const
Definition: pcb_netlist.h:126
const wxString & GetValue() const
Definition: pcb_netlist.h:129
void SetFPID(const LIB_ID &aFPID)
Definition: pcb_netlist.h:137
const LIB_ID & GetAltFPID() const
Definition: pcb_netlist.h:141
const LIB_ID & GetFPID() const
Definition: pcb_netlist.h:138
bool readNetListAndFpFiles(const std::string &aNetlist)
Load the netlist file built on the fly by Eeschema and loads footprint libraries from fp lib tables.
bool LoadFootprintFiles()
Read the list of footprint (*.mod files) and generate the list of footprints.
void SetStatusText(const wxString &aText, int aNumber=0) override
wxString formatSymbolDesc(int idx, const wxString &aReference, const wxString &aValue, const wxString &aFootprint)
void DisplayStatus()
Update the information displayed on the status bar at bottom of the main frame.
FOOTPRINT_LIST * m_FootprintsList
SYMBOLS_LISTBOX * m_symbolsListBox
int readSchematicNetlist(const std::string &aNetlist)
Read the netlist (.net) file built on the fly by Eeschema.
bool SaveFootprintAssociation(bool doSaveSchematic)
Save the edits that the user has done by sending them back to Eeschema via the kiway.
void Add(const wxString &aRef, const wxString &aFpSchName, const wxString &aFpCmpName)
Add a line to the selection list.
bool Show(bool show) override
FOOTPRINT_INFO * GetFootprintInfo(const wxString &aFootprintName)
Get info for a footprint by id.
void FootprintEnumerate(wxArrayString &aFootprintNames, const wxString &aNickname, bool aBestEfforts)
Return a list of footprint names contained within the library given by aNickname.
void MessageSet(const wxString &message)
Add a message (in bold) to message list.
void ListSet(const wxString &aList)
Add a list of items.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:76
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.
KIWAY & Kiway() const
Return a reference to the KIWAY that this object has an opportunity to participate in.
Definition: kiway_holder.h:53
virtual void ExpressMail(FRAME_T aDestination, MAIL_T aCommand, std::string &aPayload, wxWindow *aSource=nullptr)
Send aPayload to aDestination from aSource.
Definition: kiway.cpp:488
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:49
bool empty() const
Definition: lib_id.h:186
UTF8 Format() const
Definition: lib_id.cpp:117
int SetLibNickname(const UTF8 &aNickname)
Override the logical library name portion of the LIB_ID to aNickname.
Definition: lib_id.cpp:98
const UTF8 & GetLibItemName() const
Definition: lib_id.h:101
bool IsLegacy() const
Definition: lib_id.h:173
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:87
std::vector< wxString > GetLogicalLibs()
Return the logical library names, all of them that are pertinent to a look up done on this LIB_TABLE.
unsigned GetCount() const
Definition: pcb_netlist.h:234
bool IsEmpty() const
Definition: pcb_netlist.h:224
COMPONENT * GetComponent(unsigned aIndex)
Return the COMPONENT at aIndex.
Definition: pcb_netlist.h:242
void FormatCvpcbNetlist(OUTPUTFORMATTER *aOut)
Definition: pcb_netlist.h:293
bool AnyFootprintsLinked() const
virtual FP_LIB_TABLE * PcbFootprintLibs(KIWAY &aKiway)
Return the table of footprint libraries.
Definition: project.cpp:318
Implement an OUTPUTFORMATTER to a memory buffer.
Definition: richio.h:415
const std::string & GetString()
Definition: richio.h:438
void SetSelection(int index, bool State=true)
void AppendWarning(int index)
void AppendLine(const wxString &text)
const char * c_str() const
Definition: utf8.h:102
std::string::size_type size() const
Definition: utf8.h:110
wxString wx_str() const
Definition: utf8.cpp:46
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:342
This file is part of the common library.
#define _(s)
@ FRAME_SCH
Definition: frame_type.h:34
This file contains miscellaneous commonly used macros and functions.
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
@ MAIL_SCH_SAVE
Definition: mail_type.h:43
@ MAIL_ASSIGN_FOOTPRINTS
Definition: mail_type.h:42
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
static int guessNickname(FP_LIB_TABLE *aTbl, LIB_ID *aFootprintId)
Return true if the resultant LIB_ID has a certain nickname.