KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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 The 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, see <https://www.gnu.org/licenses/>.
20 */
21
22#include <confirm.h>
25#include <kiway.h>
26#include <lib_id.h>
27#include <richio.h>
28#include <string_utils.h>
29
30#include <cvpcb_mainframe.h>
32#include <project_pcb.h>
33#include <wx/msgdlg.h>
34
35
43static int guessNickname( FOOTPRINT_LIBRARY_ADAPTER* aAdapter, LIB_ID* aFootprintId )
44{
45 if( aFootprintId->GetLibNickname().size() )
46 return 0;
47
48 wxString nick;
49 wxString fpname = aFootprintId->GetLibItemName();
50
51 std::vector<wxString> nicks = aAdapter->GetLibraryNames();
52
53 // Search each library going through libraries alphabetically.
54 for( unsigned libNdx = 0; libNdx < nicks.size(); ++libNdx )
55 {
56 for( const wxString& name : aAdapter->GetFootprintNames( nicks[libNdx], true ) )
57 {
58 if( fpname == name )
59 {
60 if( !nick )
61 nick = nicks[libNdx];
62 else
63 return 2; // duplicate, the guess would not be certain
64 }
65 }
66 }
67
68 if( nick.size() )
69 {
70 aFootprintId->SetLibNickname( nick );
71 return 0;
72 }
73
74 return 1;
75}
76
77
78bool CVPCB_MAINFRAME::readNetListAndFpFiles( const std::string& aNetlist )
79{
80 wxString msg;
81 bool hasMissingNicks = false;
82
83 readSchematicNetlist( aNetlist );
84
85 if( m_symbolsListBox == nullptr )
86 return false;
87
88 wxSafeYield();
89
91
94
95 m_symbolsListBox->Clear();
96
97 if( m_netlist.AnyFootprintsLinked() )
98 {
99 for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
100 {
101 COMPONENT* component = m_netlist.GetComponent( i );
102
103 if( component->GetFPID().empty() )
104 continue;
105
106 if( component->GetFPID().IsLegacy() )
107 hasMissingNicks = true;
108 }
109 }
110
111 // Check if footprint links were generated before the footprint library table was implemented.
112 if( hasMissingNicks )
113 {
114 msg = _( "Some of the assigned footprints are legacy entries with no library names. Would "
115 "you like KiCad to attempt to convert them to the new required LIB_ID format? "
116 "(If you answer no, then these assignments will be cleared and you will need to "
117 "re-assign them manually.)" );
118
119 if( IsOK( this, msg ) )
120 {
121 msg.Clear();
122
123 try
124 {
125 for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
126 {
127 COMPONENT* component = m_netlist.GetComponent( i );
128
129 if( component->GetFPID().IsLegacy() )
130 {
131 // get this first here, it's possibly obsoleted if we get it too soon.
133
134 int guess = guessNickname( adapter, (LIB_ID*) &component->GetFPID() );
135
136 switch( guess )
137 {
138 case 0:
139 m_modified = true;
140 break;
141
142 case 1:
143 msg += wxString::Format( _( "Component '%s' footprint '%s' <b>not "
144 "found</b> in any library.\n" ),
145 component->GetReference(),
146 component->GetFPID().GetLibItemName().wx_str() );
147 break;
148
149 case 2:
150 msg += wxString::Format( _( "Component '%s' footprint '%s' was found "
151 "in <b>multiple</b> libraries.\n" ),
152 component->GetReference(),
153 component->GetFPID().GetLibItemName().wx_str() );
154 break;
155 }
156 }
157 }
158 }
159 catch( const IO_ERROR& ioe )
160 {
161 msg = ioe.What();
162 msg += wxT( "\n\n" );
163 msg += _( "First check your footprint library table entries." );
164
165 wxMessageBox( msg, _( "Problematic Footprint Library Tables" ) );
166 return false;
167 }
168
169 if( msg.size() )
170 {
171 HTML_MESSAGE_BOX dlg( this, wxEmptyString );
172
173 dlg.MessageSet( _( "The following errors occurred attempting to convert the "
174 "footprint assignments:\n\n" ) );
175 dlg.ListSet( msg );
176 dlg.MessageSet( _( "\nYou will need to reassign them manually if you want them "
177 "to be updated correctly the next time you import the "
178 "netlist in Pcbnew." ) );
179
180#if 1
181 dlg.ShowModal();
182#else
183 dlg.Fit();
184
185 // Modeless lets user watch while fixing the problems, but its not working.
186 dlg.Show( true );
187#endif
188 }
189 }
190 else
191 {
192 // Clear the legacy footprint assignments.
193 for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
194 {
195 COMPONENT* component = m_netlist.GetComponent( i );
196
197 if( component->GetFPID().IsLegacy() )
198 {
199 component->SetFPID( LIB_ID() );
200 m_modified = true;
201 }
202 }
203 }
204 }
205
206
207 // Display a dialog to select footprint selection, if the netlist
208 // and the .cmp file give 2 different valid footprints
209 std::vector <int > m_indexes; // indexes of footprints in netlist
210
211 for( unsigned ii = 0; ii < m_netlist.GetCount(); ii++ )
212 {
213 COMPONENT* component = m_netlist.GetComponent( ii );
214
215 if( component->GetAltFPID().empty() )
216 continue;
217
218 if( component->GetFPID().IsLegacy() || component->GetAltFPID().IsLegacy() )
219 continue;
220
221 m_indexes.push_back( ii );
222 }
223
224 // If a n assignment conflict is found,
225 // open a dialog to chose between schematic assignment
226 // and .cmp file assignment:
227 if( m_indexes.size() > 0 )
228 {
230
231 for( unsigned ii = 0; ii < m_indexes.size(); ii++ )
232 {
233 COMPONENT* component = m_netlist.GetComponent( m_indexes[ii] );
234
235 wxString cmpfpid = component->GetFPID().Format();
236 wxString schfpid = component->GetAltFPID().Format();
237
238 dlg.Add( component->GetReference(), schfpid, cmpfpid );
239 }
240
241 if( dlg.ShowModal() == wxID_OK )
242 {
243 // Update the fp selection:
244 for( unsigned ii = 0; ii < m_indexes.size(); ii++ )
245 {
246 COMPONENT* component = m_netlist.GetComponent( m_indexes[ii] );
247
248 int choice = dlg.GetSelection( component->GetReference() );
249
250 if( choice == 0 ) // the schematic (alt fpid) is chosen:
251 component->SetFPID( component->GetAltFPID() );
252 }
253 }
254 }
255
256 int firstUnassigned = wxNOT_FOUND;
257
258 // Populates the component list box:
259 for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
260 {
261 COMPONENT* component = m_netlist.GetComponent( i );
262
263 msg = formatSymbolDesc( m_symbolsListBox->GetCount() + 1,
264 component->GetReference(),
265 component->GetValue(),
266 From_UTF8( component->GetFPID().Format().c_str() ) );
267
268 m_symbolsListBox->AppendLine( msg );
269
270 if( firstUnassigned == wxNOT_FOUND && component->GetFPID().empty() )
271 firstUnassigned = i;
272
273 if( !m_FootprintsList->GetFootprintInfo( component->GetFPID().Format().wx_str() ) )
274 m_symbolsListBox->AppendWarning( i );
275 }
276
277 if( firstUnassigned >= 0 )
278 m_symbolsListBox->SetSelection( firstUnassigned, true );
279
281
282 return true;
283}
284
285
287{
288 std::string payload;
290
291 m_netlist.FormatCvpcbNetlist( &sf );
292
293 payload = sf.GetString();
295
296 if( doSaveSchematic )
297 {
298 payload = "";
300
301 if( payload == "success" )
302 SetStatusText( _( "Schematic saved" ), 1 );
303 }
304
305 // Changes are saved, so reset the flag
306 m_modified = false;
307
308 return true;
309}
const char * name
Store all of the related component information found in a netlist.
const wxString & GetReference() const
const wxString & GetValue() const
void SetFPID(const LIB_ID &aFPID)
const LIB_ID & GetAltFPID() const
const LIB_ID & GetFPID() const
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
int ShowModal() override
An interface to the global shared library manager that is schematic-specific and linked to one projec...
std::vector< wxString > GetFootprintNames(const wxString &aNickname, bool aBestEfforts=false)
Retrieves a list of footprint names contained in a given loaded library.
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.
virtual const wxString What() const
A composite of Problem() and Where()
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.
virtual void ExpressMail(FRAME_T aDestination, MAIL_T aCommand, std::string &aPayload, wxWindow *aSource=nullptr, bool aFromOtherThread=false)
Send aPayload to aDestination from aSource.
Definition kiway.cpp:496
std::vector< wxString > GetLibraryNames() const
Returns a list of library nicknames that are available (skips any that failed to load)
A logical library item identifier and consists of various portions much like a URI.
Definition lib_id.h:45
int SetLibNickname(const UTF8 &aLibNickname)
Override the logical library name portion of the LIB_ID to aLibNickname.
Definition lib_id.cpp:96
bool empty() const
Definition lib_id.h:189
UTF8 Format() const
Definition lib_id.cpp:115
const UTF8 & GetLibItemName() const
Definition lib_id.h:98
bool IsLegacy() const
Definition lib_id.h:176
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition lib_id.h:83
static FOOTPRINT_LIBRARY_ADAPTER * FootprintLibAdapter(PROJECT *aProject)
Implement an OUTPUTFORMATTER to a memory buffer.
Definition richio.h:418
const std::string & GetString()
Definition richio.h:441
const char * c_str() const
Definition utf8.h:104
std::string::size_type size() const
Definition utf8.h:112
wxString wx_str() const
Definition utf8.cpp:41
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition confirm.cpp:274
This file is part of the common library.
#define _(s)
@ FRAME_SCH
Definition frame_type.h:30
@ MAIL_SCH_SAVE
Definition mail_type.h:39
@ MAIL_ASSIGN_FOOTPRINTS
Definition mail_type.h:38
static int guessNickname(FOOTPRINT_LIBRARY_ADAPTER *aAdapter, LIB_ID *aFootprintId)
Return true if the resultant LIB_ID has a certain nickname.
wxString From_UTF8(const char *cstring)