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