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-2018 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 
24 #include <sch_edit_frame.h>
25 #include <sch_component.h>
26 #include <invoke_sch_dialog.h>
28 #include <kiface_i.h>
29 #include <class_library.h>
30 #include <class_libentry.h>
31 #include <set>
32 #include <vector>
33 #include <project_rescue.h>
34 #include <eeschema_config.h>
35 #include <symbol_preview_widget.h>
36 
38 {
39 public:
49  DIALOG_RESCUE_EACH( SCH_EDIT_FRAME* aParent, RESCUER& aRescuer, bool aAskShowAgain );
50 
52 
53 private:
57  wxConfigBase* m_Config;
60 
61  bool TransferDataToWindow() override;
62  bool TransferDataFromWindow() override;
63  void PopulateConflictList();
64  void PopulateInstanceList();
65  void OnConflictSelect( wxDataViewEvent& aEvent ) override;
66  void OnNeverShowClick( wxCommandEvent& aEvent ) override;
67  void OnCancelClick( wxCommandEvent& aEvent ) override;
68 
69  // Display the 2 items (old in cache and new in library) corresponding to the
70  // selected conflict in m_ListOfConflicts
72 };
73 
74 
76  bool aAskShowAgain )
77  : DIALOG_RESCUE_EACH_BASE( aParent ),
78  m_Parent( aParent ),
79  m_Rescuer( &aRescuer ),
80  m_AskShowAgain( aAskShowAgain )
81 {
83  m_SizerOldPanel->Add( m_previewOldWidget, 1, wxEXPAND | wxALL, 5 );
84 
86  m_SizerNewPanel->Add( m_previewNewWidget, 1, wxEXPAND | wxALL, 5 );
87 
89  m_stdButtonsOK->SetDefault();
90 
91  // Set the info message, customized to include the proper suffix.
92  wxString info =
93  _( "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();
110 
111  m_ListOfConflicts->AppendToggleColumn( header, wxDATAVIEW_CELL_ACTIVATABLE, width,
112  wxALIGN_CENTER );
113 
114  header = _( "Symbol Name" );
115  width = dc.GetTextExtent( header ).GetWidth() * 2;
116  m_ListOfConflicts->AppendTextColumn( header, wxDATAVIEW_CELL_INERT, width );
117 
118  header = _( "Action Taken" );
119  width = dc.GetTextExtent( header ).GetWidth() * 10;
120  m_ListOfConflicts->AppendTextColumn( header, wxDATAVIEW_CELL_INERT, width );
121 
122  header = _( "Reference" );
123  width = dc.GetTextExtent( header ).GetWidth() * 2;
124  m_ListOfInstances->AppendTextColumn( header, wxDATAVIEW_CELL_INERT, width );
125 
126  header = _( "Value" );
127  width = dc.GetTextExtent( header ).GetWidth() * 10;
128  m_ListOfInstances->AppendTextColumn( header, wxDATAVIEW_CELL_INERT, width );
129 
130  m_previewOldWidget->SetLayoutDirection( wxLayout_LeftToRight );
131  m_previewNewWidget->SetLayoutDirection( wxLayout_LeftToRight );
132 
133  Layout();
134  SetSizeInDU( 480, 360 );
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  auto info_size = m_htmlPrompt->GetTextExtent( info );
139  auto prompt_size = m_htmlPrompt->GetSize();
140  auto font_size = m_htmlPrompt->GetTextExtent( "X" );
141  auto 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  Layout();
144  GetSizer()->SetSizeHints( this );
145  SetSizeInDU( 480, 360 );
146  Center();
147 }
148 
149 
151 {
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  for( RESCUE_CANDIDATE& each_candidate : m_Rescuer->m_all_candidates )
174  {
175  data.clear();
176  data.push_back( wxVariant( true ) );
177  data.push_back( each_candidate.GetRequestedName() );
178  data.push_back( each_candidate.GetActionDescription() );
179 
180  m_ListOfConflicts->AppendItem( data );
181  }
182 
183  if( !m_Rescuer->m_all_candidates.empty() )
184  {
185  // Select the first choice
186  m_ListOfConflicts->SelectRow( 0 );
187  // Ensure this choice is displayed:
189  }
190 }
191 
192 
194 {
195  m_ListOfInstances->DeleteAllItems();
196 
197  int row = m_ListOfConflicts->GetSelectedRow();
198 
199  if( row == wxNOT_FOUND )
200  row = 0;
201 
202  RESCUE_CANDIDATE& selected_part = m_Rescuer->m_all_candidates[row];
203 
204  wxVector<wxVariant> data;
205  int count = 0;
206 
207  for( SCH_COMPONENT* each_component : *m_Rescuer->GetComponents() )
208  {
209  if( each_component->GetLibId().Format() != UTF8( selected_part.GetRequestedName() ) )
210  continue;
211 
212  SCH_FIELD* valueField = each_component->GetField( 1 );
213 
214  data.clear();
215  data.push_back( each_component->GetRef( & m_Parent->GetCurrentSheet() ) );
216  data.push_back( valueField ? valueField->GetText() : wxT( "" ) );
217  m_ListOfInstances->AppendItem( data );
218  count++;
219  }
220 
221  wxString msg = wxString::Format( _( "Instances of this symbol (%d items):" ), count );
222  m_titleInstances->SetLabelText( msg );
223 }
224 
225 
227 {
228  int row = m_ListOfConflicts->GetSelectedRow();
229 
230  if( row < 0 )
231  {
232  m_previewOldWidget->DisplayPart( nullptr, 0 );
233  m_previewNewWidget->DisplayPart( nullptr, 0 );
234  }
235  else
236  {
237  RESCUE_CANDIDATE& selected_part = m_Rescuer->m_all_candidates[row];
238  m_previewOldWidget->DisplayPart( selected_part.GetCacheCandidate(), 0 );
239  m_previewNewWidget->DisplayPart( selected_part.GetLibCandidate(), 0 );
240  }
241 }
242 
243 
244 void DIALOG_RESCUE_EACH::OnConflictSelect( wxDataViewEvent& aEvent )
245 {
246  // wxformbuilder connects this event to the _dialog_, not the data view.
247  // Make sure the correct item triggered it, otherwise we trigger recursively
248  // and get a stack overflow.
249  if( aEvent.GetEventObject() != m_ListOfConflicts )
250  return;
251 
254 }
255 
256 
258 {
259  if( !wxDialog::TransferDataFromWindow() )
260  return false;
261 
262  for( size_t index = 0; index < m_Rescuer->GetCandidateCount(); ++index )
263  {
264  wxVariant val;
265  m_ListOfConflicts->GetValue( val, index, 0 );
266  bool rescue_part = val.GetBool();
267 
268  if( rescue_part )
270  }
271  return true;
272 }
273 
274 
275 void DIALOG_RESCUE_EACH::OnNeverShowClick( wxCommandEvent& aEvent )
276 {
277  wxMessageDialog dlg( m_Parent,
278  _( "Stop showing this tool?\n"
279  "No changes will be made.\n\n"
280  "This setting can be changed from the \"Symbol Libraries\" dialog,\n"
281  "and the tool can be activated manually from the \"Tools\" menu." ),
282  _( "Rescue Symbols" ), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION );
283  int resp = dlg.ShowModal ();
284 
285  if( resp == wxID_YES )
286  {
287  m_Config->Write( RescueNeverShowEntry, true );
289  Close();
290  }
291 }
292 
293 
294 void DIALOG_RESCUE_EACH::OnCancelClick( wxCommandEvent& aEvent )
295 {
298 }
299 
300 
301 int InvokeDialogRescueEach( SCH_EDIT_FRAME* aCaller, RESCUER& aRescuer, bool aAskShowAgain )
302 {
303  DIALOG_RESCUE_EACH dlg( aCaller, aRescuer, aAskShowAgain );
304  return dlg.ShowModal();
305 }
Class UTF8 is an 8 bit string that is assuredly encoded in UTF8, and supplies special conversion supp...
Definition: utf8.h:73
virtual LIB_PART * GetLibCandidate() const
Get the part the would be loaded from the libraries, if possible, or else NULL.
Class SCH_FIELD instances are attached to a component and provide a place for the component&#39;s value...
Definition: sch_field.h:56
KIWAY & Kiway() const
Function Kiway returns a reference to the KIWAY that this object has an opportunity to participate in...
Definition: kiway_player.h:60
virtual LIB_PART * GetCacheCandidate() const
Get the part that can be loaded from the project cache, if possible, or else NULL.
SCH_EDIT_FRAME * m_Parent
GAL_TYPE GetBackend() const
Function GetBackend Returns the type of backend currently used by GAL canvas.
virtual wxString GetActionDescription() const =0
Get a description of the action proposed, for displaying in the UI.
bool TransferDataFromWindow() override
Class DIALOG_RESCUE_EACH_BASE.
const wxChar RescueNeverShowEntry[]
int InvokeDialogRescueEach(SCH_EDIT_FRAME *aCaller, RESCUER &aRescuer, bool aAskShowAgain)
Function InvokeDialogRescueEach This dialog asks the user which rescuable, cached parts he wants to r...
Schematic editor (Eeschema) main window.
virtual void OnCancelClick(wxCommandEvent &event)
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
Definition: kicad.cpp:52
boost::ptr_vector< RESCUE_CANDIDATE > m_all_candidates
bool TransferDataToWindow() override
SYMBOL_PREVIEW_WIDGET * m_previewOldWidget
Class LIB_ITEM definition.
const wxString & GetText() const
Function GetText returns the string associated with the text object.
Definition: eda_text.h:143
void DisplayPart(LIB_PART *aPart, int aUnit)
SCH_SHEET_PATH & GetCurrentSheet()
size_t GetCandidateCount()
Returen the number of rescue candidates found.
void SetSizeInDU(int x, int y)
Set the dialog to the given dimensions in "dialog units".
wxConfigBase * KifaceSettings() const
Definition: kiface_i.h:103
Definition the SCH_COMPONENT class for Eeschema.
std::vector< RESCUE_CANDIDATE * > m_chosen_candidates
void OnConflictSelect(wxDataViewEvent &aEvent) override
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
Class SCH_COMPONENT describes a real schematic component.
Definition: sch_component.h:69
void OnNeverShowClick(wxCommandEvent &aEvent) override
std::vector< SCH_COMPONENT * > * GetComponents()
Get the list of symbols that need rescued.
void OnCancelClick(wxCommandEvent &aEvent) override
wxDataViewListCtrl * m_ListOfConflicts
DIALOG_RESCUE_EACH(SCH_EDIT_FRAME *aParent, RESCUER &aRescuer, bool aAskShowAgain)
This dialog asks the user which rescuable, cached parts he wants to rescue.
EDA_DRAW_PANEL_GAL * GetGalCanvas() const
Return a pointer to GAL-based canvas of given EDA draw frame.
Definition: draw_frame.h:918
Definition for part library class.
SYMBOL_PREVIEW_WIDGET * m_previewNewWidget
virtual wxString GetRequestedName() const
Get the name that was originally requested in the schematic.
wxDataViewListCtrl * m_ListOfInstances