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 m_SizerOldPanel->Add( m_previewOldWidget, 1, wxEXPAND | wxALL, 5 );
94
96 m_SizerNewPanel->Add( m_previewNewWidget, 1, wxEXPAND | wxALL, 5 );
97
98 // Set the info message, customized to include the proper suffix.
99 wxString info =
100 _( "This schematic was made using older symbol libraries which may break the "
101 "schematic. Some symbols may need to be linked to a different symbol name. "
102 "Some symbols may need to be \"rescued\" (copied and renamed) into a new library.\n\n"
103 "The following changes are recommended to update the project." );
105
106 // wxDataViewListCtrl seems to do a poor job of laying itself out so help it along here.
107 wxString header = _( "Accept" );
108 wxFont font = m_ListOfConflicts->GetFont();
109
110 font.MakeBold();
111
112 wxClientDC dc( this );
113
114 dc.SetFont( font );
115
116 int width = dc.GetTextExtent( header ).GetWidth() * 1.25;
117
118 m_ListOfConflicts->AppendToggleColumn( header, wxDATAVIEW_CELL_ACTIVATABLE, width,
119 wxALIGN_CENTER );
120
121 header = _( "Symbol Name" );
122 width = dc.GetTextExtent( header ).GetWidth() * 2;
123 m_ListOfConflicts->AppendTextColumn( header, wxDATAVIEW_CELL_INERT, width );
124
125 header = _( "Action Taken" );
126 width = dc.GetTextExtent( header ).GetWidth() * 10;
127 m_ListOfConflicts->AppendTextColumn( header, wxDATAVIEW_CELL_INERT, width );
128
129 header = _( "Reference" );
130 width = dc.GetTextExtent( header ).GetWidth() * 2;
131 m_ListOfInstances->AppendTextColumn( header, wxDATAVIEW_CELL_INERT, width );
132
133 header = _( "Value" );
134 width = dc.GetTextExtent( header ).GetWidth() * 10;
135 m_ListOfInstances->AppendTextColumn( header, wxDATAVIEW_CELL_INERT, width );
136
137 m_previewOldWidget->SetLayoutDirection( wxLayout_LeftToRight );
138 m_previewNewWidget->SetLayoutDirection( wxLayout_LeftToRight );
139
140 // Make sure the HTML window is large enough. Some fun size juggling and
141 // fudge factors here but it does seem to work pretty reliably.
142 wxSize info_size = m_htmlPrompt->GetTextExtent( info );
143 wxSize prompt_size = m_htmlPrompt->GetSize();
144 wxSize font_size = m_htmlPrompt->GetTextExtent( "X" );
145 int approx_info_height = ( 2 * info_size.x / prompt_size.x ) * font_size.y;
146 m_htmlPrompt->SetSizeHints( 2 * prompt_size.x / 3, approx_info_height );
147
149 m_stdButtonsOK->SetLabel( _( "Rescue Symbols" ) );
150 m_stdButtonsCancel->SetLabel( _( "Skip Symbol Rescue" ) );
151 m_stdButtons->Layout();
152 GetSizer()->SetSizeHints( this );
153
154 Layout();
155 Center();
156}
157
158
160{
161}
162
163
165{
166 if( !wxDialog::TransferDataToWindow() )
167 return false;
168
171
172 if( !m_AskShowAgain )
173 m_btnNeverShowAgain->Hide();
174
175 return true;
176}
177
178
180{
181 wxVector<wxVariant> data;
182
183 for( RESCUE_CANDIDATE& each_candidate : m_Rescuer->m_all_candidates )
184 {
185 data.clear();
186 data.push_back( wxVariant( true ) );
187 data.push_back( each_candidate.GetRequestedName() );
188 data.push_back( each_candidate.GetActionDescription() );
189
190 m_ListOfConflicts->AppendItem( data );
191 }
192
193 if( !m_Rescuer->m_all_candidates.empty() )
194 {
195 // Select the first choice
196 m_ListOfConflicts->SelectRow( 0 );
197
198 // Ensure this choice is displayed:
200 }
201}
202
203
205{
206 m_ListOfInstances->DeleteAllItems();
207
208 int row = m_ListOfConflicts->GetSelectedRow();
209
210 if( row == wxNOT_FOUND )
211 row = 0;
212
213 RESCUE_CANDIDATE& selected_part = m_Rescuer->m_all_candidates[row];
214
215 wxVector<wxVariant> data;
216 int count = 0;
217
218 for( SCH_SYMBOL* eachSymbol : *m_Rescuer->GetSymbols() )
219 {
220 if( eachSymbol->GetLibId().Format() != UTF8( selected_part.GetRequestedName() ) )
221 continue;
222
223 SCH_FIELD* valueField = eachSymbol->GetField( VALUE_FIELD );
224
225 data.clear();
226 data.push_back( eachSymbol->GetRef( m_currentSheet ) );
227 data.push_back( valueField ? valueField->GetText() : wxString( wxT( "" ) ) );
228 m_ListOfInstances->AppendItem( data );
229 count++;
230 }
231
232 wxString msg = wxString::Format( _( "Instances of this symbol (%d items):" ), count );
233 m_titleInstances->SetLabelText( msg );
234}
235
236
238{
239 int row = m_ListOfConflicts->GetSelectedRow();
240
241 if( row < 0 )
242 {
243 m_previewOldWidget->DisplayPart( nullptr, 0 );
244 m_previewNewWidget->DisplayPart( nullptr, 0 );
245 }
246 else
247 {
248 RESCUE_CANDIDATE& selected_part = m_Rescuer->m_all_candidates[row];
249
251 selected_part.GetUnit(),
252 selected_part.GetConvert() );
254 selected_part.GetUnit(),
255 selected_part.GetConvert() );
256 }
257}
258
259
260void DIALOG_RESCUE_EACH::OnConflictSelect( wxDataViewEvent& aEvent )
261{
262 // wxformbuilder connects this event to the _dialog_, not the data view.
263 // Make sure the correct item triggered it, otherwise we trigger recursively
264 // and get a stack overflow.
265 if( aEvent.GetEventObject() != m_ListOfConflicts )
266 return;
267
270}
271
272
274{
275 if( !wxDialog::TransferDataFromWindow() )
276 return false;
277
278 for( size_t index = 0; index < m_Rescuer->GetCandidateCount(); ++index )
279 {
280 wxVariant val;
281 m_ListOfConflicts->GetValue( val, index, 0 );
282 bool rescue_part = val.GetBool();
283
284 if( rescue_part )
286 }
287
288 return true;
289}
290
291
292void DIALOG_RESCUE_EACH::OnNeverShowClick( wxCommandEvent& aEvent )
293{
294 wxMessageDialog dlg( GetParent(),
295 _( "Stop showing this tool?\n"
296 "No changes will be made.\n\n"
297 "This setting can be changed from the \"Symbol Libraries\" dialog,\n"
298 "and the tool can be activated manually from the \"Tools\" menu." ),
299 _( "Rescue Symbols" ), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION );
300 int resp = dlg.ShowModal ();
301
302 if( resp == wxID_YES )
303 {
304 auto cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
305
306 if( cfg )
307 cfg->m_RescueNeverShow = true;
308
310 Close();
311 }
312}
313
314
315void DIALOG_RESCUE_EACH::OnCancelClick( wxCommandEvent& aEvent )
316{
319}
320
321
322int InvokeDialogRescueEach( wxWindow* aParent, RESCUER& aRescuer, SCH_SHEET_PATH* aCurrentSheet,
323 EDA_DRAW_PANEL_GAL::GAL_TYPE aGalBackEndType, bool aAskShowAgain )
324{
325 DIALOG_RESCUE_EACH dlg( aParent, aRescuer, aCurrentSheet, aGalBackEndType, aAskShowAgain );
326 return dlg.ShowQuasiModal();
327}
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:92
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:51
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:81
void DisplayPart(LIB_SYMBOL *aSymbol, int aUnit, int aConvert=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".