KiCad PCB EDA Suite
Loading...
Searching...
No Matches
search_pane_tab.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 modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
21#include <widgets/search_pane.h>
22#include <vector>
23#include <string_utils.h>
24#include <wx/clipbrd.h>
25#include <wx/wupdlock.h>
26#include <core/kicad_algo.h>
27
28SEARCH_PANE_LISTVIEW::SEARCH_PANE_LISTVIEW( const std::shared_ptr<SEARCH_HANDLER>& aHandler, wxWindow* parent,
29 wxWindowID winid, const wxPoint& pos, const wxSize& size ) :
30 wxListView( parent, winid, pos, size, wxLC_REPORT | wxLC_VIRTUAL ),
31 m_handler( aHandler ),
32 m_sortCol( -1 ),
33 m_sortAscending( true ),
34 m_selectionDirty( false )
35{
36 SetItemCount( 0 );
37
39
40 Bind( wxEVT_LIST_ITEM_SELECTED, &SEARCH_PANE_LISTVIEW::OnItemSelected, this );
41 Bind( wxEVT_LIST_ITEM_ACTIVATED, &SEARCH_PANE_LISTVIEW::OnItemActivated, this );
42 Bind( wxEVT_LIST_ITEM_FOCUSED, &SEARCH_PANE_LISTVIEW::OnItemSelected, this );
43 Bind( wxEVT_LIST_ITEM_DESELECTED, &SEARCH_PANE_LISTVIEW::OnItemDeselected, this );
44 Bind( wxEVT_LIST_COL_CLICK, &SEARCH_PANE_LISTVIEW::OnColClicked, this );
45 Bind( wxEVT_UPDATE_UI, &SEARCH_PANE_LISTVIEW::OnUpdateUI, this );
46 Bind( wxEVT_CHAR, &SEARCH_PANE_LISTVIEW::OnChar, this );
47}
48
49
51{
52 Unbind( wxEVT_LIST_ITEM_SELECTED, &SEARCH_PANE_LISTVIEW::OnItemSelected, this );
53 Unbind( wxEVT_LIST_ITEM_ACTIVATED, &SEARCH_PANE_LISTVIEW::OnItemActivated, this );
54 Unbind( wxEVT_LIST_ITEM_FOCUSED, &SEARCH_PANE_LISTVIEW::OnItemSelected, this );
55 Unbind( wxEVT_LIST_ITEM_DESELECTED, &SEARCH_PANE_LISTVIEW::OnItemDeselected, this );
56 Unbind( wxEVT_LIST_COL_CLICK, &SEARCH_PANE_LISTVIEW::OnColClicked, this );
57 Unbind( wxEVT_UPDATE_UI, &SEARCH_PANE_LISTVIEW::OnUpdateUI, this );
58 Unbind( wxEVT_CHAR, &SEARCH_PANE_LISTVIEW::OnChar, this );
59}
60
61
62void SEARCH_PANE_LISTVIEW::GetSelectRowsList( std::vector<long>& aSelectedList )
63{
64 long idx = GetFirstSelected();
65
66 if( idx < 0 ) // Nothing selected
67 return;
68
69 aSelectedList.emplace_back( idx );
70
71 idx = GetNextSelected( idx );
72
73 while( idx >= 0 )
74 {
75 aSelectedList.emplace_back( idx );
76 idx = GetNextSelected( idx );
77 }
78}
79
80
81void SEARCH_PANE_LISTVIEW::OnItemActivated( wxListEvent& aEvent )
82{
83 long item = aEvent.GetIndex();
84
85 CallAfter(
86 [this, item]()
87 {
88 m_handler->ActivateItem( item );
89 } );
90
91 m_selectionDirty = true;
92 aEvent.Skip();
93}
94
95
96void SEARCH_PANE_LISTVIEW::OnItemSelected( wxListEvent& aEvent )
97{
98 m_selectionDirty = true;
99 aEvent.Skip();
100}
101
102
103void SEARCH_PANE_LISTVIEW::OnItemDeselected( wxListEvent& aEvent )
104{
105 m_selectionDirty = true;
106 aEvent.Skip();
107}
108
109
110void SEARCH_PANE_LISTVIEW::OnUpdateUI( wxUpdateUIEvent& aEvent )
111{
112 if( m_selectionDirty )
113 {
114 m_selectionDirty = false;
115
116 std::vector<long> list;
117 GetSelectRowsList( list );
118 m_handler->SelectItems( list );
119 }
120}
121
122
123void SEARCH_PANE_LISTVIEW::OnColClicked( wxListEvent& aEvent )
124{
125 if( aEvent.GetColumn() == m_sortCol )
126 {
128 }
129 else
130 {
131 m_sortAscending = true;
132 m_sortCol = aEvent.GetColumn();
133 }
134
135 ShowSortIndicator( m_sortCol, m_sortAscending );
136
137 std::vector<long> selection = Sort();
138
139 for( long row = 0; row < GetItemCount(); row++ )
140 {
141 if( alg::contains( selection, row ) )
142 SetItemState( row, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED );
143 else
144 SetItemState( row, 0, wxLIST_STATE_SELECTED );
145 }
146
147 Refresh();
148}
149
150
151void SEARCH_PANE_LISTVIEW::OnChar( wxKeyEvent& aEvent )
152{
153 bool handled = false;
154
155 switch( aEvent.GetKeyCode() )
156 {
157 case WXK_CONTROL_A:
158 {
159 // Select All
160 for( int row = 0; row < GetItemCount(); row++ )
161 SetItemState( row, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED );
162
163 handled = true;
164 break;
165 }
166
167 case WXK_CONTROL_C:
168 {
169 // Copy to clipboard the selected rows
170 if( wxTheClipboard->Open() )
171 {
172 wxString txt;
173
174 for( int row = 0; row < GetItemCount(); row++ )
175 {
176 if( GetItemState( row, wxLIST_STATE_SELECTED ) == wxLIST_STATE_SELECTED )
177 {
178 for( int col = 0; col < GetColumnCount(); col++ )
179 {
180 if( GetColumnWidth( col ) > 0 )
181 {
182 txt += GetItemText( row, col );
183
184 if( row <= GetItemCount() - 1 )
185 txt += wxT( "\t" );
186 }
187 }
188
189 txt += wxT( "\n" );
190 }
191 }
192
193 wxTheClipboard->SetData( new wxTextDataObject( txt ) );
194 wxTheClipboard->Close();
195 }
196
197 handled = true;
198 break;
199 }
200
201 case WXK_DOWN:
202 case WXK_NUMPAD_DOWN:
203 {
204 // Move selection down
205 long focused = GetFocusedItem();
206 if( focused < 0 )
207 focused = 0;
208
209 if( focused < GetItemCount() - 1 )
210 {
211 if( !(aEvent.GetModifiers() & wxMOD_SHIFT) )
212 {
213 int next = -1;
214
215 while( ( next = GetNextSelected( next ) ) != wxNOT_FOUND )
216 Select( next, false );
217 }
218
219 ++focused;
220 Focus( focused );
221 Select( focused );
222 }
223
224 handled = true;
225 break;
226 }
227 case WXK_UP:
228 case WXK_NUMPAD_UP:
229 {
230 // Move selection up
231 long focused = GetFocusedItem();
232
233 if( focused < 0 )
234 focused = 0;
235
236 if( focused > 0 )
237 {
238 if( !(aEvent.GetModifiers() & wxMOD_SHIFT) )
239 {
240 int next = -1;
241
242 while( ( next = GetNextSelected( next ) ) != wxNOT_FOUND )
243 Select( next, false );
244 }
245
246 --focused;
247 Focus( focused );
248 Select( focused );
249 }
250
251 handled = true;
252 break;
253 }
254 }
255
256 if( !handled )
257 aEvent.Skip();
258}
259
260
261std::vector<long> SEARCH_PANE_LISTVIEW::Sort()
262{
263 std::vector<long> selection;
264 GetSelectRowsList( selection );
265
266 m_handler->Sort( m_sortCol, m_sortAscending, &selection );
267
268 return selection;
269}
270
271
273{
274 wxWindowUpdateLocker updateLock( this );
275
276 DeleteAllColumns();
277
278 std::vector<std::tuple<wxString, int, wxListColumnFormat>> columns = m_handler->GetColumns();
279
280 for( auto& [ columnName, colProportion, colAlign ] : columns )
281 AppendColumn( wxGetTranslation( columnName ), colAlign );
282
283 int widthUnit = GetClientSize().GetWidth() / 10;
284
285 for( int ii = 0; ii < (int) columns.size(); ++ii )
286 SetColumnWidth( ii, widthUnit * std::get<1>( columns[ ii ] ) );
287}
288
289
290wxString SEARCH_PANE_LISTVIEW::OnGetItemText( long item, long column ) const
291{
292 return m_handler->GetResultCell( (int) item, (int) column );
293}
294
295
296SEARCH_PANE_TAB::SEARCH_PANE_TAB( const std::shared_ptr<SEARCH_HANDLER>& aHandler, wxWindow* parent, wxWindowID aId,
297 const wxPoint& aLocation, const wxSize& aSize ) :
298 wxPanel( parent, aId, aLocation, aSize ),
299 m_handler( aHandler )
300{
301 wxBoxSizer* sizer = new wxBoxSizer( wxVERTICAL );
302
303 m_listView = new SEARCH_PANE_LISTVIEW( aHandler, this );
304 sizer->Add( m_listView, 5, wxRIGHT | wxBOTTOM | wxEXPAND, 1 );
305
306 SetSizer( sizer );
307
308 Layout();
309 sizer->Fit( this );
310}
311
312
313void SEARCH_PANE_TAB::Search( wxString& query )
314{
315 int results = m_handler->Search( query );
316 m_listView->SetItemCount( results );
317 m_listView->Sort();
318 m_listView->Refresh();
319}
320
321
323{
324 m_listView->SetItemCount( 0 );
325 m_listView->Refresh();
326}
327
328
330{
332}
void OnItemDeselected(wxListEvent &aEvent)
void GetSelectRowsList(std::vector< long > &aSelectedList)
void OnColClicked(wxListEvent &aEvent)
void OnChar(wxKeyEvent &aEvent)
SEARCH_PANE_LISTVIEW(const std::shared_ptr< SEARCH_HANDLER > &aHandler, wxWindow *parent, wxWindowID winid=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize)
std::shared_ptr< SEARCH_HANDLER > m_handler
void OnItemSelected(wxListEvent &aEvent)
void OnItemActivated(wxListEvent &aEvent)
std::vector< long > Sort()
void OnUpdateUI(wxUpdateUIEvent &aEvent)
wxString OnGetItemText(long item, long column) const override
std::shared_ptr< SEARCH_HANDLER > m_handler
void Search(wxString &query)
SEARCH_PANE_TAB(const std::shared_ptr< SEARCH_HANDLER > &aHandler, wxWindow *parent, wxWindowID aId=wxID_ANY, const wxPoint &aLocation=wxDefaultPosition, const wxSize &aSize=wxDefaultSize)
SEARCH_PANE_LISTVIEW * m_listView
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
Definition: kicad_algo.h:100
void Refresh()
Update the board display after modifying it by a python script (note: it is automatically called by a...
CITER next(CITER it)
Definition: ptree.cpp:124