KiCad PCB EDA Suite
Loading...
Searching...
No Matches
dialog_rescue_each.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) 2015-2023 KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
25#include <symbol_library.h>
27#include <eeschema_settings.h>
28#include <invoke_sch_dialog.h>
29#include <kiface_base.h>
30#include <project_rescue.h>
31#include <sch_symbol.h>
32#include <sch_edit_frame.h>
33#include <set>
35
36#include <wx/msgdlg.h>
37#include <wx/dcclient.h>
38
39
41{
42public:
54 DIALOG_RESCUE_EACH( wxWindow* aParent, RESCUER& aRescuer, SCH_SHEET_PATH* aCurrentSheet,
55 EDA_DRAW_PANEL_GAL::GAL_TYPE aGalBackEndType, bool aAskShowAgain );
56
58
59private:
65
66 bool TransferDataToWindow() override;
67 bool TransferDataFromWindow() override;
70 void OnConflictSelect( wxDataViewEvent& aEvent ) override;
71 void OnNeverShowClick( wxCommandEvent& aEvent ) override;
72 void OnCancelClick( wxCommandEvent& aEvent ) override;
73
74 // Display the 2 items (old in cache and new in library) corresponding to the
75 // selected conflict in m_ListOfConflicts
77};
78
79
81 RESCUER& aRescuer,
82 SCH_SHEET_PATH* aCurrentSheet,
83 EDA_DRAW_PANEL_GAL::GAL_TYPE aGalBackEndType,
84 bool aAskShowAgain )
85 : DIALOG_RESCUE_EACH_BASE( aParent ),
86 m_Rescuer( &aRescuer ),
87 m_currentSheet( aCurrentSheet ),
88 m_AskShowAgain( aAskShowAgain )
89{
90 wxASSERT( aCurrentSheet );
91
93 aGalBackEndType );
94 m_SizerOldPanel->Add( m_previewOldWidget, 1, wxEXPAND | wxALL, 5 );
95
97 aGalBackEndType );
98 m_SizerNewPanel->Add( m_previewNewWidget, 1, wxEXPAND | wxALL, 5 );
99
100 // Set the info message, customized to include the proper suffix.
101 wxString info =
102 _( "This schematic was made using older symbol libraries which may break the "
103 "schematic. Some symbols may need to be linked to a different symbol name. "
104 "Some symbols may need to be \"rescued\" (copied and renamed) into a new library.\n\n"
105 "The following changes are recommended to update the project." );
107
108 // wxDataViewListCtrl seems to do a poor job of laying itself out so help it along here.
109 wxString header = _( "Accept" );
110 wxFont font = m_ListOfConflicts->GetFont();
111
112 font.MakeBold();
113
114 wxClientDC dc( this );
115
116 dc.SetFont( font );
117
118 int width = dc.GetTextExtent( header ).GetWidth() * 1.25;
119
120 m_ListOfConflicts->AppendToggleColumn( header, wxDATAVIEW_CELL_ACTIVATABLE, width,
121 wxALIGN_CENTER );
122
123 header = _( "Symbol Name" );
124 width = dc.GetTextExtent( header ).GetWidth() * 2;
125 m_ListOfConflicts->AppendTextColumn( header, wxDATAVIEW_CELL_INERT, width );
126
127 header = _( "Action Taken" );
128 width = dc.GetTextExtent( header ).GetWidth() * 10;
129 m_ListOfConflicts->AppendTextColumn( header, wxDATAVIEW_CELL_INERT, width );
130
131 header = _( "Reference" );
132 width = dc.GetTextExtent( header ).GetWidth() * 2;
133 m_ListOfInstances->AppendTextColumn( header, wxDATAVIEW_CELL_INERT, width );
134
135 header = _( "Value" );
136 width = dc.GetTextExtent( header ).GetWidth() * 10;
137 m_ListOfInstances->AppendTextColumn( header, wxDATAVIEW_CELL_INERT, width );
138
139 m_previewOldWidget->SetLayoutDirection( wxLayout_LeftToRight );
140 m_previewNewWidget->SetLayoutDirection( wxLayout_LeftToRight );
141
142 // Make sure the HTML window is large enough. Some fun size juggling and
143 // fudge factors here but it does seem to work pretty reliably.
144 wxSize info_size = m_htmlPrompt->GetTextExtent( info );
145 wxSize prompt_size = m_htmlPrompt->GetSize();
146 wxSize font_size = m_htmlPrompt->GetTextExtent( "X" );
147 int approx_info_height = ( 2 * info_size.x / prompt_size.x ) * font_size.y;
148 m_htmlPrompt->SetSizeHints( 2 * prompt_size.x / 3, approx_info_height );
149
151 m_stdButtonsOK->SetLabel( _( "Rescue Symbols" ) );
152 m_stdButtonsCancel->SetLabel( _( "Skip Symbol Rescue" ) );
153 m_stdButtons->Layout();
154 GetSizer()->SetSizeHints( this );
155
156 Layout();
157 Center();
158}
159
160
162{
163}
164
165
167{
168 if( !wxDialog::TransferDataToWindow() )
169 return false;
170
173
174 if( !m_AskShowAgain )
175 m_btnNeverShowAgain->Hide();
176
177 return true;
178}
179
180
182{
183 wxVector<wxVariant> data;
184
185 for( RESCUE_CANDIDATE& each_candidate : m_Rescuer->m_all_candidates )
186 {
187 data.clear();
188 data.push_back( wxVariant( true ) );
189 data.push_back( each_candidate.GetRequestedName() );
190 data.push_back( each_candidate.GetActionDescription() );
191
192 m_ListOfConflicts->AppendItem( data );
193 }
194
195 if( !m_Rescuer->m_all_candidates.empty() )
196 {
197 // Select the first choice
198 m_ListOfConflicts->SelectRow( 0 );
199
200 // Ensure this choice is displayed:
202 }
203}
204
205
207{
208 m_ListOfInstances->DeleteAllItems();
209
210 int row = m_ListOfConflicts->GetSelectedRow();
211
212 if( row == wxNOT_FOUND )
213 row = 0;
214
215 RESCUE_CANDIDATE& selected_part = m_Rescuer->m_all_candidates[row];
216
217 wxVector<wxVariant> data;
218 int count = 0;
219
220 for( SCH_SYMBOL* eachSymbol : *m_Rescuer->GetSymbols() )
221 {
222 if( eachSymbol->GetLibId().Format() != UTF8( selected_part.GetRequestedName() ) )
223 continue;
224
225 SCH_FIELD* valueField = eachSymbol->GetField( VALUE_FIELD );
226
227 data.clear();
228 data.push_back( eachSymbol->GetRef( m_currentSheet ) );
229 data.push_back( valueField ? valueField->GetText() : wxString( wxT( "" ) ) );
230 m_ListOfInstances->AppendItem( data );
231 count++;
232 }
233
234 wxString msg = wxString::Format( _( "Instances of this symbol (%d items):" ), count );
235 m_titleInstances->SetLabelText( msg );
236}
237
238
240{
241 int row = m_ListOfConflicts->GetSelectedRow();
242
243 if( row < 0 )
244 {
245 m_previewOldWidget->DisplayPart( nullptr, 0 );
246 m_previewNewWidget->DisplayPart( nullptr, 0 );
247 }
248 else
249 {
250 RESCUE_CANDIDATE& selected_part = m_Rescuer->m_all_candidates[row];
251
253 selected_part.GetUnit(),
254 selected_part.GetConvert() );
256 selected_part.GetUnit(),
257 selected_part.GetConvert() );
258 }
259}
260
261
262void DIALOG_RESCUE_EACH::OnConflictSelect( wxDataViewEvent& aEvent )
263{
264 // wxformbuilder connects this event to the _dialog_, not the data view.
265 // Make sure the correct item triggered it, otherwise we trigger recursively
266 // and get a stack overflow.
267 if( aEvent.GetEventObject() != m_ListOfConflicts )
268 return;
269
272}
273
274
276{
277 if( !wxDialog::TransferDataFromWindow() )
278 return false;
279
280 for( size_t index = 0; index < m_Rescuer->GetCandidateCount(); ++index )
281 {
282 wxVariant val;
283 m_ListOfConflicts->GetValue( val, index, 0 );
284 bool rescue_part = val.GetBool();
285
286 if( rescue_part )
288 }
289
290 return true;
291}
292
293
294void DIALOG_RESCUE_EACH::OnNeverShowClick( wxCommandEvent& aEvent )
295{
296 wxMessageDialog dlg( GetParent(),
297 _( "Stop showing this tool?\n"
298 "No changes will be made.\n\n"
299 "This setting can be changed from the \"Preferences\" dialog,\n"
300 "and the tool can be activated manually from the \"Tools\" menu." ),
301 _( "Rescue Symbols" ), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION );
302 int resp = dlg.ShowModal ();
303
304 if( resp == wxID_YES )
305 {
306 auto cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
307
308 if( cfg )
309 cfg->m_RescueNeverShow = true;
310
312 Close();
313 }
314}
315
316
317void DIALOG_RESCUE_EACH::OnCancelClick( wxCommandEvent& aEvent )
318{
321}
322
323
324int InvokeDialogRescueEach( wxWindow* aParent, RESCUER& aRescuer, SCH_SHEET_PATH* aCurrentSheet,
325 EDA_DRAW_PANEL_GAL::GAL_TYPE aGalBackEndType, bool aAskShowAgain )
326{
327 DIALOG_RESCUE_EACH dlg( aParent, aRescuer, aCurrentSheet, aGalBackEndType, aAskShowAgain );
328 return dlg.ShowQuasiModal();
329}
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
Class DIALOG_RESCUE_EACH_BASE.
virtual void OnCancelClick(wxCommandEvent &event)
wxDataViewListCtrl * m_ListOfConflicts
wxDataViewListCtrl * m_ListOfInstances
wxStdDialogButtonSizer * m_stdButtons
DIALOG_RESCUE_EACH(wxWindow *aParent, RESCUER &aRescuer, SCH_SHEET_PATH *aCurrentSheet, EDA_DRAW_PANEL_GAL::GAL_TYPE aGalBackEndType, bool aAskShowAgain)
This dialog asks the user which rescuable, cached parts he wants to rescue.
void OnNeverShowClick(wxCommandEvent &aEvent) override
bool TransferDataToWindow() override
void OnCancelClick(wxCommandEvent &aEvent) override
SYMBOL_PREVIEW_WIDGET * m_previewNewWidget
bool TransferDataFromWindow() override
void OnConflictSelect(wxDataViewEvent &aEvent) override
SYMBOL_PREVIEW_WIDGET * m_previewOldWidget
SCH_SHEET_PATH * m_currentSheet
void SetupStandardButtons(std::map< int, wxString > aLabels={})
int ShowQuasiModal()
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:95
bool AppendToPage(const wxString &aSource)
Definition: html_window.cpp:57
APP_SETTINGS_BASE * KifaceSettings() const
Definition: kiface_base.h:95
KIWAY & Kiway() const
Return a reference to the KIWAY that this object has an opportunity to participate in.
Definition: kiway_holder.h:53
std::vector< RESCUE_CANDIDATE * > m_chosen_candidates
std::vector< SCH_SYMBOL * > * GetSymbols()
Get the list of symbols that need rescued.
size_t GetCandidateCount()
Return the number of rescue candidates found.
boost::ptr_vector< RESCUE_CANDIDATE > m_all_candidates
virtual wxString GetActionDescription() const =0
Get a description of the action proposed, for displaying in the UI.
int GetUnit() const
virtual LIB_SYMBOL * GetCacheCandidate() const
Get the part that can be loaded from the project cache, if possible, or else NULL.
virtual wxString GetRequestedName() const
Get the name that was originally requested in the schematic.
int GetConvert() const
virtual LIB_SYMBOL * GetLibCandidate() const
Get the part the would be loaded from the libraries, if possible, or else NULL.
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
Definition: sch_field.h:52
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
Schematic symbol object.
Definition: sch_symbol.h:109
void DisplayPart(LIB_SYMBOL *aSymbol, int aUnit, int aBodyStyle=0)
An 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to and fro...
Definition: utf8.h:71
int InvokeDialogRescueEach(wxWindow *aParent, RESCUER &aRescuer, SCH_SHEET_PATH *aCurrentSheet, EDA_DRAW_PANEL_GAL::GAL_TYPE aGalBackEndType, bool aAskShowAgain)
This dialog asks the user which rescuable, cached parts he wants to rescue.
#define _(s)
Definition for symbol library class.
@ VALUE_FIELD
Field Value of part, i.e. "3.3K".