KiCad PCB EDA Suite
Loading...
Searching...
No Matches
dialog_sch_find.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) 2010 Wayne Stambaugh <[email protected]>
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
21#include <dialog_sch_find.h>
22#include <tool/actions.h>
23#include <sch_edit_frame.h>
25#include <tool/tool_manager.h>
26
27
29 const wxPoint& aPosition, const wxSize& aSize, int aStyle ) :
30 DIALOG_SCH_FIND_BASE( aParent, wxID_ANY, _( "Find" ), aPosition, aSize,
31 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | aStyle ),
32 m_frame( aParent ),
33 m_findReplaceTool( m_frame->GetToolManager()->GetTool<SCH_FIND_REPLACE_TOOL>() ),
34 m_findReplaceData( aData ),
35 m_findDirty( true )
36{
37 wxASSERT_MSG( m_findReplaceData, wxT( "can't create find dialog without data" ) );
38
41
42 if( aStyle & wxFR_REPLACEDIALOG )
43 {
44 SetTitle( _( "Find and Replace" ) );
45 m_buttonReplace->Show( true );
46 m_buttonReplaceAll->Show( true );
47 m_staticReplace->Show( true );
48 m_comboReplace->Show( true );
49 m_cbSelectedOnly->Show( true );
50 m_cbReplaceReferences->Show( true );
51 m_checkRegexMatch->Show( true );
52 }
53
54 if( m_frame->GetFrameType() == FRAME_SCH_SYMBOL_EDITOR )
55 {
56 m_findReplaceData->searchAllPins = true;
57
59 m_cbSearchPins->Hide();
60 m_cbSearchNetNames->Hide();
62
63 m_staticline1->Hide();
64 m_searchPanelLink->Hide();
65 }
66
67 m_checkMatchCase->SetValue( m_findReplaceData->matchCase );
70
71 m_cbSearchHiddenFields->SetValue( m_findReplaceData->searchAllFields );
72 m_cbReplaceReferences->SetValue( m_findReplaceData->replaceReferences );
73 m_cbSearchPins->SetValue( m_findReplaceData->searchAllPins );
74 m_cbSelectedOnly->SetValue( m_findReplaceData->searchSelectedOnly );
75
76 m_cbCurrentSheetOnly->SetValue( m_findReplaceData->searchCurrentSheetOnly );
77 m_cbCurrentSheetOnly->Enable( !m_findReplaceData->searchSelectedOnly );
78 m_cbSearchNetNames->SetValue( m_findReplaceData->searchNetNames );
79
80 if( int hotkey = ACTIONS::showSearch.GetHotKey() )
81 {
82 wxString hotkeyHint = wxString::Format( wxT( " (%s)" ), KeyNameFromKeyCode( hotkey ) );
83 m_searchPanelLink->SetLabel( m_searchPanelLink->GetLabel() + hotkeyHint );
84 m_searchPanelLink->GetParent()->Layout();
85 }
86
87 m_buttonFind->SetDefault();
89
90 // Adjust the height of the dialog to prevent controls from being hidden when
91 // switching between the find and find/replace modes of the dialog. This ignores
92 // the users preferred height if any of the controls would be hidden.
93 GetSizer()->SetSizeHints( this );
94 wxSize size = aSize;
95
96 if( aSize != wxDefaultSize )
97 {
98 wxSize bestSize = GetBestSize();
99
100 if( size.GetHeight() != bestSize.GetHeight() )
101 size.SetHeight( bestSize.GetHeight() );
102 }
103
104 SetSize( size );
105
106 GetSizer()->Fit( this ); // Needed on Ubuntu/Unity to display the dialog
107
108 // Set up tab order for proper keyboard navigation.
109 // This is needed because wxComboBox on GTK has issues with Tab key navigation.
110 m_tabOrder = {
128 };
129}
130
131
132void DIALOG_SCH_FIND::OnClose( wxCloseEvent& aEvent )
133{
134 // Notify the SCH_BASE_FRAME
135 m_frame->OnFindDialogClose();
136}
137
138
139void DIALOG_SCH_FIND::OnIdle( wxIdleEvent& aEvent )
140{
141 if( m_findDirty )
142 {
143 m_findReplaceTool->UpdateFind( ACTIONS::updateFind.MakeEvent() );
144 m_findDirty = false;
145 }
146}
147
148
149void DIALOG_SCH_FIND::OnCancel( wxCommandEvent& aEvent )
150{
151 wxCloseEvent dummy;
152 OnClose( dummy );
153}
154
155
156void DIALOG_SCH_FIND::OnCharHook( wxKeyEvent& aEvent )
157{
158 if( aEvent.GetKeyCode() == WXK_F3 )
159 {
160 updateFlags();
161 m_findReplaceData->findString = m_comboFind->GetValue();
162
163 if( aEvent.ShiftDown() )
164 m_findReplaceTool->FindNext( ACTIONS::findPrevious.MakeEvent() );
165 else
166 m_findReplaceTool->FindNext( ACTIONS::findNext.MakeEvent() );
167
168 return;
169 }
170
172}
173
174
175void DIALOG_SCH_FIND::onShowSearchPanel( wxHyperlinkEvent& event )
176{
177 wxCHECK2( m_frame->GetFrameType() == FRAME_SCH, /* void */ );
178
179 m_frame->GetToolManager()->RunAction( ACTIONS::showSearch );
180
181 Show( false );
182
183 CallAfter(
184 []()
185 {
186 if( wxWindow* frame = wxWindow::FindWindowByName( SCH_EDIT_FRAME_NAME ) )
187 static_cast<SCH_EDIT_FRAME*>( frame )->FocusSearch();
188 } );
189}
190
191
192void DIALOG_SCH_FIND::OnUpdateReplaceUI( wxUpdateUIEvent& aEvent )
193{
194 aEvent.Enable( HasFlag( wxFR_REPLACEDIALOG ) && !m_comboFind->GetValue().empty()
195 && m_findReplaceTool->HasMatch() );
196}
197
198
199void DIALOG_SCH_FIND::OnUpdateReplaceAllUI( wxUpdateUIEvent& aEvent )
200{
201 aEvent.Enable( HasFlag( wxFR_REPLACEDIALOG ) && !m_comboFind->GetValue().empty() );
202}
203
204
205void DIALOG_SCH_FIND::OnSearchForText( wxCommandEvent& aEvent )
206{
207 m_findReplaceData->findString = m_comboFind->GetValue();
208 m_findDirty = true;
209}
210
211
212void DIALOG_SCH_FIND::OnSearchForSelect( wxCommandEvent& aEvent )
213{
214 m_findReplaceData->findString = m_comboFind->GetValue();
215
216 // Move the search string to the top of the list if it isn't already there.
217 if( aEvent.GetSelection() != 0 )
218 {
219 wxString tmp = m_comboFind->GetValue();
220 m_comboFind->Delete( aEvent.GetSelection() );
221 m_comboFind->Insert( tmp, 0 );
222 m_comboFind->SetSelection( 0 );
223 }
224
225 m_findReplaceTool->UpdateFind( ACTIONS::updateFind.MakeEvent() );
226}
227
228
229void DIALOG_SCH_FIND::OnReplaceWithText( wxCommandEvent& aEvent )
230{
231 m_findReplaceData->replaceString = m_comboReplace->GetValue();
232}
233
234
235void DIALOG_SCH_FIND::OnReplaceWithSelect( wxCommandEvent& aEvent )
236{
237 m_findReplaceData->replaceString = m_comboReplace->GetValue();
238
239 // Move the replace string to the top of the list if it isn't already there.
240 if( aEvent.GetSelection() != 0 )
241 {
242 wxString tmp = m_comboReplace->GetValue();
243 m_comboReplace->Delete( aEvent.GetSelection() );
244 m_comboReplace->Insert( tmp, 0 );
245 m_comboReplace->SetSelection( 0 );
246 }
247}
248
249
250void DIALOG_SCH_FIND::OnSearchForEnter( wxCommandEvent& aEvent )
251{
252 OnFind( aEvent );
253}
254
255
256void DIALOG_SCH_FIND::OnReplaceWithEnter( wxCommandEvent& aEvent )
257{
258 OnFind( aEvent );
259}
260
261
262void DIALOG_SCH_FIND::OnOptions( wxCommandEvent& aEvent )
263{
264 if( aEvent.GetEventObject() == m_checkRegexMatch )
265 {
266 m_checkWholeWord->SetValue( false );
267 m_checkMatchCase->SetValue( false );
268 }
269 else if( aEvent.GetEventObject() == m_checkMatchCase || aEvent.GetEventObject() == m_checkWholeWord )
270 {
271 m_checkRegexMatch->SetValue( false );
272 }
273
274 updateFlags();
275 m_findDirty = true;
276}
277
279{
280 // Rebuild the search flags in m_findReplaceData from dialog settings
281 m_findReplaceData->matchCase = m_checkMatchCase->GetValue();
282 m_findReplaceData->searchAllFields = m_cbSearchHiddenFields->GetValue();
283 m_findReplaceData->searchAllPins = m_cbSearchPins->GetValue();
284 m_findReplaceData->replaceReferences = m_cbReplaceReferences->GetValue();
285 m_findReplaceData->searchNetNames = m_cbSearchNetNames->GetValue();
286
287 // Only read the current-sheet-only widget when the user can actually toggle it.
288 // While selection-only forces it on, its value doesn't reflect user intent.
289 if( m_cbCurrentSheetOnly->IsEnabled() )
290 m_findReplaceData->searchCurrentSheetOnly = m_cbCurrentSheetOnly->GetValue();
291
292 if( m_checkWholeWord->GetValue() )
294 else if( m_checkRegexMatch->IsShown() && m_checkRegexMatch->GetValue() )
296 else
298
299 if( m_cbSelectedOnly->GetValue() )
300 {
301 m_cbCurrentSheetOnly->Enable( false );
302 m_findReplaceData->searchSelectedOnly = true;
303 }
304 else
305 {
306 m_cbCurrentSheetOnly->SetValue( m_findReplaceData->searchCurrentSheetOnly );
307 m_cbCurrentSheetOnly->Enable( true );
308 m_findReplaceData->searchSelectedOnly = false;
309 }
310}
311
312
313void DIALOG_SCH_FIND::OnFind( wxCommandEvent& aEvent )
314{
315 updateFlags(); // Ensure search flags are up to date
316
317 int index = m_comboFind->FindString( m_comboFind->GetValue(), true );
318
319 if( index == wxNOT_FOUND )
320 {
321 m_comboFind->Insert( m_comboFind->GetValue(), 0 );
322 }
323 else if( index != 0 )
324 {
325 /* Move the search string to the top of the list if it isn't already there. */
326 wxString tmp = m_comboFind->GetValue();
327 m_comboFind->Delete( index );
328 m_comboFind->Insert( tmp, 0 );
329 m_comboFind->SetSelection( 0 );
330 }
331
332 m_findReplaceTool->FindNext( ACTIONS::findNext.MakeEvent() );
333}
334
335
336void DIALOG_SCH_FIND::OnReplace( wxCommandEvent& aEvent )
337{
338 updateFlags(); // Ensure search flags are up to date
339
340 int index = m_comboReplace->FindString( m_comboReplace->GetValue(), true );
341
342 if( index == wxNOT_FOUND )
343 {
344 m_comboReplace->Insert( m_comboReplace->GetValue(), 0 );
345 }
346 else if( index != 0 )
347 {
348 /* Move the search string to the top of the list if it isn't already there. */
349 wxString tmp = m_comboReplace->GetValue();
350 m_comboReplace->Delete( index );
351 m_comboReplace->Insert( tmp, 0 );
352 m_comboReplace->SetSelection( 0 );
353 }
354
355 if( aEvent.GetId() == wxID_REPLACE )
356 m_findReplaceTool->ReplaceAndFindNext( ACTIONS::replaceAndFindNext.MakeEvent() );
357 else if( aEvent.GetId() == wxID_REPLACE_ALL )
358 m_findReplaceTool->ReplaceAll( ACTIONS::replaceAll.MakeEvent() );
359}
360
361
363{
364 int index = m_comboFind->FindString( m_comboFind->GetValue(), true );
365
366 if( index == wxNOT_FOUND )
367 {
368 m_comboFind->Insert( m_comboFind->GetValue(), 0 );
369 }
370 else if( index != 0 )
371 {
372 /* Move the search string to the top of the list if it isn't already there. */
373 wxString tmp = m_comboFind->GetValue();
374 m_comboFind->Delete( index );
375 m_comboFind->Insert( tmp, 0 );
376 }
377
378 return m_comboFind->GetStrings();
379}
380
381
382void DIALOG_SCH_FIND::SetFindEntries( const wxArrayString& aEntries, const wxString& aFindString )
383{
384 m_comboFind->Append( aEntries );
385
386 while( m_comboFind->GetCount() > 10 )
387 {
388 m_frame->GetFindHistoryList().pop_back();
389 m_comboFind->Delete( m_comboFind->GetCount() - 1 );
390 }
391
392 if( !aFindString.IsEmpty() )
393 {
394 m_comboFind->SetValue( aFindString );
395 m_comboFind->SelectAll();
396 }
397 else if( m_comboFind->GetCount() )
398 {
399 m_comboFind->SetSelection( 0 );
400 m_comboFind->SelectAll();
401 }
402}
403
404
405void DIALOG_SCH_FIND::SetReplaceEntries( const wxArrayString& aEntries )
406{
407 m_comboReplace->Append( aEntries );
408
409 while( m_comboReplace->GetCount() > 10 )
410 {
411 m_frame->GetReplaceHistoryList().pop_back();
412 m_comboReplace->Delete( m_comboReplace->GetCount() - 1 );
413 }
414
415 if( m_comboReplace->GetCount() )
416 {
417 m_comboReplace->SetSelection( 0 );
418 m_comboReplace->SelectAll();
419 }
420}
int index
static TOOL_ACTION replaceAll
Definition actions.h:119
static TOOL_ACTION updateFind
Definition actions.h:120
static TOOL_ACTION findPrevious
Definition actions.h:116
static TOOL_ACTION replaceAndFindNext
Definition actions.h:118
static TOOL_ACTION findNext
Definition actions.h:115
static TOOL_ACTION showSearch
Definition actions.h:112
wxCheckBox * m_cbSearchHiddenFields
wxRadioButton * m_radioForward
DIALOG_SCH_FIND_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &title=_("Find"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
wxHyperlinkCtrl * m_searchPanelLink
wxRadioButton * m_radioBackward
void OnSearchForSelect(wxCommandEvent &aEvent) override
void OnReplaceWithEnter(wxCommandEvent &event) override
wxArrayString GetFindEntries() const
void OnIdle(wxIdleEvent &event) override
SCH_FIND_REPLACE_TOOL * m_findReplaceTool
SCH_SEARCH_DATA * m_findReplaceData
SCH_BASE_FRAME * m_frame
void OnUpdateReplaceUI(wxUpdateUIEvent &aEvent) override
void SetReplaceEntries(const wxArrayString &aEntries)
void SetFindEntries(const wxArrayString &aEntries, const wxString &aFindString)
void OnReplaceWithText(wxCommandEvent &aEvent) override
void OnCharHook(wxKeyEvent &aEvent) override
void OnReplaceWithSelect(wxCommandEvent &aEvent) override
DIALOG_SCH_FIND(SCH_BASE_FRAME *aParent, SCH_SEARCH_DATA *aData, const wxPoint &aPosition=wxDefaultPosition, const wxSize &aSize=wxDefaultSize, int aStyle=0)
void OnUpdateReplaceAllUI(wxUpdateUIEvent &aEvent) override
void OnSearchForText(wxCommandEvent &aEvent) override
void OnClose(wxCloseEvent &aEvent) override
void OnReplace(wxCommandEvent &aEvent) override
void OnSearchForEnter(wxCommandEvent &event) override
void OnFind(wxCommandEvent &aEvent) override
void OnCancel(wxCommandEvent &aEvent) override
void OnOptions(wxCommandEvent &event) override
void onShowSearchPanel(wxHyperlinkEvent &event) override
std::vector< wxWindow * > m_tabOrder
bool Show(bool show) override
void OptOut(wxWindow *aWindow)
Opt out of control state saving.
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition dialog_shim.h:94
virtual void OnCharHook(wxKeyEvent &aEvt)
A shim class between EDA_DRAW_FRAME and several derived classes: SYMBOL_EDIT_FRAME,...
Schematic editor (Eeschema) main window.
Handle actions specific to the schematic editor.
#define _(s)
#define SCH_EDIT_FRAME_NAME
@ FRAME_SCH_SYMBOL_EDITOR
Definition frame_type.h:31
@ FRAME_SCH
Definition frame_type.h:30
wxString KeyNameFromKeyCode(int aKeycode, bool *aIsFound)
Return the key name from the key code.
std::vector< FAB_LAYER_COLOR > dummy