KiCad PCB EDA Suite
Loading...
Searching...
No Matches
eda_reorderable_list_dialog.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
20#include <algorithm>
21#include <set>
22#include <bitmaps.h>
23#include <string_utils.h>
26
27
28static int DEFAULT_SINGLE_COL_WIDTH = 260;
29
30
31EDA_REORDERABLE_LIST_DIALOG::EDA_REORDERABLE_LIST_DIALOG( wxWindow* aParent, const wxString& aTitle,
32 const std::vector<wxString>& aAllItems,
33 const std::vector<wxString>& aEnabledItems ) :
34 EDA_REORDERABLE_LIST_DIALOG_BASE( aParent, wxID_ANY, aTitle ),
35 m_availableItems( aAllItems ),
36 m_enabledItems( aEnabledItems ),
37 m_selectedAvailable( 0 ),
38 m_selectedEnabled( 0 )
39{
40 m_btnUp->SetBitmap( KiBitmapBundle( BITMAPS::small_up ) );
41 m_btnDown->SetBitmap( KiBitmapBundle( BITMAPS::small_down ) );
42
43 // DIALOG_SHIM needs a unique hash_key because classname is not sufficient
44 // because so many dialogs share this same class, with different numbers of
45 // columns, different column names, and column widths.
46 m_hash_key = TO_UTF8( aTitle );
47
48 m_availableListBox->InsertColumn( 0, wxEmptyString, wxLIST_FORMAT_LEFT,
50 m_enabledListBox->InsertColumn( 0, wxEmptyString, wxLIST_FORMAT_LEFT,
52
54
56
57 // this line fixes an issue on Linux Ubuntu using Unity (dialog not shown),
58 // and works fine on all systems
59 GetSizer()->Fit( this );
60
61 Centre();
62}
63
64
66{
67 m_availableListBox->DeleteAllItems();
68 m_enabledListBox->DeleteAllItems();
69
70 std::set<wxString> enabledSet;
71
72 for( size_t idx = 0; idx < m_enabledItems.size(); ++idx )
73 {
74 wxListItem info;
75 info.m_itemId = idx;
76 info.m_col = 0;
77 info.m_text = m_enabledItems[idx];
79 info.m_mask = wxLIST_MASK_TEXT | wxLIST_MASK_WIDTH;
80
81 m_enabledListBox->InsertItem( info );
82
83 if( m_selectedEnabled == static_cast<long>( idx ) )
84 m_enabledListBox->SetItemState( idx, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED );
85
86 enabledSet.insert( m_enabledItems[idx] );
87 }
88
89 m_availableItems.erase( std::remove_if( m_availableItems.begin(), m_availableItems.end(),
90 [&]( const wxString& aItem ) -> bool
91 {
92 return enabledSet.count( aItem );
93 } ),
94 m_availableItems.end() );
95
96 for( size_t idx = 0; idx < m_availableItems.size(); ++idx )
97 {
98 wxListItem info;
99 info.m_itemId = idx;
100 info.m_col = 0;
101 info.m_text = m_availableItems[idx];
103 info.m_mask = wxLIST_MASK_TEXT | wxLIST_MASK_WIDTH;
104
105 m_availableListBox->InsertItem( info );
106
107 if( m_selectedAvailable == static_cast<long>( idx ) )
108 m_availableListBox->SetItemState( idx, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED );
109 }
110
111 if( !m_availableItems.empty() )
112 m_availableListBox->EnsureVisible( m_selectedAvailable );
113
114 if( !m_enabledItems.empty() )
115 m_enabledListBox->EnsureVisible( m_selectedEnabled );
116
117 m_btnAdd->Enable( !m_availableItems.empty() );
118 m_btnRemove->Enable( !m_enabledItems.empty() );
119}
120
121
122void EDA_REORDERABLE_LIST_DIALOG::onAddItem( wxCommandEvent& aEvent )
123{
124 wxListItem info;
125
127 {
128 wxBell();
129 return;
130 }
131
132 m_availableItems.erase( m_availableItems.begin() + info.m_itemId );
134
135 long pos = std::min( m_selectedEnabled + 1, static_cast<long>( m_enabledItems.size() ) );
136
137 info.m_itemId = pos;
138 info.m_mask = wxLIST_MASK_TEXT;
139
140 m_enabledItems.insert( m_enabledItems.begin() + pos, info.m_text );
141 m_enabledListBox->InsertItem( info );
142}
143
144
145void EDA_REORDERABLE_LIST_DIALOG::onRemoveItem( wxCommandEvent& aEvent )
146{
147 wxListItem info;
148
149 if( !getSelectedItem( m_enabledListBox, info ) || info.m_itemId == 0 )
150 {
151 wxBell();
152 return;
153 }
154
155 m_enabledItems.erase( m_enabledItems.begin() + info.m_itemId );
156 m_enabledListBox->DeleteItem( m_selectedEnabled );
157
159 static_cast<long>( m_enabledItems.size() - 1 ) );
160
161 m_enabledListBox->SetItemState( m_selectedEnabled, wxLIST_STATE_SELECTED,
162 wxLIST_STATE_SELECTED );
163
164 long pos = std::max( long( 0 ), m_selectedAvailable );
165 info.m_itemId = pos;
166
167 m_availableItems.insert( m_availableItems.begin() + pos, info.m_text );
168 m_availableListBox->InsertItem( info );
169}
170
171
172void EDA_REORDERABLE_LIST_DIALOG::onMoveUp( wxCommandEvent& aEvent )
173{
174 wxListItem info;
175
176 if( !getSelectedItem( m_enabledListBox, info ) || info.m_itemId == 0 )
177 {
178 wxBell();
179 return;
180 }
181
182 auto current = m_enabledItems.begin() + info.m_itemId;
183 auto prev = m_enabledItems.begin() + info.m_itemId - 1;
184
185 std::iter_swap( current, prev );
186
188
189 updateItems();
190}
191
192
193void EDA_REORDERABLE_LIST_DIALOG::onMoveDown( wxCommandEvent& aEvent )
194{
195 wxListItem info;
196
198 || info.m_itemId == static_cast<long>( m_enabledItems.size() ) - 1 )
199 {
200 wxBell();
201 return;
202 }
203
204 auto current = m_enabledItems.begin() + info.m_itemId;
205 auto prev = m_enabledItems.begin() + info.m_itemId + 1;
206
207 std::iter_swap( current, prev );
208
210
211 updateItems();
212}
213
214
215bool EDA_REORDERABLE_LIST_DIALOG::getSelectedItem( wxListCtrl* aList, wxListItem& aInfo )
216{
217 long item = aList->GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
218
219 if( item < 0 )
220 return false;
221
222 aInfo.m_mask = wxLIST_MASK_DATA | wxLIST_MASK_STATE | wxLIST_MASK_TEXT;
223 aInfo.m_itemId = item;
224 aInfo.m_col = 0;
225
226 if( !aList->GetItem( aInfo ) )
227 return false;
228
229 return true;
230}
231
232
234{
235 wxListItem info;
236
238 {
240 return;
241 }
242
243 m_selectedEnabled = info.m_itemId;
244}
245
246
248{
249 wxListItem info;
250
252 {
254 return;
255 }
256
257 m_selectedAvailable = info.m_itemId;
258}
259
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap)
Definition: bitmap.cpp:110
void SetupStandardButtons(std::map< int, wxString > aLabels={})
std::string m_hash_key
Definition: dialog_shim.h:213
Class EDA_REORDERABLE_LIST_DIALOG_BASE.
std::vector< wxString > m_availableItems
void onAvailableListItemSelected(wxListEvent &event) override
bool getSelectedItem(wxListCtrl *aList, wxListItem &aInfo)
void onMoveUp(wxCommandEvent &aEvent) override
void onMoveDown(wxCommandEvent &aEvent) override
void onEnabledListItemSelected(wxListEvent &event) override
EDA_REORDERABLE_LIST_DIALOG(wxWindow *aParent, const wxString &aTitle, const std::vector< wxString > &aAllItems, const std::vector< wxString > &aEnabledItems)
void onRemoveItem(wxCommandEvent &aEvent) override
void onAddItem(wxCommandEvent &aEvent) override
std::vector< wxString > m_enabledItems
void SetBitmap(const wxBitmapBundle &aBmp)
static int DEFAULT_SINGLE_COL_WIDTH
static int DEFAULT_SINGLE_COL_WIDTH
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: string_utils.h:398