KiCad PCB EDA Suite
Loading...
Searching...
No Matches
listbox_tricks.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) 2024 KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
25
26#include <wx/clipbrd.h>
27#include <wx/listbox.h>
28#include <wx/menu.h>
29#include <wx/window.h>
30
31#include <bitmaps.h>
33#include <widgets/ui_common.h>
34
35
36wxDEFINE_EVENT( EDA_EVT_LISTBOX_COPY, wxCommandEvent );
37wxDEFINE_EVENT( EDA_EVT_LISTBOX_CUT, wxCommandEvent );
38wxDEFINE_EVENT( EDA_EVT_LISTBOX_PASTE, wxCommandEvent );
39wxDEFINE_EVENT( EDA_EVT_LISTBOX_DELETE, wxCommandEvent );
40wxDEFINE_EVENT( EDA_EVT_LISTBOX_DUPLICATE, wxCommandEvent );
41
42wxDEFINE_EVENT( EDA_EVT_LISTBOX_CHANGED, wxCommandEvent );
43
44
45LISTBOX_TRICKS::LISTBOX_TRICKS( wxWindow& aParent, wxListBox& aListBox ) :
46 m_parent( aParent ), m_listBox( aListBox )
47{
48 // Init default menu labels
49 m_menuStrings = { {
50 { ID_COPY, _( "Copy" ) },
51 { ID_PASTE, _( "Paste" ) },
52 { ID_CUT, _( "Cut" ) },
53 { ID_DUPLICATE, _( "Duplicate" ) },
54 { ID_DELETE, _( "Delete" ) },
55 } };
56
57
58 m_listBox.Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( LISTBOX_TRICKS::OnListBoxRDown ),
59 nullptr, this );
60 m_listBox.Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( LISTBOX_TRICKS::OnListBoxKeyDown ),
61 nullptr, this );
62
63 Connect( EDA_EVT_LISTBOX_DELETE, wxCommandEventHandler( LISTBOX_TRICKS::OnListBoxDelete ) );
64 Connect( EDA_EVT_LISTBOX_COPY, wxCommandEventHandler( LISTBOX_TRICKS::OnListBoxCopy ) );
65 Connect( EDA_EVT_LISTBOX_CUT, wxCommandEventHandler( LISTBOX_TRICKS::OnListBoxCut ) );
66 Connect( EDA_EVT_LISTBOX_PASTE, wxCommandEventHandler( LISTBOX_TRICKS::OnListBoxPaste ) );
67 Connect( EDA_EVT_LISTBOX_DUPLICATE, wxCommandEventHandler( LISTBOX_TRICKS::OnListBoxDuplicate ) );
68}
69
70
72{
73 m_listBox.Disconnect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( LISTBOX_TRICKS::OnListBoxRDown ),
74 nullptr, this );
75 m_listBox.Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( LISTBOX_TRICKS::OnListBoxKeyDown ),
76 nullptr, this );
77
78 Disconnect( EDA_EVT_LISTBOX_DELETE, wxCommandEventHandler( LISTBOX_TRICKS::OnListBoxDelete ) );
79 Disconnect( EDA_EVT_LISTBOX_COPY, wxCommandEventHandler( LISTBOX_TRICKS::OnListBoxCopy ) );
80 Disconnect( EDA_EVT_LISTBOX_CUT, wxCommandEventHandler( LISTBOX_TRICKS::OnListBoxCut ) );
81 Disconnect( EDA_EVT_LISTBOX_PASTE, wxCommandEventHandler( LISTBOX_TRICKS::OnListBoxPaste ) );
82 Disconnect( EDA_EVT_LISTBOX_DUPLICATE, wxCommandEventHandler( LISTBOX_TRICKS::OnListBoxDuplicate ) );
83}
84
85
86void LISTBOX_TRICKS::SetMenuLabels( const std::map<MENU_ID, wxString>& aItems )
87{
88 for( const auto& [id, string] : aItems )
89 {
90 m_menuStrings[id] = string;
91 }
92}
93
94
96{
97 wxArrayInt selections;
98 m_listBox.GetSelections( selections );
99
100 std::sort( selections.begin(), selections.end() );
101
102 for( int ii = selections.GetCount() - 1; ii >= 0; ii-- )
103 m_listBox.Delete( selections[ii] );
104
105 m_listBox.SetSelection( wxNOT_FOUND );
106 if( m_listBox.GetCount() > 0 )
107 m_listBox.SetSelection( std::max( 0, selections[0] - 1 ) );
108
109 wxPostEvent( &m_listBox, wxCommandEvent( EDA_EVT_LISTBOX_CHANGED ) );
110 return selections;
111}
112
113
115{
116 wxArrayInt selections;
117 m_listBox.GetSelections( selections );
118
119 wxArrayString result;
120 for( size_t ii = 0; ii < selections.GetCount(); ii++ )
121 result.Add( m_listBox.GetString( selections[ii] ) );
122
123 return result;
124}
125
126
128{
129 wxArrayInt selections;
130 m_listBox.GetSelections( selections );
131
132 int insertAt = selections.GetCount() > 0 ? selections.back() + 1 : m_listBox.GetCount();
133
134 m_listBox.SetSelection( wxNOT_FOUND );
135
136 for( size_t ii = 0; ii < selections.GetCount(); ii++ )
137 {
138 wxString filter = m_listBox.GetString( selections[ii] );
139 m_listBox.Insert( filter, insertAt );
140 m_listBox.SetSelection( insertAt );
141 insertAt++;
142 }
143
144 wxPostEvent( &m_listBox, wxCommandEvent( EDA_EVT_LISTBOX_CHANGED ) );
145}
146
147
149{
150 wxArrayString filters = listBoxGetSelected();
151
152 wxString result;
153 for( const wxString& filter : filters )
154 {
155 result += filter + wxT( "\n" );
156 }
157
158 if( wxTheClipboard->Open() )
159 {
160 wxTheClipboard->SetData( new wxTextDataObject( result ) );
161 wxTheClipboard->Close();
162 }
163}
164
165
167{
168 wxArrayString lines;
169 if( wxTheClipboard->Open() )
170 {
171 wxTextDataObject data;
172 wxTheClipboard->GetData( data );
173
174 wxString text = data.GetText();
175 text.Trim( false );
176 text.Trim( true );
177 lines = wxSplit( text, '\n' );
178
179 wxTheClipboard->Close();
180 }
181
182 wxArrayInt selections;
183 m_listBox.GetSelections( selections );
184 int insertAt = selections.GetCount() > 0 ? selections.back() + 1 : m_listBox.GetCount();
185
186 for( wxString& line : lines )
187 {
188 line.Trim( false );
189 line.Trim( true );
190 }
191
192 m_listBox.InsertItems( lines, insertAt );
193
194 m_listBox.SetSelection( wxNOT_FOUND );
195 for( size_t ii = insertAt; ii < insertAt + lines.GetCount(); ii++ )
196 m_listBox.SetSelection( ii );
197
198 wxPostEvent( &m_listBox, wxCommandEvent( EDA_EVT_LISTBOX_CHANGED ) );
199}
200
201
203{
204 listBoxCopy();
205 wxArrayInt deleted = listBoxDeleteSelected();
206
207 size_t select = deleted.GetCount() > 0 ? deleted[0] : m_listBox.GetCount();
208
209 m_listBox.SetSelection( wxNOT_FOUND );
210 m_listBox.SetSelection( std::min( select, (size_t) m_listBox.GetCount() - 1 ) );
211}
212
213
214void LISTBOX_TRICKS::OnListBoxRDown( wxMouseEvent& aEvent )
215{
216 wxMenu menu;
217
218 const auto mstr = [&]( const MENU_ID& id )
219 {
220 return m_menuStrings[id];
221 };
222
223 // clang-format off
225 mstr( ID_COPY ) + "\tCtrl+C",
226 KiBitmap( BITMAPS::copy ) );
228 mstr( ID_CUT ) + "\tCtrl+X",
229 KiBitmap( BITMAPS::cut ) );
231 mstr( ID_PASTE ) + "\tCtrl+V",
232 KiBitmap( BITMAPS::paste ) );
234 mstr( ID_DUPLICATE ) + "\tCtrl+D",
235 KiBitmap( BITMAPS::duplicate ) );
237 mstr( ID_DELETE ) + "\tDel",
238 KiBitmap( BITMAPS::trash ) );
239 // clang-format on
240
241 menu.Bind( wxEVT_COMMAND_MENU_SELECTED,
242 [&]( wxCommandEvent& aCmd )
243 {
244 switch( aEvent.GetId() )
245 {
246 case ID_COPY: listBoxCopy(); break;
247 case ID_PASTE: listBoxPaste(); break;
248 case ID_CUT: listBoxCut(); break;
249 case ID_DELETE: listBoxDeleteSelected(); break;
250 case ID_DUPLICATE: listBoxDuplicateSelected(); break;
251 default: aEvent.Skip();
252 }
253 } );
254
255 m_parent.PopupMenu( &menu );
256}
257
258
259void LISTBOX_TRICKS::OnListBoxKeyDown( wxKeyEvent& aEvent )
260{
261 if( aEvent.GetKeyCode() == WXK_DELETE )
262 {
264 }
265 else
266 {
267 if( aEvent.ControlDown() )
268 {
269 switch( aEvent.GetKeyCode() )
270 {
271 case 'C': listBoxCopy(); break;
272 case 'V': listBoxPaste(); break;
273 case 'X': listBoxCut(); break;
274 case 'D': listBoxDuplicateSelected(); break;
275 default: aEvent.Skip();
276 }
277 }
278 else
279 aEvent.Skip();
280 }
281}
282
283
284void LISTBOX_TRICKS::OnListBoxDelete( wxCommandEvent& aEvent )
285{
287}
288
289
290void LISTBOX_TRICKS::OnListBoxCopy( wxCommandEvent& aEvent )
291{
292 listBoxCopy();
293}
294
295
296void LISTBOX_TRICKS::OnListBoxCut( wxCommandEvent& aEvent )
297{
298 listBoxCut();
299}
300
301
302void LISTBOX_TRICKS::OnListBoxPaste( wxCommandEvent& aEvent )
303{
304 listBoxPaste();
305}
306
307
308void LISTBOX_TRICKS::OnListBoxDuplicate( wxCommandEvent& aEvent )
309{
311}
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition: bitmap.cpp:104
wxListBox & m_listBox
void OnListBoxCut(wxCommandEvent &aEvent)
void listBoxDuplicateSelected()
Duplicate the selected filters.
void OnListBoxDuplicate(wxCommandEvent &aEvent)
LISTBOX_TRICKS(wxWindow &aWindow, wxListBox &aListBox)
void OnListBoxPaste(wxCommandEvent &aEvent)
void OnListBoxCopy(wxCommandEvent &aEvent)
wxArrayString listBoxGetSelected() const
void OnListBoxDelete(wxCommandEvent &aEvent)
void OnListBoxKeyDown(wxKeyEvent &aEvent)
MENU_ID
These are the ids for the menu.
wxArrayInt listBoxDeleteSelected()
Delete the selected filters.
void SetMenuLabels(const std::map< MENU_ID, wxString > &aItems)
std::map< MENU_ID, wxString > m_menuStrings
wxWindow & m_parent
void OnListBoxRDown(wxMouseEvent &aEvent)
#define _(s)
wxDEFINE_EVENT(EDA_EVT_LISTBOX_COPY, wxCommandEvent)
KICOMMON_API wxMenuItem * AddMenuItem(wxMenu *aMenu, int aId, const wxString &aText, const wxBitmapBundle &aImage, wxItemKind aType=wxITEM_NORMAL)
Create and insert a menu item with an icon into aMenu.
Definition: ui_common.cpp:372
Functions to provide common constants and other functions to assist in making a consistent UI.