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 (C) 2022-2023 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 <kiway.h>
23#include <vector>
24#include <string_utils.h>
25#include <wx/clipbrd.h>
26#include <core/kicad_algo.h>
27
29 wxWindowID winid, const wxPoint& pos,
30 const wxSize& size ) :
31 wxListView( parent, winid, pos, size, wxLC_REPORT | wxLC_VIRTUAL ),
32 m_handler( handler ),
33 m_sortCol( -1 ),
34 m_sortAscending( true ),
35 m_selectionDirty( false )
36{
37 SetItemCount( 0 );
38
40
41 Bind( wxEVT_LIST_ITEM_SELECTED, &SEARCH_PANE_LISTVIEW::OnItemSelected, this );
42 Bind( wxEVT_LIST_ITEM_ACTIVATED, &SEARCH_PANE_LISTVIEW::OnItemActivated, this );
43 Bind( wxEVT_LIST_ITEM_FOCUSED, &SEARCH_PANE_LISTVIEW::OnItemSelected, this );
44 Bind( wxEVT_LIST_ITEM_DESELECTED, &SEARCH_PANE_LISTVIEW::OnItemDeselected, this );
45 Bind( wxEVT_LIST_COL_CLICK, &SEARCH_PANE_LISTVIEW::OnColClicked, this );
46 Bind( wxEVT_UPDATE_UI, &SEARCH_PANE_LISTVIEW::OnUpdateUI, this );
47 Bind( wxEVT_CHAR, &SEARCH_PANE_LISTVIEW::OnChar, this );
48}
49
50
52{
53 Unbind( wxEVT_LIST_ITEM_SELECTED, &SEARCH_PANE_LISTVIEW::OnItemSelected, this );
54 Unbind( wxEVT_LIST_ITEM_ACTIVATED, &SEARCH_PANE_LISTVIEW::OnItemActivated, this );
55 Unbind( wxEVT_LIST_ITEM_FOCUSED, &SEARCH_PANE_LISTVIEW::OnItemSelected, this );
56 Unbind( wxEVT_LIST_ITEM_DESELECTED, &SEARCH_PANE_LISTVIEW::OnItemDeselected, this );
57 Unbind( wxEVT_LIST_COL_CLICK, &SEARCH_PANE_LISTVIEW::OnColClicked, this );
58 Unbind( wxEVT_UPDATE_UI, &SEARCH_PANE_LISTVIEW::OnUpdateUI, this );
59 Unbind( wxEVT_CHAR, &SEARCH_PANE_LISTVIEW::OnChar, this );
60}
61
62
63void SEARCH_PANE_LISTVIEW::GetSelectRowsList( std::vector<long>& aSelectedList )
64{
65 long idx = GetFirstSelected();
66
67 if( idx < 0 ) // Nothing selected
68 return;
69
70 aSelectedList.emplace_back( idx );
71
72 idx = GetNextSelected( idx );
73
74 while( idx >= 0 )
75 {
76 aSelectedList.emplace_back( idx );
77 idx = GetNextSelected( idx );
78 }
79}
80
81
82void SEARCH_PANE_LISTVIEW::OnItemActivated( wxListEvent& aEvent )
83{
84 long item = aEvent.GetIndex();
85
86 CallAfter(
87 [this, item]()
88 {
89 m_handler->ActivateItem( item );
90 } );
91
92 m_selectionDirty = true;
93 aEvent.Skip();
94}
95
96
97void SEARCH_PANE_LISTVIEW::OnItemSelected( wxListEvent& aEvent )
98{
99 m_selectionDirty = true;
100 aEvent.Skip();
101}
102
103
104void SEARCH_PANE_LISTVIEW::OnItemDeselected( wxListEvent& aEvent )
105{
106 m_selectionDirty = true;
107 aEvent.Skip();
108}
109
110
111void SEARCH_PANE_LISTVIEW::OnUpdateUI( wxUpdateUIEvent& aEvent )
112{
113 if( m_selectionDirty )
114 {
115 m_selectionDirty = false;
116
117 std::vector<long> list;
118 GetSelectRowsList( list );
119 m_handler->SelectItems( list );
120 }
121}
122
123
124void SEARCH_PANE_LISTVIEW::OnColClicked( wxListEvent& aEvent )
125{
126 if( aEvent.GetColumn() == m_sortCol )
127 {
129 }
130 else
131 {
132 m_sortAscending = true;
133 m_sortCol = aEvent.GetColumn();
134 }
135
136 ShowSortIndicator( m_sortCol, m_sortAscending );
137
138 std::vector<long> selection = Sort();
139
140 for( long row = 0; row < GetItemCount(); row++ )
141 {
142 if( alg::contains( selection, row ) )
143 SetItemState( row, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED );
144 else
145 SetItemState( row, 0, wxLIST_STATE_SELECTED );
146 }
147
148 Refresh();
149}
150
151
152void SEARCH_PANE_LISTVIEW::OnChar( wxKeyEvent& aEvent )
153{
154 if( aEvent.GetKeyCode() == WXK_CONTROL_A )
155 {
156 // Select All
157 for( int row = 0; row < GetItemCount(); row++ )
158 SetItemState( row, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED );
159 }
160 else if( aEvent.GetKeyCode() == WXK_CONTROL_C )
161 {
162 // Copy to clipboard the selected rows
163 if( wxTheClipboard->Open() )
164 {
165 wxString txt;
166 for( int row = 0; row < GetItemCount(); row++ )
167 {
168 if( GetItemState( row, wxLIST_STATE_SELECTED ) == wxLIST_STATE_SELECTED )
169 {
170 for( int col = 0; col < GetColumnCount(); col++ )
171 {
172 if( GetColumnWidth( col ) > 0 )
173 {
174 txt += GetItemText( row, col );
175 if( row <= GetItemCount() - 1 )
176 txt += wxT( "\t" );
177 }
178 }
179 txt += wxT( "\n" );
180 }
181 }
182
183 wxTheClipboard->SetData( new wxTextDataObject( txt ) );
184 wxTheClipboard->Close();
185 }
186 }
187}
188
189
190std::vector<long> SEARCH_PANE_LISTVIEW::Sort()
191{
192 std::vector<long> selection;
193 GetSelectRowsList( selection );
194
195 m_handler->Sort( m_sortCol, m_sortAscending, &selection );
196
197 return selection;
198}
199
200
202{
203 Freeze();
204 DeleteAllColumns();
205
206 std::vector<std::tuple<wxString, int, wxListColumnFormat>> columns = m_handler->GetColumns();
207
208 for( auto& [ columnName, colProportion, colAlign ] : columns )
209 AppendColumn( wxGetTranslation( columnName ), colAlign );
210
211 int widthUnit = GetClientSize().GetWidth() / 10;
212
213 for( int ii = 0; ii < (int) columns.size(); ++ii )
214 SetColumnWidth( ii, widthUnit * std::get<1>( columns[ ii ] ) );
215
216 Thaw();
217}
218
219
220wxString SEARCH_PANE_LISTVIEW::OnGetItemText( long item, long column ) const
221{
222 return m_handler->GetResultCell( (int) item, (int) column );
223}
224
225
226SEARCH_PANE_TAB::SEARCH_PANE_TAB( SEARCH_HANDLER* handler, wxWindow* parent, wxWindowID aId,
227 const wxPoint& aLocation, const wxSize& aSize ) :
228 wxPanel( parent, aId, aLocation, aSize ),
229 m_handler( handler )
230{
231 wxBoxSizer* sizer = new wxBoxSizer( wxVERTICAL );
232
233 m_listView = new SEARCH_PANE_LISTVIEW( handler, this );
234 sizer->Add( m_listView, 5, wxRIGHT | wxBOTTOM | wxEXPAND, 1 );
235
236 SetSizer( sizer );
237
238 Layout();
239 sizer->Fit( this );
240}
241
242
243void SEARCH_PANE_TAB::Search( wxString& query )
244{
245 int results = m_handler->Search( query );
246 m_listView->SetItemCount( results );
247 m_listView->Sort();
248 m_listView->Refresh();
249}
250
251
253{
254 m_listView->SetItemCount( 0 );
255 m_listView->Refresh();
256}
257
258
260{
262}
std::vector< std::tuple< wxString, int, wxListColumnFormat > > GetColumns() const
Definition: search_pane.h:39
virtual wxString GetResultCell(int row, int col)=0
virtual void Sort(int aCol, bool aAscending, std::vector< long > *aSelection)=0
virtual void SelectItems(std::vector< long > &aItemRows)
Definition: search_pane.h:48
virtual void ActivateItem(long aItemRow)
Definition: search_pane.h:49
virtual int Search(const wxString &string)=0
void OnItemDeselected(wxListEvent &aEvent)
SEARCH_PANE_LISTVIEW(SEARCH_HANDLER *handler, wxWindow *parent, wxWindowID winid=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize)
void GetSelectRowsList(std::vector< long > &aSelectedList)
void OnColClicked(wxListEvent &aEvent)
void OnChar(wxKeyEvent &aEvent)
void OnItemSelected(wxListEvent &aEvent)
SEARCH_HANDLER * m_handler
void OnItemActivated(wxListEvent &aEvent)
std::vector< long > Sort()
void OnUpdateUI(wxUpdateUIEvent &aEvent)
wxString OnGetItemText(long item, long column) const override
SEARCH_HANDLER * m_handler
void Search(wxString &query)
SEARCH_PANE_LISTVIEW * m_listView
SEARCH_PANE_TAB(SEARCH_HANDLER *handler, wxWindow *parent, wxWindowID aId=wxID_ANY, const wxPoint &aLocation=wxDefaultPosition, const wxSize &aSize=wxDefaultSize)
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...