KiCad PCB EDA Suite
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-2021 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#include <vector>
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 );
57
59
60private:
66
67 bool TransferDataToWindow() override;
68 bool TransferDataFromWindow() override;
71 void OnConflictSelect( wxDataViewEvent& aEvent ) override;
72 void OnNeverShowClick( wxCommandEvent& aEvent ) override;
73 void OnCancelClick( wxCommandEvent& aEvent ) override;
74
75 // Display the 2 items (old in cache and new in library) corresponding to the
76 // selected conflict in m_ListOfConflicts
78};
79
80
82 RESCUER& aRescuer,
83 SCH_SHEET_PATH* aCurrentSheet,
84 EDA_DRAW_PANEL_GAL::GAL_TYPE aGalBackEndType,
85 bool aAskShowAgain )
86 : DIALOG_RESCUE_EACH_BASE( aParent ),
87 m_Rescuer( &aRescuer ),
88 m_currentSheet( aCurrentSheet ),
89 m_AskShowAgain( aAskShowAgain )
90{
91 wxASSERT( aCurrentSheet );
92
94 m_SizerOldPanel->Add( m_previewOldWidget, 1, wxEXPAND | wxALL, 5 );
95
97 m_SizerNewPanel->Add( m_previewNewWidget, 1, wxEXPAND | wxALL, 5 );
98
99 // Set the info message, customized to include the proper suffix.
100 wxString info =
101 _( "This schematic was made using older symbol libraries which may break the "
102 "schematic. Some symbols may need to be linked to a different symbol name. "
103 "Some symbols may need to be \"rescued\" (copied and renamed) into a new library.\n\n"
104 "The following changes are recommended to update the project." );
106
107 // wxDataViewListCtrl seems to do a poor job of laying itself out so help it along here.
108 wxString header = _( "Accept" );
109 wxFont font = m_ListOfConflicts->GetFont();
110
111 font.MakeBold();
112
113 wxClientDC dc( this );
114
115 dc.SetFont( font );
116
117 int width = dc.GetTextExtent( header ).GetWidth();
118
119 m_ListOfConflicts->AppendToggleColumn( header, wxDATAVIEW_CELL_ACTIVATABLE, width,
120 wxALIGN_CENTER );
121
122 header = _( "Symbol Name" );
123 width = dc.GetTextExtent( header ).GetWidth() * 2;
124 m_ListOfConflicts->AppendTextColumn( header, wxDATAVIEW_CELL_INERT, width );
125
126 header = _( "Action Taken" );
127 width = dc.GetTextExtent( header ).GetWidth() * 10;
128 m_ListOfConflicts->AppendTextColumn( header, wxDATAVIEW_CELL_INERT, width );
129
130 header = _( "Reference" );
131 width = dc.GetTextExtent( header ).GetWidth() * 2;
132 m_ListOfInstances->AppendTextColumn( header, wxDATAVIEW_CELL_INERT, width );
133
134 header = _( "Value" );
135 width = dc.GetTextExtent( header ).GetWidth() * 10;
136 m_ListOfInstances->AppendTextColumn( header, wxDATAVIEW_CELL_INERT, width );
137
138 m_previewOldWidget->SetLayoutDirection( wxLayout_LeftToRight );
139 m_previewNewWidget->SetLayoutDirection( wxLayout_LeftToRight );
140
141 Layout();
142 setSizeInDU( 480, 360 );
143
144 // Make sure the HTML window is large enough. Some fun size juggling and
145 // fudge factors here but it does seem to work pretty reliably.
146 wxSize info_size = m_htmlPrompt->GetTextExtent( info );
147 wxSize prompt_size = m_htmlPrompt->GetSize();
148 wxSize font_size = m_htmlPrompt->GetTextExtent( "X" );
149 int approx_info_height = ( 2 * info_size.x / prompt_size.x ) * font_size.y;
150 m_htmlPrompt->SetSizeHints( 2 * prompt_size.x / 3, approx_info_height );
151
153
154 Layout();
155 GetSizer()->SetSizeHints( this );
156 setSizeInDU( 480, 360 );
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 for( RESCUE_CANDIDATE& each_candidate : m_Rescuer->m_all_candidates )
185 {
186 data.clear();
187 data.push_back( wxVariant( true ) );
188 data.push_back( each_candidate.GetRequestedName() );
189 data.push_back( each_candidate.GetActionDescription() );
190
191 m_ListOfConflicts->AppendItem( data );
192 }
193
194 if( !m_Rescuer->m_all_candidates.empty() )
195 {
196 // Select the first choice
197 m_ListOfConflicts->SelectRow( 0 );
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() : 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 return true;
288}
289
290
291void DIALOG_RESCUE_EACH::OnNeverShowClick( wxCommandEvent& aEvent )
292{
293 wxMessageDialog dlg( GetParent(),
294 _( "Stop showing this tool?\n"
295 "No changes will be made.\n\n"
296 "This setting can be changed from the \"Symbol Libraries\" dialog,\n"
297 "and the tool can be activated manually from the \"Tools\" menu." ),
298 _( "Rescue Symbols" ), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION );
299 int resp = dlg.ShowModal ();
300
301 if( resp == wxID_YES )
302 {
303 auto cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
304
305 if( cfg )
306 cfg->m_RescueNeverShow = true;
307
309 Close();
310 }
311}
312
313
314void DIALOG_RESCUE_EACH::OnCancelClick( wxCommandEvent& aEvent )
315{
318}
319
320
321int InvokeDialogRescueEach( wxWindow* aParent, RESCUER& aRescuer, SCH_SHEET_PATH* aCurrentSheet,
322 EDA_DRAW_PANEL_GAL::GAL_TYPE aGalBackEndType, bool aAskShowAgain )
323{
324 DIALOG_RESCUE_EACH dlg( aParent, aRescuer, aCurrentSheet, aGalBackEndType, aAskShowAgain );
325 return dlg.ShowQuasiModal();
326}
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
Class DIALOG_RESCUE_EACH_BASE.
virtual void OnCancelClick(wxCommandEvent &event)
wxDataViewListCtrl * m_ListOfConflicts
wxDataViewListCtrl * m_ListOfInstances
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()
void setSizeInDU(int x, int y)
Set the dialog to the given dimensions in "dialog units".
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:87
bool AppendToPage(const wxString &aSource)
Definition: html_window.cpp:57
APP_SETTINGS_BASE * KifaceSettings() const
Definition: kiface_base.h:93
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:50
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:79
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)
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
Definition for symbol library class.
@ VALUE_FIELD
Field Value of part, i.e. "3.3K".