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 The 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
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#include <confirm.h>
36
37#include <wx/msgdlg.h>
38#include <wx/dcclient.h>
39
40
42{
43public:
55 DIALOG_RESCUE_EACH( wxWindow* aParent, RESCUER& aRescuer, SCH_SHEET_PATH* aCurrentSheet,
56 EDA_DRAW_PANEL_GAL::GAL_TYPE aGalBackEndType, bool aAskShowAgain );
58
59private:
60 bool TransferDataToWindow() override;
61 bool TransferDataFromWindow() override;
64 void OnConflictSelect( wxDataViewEvent& aEvent ) override;
65 void OnNeverShowClick( wxCommandEvent& aEvent ) override;
66 void OnCancelClick( wxCommandEvent& aEvent ) override;
67
68 // Display the 2 items (old in cache and new in library) corresponding to the
69 // selected conflict in m_ListOfConflicts
71
72private:
78};
79
80
81DIALOG_RESCUE_EACH::DIALOG_RESCUE_EACH( wxWindow* aParent, RESCUER& aRescuer, SCH_SHEET_PATH* aCurrentSheet,
82 EDA_DRAW_PANEL_GAL::GAL_TYPE aGalBackEndType, bool aAskShowAgain ) :
83 DIALOG_RESCUE_EACH_BASE( aParent ),
84 m_rescuer( &aRescuer ),
85 m_currentSheet( aCurrentSheet ),
86 m_askShowAgain( aAskShowAgain )
87{
88 wxASSERT( aCurrentSheet );
89
90 m_previewOldWidget = new SYMBOL_PREVIEW_WIDGET( m_previewOldPanel, &Kiway(), false, aGalBackEndType );
91 m_SizerOldPanel->Add( m_previewOldWidget, 1, wxEXPAND | wxALL, 5 );
92
93 m_previewNewWidget = new SYMBOL_PREVIEW_WIDGET( m_previewNewPanel, &Kiway(), false, aGalBackEndType );
94 m_SizerNewPanel->Add( m_previewNewWidget, 1, wxEXPAND | wxALL, 5 );
95
96 // Set the info message, customized to include the proper suffix.
97 wxString info = _( "This schematic was made using older symbol libraries which may break the "
98 "schematic. Some symbols may need to be linked to a different symbol name. "
99 "Some symbols may need to be \"rescued\" (copied and renamed) into a new library.\n\n"
100 "The following changes are recommended to update the project." );
101 m_htmlPrompt->AppendToPage( info );
102
103 // wxDataViewListCtrl seems to do a poor job of laying itself out so help it along here.
104 wxString header = _( "Accept" );
105 wxFont font = m_ListOfConflicts->GetFont();
106
107 font.MakeBold();
108
109 wxClientDC dc( this );
110
111 dc.SetFont( font );
112
113 int width = dc.GetTextExtent( header ).GetWidth() * 1.25;
114
115 m_ListOfConflicts->AppendToggleColumn( header, wxDATAVIEW_CELL_ACTIVATABLE, width, wxALIGN_CENTER );
116
117 header = _( "Symbol Name" );
118 width = dc.GetTextExtent( header ).GetWidth() * 2;
119 m_ListOfConflicts->AppendTextColumn( header, wxDATAVIEW_CELL_INERT, width );
120
121 header = _( "Action Taken" );
122 width = dc.GetTextExtent( header ).GetWidth() * 10;
123 m_ListOfConflicts->AppendTextColumn( header, wxDATAVIEW_CELL_INERT, width );
124
125 header = _( "Reference" );
126 width = dc.GetTextExtent( header ).GetWidth() * 2;
127 m_ListOfInstances->AppendTextColumn( header, wxDATAVIEW_CELL_INERT, width );
128
129 header = _( "Value" );
130 width = dc.GetTextExtent( header ).GetWidth() * 10;
131 m_ListOfInstances->AppendTextColumn( header, wxDATAVIEW_CELL_INERT, width );
132
133 m_previewOldWidget->SetLayoutDirection( wxLayout_LeftToRight );
134 m_previewNewWidget->SetLayoutDirection( wxLayout_LeftToRight );
135
136 // Make sure the HTML window is large enough. Some fun size juggling and
137 // fudge factors here but it does seem to work pretty reliably.
138 wxSize info_size = m_htmlPrompt->GetTextExtent( info );
139 wxSize prompt_size = m_htmlPrompt->GetSize();
140 wxSize font_size = m_htmlPrompt->GetTextExtent( "X" );
141 int approx_info_height = ( 2 * info_size.x / prompt_size.x ) * font_size.y;
142 m_htmlPrompt->SetSizeHints( 2 * prompt_size.x / 3, approx_info_height );
143
145 m_stdButtonsOK->SetLabel( _( "Rescue Symbols" ) );
146 m_stdButtonsCancel->SetLabel( _( "Skip Symbol Rescue" ) );
147 m_stdButtons->Layout();
148 GetSizer()->SetSizeHints( this );
149
150 Layout();
151 Center();
152}
153
154
156{
157 if( !wxDialog::TransferDataToWindow() )
158 return false;
159
162
163 if( !m_askShowAgain )
164 m_btnNeverShowAgain->Hide();
165
166 return true;
167}
168
169
171{
172 wxVector<wxVariant> data;
173
174 for( RESCUE_CANDIDATE& each_candidate : m_rescuer->m_all_candidates )
175 {
176 data.clear();
177 data.push_back( wxVariant( true ) );
178 data.push_back( each_candidate.GetRequestedName() );
179 data.push_back( each_candidate.GetActionDescription() );
180
181 m_ListOfConflicts->AppendItem( data );
182 }
183
184 if( !m_rescuer->m_all_candidates.empty() )
185 {
186 // Select the first choice
187 m_ListOfConflicts->SelectRow( 0 );
188
189 // Ensure this choice is displayed:
191 }
192}
193
194
196{
197 m_ListOfInstances->DeleteAllItems();
198
199 int row = m_ListOfConflicts->GetSelectedRow();
200
201 if( row == wxNOT_FOUND )
202 row = 0;
203
204 RESCUE_CANDIDATE& selected_part = m_rescuer->m_all_candidates[row];
205
206 wxVector<wxVariant> data;
207 int count = 0;
208
209 for( SCH_SYMBOL* eachSymbol : *m_rescuer->GetSymbols() )
210 {
211 if( eachSymbol->GetLibId().Format() != UTF8( selected_part.GetRequestedName() ) )
212 continue;
213
214 SCH_FIELD* valueField = eachSymbol->GetField( FIELD_T::VALUE );
215
216 data.clear();
217 data.push_back( eachSymbol->GetRef( m_currentSheet ) );
218 data.push_back( valueField ? valueField->GetText() : wxString( wxT( "" ) ) );
219 m_ListOfInstances->AppendItem( data );
220 count++;
221 }
222
223 wxString msg = wxString::Format( _( "Instances of this symbol (%d items):" ), count );
224 m_titleInstances->SetLabelText( msg );
225}
226
227
229{
230 int row = m_ListOfConflicts->GetSelectedRow();
231
232 if( row < 0 )
233 {
234 m_previewOldWidget->DisplayPart( nullptr, 0, 0 );
235 m_previewNewWidget->DisplayPart( nullptr, 0, 0 );
236 }
237 else
238 {
239 RESCUE_CANDIDATE& selected_part = m_rescuer->m_all_candidates[row];
240
241 m_previewOldWidget->DisplayPart( selected_part.GetCacheCandidate(), selected_part.GetUnit(),
242 selected_part.GetBodyStyle() );
243 m_previewNewWidget->DisplayPart( selected_part.GetLibCandidate(), selected_part.GetUnit(),
244 selected_part.GetBodyStyle() );
245 }
246}
247
248
249void DIALOG_RESCUE_EACH::OnConflictSelect( wxDataViewEvent& aEvent )
250{
251 // wxformbuilder connects this event to the _dialog_, not the data view.
252 // Make sure the correct item triggered it, otherwise we trigger recursively
253 // and get a stack overflow.
254 if( aEvent.GetEventObject() != m_ListOfConflicts )
255 return;
256
259}
260
261
263{
264 if( !wxDialog::TransferDataFromWindow() )
265 return false;
266
267 for( size_t index = 0; index < m_rescuer->GetCandidateCount(); ++index )
268 {
269 wxVariant val;
270 m_ListOfConflicts->GetValue( val, index, 0 );
271 bool rescue_part = val.GetBool();
272
273 if( rescue_part )
274 m_rescuer->m_chosen_candidates.push_back( &m_rescuer->m_all_candidates[index] );
275 }
276
277 return true;
278}
279
280
281void DIALOG_RESCUE_EACH::OnNeverShowClick( wxCommandEvent& aEvent )
282{
283 KICAD_MESSAGE_DIALOG dlg( GetParent(),
284 _( "Stop showing this tool?\n"
285 "No changes will be made.\n\n"
286 "This setting can be changed from the \"Preferences\" dialog,\n"
287 "and the tool can be activated manually from the \"Tools\" menu." ),
288 _( "Rescue Symbols" ), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION );
289 int resp = dlg.ShowModal ();
290
291 if( resp == wxID_YES )
292 {
293 auto cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
294
295 if( cfg )
296 cfg->m_RescueNeverShow = true;
297
298 m_rescuer->m_chosen_candidates.clear();
299 Close();
300 }
301}
302
303
304void DIALOG_RESCUE_EACH::OnCancelClick( wxCommandEvent& aEvent )
305{
306 m_rescuer->m_chosen_candidates.clear();
308}
309
310
311int InvokeDialogRescueEach( wxWindow* aParent, RESCUER& aRescuer, SCH_SHEET_PATH* aCurrentSheet,
312 EDA_DRAW_PANEL_GAL::GAL_TYPE aGalBackEndType, bool aAskShowAgain )
313{
314 DIALOG_RESCUE_EACH dlg( aParent, aRescuer, aCurrentSheet, aGalBackEndType, aAskShowAgain );
315 return dlg.ShowQuasiModal();
316}
int index
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
virtual void OnCancelClick(wxCommandEvent &event)
wxDataViewListCtrl * m_ListOfConflicts
wxDataViewListCtrl * m_ListOfInstances
wxStdDialogButtonSizer * m_stdButtons
DIALOG_RESCUE_EACH_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &title=_("Project Rescue Helper"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
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
~DIALOG_RESCUE_EACH()=default
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={})
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.
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.
virtual LIB_SYMBOL * GetLibCandidate() const
Get the part the would be loaded from the libraries, if possible, or else NULL.
int GetBodyStyle() const
virtual const wxString & GetText() const override
Return the string associated with the text object.
Definition sch_field.h:116
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:76
An 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to and fro...
Definition utf8.h:71
This file is part of the common library.
#define KICAD_MESSAGE_DIALOG
Definition confirm.h:52
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)
@ VALUE
Field Value of part, i.e. "3.3K".