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
28 wxWindowID winid, const wxPoint& pos,
29 const wxSize& size ) :
30 wxListView( parent, winid, pos, size, wxLC_REPORT | wxLC_VIRTUAL ),
31 m_handler( handler ),
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 Sort();
138 Refresh();
139}
140
141
142void SEARCH_PANE_LISTVIEW::OnChar( wxKeyEvent& aEvent )
143{
144 if( aEvent.GetKeyCode() == WXK_CONTROL_A )
145 {
146 // Select All
147 for( int row = 0; row < GetItemCount(); row++ )
148 SetItemState( row, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED );
149 }
150 else if( aEvent.GetKeyCode() == WXK_CONTROL_C )
151 {
152 // Copy to clipboard the selected rows
153 if( wxTheClipboard->Open() )
154 {
155 wxString txt;
156 for( int row = 0; row < GetItemCount(); row++ )
157 {
158 if( GetItemState( row, wxLIST_STATE_SELECTED ) == wxLIST_STATE_SELECTED )
159 {
160 for( int col = 0; col < GetColumnCount(); col++ )
161 {
162 if( GetColumnWidth( col ) > 0 )
163 {
164 txt += GetItemText( row, col );
165 if( row <= GetItemCount() - 1 )
166 txt += wxT( "\t" );
167 }
168 }
169 txt += wxT( "\n" );
170 }
171 }
172
173 wxTheClipboard->SetData( new wxTextDataObject( txt ) );
174 wxTheClipboard->Close();
175 }
176 }
177}
178
179
181{
183}
184
185
187{
188 Freeze();
189 DeleteAllColumns();
190
191 std::vector<std::tuple<wxString, int, wxListColumnFormat>> columns = m_handler->GetColumns();
192
193 for( auto& [ columnName, colProportion, colAlign ] : columns )
194 AppendColumn( wxGetTranslation( columnName ), colAlign );
195
196 int widthUnit = GetClientSize().GetWidth() / 10;
197
198 for( int ii = 0; ii < (int) columns.size(); ++ii )
199 SetColumnWidth( ii, widthUnit * std::get<1>( columns[ ii ] ) );
200
201 Thaw();
202}
203
204
205wxString SEARCH_PANE_LISTVIEW::OnGetItemText( long item, long column ) const
206{
207 return m_handler->GetResultCell( (int) item, (int) column );
208}
209
210
211SEARCH_PANE_TAB::SEARCH_PANE_TAB( SEARCH_HANDLER* handler, wxWindow* parent, wxWindowID aId,
212 const wxPoint& aLocation, const wxSize& aSize ) :
213 wxPanel( parent, aId, aLocation, aSize ),
214 m_handler( handler )
215{
216 wxBoxSizer* sizer = new wxBoxSizer( wxVERTICAL );
217
218 m_listView = new SEARCH_PANE_LISTVIEW( handler, this );
219 sizer->Add( m_listView, 5, wxRIGHT | wxBOTTOM | wxEXPAND, 1 );
220
221 SetSizer( sizer );
222
223 Layout();
224 sizer->Fit( this );
225}
226
227
228void SEARCH_PANE_TAB::Search( wxString& query )
229{
230 int results = m_handler->Search( query );
231 m_listView->SetItemCount( results );
232 m_listView->Sort();
233 m_listView->Refresh();
234}
235
236
238{
239 m_listView->SetItemCount( 0 );
240 m_listView->Refresh();
241}
242
243
245{
247}
virtual void Sort(int aCol, bool aAscending)=0
std::vector< std::tuple< wxString, int, wxListColumnFormat > > GetColumns() const
Definition: search_pane.h:39
virtual wxString GetResultCell(int row, int col)=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)
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)
void Refresh()
Update the board display after modifying it by a python script (note: it is automatically called by a...