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