KiCad PCB EDA Suite
eda_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) 2007 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
6  * Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
26 #include <fctsys.h>
27 #include <macros.h>
28 #include <eda_draw_frame.h>
29 #include <kicad_string.h>
30 #include <dialog_helpers.h>
31 
32 
33 // wxWidgets spends *far* too long calcuating column widths (most of it, believe it or
34 // not, in repeatedly creating/destroying a wxDC to do the measurement in).
35 // Use default column widths instead.
36 static int DEFAULT_COL_WIDTHS[] = { 200, 600 };
37 
38 
39 
40 EDA_LIST_DIALOG::EDA_LIST_DIALOG( EDA_DRAW_FRAME* aParent, const wxString& aTitle,
41  const wxArrayString& aItemHeaders,
42  const std::vector<wxArrayString>& aItemList,
43  const wxString& aSelection ) :
44  EDA_LIST_DIALOG_BASE( aParent, wxID_ANY, aTitle )
45 {
46  m_itemsList = &aItemList;
47 
48  m_filterBox->SetHint( _( "Filter" ) );
49 
50  initDialog( aItemHeaders, aSelection );
51 
52  // DIALOG_SHIM needs a unique hash_key because classname is not sufficient
53  // because so many dialogs share this same class, with different numbers of
54  // columns, different column names, and column widths.
55  m_hash_key = TO_UTF8( aTitle );
56 
57  m_sdbSizerOK->SetDefault();
58 
59  // this line fixes an issue on Linux Ubuntu using Unity (dialog not shown),
60  // and works fine on all systems
61  GetSizer()->Fit( this );
62 
63  Centre();
64 }
65 
66 
67 void EDA_LIST_DIALOG::initDialog( const wxArrayString& aItemHeaders, const wxString& aSelection )
68 {
69  for( unsigned i = 0; i < aItemHeaders.Count(); i++ )
70  {
71  m_listBox->InsertColumn( i, aItemHeaders.Item( i ),
72  wxLIST_FORMAT_LEFT, DEFAULT_COL_WIDTHS[ i ] );
73  }
74 
75  InsertItems( *m_itemsList, 0 );
76 
77  if( !aSelection.IsEmpty() )
78  {
79  long sel = m_listBox->FindItem( -1, aSelection );
80 
81  if( sel != wxNOT_FOUND )
82  {
83  m_listBox->SetItemState( sel, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED );
84 
85  // Set to a small size so EnsureVisible() won't be foiled by later additions.
86  // ListBox will expand to fit later.
87  m_listBox->SetSize( m_listBox->GetSize().GetX(), 100 );
88  m_listBox->EnsureVisible( sel );
89  }
90  }
91 }
92 
93 
94 void EDA_LIST_DIALOG::SetListLabel( const wxString& aLabel )
95 {
96  m_listLabel->SetLabel( aLabel );
97  m_listBox->SetSingleStyle( wxLC_NO_HEADER, true );
98 }
99 
100 
101 void EDA_LIST_DIALOG::SetOKLabel( const wxString& aLabel )
102 {
103  m_sdbSizerOK->SetLabel( aLabel );
104 }
105 
106 
107 void EDA_LIST_DIALOG::textChangeInFilterBox( wxCommandEvent& event )
108 {
109  wxString filter;
110  wxString itemName;
111 
112  filter = wxT( "*" ) + m_filterBox->GetLineText( 0 ).MakeLower() + wxT( "*" );
113 
114  m_listBox->DeleteAllItems();
115 
116  for( const wxArrayString& row : *m_itemsList )
117  {
118  itemName = row.Item( 0 );
119 
120  if( itemName.MakeLower().Matches( filter ) )
121  Append( row );
122  }
123 
124  sortList();
125 }
126 
127 
128 wxString EDA_LIST_DIALOG::GetTextSelection( int aColumn )
129 {
130  wxCHECK_MSG( unsigned( aColumn ) < unsigned( m_listBox->GetColumnCount() ), wxEmptyString,
131  wxT( "Invalid list control column." ) );
132 
133  long item = m_listBox->GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
134 
135  if( item >= 0 ) // if something is selected.
136  {
137  wxListItem info;
138 
139  info.m_mask = wxLIST_MASK_TEXT;
140  info.m_itemId = item;
141  info.m_col = aColumn;
142 
143  if( m_listBox->GetItem( info ) )
144  return info.m_text;
145  }
146 
147  return wxEmptyString;
148 }
149 
150 
151 void EDA_LIST_DIALOG::Append( const wxArrayString& itemList )
152 {
153  long itemIndex = m_listBox->InsertItem( m_listBox->GetItemCount(), itemList[0] );
154 
155  m_listBox->SetItemPtrData( itemIndex, wxUIntPtr( &itemList[0] ) );
156 
157  // Adding the next columns content
158  for( unsigned i = 1; i < itemList.size(); i++ )
159  m_listBox->SetItem( itemIndex, i, itemList[i] );
160 }
161 
162 
163 void EDA_LIST_DIALOG::InsertItems( const std::vector< wxArrayString >& itemList, int position )
164 {
165  for( unsigned row = 0; row < itemList.size(); row++ )
166  {
167  wxASSERT( (int) itemList[row].GetCount() == m_listBox->GetColumnCount() );
168 
169  for( unsigned col = 0; col < itemList[row].GetCount(); col++ )
170  {
171  wxListItem info;
172  info.m_itemId = row + position;
173  info.m_col = col;
174  info.m_text = itemList[row].Item( col );
175  info.m_width = DEFAULT_COL_WIDTHS[ col ];
176  info.m_mask = wxLIST_MASK_TEXT | wxLIST_MASK_WIDTH;
177 
178  if( col == 0 )
179  {
180  info.m_data = wxUIntPtr( &itemList[row].Item( col ) );
181  info.m_mask |= wxLIST_MASK_DATA;
182 
183  m_listBox->InsertItem( info );
184  }
185  else
186  {
187  m_listBox->SetItem( info );
188  }
189  }
190  }
191 
192  sortList();
193 }
194 
195 
196 void EDA_LIST_DIALOG::onListItemActivated( wxListEvent& event )
197 {
198  EndModal( wxID_OK );
199 }
200 
201 
202 /* Sort alphabetically, case insensitive.
203  */
204 static int wxCALLBACK myCompareFunction( wxIntPtr aItem1, wxIntPtr aItem2,
205  wxIntPtr WXUNUSED( aSortData ) )
206 {
207  wxString* component1Name = (wxString*) aItem1;
208  wxString* component2Name = (wxString*) aItem2;
209 
210  return StrNumCmp( *component1Name, *component2Name, true );
211 }
212 
213 
215 {
216  m_listBox->SortItems( myCompareFunction, 0 );
217 }
void initDialog(const wxArrayString &aItemHeaders, const wxString &aSelection)
wxString GetTextSelection(int aColumn=0)
Function GetTextSelection return the selected text from aColumn in the wxListCtrl in the dialog.
int StrNumCmp(const wxString &aString1, const wxString &aString2, bool aIgnoreCase)
Compare two strings with alphanumerical content.
Definition: string.cpp:382
void textChangeInFilterBox(wxCommandEvent &event) override
std::string m_hash_key
Definition: dialog_shim.h:198
void SetOKLabel(const wxString &aLabel)
EDA_LIST_DIALOG(EDA_DRAW_FRAME *aParent, const wxString &aTitle, const wxArrayString &aItemHeaders, const std::vector< wxArrayString > &aItemList, const wxString &aRefText)
Constructor:
void Append(const wxArrayString &aItemStr)
The base class for create windows for drawing purpose.
This file contains miscellaneous commonly used macros and functions.
static int wxCALLBACK myCompareFunction(wxIntPtr aItem1, wxIntPtr aItem2, wxIntPtr WXUNUSED(aSortData))
Helper dialog and control classes.
Class EDA_LIST_DIALOG_BASE.
const std::vector< wxArrayString > * m_itemsList
#define _(s)
Definition: 3d_actions.cpp:33
#define TO_UTF8(wxstring)
static int DEFAULT_COL_WIDTHS[]
void InsertItems(const std::vector< wxArrayString > &aItemList, int aPosition=0)
void onListItemActivated(wxListEvent &event) override
void SetListLabel(const wxString &aLabel)