KiCad PCB EDA Suite
displlst.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-2013 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 
30 #include <fctsys.h>
31 #include <macros.h>
32 #include <draw_frame.h>
33 #include <kicad_string.h>
34 #include <dialog_helpers.h>
35 
36 
37 // wxWidgets spends *far* too long calcuating column widths (most of it, believe it or
38 // not, in repeatedly creating/destroying a wxDC to do the measurement in).
39 // Use default column widths instead.
40 static int DEFAULT_COL_WIDTHS[] = { 200, 600 };
41 
42 
43 
44 EDA_LIST_DIALOG::EDA_LIST_DIALOG( EDA_DRAW_FRAME* aParent, const wxString& aTitle,
45  const wxArrayString& aItemHeaders,
46  const std::vector<wxArrayString>& aItemList,
47  const wxString& aSelection,
48  void( *aCallBackFunction )( wxString&, void* ),
49  void* aCallBackFunctionData,
50  bool aSortList, bool aShowHeaders ) :
51  EDA_LIST_DIALOG_BASE( aParent, wxID_ANY, aTitle )
52 {
53  m_sortList = aSortList;
54  m_cb_func = aCallBackFunction;
55  m_cb_data = aCallBackFunctionData;
56  m_itemsListCp = &aItemList;
57 
58  m_filterBox->SetHint( _( "Filter" ) );
59 
60  initDialog( aItemHeaders, aSelection );
61 
62  if( !aShowHeaders )
63  m_listBox->SetSingleStyle( wxLC_NO_HEADER, true );
64 
65  // DIALOG_SHIM needs a unique hash_key because classname is not sufficient
66  // because so many dialogs share this same class, with different numbers of
67  // columns, different column names, and column widths.
68  m_hash_key = TO_UTF8( aTitle );
69 
70  m_sdbSizerOK->SetDefault();
71 
72  // this line fixes an issue on Linux Ubuntu using Unity (dialog not shown),
73  // and works fine on all systems
74  GetSizer()->Fit( this );
75 
76  Centre();
77 }
78 
79 
80 void EDA_LIST_DIALOG::initDialog( const wxArrayString& aItemHeaders, const wxString& aSelection)
81 {
82  for( unsigned i = 0; i < aItemHeaders.Count(); i++ )
83  m_listBox->InsertColumn( i, aItemHeaders.Item( i ),
84  wxLIST_FORMAT_LEFT, DEFAULT_COL_WIDTHS[ i ] );
85 
87 
88  if( m_cb_func == NULL )
89  {
90  m_messages->Show( false );
91  m_staticTextMsg->Show( false );
92  }
93 
94  if( !aSelection.IsEmpty() )
95  {
96  for( unsigned row = 0; row < m_itemsListCp->size(); ++row )
97  {
98  if( (*m_itemsListCp)[row][0] == aSelection )
99  {
100  m_listBox->SetItemState( row, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED );
101 
102  // Set to a small size so EnsureVisible() won't be foiled by later additions.
103  // ListBox will expand to fit later.
104  m_listBox->SetSize( m_listBox->GetSize().GetX(), 100 );
105  m_listBox->EnsureVisible( row );
106 
107  break;
108  }
109  }
110  }
111 }
112 
113 
114 void EDA_LIST_DIALOG::SetFilterHint( const wxString& aHint )
115 {
116  m_filterBox->SetHint( aHint );
117 }
118 
119 
120 void EDA_LIST_DIALOG::SetListLabel( const wxString& aLabel )
121 {
122  m_listLabel->SetLabel( aLabel );
123 }
124 
125 
126 void EDA_LIST_DIALOG::SetOKLabel( const wxString& aLabel )
127 {
128  m_sdbSizerOK->SetLabel( aLabel );
129 }
130 
131 
132 void EDA_LIST_DIALOG::textChangeInFilterBox( wxCommandEvent& event )
133 {
134  wxString filter;
135  wxString itemName;
136 
137  filter = wxT( "*" ) + m_filterBox->GetLineText( 0 ).MakeLower() + wxT( "*" );
138 
139  m_listBox->DeleteAllItems();
140 
141  for( unsigned i = 0; i < m_itemsListCp->size(); i++ )
142  {
143  itemName = (*m_itemsListCp)[i].Item( 0 );
144 
145  if( itemName.MakeLower().Matches( filter ) )
146  {
147  Append( (*m_itemsListCp)[i] );
148  }
149  }
150 
151  if( m_sortList )
152  sortList();
153 }
154 
155 
156 wxString EDA_LIST_DIALOG::GetTextSelection( int aColumn )
157 {
158  wxCHECK_MSG( unsigned( aColumn ) < unsigned( m_listBox->GetColumnCount() ), wxEmptyString,
159  wxT( "Invalid list control column." ) );
160 
161  long item = m_listBox->GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
162 
163  if( item >= 0 ) // if something is selected.
164  {
165  wxListItem info;
166 
167  info.m_mask = wxLIST_MASK_TEXT;
168  info.m_itemId = item;
169  info.m_col = aColumn;
170 
171  if( m_listBox->GetItem( info ) )
172  return info.m_text;
173  }
174 
175  return wxEmptyString;
176 }
177 
178 
179 void EDA_LIST_DIALOG::Append( const wxArrayString& itemList )
180 {
181  long itemIndex = m_listBox->InsertItem( m_listBox->GetItemCount(), itemList[0] );
182 
183  m_listBox->SetItemPtrData( itemIndex, wxUIntPtr( &itemList[0] ) );
184 
185  // Adding the next columns content
186  for( unsigned i = 1; i < itemList.size(); i++ )
187  {
188  m_listBox->SetItem( itemIndex, i, itemList[i] );
189  }
190 }
191 
192 
193 void EDA_LIST_DIALOG::InsertItems( const std::vector< wxArrayString >& itemList, int position )
194 {
195  for( unsigned row = 0; row < itemList.size(); row++ )
196  {
197  wxASSERT( (int) itemList[row].GetCount() == m_listBox->GetColumnCount() );
198 
199  for( unsigned col = 0; col < itemList[row].GetCount(); col++ )
200  {
201  wxListItem info;
202  info.m_itemId = row + position;
203  info.m_col = col;
204  info.m_text = itemList[row].Item( col );
205  info.m_width = DEFAULT_COL_WIDTHS[ col ];
206  info.m_mask = wxLIST_MASK_TEXT | wxLIST_MASK_WIDTH;
207 
208  if( col == 0 )
209  {
210  info.m_data = wxUIntPtr( &itemList[row].Item( col ) );
211  info.m_mask |= wxLIST_MASK_DATA;
212 
213  m_listBox->InsertItem( info );
214  }
215  else
216  {
217  m_listBox->SetItem( info );
218  }
219  }
220  }
221 
222  if( m_sortList )
223  sortList();
224 }
225 
226 
227 void EDA_LIST_DIALOG::onListItemSelected( wxListEvent& event )
228 {
229  if( m_cb_func )
230  {
231  m_messages->Clear();
232  wxString text = GetTextSelection();
233  m_cb_func( text, m_cb_data );
234  m_messages->WriteText( text );
235  }
236 }
237 
238 
239 void EDA_LIST_DIALOG::onListItemActivated( wxListEvent& event )
240 {
241  EndModal( wxID_OK );
242 }
243 
244 
245 /* Sort alphabetically, case insensitive.
246  */
247 static int wxCALLBACK myCompareFunction( wxIntPtr aItem1, wxIntPtr aItem2,
248  wxIntPtr WXUNUSED( aSortData ) )
249 {
250  wxString* component1Name = (wxString*) aItem1;
251  wxString* component2Name = (wxString*) aItem2;
252 
253  return StrNumCmp( *component1Name, *component2Name, INT_MAX, true );
254 }
255 
256 
258 {
259  m_listBox->SortItems( myCompareFunction, 0 );
260 }
void initDialog(const wxArrayString &aItemHeaders, const wxString &aSelection)
Definition: displlst.cpp:80
wxString GetTextSelection(int aColumn=0)
Function GetTextSelection return the selected text from aColumn in the wxListCtrl in the dialog...
Definition: displlst.cpp:156
static int DEFAULT_COL_WIDTHS[]
Definition: displlst.cpp:40
void textChangeInFilterBox(wxCommandEvent &event) override
Definition: displlst.cpp:132
std::string m_hash_key
Definition: dialog_shim.h:144
void SetOKLabel(const wxString &aLabel)
Definition: displlst.cpp:126
void Append(const wxArrayString &aItemStr)
Definition: displlst.cpp:179
const std::vector< wxArrayString > * m_itemsListCp
The base class for create windows for drawing purpose.
Definition: draw_frame.h:78
static int wxCALLBACK myCompareFunction(wxIntPtr aItem1, wxIntPtr aItem2, wxIntPtr WXUNUSED(aSortData))
Definition: displlst.cpp:247
This file contains miscellaneous commonly used macros and functions.
EDA_LIST_DIALOG(EDA_DRAW_FRAME *aParent, const wxString &aTitle, const wxArrayString &aItemHeaders, const std::vector< wxArrayString > &aItemList, const wxString &aRefText, void(*aCallBackFunction)(wxString &text, void *data)=NULL, void *aCallBackFunctionData=NULL, bool aSortList=false, bool aShowHeaders=true)
Constructor:
Definition: displlst.cpp:44
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes...
Definition: macros.h:47
Helper dialog and control classes.
Class EDA_LIST_DIALOG_BASE.
void onListItemSelected(wxListEvent &event) override
Definition: displlst.cpp:227
void SetFilterHint(const wxString &aHint)
Definition: displlst.cpp:114
size_t i
Definition: json11.cpp:597
int StrNumCmp(const wxString &aString1, const wxString &aString2, int aLength, bool aIgnoreCase)
Function StrNumCmp is a routine compatible with qsort() to sort by alphabetical order.
Definition: string.cpp:315
void InsertItems(const std::vector< wxArrayString > &aItemList, int aPosition=0)
Definition: displlst.cpp:193
void(* m_cb_func)(wxString &text, void *data)
void onListItemActivated(wxListEvent &event) override
Definition: displlst.cpp:239
void SetListLabel(const wxString &aLabel)
Definition: displlst.cpp:120