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 CallAfter(
84 [&]()
85 {
86 m_handler->ActivateItem( aEvent.GetIndex() );
87 } );
88
89 m_selectionDirty = true;
90 aEvent.Skip();
91}
92
93
94void SEARCH_PANE_LISTVIEW::OnItemSelected( wxListEvent& aEvent )
95{
96 m_selectionDirty = true;
97 aEvent.Skip();
98}
99
100
101void SEARCH_PANE_LISTVIEW::OnItemDeselected( wxListEvent& aEvent )
102{
103 m_selectionDirty = true;
104 aEvent.Skip();
105}
106
107
108void SEARCH_PANE_LISTVIEW::OnUpdateUI( wxUpdateUIEvent& aEvent )
109{
110 if( m_selectionDirty )
111 {
112 m_selectionDirty = false;
113
114 std::vector<long> list;
115 GetSelectRowsList( list );
116 m_handler->SelectItems( list );
117 }
118}
119
120
121void SEARCH_PANE_LISTVIEW::OnColClicked( wxListEvent& aEvent )
122{
123 if( aEvent.GetColumn() == m_sortCol )
124 {
126 }
127 else
128 {
129 m_sortAscending = true;
130 m_sortCol = aEvent.GetColumn();
131 }
132
133 ShowSortIndicator( m_sortCol, m_sortAscending );
134
135 Sort();
136 Refresh();
137}
138
139
140void SEARCH_PANE_LISTVIEW::OnChar( wxKeyEvent& aEvent )
141{
142 if( aEvent.GetKeyCode() == WXK_CONTROL_A )
143 {
144 // Select All
145 for( int row = 0; row < GetItemCount(); row++ )
146 SetItemState( row, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED );
147 }
148 else if( aEvent.GetKeyCode() == WXK_CONTROL_C )
149 {
150 // Copy to clipboard the selected rows
151 if( wxTheClipboard->Open() )
152 {
153 wxString txt;
154 for( int row = 0; row < GetItemCount(); row++ )
155 {
156 if( GetItemState( row, wxLIST_STATE_SELECTED ) == wxLIST_STATE_SELECTED )
157 {
158 for( int col = 0; col < GetColumnCount(); col++ )
159 {
160 if( GetColumnWidth( col ) > 0 )
161 {
162 txt += GetItemText( row, col );
163 if( row <= GetItemCount() - 1 )
164 txt += wxT( "\t" );
165 }
166 }
167 txt += wxT( "\n" );
168 }
169 }
170
171 wxTheClipboard->SetData( new wxTextDataObject( txt ) );
172 wxTheClipboard->Close();
173 }
174 }
175}
176
177
179{
181}
182
183
185{
186 Freeze();
187 DeleteAllColumns();
188
189 std::vector<std::tuple<wxString, int, wxListColumnFormat>> columns = m_handler->GetColumns();
190
191 for( auto& [ columnName, colProportion, colAlign ] : columns )
192 AppendColumn( wxGetTranslation( columnName ), colAlign );
193
194 int widthUnit = GetClientSize().GetWidth() / 10;
195
196 for( int ii = 0; ii < (int) columns.size(); ++ii )
197 SetColumnWidth( ii, widthUnit * std::get<1>( columns[ ii ] ) );
198
199 Thaw();
200}
201
202
203wxString SEARCH_PANE_LISTVIEW::OnGetItemText( long item, long column ) const
204{
205 return m_handler->GetResultCell( (int) item, (int) column );
206}
207
208
209SEARCH_PANE_TAB::SEARCH_PANE_TAB( SEARCH_HANDLER* handler, wxWindow* parent, wxWindowID aId,
210 const wxPoint& aLocation, const wxSize& aSize ) :
211 wxPanel( parent, aId, aLocation, aSize ),
212 m_handler( handler )
213{
214 wxBoxSizer* sizer = new wxBoxSizer( wxVERTICAL );
215
216 m_listView = new SEARCH_PANE_LISTVIEW( handler, this );
217 sizer->Add( m_listView, 5, wxRIGHT | wxBOTTOM | wxEXPAND, 1 );
218
219 SetSizer( sizer );
220
221 Layout();
222 sizer->Fit( this );
223}
224
225
226void SEARCH_PANE_TAB::Search( wxString& query )
227{
228 int results = m_handler->Search( query );
229 m_listView->SetItemCount( results );
230 m_listView->Sort();
231 m_listView->Refresh();
232}
233
234
236{
237 m_listView->SetItemCount( 0 );
238 m_listView->Refresh();
239}
240
241
243{
245}
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...